#line 8 "/home/travis/build/felix-lang/felix/src/packages/logic.fdoc"
  typedef bool = 2;
  
  Standard operations on boolean type.
  open class Bool
  {
    Short cut and via closure
    noinline fun andthen (x: bool, y:1->bool) : bool =>
      if x then #y else false
    ;
  
    Disjunction: logical and.
    fun land: bool * bool -> bool = "$1&&$2";      // x and y
  
    Negated and.
    fun nand: bool * bool -> bool = "!($1&&$2)";   // not (x and y)
  
    Conjunction: logical or.
    fun lor: bool * bool -> bool = "$1||$2";       // x or y
  
    Negated or.
    fun nor: bool * bool -> bool = "!($1||$2)";    // not (x or y)
  
    Logical exclusive or.
    fun xor: bool * bool -> bool = "$1!=$2";       // (x or y) and not (x and y)
  
    Logical negation.
    fun lnot: bool -> bool = "!$1";                // not x
  
    Logical implication.
    fun implies: bool * bool -> bool = "!$1||$2";  // not x or y
  
    Mutating or.
    proc |= : &bool * bool = "*$1|=$2;";
  
    Mutating and.
    proc &= : &bool * bool = "*$1&=$2;";
  
    // Elide double negations.
    reduce dneg(x:bool): lnot (lnot x) => x;
  
    // Elide double negations.
    reduce dneg(x:bool,y:bool): lnot (nand(x,y)) => land(x,y);
  
    // Elide double negations.
    reduce dneg(x:bool,y:bool): lnot (nor(x,y)) => lor(x,y);
  }
  
  instance FloatAddgrp[2] {
    fun zero () => 0 :>> 2;
    fun - (x:2) => (sub (2, caseno x)) :>> 2;
    fun + (x:2, y:2) : 2 => (add ((caseno x , caseno y)) % 2) :>> 2;
    fun - (x:2, y:2) : 2 => (add (2, sub(caseno x , caseno y)) % 2) :>> 2;
  }
  
  instance Str[bool] {
    Convert bool to string.
    fun str (b:bool) : string => if b then "true" else "false" endif;
  }
  
  instance Tord[bool] {
    Total ordering of bools, false < true.
    Note that x < y is equivalent to x implies y.
    fun < : bool * bool -> bool = "$1<$2";
  }
  
  open Tord[bool];
  open Show[bool];
  open Addgrp[bool];