Tristate - wanna?

Timon Gehr timon.gehr at gmx.ch
Sat Oct 26 17:13:59 PDT 2013


On 10/26/2013 11:06 PM, Andrei Alexandrescu wrote:
> On 10/26/13 12:17 PM, Walter Bright wrote:
>> On 10/26/2013 8:42 AM, Andrei Alexandrescu wrote:
>>> While messing with std.allocator I explored the type below. I ended up
>>> not using
>>> it, but was surprised that implementing it was quite nontrivial.
>>> Should we add
>>> it to stdlib?
>>>
>>> Theory: http://en.wikipedia.org/wiki/Three-state_logic
>>
>> When I worked on the ABEL programming language, which was for designing
>> programmable logic devices, we found it useful to have an additional
>> state, "don't care".
>
> Yah, that would be four-valued logic:
> http://en.wikipedia.org/wiki/Four-valued_logic.
>
> One challenge in Tristate (or the as-of-yet-unwritten Fourstate) is to
> define the primitives |, &, ^, and ~ with minimum of operations. For
> example Tristate still has conditionals in two of them, which I think
> could be cleverly avoided.
>
>
> Andrei
>
>

The following implementation does not use conditionals; probably not 
minimal.

struct Tristate{
     private ubyte value;
     private static Tristate make(ubyte b){
         Tristate r = void;
         r.value = b;
         return r;
     }

     enum no = make(0), yes = make(2), unknown = make(6);

     this(bool b) { value = b; }

     void opAssign(bool b) { value = b; }

     Tristate opUnary(string s)() if (s == "~"){
         return make((193>>value&3)<<1);
     }

     Tristate opBinary(string s)(Tristate rhs) if (s == "|"){
         return make((12756>>(value+rhs.value)&3)<<1);
     }

     Tristate opBinary(string s)(Tristate rhs) if (s == "&"){
         return make((13072>>(value+rhs.value)&3)<<1);
     }

     Tristate opBinary(string s)(Tristate rhs) if (s == "^"){
         return make((13252>>(value+rhs.value)&3)<<1);
     }
}

unittest{
     with(Tristate){
         assert(~no==yes&&~yes==no&&~unknown==unknown);

         assert((no|no)==no&&(no|yes)==yes&&(yes|no)==yes&&(yes|yes)==yes&&
                (no|unknown)==unknown&&(yes|unknown)==yes &&
 
(unknown|no)==unknown&&(unknown|yes)==yes&&(unknown|unknown)==unknown);

         assert((no&no)==no&&(no&yes)==no&&(yes&no)==no&&(yes&yes)==yes&&
                (no&unknown)==no&&(yes&unknown)==unknown&&
 
(unknown&no)==no&&(unknown&yes)==unknown&&(unknown&unknown)==unknown);

         assert((no^no)==no&&(no^yes)==yes&&(yes^no)==yes&&(yes^yes)==no&&
                (no^unknown)==unknown&&(yes^unknown)==unknown&&
 
(unknown^no)==unknown&&(unknown^yes)==unknown&&(unknown^unknown)==unknown);
     }
}




More information about the Digitalmars-d mailing list