How to prove distributivity (propositional validity property 6) in LEAN? - functional-programming

Having gone through most exercises and also solved/proved in LEAN the first five propositional validities/properties at the end of chapter 3 in the LEAN manual, I still have trouble with the following implication (one of the implications needed for the proof of property 6):
theorem Distr_or_L (p q r : Prop) : (p ∨ q) ∧ (p ∨ r) → p ∨ (q ∧ r) :=
begin
intros pqpr,
have porq : p ∨ q, from pqpr.left,
have porr : p ∨ r, from pqpr.right,
sorry
end
The difficulty I face is mainly due to the case when p is not true, as I don't know how to combine, using LEAN tools, the two sides of the and in the hypothesis to obtain the fact that both q and r must hold under that scenario. I would greatly appreciate any help here; please help me understand how to construct this proof in the above setting without importing any other tactics except those in standard LEAN. For completeness, here is my proof of the other direction:
theorem Distr_or_R (p q r : Prop) : p ∨ (q ∧ r) → (p ∨ q) ∧ (p ∨ r) :=
begin
intros pqr,
exact or.elim pqr
( assume hp: p, show (p ∨ q) ∧ (p ∨ r), from
and.intro (or.intro_left q hp) (or.intro_left r hp) )
( assume hqr : (q ∧ r), show (p ∨ q) ∧ (p ∨ r), from
and.intro (or.intro_right p hqr.left) (or.intro_right p hqr.right) )
end

Hint. Try case splitting on both porq and porr.
Here's a solution
theorem Distr_or_L (p q r : Prop) : (p ∨ q) ∧ (p ∨ r) → p ∨ (q ∧ r) :=
begin
intros pqpr,
have porq : p ∨ q, from pqpr.left,
have porr : p ∨ r, from pqpr.right,
{ cases porq with hp hq,
{ exact or.inl hp },
{ cases porr with hp hr,
{ exact or.inl hp },
{ exact or.inr ⟨hq, hr⟩ } } }
end

Here is an asnwer for say problem without using cases. (explained later in tbe mentioned book)
example : p ∨ (q ∧ r) ↔ (p ∨ q) ∧ (p ∨ r) :=
Iff.intro
(fun hpqr => Or.elim hpqr
(fun hp: p =>
show (p ∨ q) ∧ (p ∨ r) from And.intro (Or.inl hp) (Or.inl hp))
(fun hqr: q ∧ r =>
show (p ∨ q) ∧ (p ∨ r) from And.intro (Or.inr hqr.left) (Or.inr hqr.right)))
(fun hpqpr: (p ∨ q) ∧ (p ∨ r) =>
have hpq: (p ∨ q) := hpqpr.left;
have hpr: (p ∨ r) := hpqpr.right;
Or.elim hpq
(fun hp: p => show p ∨ (q ∧ r) from Or.inl hp)
(fun hq: q => Or.elim hpr
(fun hp: p => show p ∨ (q ∧ r) from Or.inl hp)
(fun hr: r => show p ∨ (q ∧ r) from Or.inr (And.intro hq hr))))
You're using the information in the right part of the conjunction, otherwise, the left part doesn't give any info regarding r.

Related

Substitute the variables in the Isabelle/HOL Isar proof

I'm writing an Isar proof inside the Isabelle2020 and working with the locales.
On some point I want to use the axiom from the locale, which states
((A.par x y) ∧ (F x ≃ F y)) → (x ≃ y)
where "A" is another locale given as the information for the one where the above axiom is stored, "A.par" is simply a predicate then.
All the predicates and functions in the Axiom use polymorphic types, the free variable "x" itself is of type 'a, for example, the function "F" is of type 'a => 'b and "G" is of type 'b => 'c:
F :: "'a => 'b"
G :: "'b => 'c"
x :: "'a"
Generally, I have to axioms of this form: one for the locale "F" (showed above) and one for the locale "G" (which is exactly the same but with other types here):
((A.par x y) ∧ (G x ≃ G y)) → (x ≃ y)
The problem is that inside the proof I want to use this axiom but applied as
(A.par (F x) (F y)) ∧ (G(F x) ≃ G(F y)) → (F x) ≃ (F y)
Here the types coincide (as I see), because "F x" is of type 'b and "G" is applied exactly on this type.
And it seems I have to explicitly show the prover that "(F x)" here should be considered as "x" in the axiom and so on.
The proof step itself is just to apply the lemma to the conclusion I have already got:
(A.par (F x) (F y)) ∧ (G(F x) ≃ G(F y))
to get
(F x) ≃ (F y)
If we take a look on the output of the Isabelle we will see these:
USING 1)
((E (domain' (F x)) ∧ ¬ (¬ (E (domain' (F y))) ∨ domain' (F x) ≠ domain'
(F y))) ∧ E (codomain' (F x)) ∧ ¬ (¬ (E (codomain' (F y))) ∨ codomain'
(F x) ≠ codomain' (F y))) ∧ E (G (F x)) ∧ ¬ (¬ (E (G (F y))) ∨ G (F x) ≠ G
(F y))
AND 2)
(E ?x ∧ ¬ (¬ (E ?y) ∨ ?x ≠ ?y)) ← (((E (domain' ?x) ∧ ¬ (¬ (E (domain' ?y
)) ∨ domain' ?x ≠ domain' ?y)) ∧ E (codomain' ?x) ∧ ¬ (¬ (E (codomain' ?y
)) ∨ codomain' ?x ≠ codomain' ?y)) ∧ E (G ?x) ∧ ¬ (¬ (E (G ?y)) ∨ G ?x ≠ G
?y))
GET THIS
E (F x) ∧ ¬ (¬ (E (F y)) ∨ F x ≠ F y)
So, here one should merely use the 2)nd fact with substituted schematic variables by "F x" and "F y".
Will be glad to see any suggestions.

