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