Section WEAK_COMPLETENESS.
Definition ContradictionF_bool : bool :=
false.
Definition NegationF_bool (b1 : bool) : bool :=
match b1 with
| true => false
| false => true
end.
Definition ConjunctionF_bool (b1 : bool) (b2 : bool) : bool :=
match b1, b2 with
| true, true => true
| true, false => false
| false, true => false
| false, false => false
end.
Definition DisjunctionF_bool (b1 : bool) (b2 : bool) : bool :=
match b1, b2 with
| true, true => true
| true, false => true
| false, true => true
| false, false => false
end.
Definition ImplicationF_bool (b1 : bool) (b2 : bool) : bool :=
match b1, b2 with
| true, true => true
| true, false => false
| false, true => true
| false, false => true
end.
Definition BiconditionalF_bool (b1 : bool) (b2 : bool) : bool :=
match b1, b2 with
| true, true => true
| true, false => false
| false, true => false
| false, false => true
end.
Fixpoint eval_bool (env : propLetter -> bool) (p : formula) {struct p} : bool :=
match p with
| AtomF i => env i
| ContradictionF => ContradictionF_bool
| NegationF p1 => NegationF_bool (eval_bool env p1)
| ConjunctionF p1 p2 => ConjunctionF_bool (eval_bool env p1) (eval_bool env p2)
| DisjunctionF p1 p2 => DisjunctionF_bool (eval_bool env p1) (eval_bool env p2)
| ImplicationF p1 p2 => ImplicationF_bool (eval_bool env p1) (eval_bool env p2)
| BiconditionalF p1 p2 => BiconditionalF_bool (eval_bool env p1) (eval_bool env p2)
end.
Definition finite_entails (Gamma : list formula) (C : formula) : Prop :=
forall e : propLetter -> bool, (forall H, In H Gamma -> eval_bool e H = true) -> eval_bool e C = true.
#[local] Hint Unfold finite_entails : simplication_hints.
Fixpoint occurs (i : propLetter) (p : formula) {struct p} : Prop :=
match p with
| AtomF i' => i = i'
| ContradictionF => False
| NegationF p1 => occurs i p1
| ConjunctionF p1 p2 => occurs i p1 \/ occurs i p2
| DisjunctionF p1 p2 => occurs i p1 \/ occurs i p2
| ImplicationF p1 p2 => occurs i p1 \/ occurs i p2
| BiconditionalF p1 p2 => occurs i p1 \/ occurs i p2
end.
Definition gen_context_for (env : propLetter -> bool) : list propLetter -> list formula :=
L.map (fun i : propLetter => if env i then AtomF i else NegationF (AtomF i)).

Lemma infers_dec (C : formula)
: { ls : list propLetter | ⟪ OCCURS : forall l, In l ls <-> occurs l C ⟫ /\ ⟪ INFERS_DEC : forall e, let Gamma := E.fromList (gen_context_for e ls) in if eval_bool e C then Gamma ⊢ C else Gamma ⊢ NegationF C ⟫ }.