Load loadpath.
(* make sure to fix loadpath to point to Ssreflect theories *)
fintype finfun finset fingraph path.
(* as well as AF libraries on your machine *)
Set Implicit Arguments.
Unset Strict Implicit.
Module TRANS.
Record Sig
(clause: finType) (* clause is some finite type *)
(entails: {set clause} -> clause -> bool) (* clauseset s entails clause c *)
(redund: {set clause} -> clause -> bool) (* clause c is redundant in s *)
: Type := Make {
(* entailment is closed under set union *)
entailsU: forall (c: clause) (s1 s2: {set clause}),
entails s1 c -> entails (s1 :|: s2) c;
(* redundancy is closed under set union *)
redundU: forall (c: clause) (s1 s2: {set clause}),
redund s1 c -> redund (s1 :|: s2) c;
(* a clause can't contribute to its own redundancy *)
redundU2: forall (c: clause) (s: {set clause}),
redund (c |: s) c -> redund s c;
(* when redundant clause c2 is removed, c remains redundant -- this axiom encodes a sort of transitivity condition on the redundancy criteria *)
redundD: forall (c c2: clause) (s: {set clause}),
redund s c -> redund s c2 -> redund (s :\ c2) c
}.
End TRANS.
(* here we prove that the following transition relation terminates: 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]. *)
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).

Lemma deriv0 (s: clauseset) : deriv s s.
Definition closed {T: finType} (e: rel T) (a: pred T) :=
forall x y : T, e x y -> a x -> a y.