Load loadpath.
Permutation Coq.MSets.MSetAVL.
veristar.compare veristar.redblack.
(** The clause datatype and related definitions and lemmas *)
(** pure_atom: pure atoms *)
Inductive pure_atom := Eqv : expr -> expr -> pure_atom.
Let var1 : var := Z2id 1.
Let var0 : var := Z2id 0.
Let var2 : var := Z2id 2.
Fixpoint list_prio {A} (weight: var) (l: list A) (p: var) : var :=
match l with
| nil => p
| _::l' => list_prio weight l' (add_id weight p)
end.
(** Weight the positive atoms 1 each, and the negative atoms 2 each. Then the highest-priority terms will be the positive unit clauses *)
Definition prio (gamma delta: list pure_atom) : var :=
list_prio var2 gamma (list_prio var1 delta var0).
(** clause: clauses are either pure (no spatial atoms), negative spatial (spatial atom on the left) or positive spatial. *)
Inductive clause : Type :=
| PureClause : forall (gamma : list pure_atom) (delta : list pure_atom)
(priority : var)
(prio_ok: prio gamma delta = priority), clause
| PosSpaceClause : forall (gamma : list pure_atom) (delta : list pure_atom)
(sigma : list space_atom), clause
| NegSpaceClause : forall (gamma : list pure_atom) (sigma : list space_atom)
(delta : list pure_atom), clause.
Definition expr_cmp e e' :=
match e, e' with
| Nil , Nil => Eq
| Nil, _ => Lt
| _, Nil => Gt
| Var v, Var v' => Ident.compare v v'
end.
Hint Resolve expr_cspec.
Definition pure_atom_cmp (a a': pure_atom) : comparison :=
match a, a' with
| Eqv e1 e2, Eqv e1' e2' =>
match expr_cmp e1 e1' with
Eq => expr_cmp e2 e2' | c => c
end
end.
Hint Rewrite @comp_refl using solve[auto] : comp.
Ltac comp_tac :=
progress (autorewrite with comp in *; auto)
|| discriminate
|| solve [eapply comp_trans;  eauto]
|| subst
|| match goal with
| H: Lt = ?A |- context [?A] => rewrite <- H
| H: Gt = ?A |- context [?A] => rewrite <- H
| H: Eq = ?A |- context [?A] => rewrite <- H
end.

Lemma pure_atom_cspec: CompSpec' pure_atom_cmp.