How do I solve this equation with logical equivalence laws?

The problem is :
Show that ¬ p → (q → r) and q → (p v r) are logically equivalent.
I'm having trouble proving this with the use of Logical Identities. Any help is much appreciated.
See this can be proved like this.
~p --> (q --> r)
~~p v (q --> r) -- (p -->q = ~p v q) --Implication law
p v (~q v r) -- (~ (~p) = p ) -- Double negation law
~q v (p v r) -- (P ∨ (Q ∨ R) ≡ (P ∨ Q) ∨ R) -- associativity Law
q --> (p v r) -- Implication law

Proving a theorem about parser combinators

I've written some simple parser combinators (without backtracking etc.). Here are the important definitions for my problem.
type_synonym ('a, 's) parser = "'s list ⇒ ('a * 's list) option"
definition sequenceP :: "('a, 's) parser
⇒ ('b, 's) parser
⇒ ('b, 's) parser" (infixl ">>P" 60) where
"sequenceP p q ≡ λ i .
(case p i of
None ⇒ None
| Some v ⇒ q (snd v))"
definition consumerP :: "('a, 's) parser ⇒ bool" where
"consumerP p ≡ (∀ i . (case p i of
None ⇒ True |
Some v ⇒ length (snd v) ≤ length i))"
I do want to proof the following lemma.
lemma consumerPI: "consumerP p ⟹ consumerP q ⟹ consumerP (p >>P q)"
apply (unfold sequenceP_def)
apply (simp (no_asm) add:consumerP_def)
apply clarsimp
apply (case_tac "case p i of None ⇒ None | Some v ⇒ q (snd v)")
apply simp
apply clarsimp
apply (case_tac "p i")
apply simp
apply clarsimp
apply (unfold consumerP_def)
I arrive at this proof state, at which I fail to continue.
goal (1 subgoal):
1. ⋀i a b aa ba.
⟦∀i. case p i of None ⇒ True | Some v ⇒ length (snd v) ≤ length i;
∀i. case q i of None ⇒ True | Some v ⇒ length (snd v) ≤ length i; q ba = Some (a, b); p i = Some (aa, ba)⟧
⟹ length b ≤ length i
Can anybody give me a tip how to solve this goal?
Thanks in advance!
It turns out that if you just want to prove the lemma, without further insight, then
lemma consumerPI: "consumerP p ⟹ consumerP q ⟹ consumerP (p >>P q)"
by (smt consumerP_def le_trans option.case_eq_if sequenceP_def)
does the job.
If you want to have insight, you want to go for a structured proof. First identify some useful lemmas about consumerP, and then write a Isar proof that details the necessary steps.
lemma consumerPI[intro!]:
assumes "⋀ i x r . p i = Some (x,r) ⟹ length r ≤ length i"
shows "consumerP p"
unfolding consumerP_def by (auto split: option.split elim: assms)
lemma consumerPE[elim, consumes 1]:
assumes "consumerP p"
assumes "p i = Some (x,r)"
shows "length r ≤ length i"
using assms by (auto simp add: consumerP_def split: option.split_asm)
lemma consumerP_sequencePI: "consumerP p ⟹ consumerP q ⟹ consumerP (p >>P q)"
proof-
assume "consumerP p"
assume "consumerP q"
show "consumerP (p >>P q)"
proof(rule consumerPI)
fix i x r
assume "(p >>P q) i = Some (x, r)"
then obtain x' r' where "p i = Some (x', r')" and "q r' = Some (x,r)"
by (auto simp add: sequenceP_def split:option.split_asm)
from `consumerP q` and `q r' = Some (x, r)`
have "length r ≤ length r'" by (rule consumerPE)
also
from `consumerP p` and `p i = Some (x', r')`
have "length r' ≤ length i" by (rule consumerPE)
finally
show "length r ≤ length i".
qed
qed
In fact, for this definition you can very nicely use the inductive command, and get intro and elim rules for free:
inductive consumerP where
consumerPI: "(⋀ i x r . p i = Some (x,r) ⟹ length r ≤ length i) ⟹ consumerP p"
In the above proof, you can replace by (rule consumerPE) by by cases and it works.

