ICL.ctab
Require Export PropL.
Implicit Types x y z : var.
Implicit Types s t : form.
Implicit Types alpha beta : assn.
Implicit Types A B : context.
Implicit Types m n k : nat.
Implicit Types x y z : var.
Implicit Types s t : form.
Implicit Types alpha beta : assn.
Implicit Types A B : context.
Implicit Types m n k : nat.
Fixpoint eval alpha s : bool :=
match s with
| Var x => alpha x
| Imp s t => if eval alpha s then eval alpha t else true
| Fal => false
end.
Fixpoint satis alpha s : Prop :=
match s with
| Var x => if alpha x then True else False
| Imp s1 s2 => satis alpha s1 -> satis alpha s2
| Fal => False
end.
Lemma satis_eval alpha s :
satis alpha s <-> eval alpha s = true.
Proof.
induction s as [x|s1 IH1 s2 IH2|]; simpl.
- destruct (alpha x); intuition.
- destruct (eval alpha s1); intuition.
- intuition.
Qed.
Instance satis_dec alpha s : dec (satis alpha s).
Proof.
eapply dec_prop_iff.
- symmetry. apply satis_eval.
- auto.
Qed.
Lemma satis_pos_imp alpha s t :
satis alpha (Imp s t) <-> ~ satis alpha s \/ satis alpha t.
Proof.
simpl. decide (satis alpha s) ; tauto.
Qed.
Lemma satis_neg_imp alpha s t :
~ satis alpha (Imp s t) <-> satis alpha s /\ ~ satis alpha t.
Proof.
simpl. decide (satis alpha s) ; tauto.
Qed.
Definition valid s : Prop :=
forall alpha, satis alpha s.
Lemma valid_unsat s :
valid s <-> ~ exists alpha, satis alpha (Not s).
Proof.
rewrite DM_exists.
split.
- intros F alpha G. apply G, F.
- intros F alpha. apply dec_DN; auto. apply F.
Qed.
Definition bent A s : Prop :=
forall alpha, (forall t, t el A -> satis alpha t) -> satis alpha s.
Lemma ndc_bent A s :
ndc A s -> bent A s.
Proof.
intros E alpha F.
induction E as [A s E|A s t _ IH|A s t _ IHs _ IHt|A s _ IH] ; simpl in *.
- apply F, E.
- intros G. apply IH. intros u [[]|H]; auto.
- apply (IHs F), (IHt F).
- decide (satis alpha s) as [G|G]. exact G.
exfalso ; apply IH. intros t [[]|H]; auto.
Qed.
Inductive sform : Type :=
| Pos : form -> sform
| Neg : form -> sform.
Definition clause := list sform.
Notation "+ s" := (Pos s) (at level 35).
Notation "- s" := (Neg s).
Implicit Types S T : sform.
Implicit Types C D : clause.
Instance sform_eq_dec S T : dec (S = T).
Proof.
unfold dec. repeat decide equality.
Qed.
Definition uns S : form :=
match S with +s => s | -s => Not s end.
Fixpoint satis' alpha C : Prop :=
match C with
| nil => True
| T::C' => satis alpha (uns T) /\ satis' alpha C'
end.
Definition sat C := exists alpha, satis' alpha C.
Lemma satis_iff alpha C :
satis' alpha C <-> forall S, S el C -> satis alpha (uns S).
Proof.
induction C; simpl; intuition; subst; auto.
Qed.
Lemma satis_in alpha C S :
satis' alpha C -> S el C -> satis alpha (uns S).
Proof.
intros E. apply satis_iff, E.
Qed.
Lemma satis_weak alpha C C' :
C <<= C' -> satis' alpha C' -> satis' alpha C.
Proof.
rewrite !satis_iff. auto.
Qed.
Lemma sat_weak C C' :
C <<= C' -> sat C' -> sat C.
Proof.
intros E [alpha F]. exists alpha. eauto using satis_weak.
Qed.
Entailment of clauses
Definition cent C D : Prop :=
forall alpha, satis' alpha C -> satis' alpha D.
Lemma cent_weak C D D' :
D <<= D' -> cent C D' -> cent C D.
Proof.
intros F G alpha K. apply (satis_weak F),G, K.
Qed.
Lemma cent_sat C D :
cent C D -> sat C -> sat D.
Proof.
intros F [alpha G]. exists alpha. apply F, G.
Qed.
Definition svar S : Prop :=
match S with
| +Var _ | -Var _ => True
| _ => False
end.
Definition solved C : Prop :=
(forall S, S el C -> svar S) /\ forall x, +Var x el C -> ~ -Var x el C.
Definition phi C x := if decision (+Var x el C) then true else false.
Lemma solved_phi C :
solved C -> satis' (phi C) C.
Proof.
intros [F G]. apply satis_iff.
intros S K. assert (L := F S K).
destruct S as [[x| |]|[x| |]];
inv L; simpl; unfold phi;
decide (+Var x el C) as [L|L]; auto.
apply G in L. auto.
Qed.
Lemma solved_sat C :
solved C -> sat C.
Proof.
intros F. exists (phi C). apply solved_phi, F.
Qed.
Lemma solved_nil :
solved nil.
Proof.
firstorder.
Qed.
Lemma solved_pos_var x C :
solved C -> ~ -Var x el C -> solved (+Var x :: C).
Proof.
intros F G. split.
- intros S [K|K].
+ subst S. simpl; auto.
+ apply F, K.
- intros y [K|K] [L|L]; try inv K; try inv L; auto.
eapply F; eauto.
Qed.
Lemma solved_neg_var x C :
solved C -> ~ +Var x el C -> solved (-Var x :: C).
Proof.
intros F G. split.
- intros S [K|K].
+ subst S. simpl; auto.
+ apply F, K.
- intros y [K|K] [L|L]; try inv K; try inv L; auto.
eapply F; eauto.
Qed.
Lemma cent_solved_sat C D :
cent C D -> solved C -> sat D.
Proof.
intros G F. apply (cent_sat G), solved_sat, F.
Qed.
Record ref_pred (rho : clause -> Prop) :=
{ ref_Fal : forall C, +Fal el C -> rho C;
ref_weak : forall C C', C <<= C' -> rho C -> rho C';
ref_clash : forall x C, +Var x el C -> -Var x el C -> rho C;
ref_pos_imp : forall s t C, rho (-s::C) -> rho (+t::C) -> rho (+Imp s t::C);
ref_neg_imp : forall s t C, rho (+s::-t::C) -> rho (-Imp s t::C);
ref_sound : forall C, rho C -> ~ sat C }.
Lemma ref_unsat :
ref_pred (fun C => ~ sat C).
Proof.
split.
- intros C E [alpha F]. apply (satis_in F E).
- intros C C' A E F. apply E. revert A F. apply sat_weak.
- intros s C A B [alpha E]. apply (satis_in E B), (satis_in E A).
- intros s t C A B [alpha [E F]]. apply satis_pos_imp in E as [E|E].
+ apply A. exists alpha. simpl. auto.
+ apply B. exists alpha. simpl. auto.
- intros s t C A [alpha [E F]]. apply A. exists alpha. simpl in *.
apply satis_neg_imp in E as [E G]. auto.
- auto.
Qed.
Lemma ref_ndc :
ref_pred (fun C => ndc (map uns C) Fal).
Proof.
split; simpl.
- intros C A. apply ndcA. exact (in_map uns _ _ A).
- intros C C' A. apply ndc_weak. apply incl_map, A.
- intros x C A B. apply ndcIE with (s:=Var x) ; apply ndcA.
+ exact (in_map uns _ _ B).
+ exact (in_map uns _ _ A).
- intros s t C A B. apply ndcIE with (s:= Not s).
+ apply ndcW, ndcII, A.
+ apply ndcII. apply ndcIE with (s:=t).
* apply ndcW, ndcW, ndcII, B.
* apply ndcIE with (s:=s) ; apply ndcA ; auto.
- intros s t C A. apply ndcIE with (s:= Imp s t).
+ apply ndcA ; auto.
+ apply ndcII, ndcE. apply ndcIE with (s:= Not t).
* { apply ndcIE with (s:= s).
- apply ndcW, ndcW, ndcII, ndcII. revert A. apply ndc_weak. firstorder.
- apply ndcA ; auto. }
* { apply ndcII. apply ndcIE with (s:= Imp s t).
- apply ndcA ; auto.
- apply ndcII, ndcA ; auto. }
- intros C F [alpha G].
apply ndc_bent in F. apply (F alpha).
intros t K.
apply in_map_iff in K as [[u|u] [K1 K2]];
subst t; revert K2; apply satis_in, G.
Qed.
Inductive rec C : clause -> Type :=
| recNil : rec C nil
| recPF D : rec C (+Fal :: D)
| recNF D : rec C D -> rec C (-Fal ::D)
| recPV D x : -Var x el C -> rec C (+Var x :: D)
| recPV' D x : ~ -Var x el C -> rec (+Var x :: C) D -> rec C (+Var x :: D)
| recNV D x : +Var x el C -> rec C (-Var x :: D)
| recNV' D x : ~ +Var x el C -> rec (-Var x :: C) D -> rec C (-Var x :: D)
| recPI D s t : rec C (-s :: D) -> rec C (+t :: D) -> rec C (+Imp s t :: D)
| recNI D s t : rec C (+s :: -t :: D) -> rec C (-Imp s t :: D).
Fixpoint sizeF s : nat :=
match s with
| Imp s1 s2 => 1 + sizeF s1 + sizeF s2
| _ => 1
end.
Fixpoint size C : nat :=
match C with
| nil => 0
| +s::C' => sizeF s + size C'
| -s::C' => sizeF s + size C'
end.
Definition provider C D : rec C D.
Proof.
revert D C.
refine (size_recursion size _).
intros [|[[x|s t|]|[x|s t|]] D] IH C.
- constructor.
- decide (-Var x el C) as [E|E].
+ apply (recPV _ E).
+ apply (recPV' E). apply IH. simpl ; omega.
- constructor ; apply IH ; simpl ; omega.
- constructor ; apply IH ; simpl ; omega.
- decide (+Var x el C) as [E|E].
+ apply (recNV _ E).
+ apply (recNV' E). apply IH. simpl ; omega.
- constructor ; apply IH ; simpl ; omega.
- constructor ; apply IH ; simpl ; omega.
Qed.
Section RL.
Variable rho : clause -> Prop.
Variable Rho : ref_pred rho.
Definition decider C D :
rec C D -> solved C ->
{E | solved E /\ cent E (D ++ C)} + {rho (D ++ C)}.
Proof.
intros F G.
induction F as [C|C D|C D _ IH|C D x F|C D x F _ IH|C D x F|C D x F _ IH|
C D s t _ IHs _ IHt|C D s t _ IH] ; simpl.
- left. exists C. firstorder.
- right. apply ref_Fal; auto.
- destruct (IH G) as [[E [F1 F2]]|F].
+ left. exists E. split. exact F1.
revert F2. unfold cent. simpl. auto.
+ right. revert F. apply ref_weak; auto.
- right. apply ref_clash with (x:=x); auto.
- destruct IH as [[E [K1 K2]]|K].
+ apply solved_pos_var; auto.
+ left. exists E. split. exact K1.
revert K2. apply cent_weak; auto.
+ right. revert K. apply ref_weak; auto.
- right. apply ref_clash with (x:=x); auto.
- destruct IH as [[E [K1 K2]]|K].
+ apply solved_neg_var; auto.
+ left. exists E. split. exact K1.
revert K2. apply cent_weak; auto.
+ right. revert K. apply ref_weak; auto.
- destruct (IHs G) as [[E [K1 K2]]|K].
+ left. exists E. split. exact K1.
intros alpha L. apply K2 in L. simpl in *; tauto.
+ destruct (IHt G) as [[E [L1 L2]]|L].
* left. exists E. split. exact L1.
intros alpha L. apply L2 in L. simpl in *; tauto.
* right. apply ref_pos_imp; auto.
- destruct (IH G) as [[E [K1 K2]]|K].
+ left. exists E. split. exact K1.
intros alpha L. apply K2 in L. simpl in *. tauto.
+ right. apply ref_neg_imp; auto.
Qed.
Lemma solved_ref C :
{D| solved D /\ cent D C} + {rho C}.
Proof.
destruct (decider (provider nil C)) as [[E [F1 F2]]|F].
- apply solved_nil.
- left. exists E. revert F2. simpl_list. auto.
- right. revert F. simpl_list. auto.
Qed.
Lemma refutation C :
{sat C} + {rho C}.
Proof.
destruct (solved_ref C) as [[D [F1 F2]]|F];
eauto using cent_solved_sat.
Qed.
Lemma ref_iff_unsat C :
rho C <-> ~ sat C.
Proof.
generalize (ref_sound Rho (C:=C)), (refutation C); tauto.
Qed.
Lemma ref_dec C :
dec (rho C).
Proof.
unfold dec.
generalize (refutation C), (ref_iff_unsat C); tauto.
Qed.
End RL.
Lemma satis_pos f A :
satis' f (map Pos A) <-> forall s, s el A -> satis f s.
Proof.
induction A; simpl; firstorder; subst; auto.
Qed.
Lemma uns_pos A :
map uns (map Pos A) = A.
Proof.
induction A; simpl; congruence.
Qed.
Instance ndc_dec A s :
dec (ndc A s).
Proof.
generalize (ref_dec ref_ndc (-s :: map Pos A)).
simpl. rewrite uns_pos. apply dec_prop_iff.
symmetry. apply ndc_refute.
Qed.
Lemma bent_iff_unsat A s :
bent A s <-> ~ sat (-s :: map Pos A).
Proof.
split.
- intros D [f [E F]]. apply E, (D f). apply satis_pos, F.
- intros D f E. decide (satis f s) as [F|F]. exact F. exfalso.
apply D. exists f. split. exact F. apply satis_pos, E.
Qed.
Lemma ndc_iff_sem A s :
ndc A s <-> bent A s.
Proof.
rewrite bent_iff_unsat.
rewrite ndc_refute.
generalize (ref_iff_unsat ref_ndc (-s :: map Pos A)).
simpl. rewrite uns_pos.
auto.
Qed.