(** * Lattice for dataflow analysis *)
Module VA <: SEMILATTICE.
Inductive t' := Bot | State (ae: aenv) (am: amem).
Definition t := t'.
Definition eq (x y: t) :=
match x, y with
| Bot, Bot => True
| State ae1 am1, State ae2 am2 =>
AE.eq ae1 ae2 /\ forall bc m, mmatch bc m am1 <-> mmatch bc m am2
| _, _ => False
end.

(* Specifications: *)
Lemma eq_refl: forall x, eq x x.
Lemma eq_sym: forall x y, eq x y -> eq y x.
Lemma eq_trans: forall x y z, eq x y -> eq y z -> eq x z.
Definition beq (x y: t) : bool :=
match x, y with
| Bot, Bot => true
| State ae1 am1, State ae2 am2 => AE.beq ae1 ae2 && mbeq am1 am2
| _, _ => false
end.
Lemma beq_correct: forall x y, beq x y = true -> eq x y.
Definition ge (x y: t) : Prop :=
match x, y with
| _, Bot => True
| Bot, _ => False
| State ae1 am1, State ae2 am2 => AE.ge ae1 ae2 /\ forall bc m, mmatch bc m am2 -> mmatch bc m am1
end.
Lemma ge_refl: forall x y, eq x y -> ge x y.
Lemma ge_trans: forall x y z, ge x y -> ge y z -> ge x z.
Definition bot : t := Bot.
Lemma ge_bot: forall x, ge x bot.
Definition lub (x y: t) : t :=
match x, y with
| Bot, _ => y
| _, Bot => x
| State ae1 am1, State ae2 am2 => State (AE.lub ae1 ae2) (mlub am1 am2)
end.
Lemma ge_lub_left: forall x y, ge (lub x y) x.
Lemma ge_lub_right: forall x y, ge (lub x y) y.
End VA.