Set Implicit Arguments.
Unset Strict Implicit.
Set Primitive Projections.
Set Maximal Implicit Insertion.
Set Universe Polymorphism.
Class ValNull (val : Type) := {
null : val
}.
Section Defs.
Context {A val : Type}.
Context {HA : RelDec (@eq A)} {HR : RelDec_Correct HA}.
Context {VNB : ValNull val}.
Definition stack := A -> val.
Definition stack_empty : stack := fun x => null.
Definition stack_get (x : A) : stack -> val  := fun s => s x.
Definition stack_add x v s : stack :=
fun x' => if x' ?[ eq ] x then v else s x'.

(* Specifications: *)
Lemma stack_lookup_add (s : stack) (x : A) (v : val) :
((stack_add x v s) : stack) x = v.
Lemma stack_lookup_add2 (x y : A) (v : val) (s : stack) (Hneq: x <> y) :
(stack_add x v s) y = s y.
Lemma stack_add_same (s: stack) x:
stack_add x (s x) s = s.
Lemma stack_add_overwrite (s: stack) x v v':
stack_add x v (stack_add x v' s) = stack_add x v s.
Lemma stack_add_val_eq (s : stack) (x : A) v1 v2 (Hs : stack_add x v1 s = stack_add x v2 s) :
v1 = v2.