(** The trivial separation algebra over the unit type.  This SA
    is the identity of the product SA operator, up to isomorphism.
*)

  Instance Join_unit : Join unit := fun x y z => True.Instance Perm_unit : Perm_alg unit.Instance Sep_unit: Sep_alg unit.Instance Sing_unit: Sing_alg unit.Instance Canc_unit: Canc_alg unit.Instance Disj_unit: Disj_alg unit.Instance Cross_unit: Cross_alg unit.(** The trivial separation algebra over the void type. This SA
    is the identity of the coproduct (disjoint sum) SA operator, up to isomorphism.
*)

  Inductive Void : Type :=.Instance Join_void : Join Void := fun x y z => False.Instance Perm_void : Perm_alg Void.Instance Sep_void: Sep_alg Void.Instance Canc_void: Canc_alg Void.Instance Disj_void: Disj_alg Void.Instance Cross_void: Cross_alg Void.(** The separation algebra over booleans, e.g. Z/2 with bounded addition *)

  Inductive join_bool : bool -> bool -> bool -> Prop :=
  | jb_fff: join_bool false false false
  | jb_tft: join_bool true false true
  | jb_ftt: join_bool false true true.(** The separation algebra over booleans, e.g. Z/2 with bounded addition *)

  Inductive join_bool : bool -> bool -> bool -> Prop :=
  | jb_fff: join_bool false false false
  | jb_tft: join_bool true false true
  | jb_ftt: join_bool false true true.(** The separation algebra over booleans, e.g. Z/2 with bounded addition *)

  Inductive join_bool : bool -> bool -> bool -> Prop :=
  | jb_fff: join_bool false false false
  | jb_tft: join_bool true false true
  | jb_ftt: join_bool false true true.(** The separation algebra over booleans, e.g. Z/2 with bounded addition *)

  Inductive join_bool : bool -> bool -> bool -> Prop :=
  | jb_fff: join_bool false false false
  | jb_tft: join_bool true false true
  | jb_ftt: join_bool false true true.Instance Join_bool : Join bool := join_bool.Instance Perm_bool: Perm_alg bool.Instance Sep_bool: Sep_alg bool.Instance Sing_bool: Sing_alg bool.Instance Canc_bool: Canc_alg bool.Instance Disj_bool: Disj_alg bool.Instance Cross_bool: Cross_alg bool.(** The "equivalance" or discrete SA.  In this SA, every element of an arbitrary
    set is made an idempotent element.  We do not add this as a global
    Instance, because it is too widely applicable in cases where we do not
    desire it.
*)

  Instance Join_equiv (A: Type) : Join A := fun x y z => x=y/\y=z.Instance Perm_equiv (A: Type) :  @Perm_alg A (Join_equiv A).Instance Sep_equiv (A: Type): Sep_alg A.Instance Canc_equiv (A: Type): Canc_alg A.Instance Disj_equiv (A: Type): Disj_alg A.Instance Cross_equiv (A: Type): Cross_alg A.

(* Specifications: *)
Lemma join_equiv_refl: forall A (v: A), @join A (Join_equiv A) v v v.