Convert this logic sentence to Conjunctive Normal Form

I am struggling to convert this sentence to CNF:
(A ∨ B) ⇔ (C ∧ D).
I have already tried to use the Biconditional elimination logic rule to eliminate the ⇔.
(A ∨ B) → (C ∧ D) ∧ (C ∧ D) → (A ∨ B).
Then I eliminated the → with the Implication elimination logic rule. Now I have
¬(A ∨ B) ∨ (C ∧ D) ∧ ¬(C ∧ D) ∨ (A ∨ B).
I am pretty much stuck here. My professor says I should use Distributivity rule to reduce the sentence. I can't seem to find anything that matches the requirements of Distributivity rule. So, I can't seem to use Distributivity rule before doing some logical rule that I do not know of.
What am I missing here? Can Stack Overflow help me to resume the conversion to CNF?
You began with the expression:
(A ∨ B) ⇔ (C ∧ D).
You tried to perform the first few steps. Here I added brackets to be clear and correct:
[(A ∨ B) → (C ∧ D)] ∧ [(C ∧ D) → (A ∨ B)]. (by definition of ⇔)
[¬(A ∨ B) ∨ (C ∧ D)] ∧ [¬(C ∧ D) ∨ (A ∨ B)]. (by definition of →)
Apply the De Morgan negation law to ¬(A ∨ B) and ¬(C ∧ D):
[(¬A ∧ ¬B) ∨ (C ∧ D)] ∧ [(¬C ∨ ¬D) ∨ (A ∨ B)].
Simplify the right half:
[(¬A ∧ ¬B) ∨ (C ∧ D)] ∧ [¬C ∨ ¬D ∨ A ∨ B].
The distributive law for ∨ over ∧ states that: X ∨ (Y ∧ Z) ⇔ (X ∨ Y) ∧ (X ∨ Z).
We apply the law to the left half, with X = (¬A ∧ ¬B), Y = C, Z = D:
[((¬A ∧ ¬B) ∨ C) ∧ ((¬A ∧ ¬B) ∨ D)] ∧ [¬C ∨ ¬D ∨ A ∨ B].
Apply the distributive law to two subexpressions in the left half:
[[(¬A ∨ C) ∧ (¬B ∨ C)] ∧ [(¬A ∨ D) ∧ (¬B ∨ D)]] ∧ [¬C ∨ ¬D ∨ A ∨ B].
Remove the extra brackets because ∧ is associative and commutative:
(¬A ∨ C) ∧ (¬B ∨ C) ∧ (¬A ∨ D) ∧ (¬B ∨ D) ∧ [¬C ∨ ¬D ∨ A ∨ B].
Rearrange the variables, and we have our final formula in conjunctive normal form (CNF):
(¬A ∨ C) ∧ (¬A ∨ D) ∧ (¬B ∨ C) ∧ (¬B ∨ D) ∧ (A ∨ B ∨ ¬C ∨ ¬D).

Why can I prove ⟦ ( ∃ x. P ) ∧ ( ∃ x. Q ) ⟧ ⟹ ∃ x. (P ∧ Q)?

I'm an Isabelle beginner, learning the basics. To my surprise, I just proved
lemma "⟦ ( ∃ x. P ) ∧ ( ∃ x. Q ) ⟧ ⟹ ∃ x. (P ∧ Q)"
apply ( auto )
done
in Isabelle/HOL. Now assuming that P and Q range over arbitrary predicates, this is false, just instantiate P to x = 1 and Q to x = 2.
Of course the mistake must be on my side, but where is my misconception?
As was already indicated in the comment, P and Q in your example are not predicates, they are simply Boolean variables. If you type term P, you will get simply bool. Since HOL types are nonempty, ∃x. P is equivalent to P and similarly for Q, so your assumptions force P and Q to be True, which obviously implies the statement you proved.
What you meant is
lemma "⟦(∃x. P x) ∧ (∃x. Q x)⟧ ⟹ ∃x. P x ∧ Q x"
This is wrong, and simply by writing down the lemma, quickcheck will already provide you with a counterexample automatically.
Also note that the brackets ⟦…⟧ are not required for a single assumption (like in your case). Furthermore, it is uncommon to use the HOL conjunction operator ∧ to combine assumptions. You would more commonly state this lemma as
lemma "⟦∃x. P x; ∃x. Q x⟧ ⟹ ∃x. P x ∧ Q x"
or
lemma "∃x. P x ⟹ ∃x. Q x ⟹ ∃x. P x ∧ Q x"
This form is easier to handle than the one with the HOL ∧, since you can instantiate particular assumptions.

Resources