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);
    }
}


Reply via email to