Module Terminate. Section Terminate.
Variable (clause: finType)
(entails: {set clause} -> clause -> bool)
(redund: {set clause} -> clause -> bool)
(Trans: TRANS.Sig entails redund).
Notation redundU := (TRANS.redundU Trans).
Notation redundU2 := (TRANS.redundU2 Trans).
Notation redundD := (TRANS.redundD Trans).
(*Notation clauseset := ({set clause}).*)
Definition clauseset := set_finType clause.
(* set of clauses addable to s *)
Definition add (s: clauseset) : clauseset :=
[set c | [&& ~~redund s c &
[exists s0: clauseset, [&& s0 \subset s & entails s0 c]]]].
(* set of clauses removable from s *)
Definition rem (s: clauseset) : clauseset := [set c | redund s c].
(* the transition relation, expressed as a function to bool *)
Definition trans (s s': clauseset) :=
[exists c: clause,
if [&& c \in add s & c \notin s] then s' == c |: s
else if [&& c \in rem s & c \in s] then s' == s :\ c
else false].
(* a derivation is the graph induced by the refl. transitive closure of trans *)
Notation deriv := (connect trans).
(* predicate a is closed under "edge" relation e *)
Definition closed {T: finType} (e: rel T) (a: pred T) :=
forall x y : T, e x y -> a x -> a y.
Definition removed (c: clause) {s s'': clauseset} (step: trans s s'') :=
(c \in s) && (c \notin s'').
Definition added (c: clause) {s s'': clauseset} (step: trans s s'') :=
(c \notin s) && (c \in s'').
Definition adds (c: clause) (s s': clauseset) (trace: deriv s s') :=
[&& c \notin s & c \in s'].
Definition removes (c: clause) (s s': clauseset) (trace: deriv s s') :=
[&& c \in s & c \notin s'].
(* here's a different characterization based on sequences of states *)
(* "path trans s p" means the sequence (s :: p) defines a graph with edges related by trans.  uniq is pairwise difference. *)
(* now we prove that equality on clausesets is AF *)
(* cs2id: an injection from clausesets to values of type Finite #|clauseset|. enum_rank produces a value of type 'I_(#|clauseset|), where 'I_n is the type of ordinals < n. *)
Program Definition cs2id (s: clauseset) : Finite #|clauseset| :=
@FinIntro #|clauseset| (enum_rank s) _.
Next Obligation. by apply: (ltP (ltn_ord (enum_rank s))). Qed.
move: (af_cofmap cs2id (af_finite #|clauseset|)).
rewrite/almost_full; move=> [p] H1; exists p.
apply: (@sec_strengthen _ _ (fun x y => eq_fin (cs2id x) (cs2id y)))=> // x y.
rewrite/cs2id=> /=; case=> H2; apply/eqP.
by apply: enum_rank_inj; apply: (ord_inj H2).
Qed.

Lemma clos_trans_1n_deriv_plus (s1 s2: clauseset) :
Relation_Operators.clos_trans_1n clauseset
(fun s s' : clauseset => trans s s') s1 s2 ->
deriv_plus s1 s2.