Module LEq <: SEMILATTICE.
Definition t := res eqs.
Definition eq (x y: t) :=
match x, y with
| OK a, OK b => EqSet.Equal a b
| Error _, Error _ => True
| _, _ => False
end.
Definition beq (x y: t) :=
match x, y with
| OK a, OK b => EqSet.equal a b
| Error _, Error _ => true
| _, _ => false
end.
Definition ge (x y: t) :=
match x, y with
| OK a, OK b => EqSet.Subset b a
| Error _, _ => True
| _, Error _ => False
end.
Definition bot: t := OK empty_eqs.
Program Definition lub (x y: t) : t :=
match x, y return _ with
| OK a, OK b =>
OK (mkeqs (EqSet.union (eqs1 a) (eqs1 b))
(EqSet2.union (eqs2 a) (eqs2 b)) _)
| OK _, Error _ => y
| Error _, _ => x
end.
Next Obligation.
split; intros.
apply EqSet2.union_1 in H. destruct H; rewrite eqs_same in H.
apply EqSet.union_2; auto. apply EqSet.union_3; auto.
apply EqSet.union_1 in H. destruct H; rewrite <- eqs_same in H.
apply EqSet2.union_2; auto. apply EqSet2.union_3; auto.
Qed.

Lemma ge_lub_left: forall x y, ge (lub x y) x.