(* * Copyright (c) 2009-2010, Andrew Appel, Robert Dockins and Aquinas Hobor. * *)
(* This file defines a series of lemmas for proving functions from the carrier set of one SA to the carrier set of another are join homomorphisms, and then shows that some simple properties of SA elems, like identity, comparability, etc., are preserved by join homs.  The idea is due to Rob. *)
(* Two-argument join homomorphisms *)
Section join_hom2.
Variables (A B C: Type)
(JA: Join A)
(JB: Join B)
(JC: Join C)
(f: A -> B -> C).
Definition join_hom2 := forall (a1 a2 a3: A)(b1 b2 b3: B),
join a1 a2 a3
-> join b1 b2 b3
-> join (f a1 b1) (f a2 b2) (f a3 b3).
(* Two-argument join homomorphisms with a dummy argument *)
Definition join_hom2' := forall (a1 a2 a3: A)(b1 b2 b3: B),
join a1 a2 a3
-> join (f a1 b1) (f a2 b2) (f a3 b3).
End join_hom2.
Arguments join_hom2 [A B C JA JB JC] _.
Arguments join_hom2' [A B C JA] _ _.

(* Specifications: *)
(* [id] is join hom *)
Lemma join_hom_id (A: Type) (JA: Join A) : join_hom (fun x => x).
Lemma join_hom_prodA'
: forall e: B, join e e e -> join_hom (fun a :A'  => (a, e)).
(* The function from [b] to [(e, b')] *)
Lemma join_hom_prodB
: forall e: A', join e e e -> join_hom (fun b: B => (e, g b)).
Lemma join_hom_prodB'
: forall e: A, join e e e -> join_hom (fun b : B' => (e, b)).
(* Projections are join hom. *)
Lemma join_hom_proj1
: join_hom (fun p: A*B => fst p).
Lemma join_hom_sum_l
: join_hom (fun s: A+B =>
match s with
| inl x => inl _ (f x)
| inr y => inr _ y
end).
Lemma join_hom_sum_r
: join_hom (fun s: A+B =>
match s with
| inl x => inl _ x
| inr y => inr _ (g y)
end).
Lemma join_hom_inj_l
: join_hom (fun a : A=> inl Void (f a)).
Lemma join_hom2_list_cons
: join_hom2 (fun a l => a :: l).