End LPMap1.
(** Given a semi-lattice with top [L], the following functor implements a semi-lattice-with-top structure over finite maps from positive numbers to [L.t]. The default value for these maps is [L.top].  Bottom elements are smashed. *)
Module LPMap(L: SEMILATTICE_WITH_TOP) <: SEMILATTICE_WITH_TOP.
Inductive t' : Type :=
| Bot: t'
| Top_except: PTree.t L.t -> t'.
Definition t: Type := t'.
Definition get (p: positive) (x: t) : L.t :=
match x with
| Bot => L.bot
| Top_except m => match m!p with None => L.top | Some x => x end
end.
Definition set (p: positive) (v: L.t) (x: t) : t :=
match x with
| Bot => Bot
| Top_except m =>
if L.beq v L.bot
then Bot
else Top_except (if L.beq v L.top then PTree.remove p m else PTree.set p v m)
end.

Lemma gsspec:
forall p v x q,
x <> Bot -> ~L.eq v L.bot ->
L.eq (get q (set p v x)) (if peq q p then v else get q x).