How to execute proof by cases which customized by ourself - isabelle

I'd like to prove a lemma by cases. Assume that I have two variables r1 and r2, r2 is free variable, and r1 r2 belongs to same datatypes. Thus there is an idea that I want to prove the lemma by cases of r1 = r2 and r1 != r2. I know there exists a struct of proof(cases) in isabelle, but how to proof by the cases r2 of ...
∀q∈reg2q r1 v. sem_reg q v = {w. LTS_is_reachable (fst (trans2LTS r1 v)) (snd (trans2LTS r1 v)) q w ε} ⟹
q ∈ reg2q r1 v ⟹
LTS_is_reachable (fst (trans2LTS r1 v) ∪ fst (trans2LTS r2 v)) (insert (Alter r1 r2, r1) (insert (Alter r1 r2, r2) (snd (trans2LTS r1 v) ∪ snd (trans2LTS r2 v)))) q x ε ⟹
LTS_is_reachable (fst (trans2LTS r1 v)) (snd (trans2LTS r1 v)) q x ε
Any help will be appreciated a lot.

Related

How to prove universal quantifiers from narrow to large range?

proof universal quantifiers from narrow to large range. There are two theorems. `
lemma "(∀l k. l< i ∧ k<j⟶ (f l k))
⟹ (∀l. l< i⟶ (f l j))
⟹ (∀l k. l<i ∧ k≤j⟶ (f l k))"
oops
``
lemma "(∀l k. l< i ∧ k<j⟶ (f l k)) ⟹
(∀l. l< i⟶ (f l j)) ⟹ (∀k. k<j⟶ (f i k)) ⟹ f i j
⟹ (∀l k. l≤ i ∧ k≤j⟶ (f l k))"
oops
`
The universal quantifier modifies two small range can be proved; can it prove the large range?
You forget to add a type annotations to force the variables to have type int or nat.
After fixing that, the proofs works exactly as you would do it by hand.

The lemma defined in fun can work, but can not work in inductive predicate

type_synonym ('q,'a) LTS = "('q * 'a set * 'q) set"
primrec LTS_is_reachable :: "('q, 'a) LTS \<Rightarrow> 'q \<Rightarrow> 'a list \<Rightarrow> 'q \<Rightarrow> bool" where
"LTS_is_reachable \<Delta> q [] q' = (q = q')"|
"LTS_is_reachable \<Delta> q (a # w) q' =
(\<exists>q'' \<sigma>. a \<in> \<sigma> \<and> (q, \<sigma>, q'') \<in> \<Delta> \<and> LTS_is_reachable \<Delta> q'' w q')"
lemma DeltLTSlemma:"LTS_is_reachable Δ q x y \<Longrightarrow>LTS_is_reachable {(f a, b, f c)| a b c. (a,b,c)\<in> Δ } (f q) x (f y)"
apply(induct x arbitrary:q)
apply auto
done
I've defined a fun LTS_is_reachable as above, and give a lemma to prove it. But for introduce a new relation in the LTS system, i change the form into the inductive predivate below. This lemma can not work, and I am not able to handle this.
type_synonym ('q,'a) LTS = "('q * 'a set * 'q) set"
inductive LTS_is_reachable :: "('q, 'a) LTS \<Rightarrow> 'q \<Rightarrow> 'a list \<Rightarrow> 'q \<Rightarrow> bool" where
LTS_Empty:"LTS_is_reachable \<Delta> q [] q"|
LTS_Step:"(\<exists>q'' \<sigma>. a \<in> \<sigma> \<and> (q, \<sigma>, q'') \<in> \<Delta> \<and> LTS_is_reachable \<Delta> q'' w q') \<Longrightarrow> LTS_is_reachable \<Delta> q (a # w) q'"|
LTS_Epi:"(\<exists>q''. (q,{},q'') \<in> \<Delta> \<and> LTS_is_reachable \<Delta> q'' l q') \<Longrightarrow> LTS_is_reachable \<Delta> q l q'"
inductive_cases LTS_Step_cases[elim!]:"LTS_is_reachable \<Delta> q (a # w) q'"
inductive_cases LTS_Epi_cases[elim!]:"LTS_is_reachable \<Delta> q l q'"
inductive_cases LTS_Empty_cases[elim!]:"LTS_is_reachable \<Delta> q [] q"
lemma "LTS_is_reachable {(q, v, y)} q x y ⟹ LTS_is_reachable {(f q, v, f y)} (f q) x (f y)"
proof(induct x arbitrary:q)
case Nil
then show ?case
by (metis (no_types, lifting) LTS_Empty LTS_Epi LTS_Epi_cases Pair_inject list.distinct(1) singletonD singletonI)
next
case (Cons a x)
then show ?case
qed
Thank you very much for your help.
Using your inductive definition of LTS_is_reachable, you can prove your original lemma DeltLTSlemma by rule induction, that is, by using proof (induction rule: LTS_is_reachable.induct). You can learn more about rule induction in Section 3.5 of Programming and Proving in
Isabelle/HOL. As a side remark, note that you can avoid using inductive_cases since nowadays structured proofs (i.e., Isar proofs) are strongly preferred over unstructured proofs (i.e., apply-scripts).

Refine and fix the unused fixed parameter on the isar proof

I am trying to refine the proof on the complete path proving as shown below:
lemma completePathProp:
assumes a1:"p \<in> complete_Path a b"
shows "(b \<in> bundles) \<longrightarrow> unique_originate a n
\<longrightarrow> (\<forall> n'. ((n'\<in> nodes b) \<and> last p=n' \<longrightarrow>(n'=n | (n,n'):(edges b)^+)))"
(is "?cons1 p")
and "p \<noteq>[]" (is "?cons2 p")
and "\<forall>m. m\<in>(set p)\<and>node_sign m=+ \<and> a\<sqsubset> node_term m
\<longrightarrow>
(\<forall>m'.(m'\<Rightarrow>\<^sup>+ m)\<and> a\<sqsubset> node_term m'\<longrightarrow> m'\<in>(set p))"
(is "?cons3 p")
using a1
proof (induction)
fix m m2 p
let ?p="p # slice_arr_cons (strand m) (index m) (index m2 - index m)"
show "?cons1 p \<and> ?cons2 p \<and> ?cons3 p "
But I meet the problem that isabelle can not refine the proof automatically that:
goal (9 subgoals):
1. ⋀m2 m p.
non_originate a (strand m2) ⟹
node_sign m2 = + ⟹
a ⊏ node_term m2 ⟹
first_node_in_nonorigi_strand a m2 m ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
last p = m ⟹
b ∈ bundles ⟶
unique_originate a n ⟶
(∀n'. n' ∈ nodes b ∧ last (p # slice_arr_cons (strand m) (index m) (index m2 - index m)) = n' ⟶
n' = n ∨ n ≺⇩b n')
2. ⋀m2 m p.
non_originate a (strand m2) ⟹
node_sign m2 = + ⟹
a ⊏ node_term m2 ⟹
first_node_in_nonorigi_strand a m2 m ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
last p = m ⟹ p # slice_arr_cons (strand m) (index m) (index m2 - index m) ≠ []
3. ⋀m2 m p.
non_originate a (strand m2) ⟹
node_sign m2 = + ⟹
a ⊏ node_term m2 ⟹
first_node_in_nonorigi_strand a m2 m ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
last p = m ⟹
∀ma. ma ∈ set (p # slice_arr_cons (strand m) (index m) (index m2 - index m)) ∧
node_sign ma = + ∧ a ⊏ node_term ma ⟶
(∀m'. m' ⇒⇧+ ma ∧ a ⊏ node_term m' ⟶
m' ∈ set (p # slice_arr_cons (strand m) (index m) (index m2 - index m)))
4. ⋀m m2.
unique_originate a m ⟹
strand m2 = strand m ⟹
a ⊏ node_term m2 ⟹
node_sign m2 = + ⟹
b ∈ bundles ⟶
unique_originate a n ⟶
(∀n'. n' ∈ nodes b ∧ last (slice_arr_cons (strand m) (index m) (index m2 - index m)) = n' ⟶
n' = n ∨ n ≺⇩b n')
5. ⋀m m2.
unique_originate a m ⟹
strand m2 = strand m ⟹
a ⊏ node_term m2 ⟹ node_sign m2 = + ⟹ slice_arr_cons (strand m) (index m) (index m2 - index m) ≠ []
6. ⋀m m2.
unique_originate a m ⟹
strand m2 = strand m ⟹
a ⊏ node_term m2 ⟹
node_sign m2 = + ⟹
∀ma. ma ∈ set (slice_arr_cons (strand m) (index m) (index m2 - index m)) ∧
node_sign ma = + ∧ a ⊏ node_term ma ⟶
(∀m'. m' ⇒⇧+ ma ∧ a ⊏ node_term m' ⟶
m' ∈ set (slice_arr_cons (strand m) (index m) (index m2 - index m)))
7. ⋀m1 m2 p.
m1 → m2 ⟹
m1 ∈ nodes b ⟹
(m1, m2) ∈ edges b ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
a ⊏ node_term m2 ⟹
last p = m1 ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last (p # [m2]) = n' ⟶ n' = n ∨ n ≺⇩b n')
8. ⋀m1 m2 p.
m1 → m2 ⟹
m1 ∈ nodes b ⟹
(m1, m2) ∈ edges b ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
a ⊏ node_term m2 ⟹ last p = m1 ⟹ p # [m2] ≠ []
9. ⋀m1 m2 p.
m1 → m2 ⟹
m1 ∈ nodes b ⟹
(m1, m2) ∈ edges b ⟹
p ∈ complete_Path a b ⟹
b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last p = n' ⟶ n' = n ∨ n ≺⇩b n') ⟹
p ≠ [] ⟹
∀m. m ∈ set p ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set p) ⟹
a ⊏ node_term m2 ⟹
last p = m1 ⟹
∀m. m ∈ set (p # [m2]) ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set (p # [m2]))
Failed to refine any pending goal
Local statement fails to refine any pending goal
Failed attempt to solve goal by exported rule:
(b ∈ bundles ⟶ unique_originate a n ⟶ (∀n'. n' ∈ nodes b ∧ last ?pa2 = n' ⟶ n' = n ∨ n ≺⇩b n')) ∧
?pa2 ≠ [] ∧
(∀m. m ∈ set ?pa2 ∧ node_sign m = + ∧ a ⊏ node_term m ⟶
(∀m'. m' ⇒⇧+ m ∧ a ⊏ node_term m' ⟶ m' ∈ set ?pa2))
I found that there are total 9 subgoals on the lemma proving, and on the subgoal 5 and 6, parameter q is unused, is this cause the error, and how to fix it?

How to solve the proof state about Isar text

I'm writing a lemma according to the Proof state and isar text, and meet some difficult. There is a proof state that
(y, z) ∈ (edges b)⇧+ ∪ {(a, n2). a ≼⇩b n1} ⟹
n1 ∈ nodes b ⟹ n2 ∉ nodes b ⟹ y ≺⇩b z ⟶ y ≠ z ⟹ z = n2 ⟹ b ∈ bundles ⟹ y ≠ z
According to the tip, I try to write down below code:
(y, z) \<in> (edges b)\<^sup>+ \<union> {(a, n2). (a, n1) \<in> (edges b)\<^sup>*} \<Longrightarrow> n1 \<in> nodes b\<Longrightarrow>
n2 \<notin> nodes b\<Longrightarrow> (y, z) \<in> (edges b)\<^sup>+ \<longrightarrow> y \<noteq> z\<Longrightarrow> z = n2\<Longrightarrow> b \<in> bundles\<Longrightarrow> y \<noteq> z"
But it mentions me that Failed to refine any pending goal Local statement fails to refine any pending goal Failed attempt to solve goal by exported rule:
((y, z) ∈ (edges b)⇧+ ∪ {(a, n2). a ≼⇩b n1}) ⟹
(n1 ∈ nodes b) ⟹
(n2 ∉ nodes b) ⟹ (y ≺⇩b z ⟶ y ≠ z) ⟹ (z = n2) ⟹ (b ∈ bundles) ⟹ y ≠ z
I see that there are extra brackets here, how to solve it. Thank you.
definition:
datatype
Sign=positive ("+" 100)
|negative ("-" 100)
typedecl sigma
type_synonym signed_msg="Sign\<times> msg"
type_synonym node=" sigma \<times> nat"
type_synonym strand_space="sigma \<Rightarrow> signed_msg list "
consts
Sigma_set::"sigma set" ("\<Sigma>")
SP::"strand_space"
definition Domain::"node set" where
"Domain == {(n1,i). n1 \<in> \<Sigma> \<and> i < length (SP n1)}"
definition strand::"node \<Rightarrow> sigma" where
"strand n==fst n"
definition index ::"node \<Rightarrow> nat" where
"index n == snd n"
definition node_sign ::"node \<Rightarrow> Sign" where
"node_sign n ==fst (nth (SP(fst(n))) (snd(n)) )"
definition
node_term ::"node\<Rightarrow>msg" where
"node_term n== snd (nth (SP(fst(n))) (snd(n)) )"
definition casual1:: "( node \<times> node ) set " where
"casual1 == { (n1,n2) . n1 \<in> Domain \<and> n2 \<in> Domain \<and>
node_sign n1= + \<and>
node_sign n2= -
\<and> node_term n1= node_term n2
\<and> strand n1 \<noteq> strand n2
} "
syntax
"_casual1"::" node \<Rightarrow>node\<Rightarrow>bool" (infix "\<rightarrow>" 100)
translations
"n1\<rightarrow>n2 "=="(n1 ,n2) \<in> CONST casual1"
definition casual2::"(node \<times> node) set" where
"casual2 == { (n1,n2) . n1 \<in> Domain \<and> n2 \<in> Domain \<and>
(strand n1)= (strand n2 ) \<and> Suc (index n1)=index n2} "
syntax
"_casual2"::" node \<Rightarrow>node\<Rightarrow>bool" (infix "\<Rightarrow>" 50)
translations
"n1\<Rightarrow>n2 "=="(n1 ,n2):CONST casual2"
syntax
"_casual2Trans"::" node \<Rightarrow>node\<Rightarrow>bool" (infix "\<Rightarrow>\<^sup>+" 50)
translations
"n1\<Rightarrow>\<^sup>+ n2 "=="(n1 ,n2):CONST casual2⇧+"
syntax
"_casual2TransReflex"::" node \<Rightarrow>node\<Rightarrow>bool" (infix "\<Rightarrow>\<^sup>*" 50)
translations
"n1\<Rightarrow>\<^sup>*n2 "=="(n1 ,n2):CONST casual2^*"
definition casual3::"(node \<times> node) set" where
"casual3 == { (n1,n2) . n1\<rightarrow>n2 \<or>(n1, n2):(casual2⇧+) }"
syntax
"_casual3"::" node \<Rightarrow>node\<Rightarrow>bool" (infix "\<mapsto> " 50)
translations
"n1\<mapsto> n2 "=="(n1 ,n2): CONST casual3"
type_synonym edge="node \<times> node"
type_synonym graph="node set \<times> edge set"
definition Atoms::"msg set" where
"Atoms=={a. (\<exists> ag. a=Agent ag) \<or> (\<exists> n. a=Number n)
\<or>(\<exists> n. a=Nonce n) | (\<exists> k. a=Key k)}"
syntax
Is_atom::"msg \<Rightarrow> bool"
translations
"Is_atom m"=="m \<in> CONST Atoms"
definition KP::"key set" where
"KP=={k. \<exists> A. (k=pubK A)|(A \<in> bad \<and>(k=priK A |k=shrK A))}"
definition T:: "msg set" where
"T== {t. t: Atoms\<and> (\<forall> k. t \<noteq> Key k)}"
definition Is_K_strand::"sigma \<Rightarrow> bool " where
"Is_K_strand KS == (\<exists> k. k\<in> KP \<and> (SP KS)=[(+, Key k)])"
definition
Is_T_strand::"sigma \<Rightarrow> bool" where
"Is_T_strand KS== (\<exists> t. t \<in> T \<and> (SP KS)=[(+, t)]) "
definition
Is_E_strand ::"sigma \<Rightarrow> bool " where
"Is_E_strand KS == (\<exists> k. \<exists> h. (SP KS)=[(-, (Key k)),(-,h),(+, (Crypt k h))])"
definition
Is_D_strand::"sigma \<Rightarrow>bool" where
"Is_D_strand KS== (\<exists> k. \<exists> k'. \<exists> h. k'=invKey k\<and> (SP KS)=[(-, (Key k')),(-, (Crypt k h)),(+,h)])"
definition
Is_Cat_strand::"sigma \<Rightarrow>bool" where
"Is_Cat_strand KS== (\<exists> g. \<exists> h. (SP KS)=[(-, g),(-, h),(+, MPair g h)])"
definition
Is_Sep_strand::"sigma \<Rightarrow>bool" where
"Is_Sep_strand KS== (\<exists> g. \<exists> h. (SP KS)=[(-, MPair g h),(+, g),(+, h)])"
definition
Is_Flush_strand::"sigma \<Rightarrow>bool" where
"Is_Flush_strand KS== (\<exists> g. (SP KS)=[(-, g )])"
definition
Is_Tee_strand::"sigma \<Rightarrow>bool" where
"Is_Tee_strand KS== (\<exists> g. (SP KS)=[(-, g),(+, g),(+, g )])"
definition Is_penetrator_strand:: "sigma \<Rightarrow> bool" where
"Is_penetrator_strand s==
( Is_Tee_strand s | Is_Flush_strand s | Is_Cat_strand s |
Is_Sep_strand s | Is_E_strand s | Is_D_strand s |
Is_T_strand s | Is_K_strand s)"
definition Is_regular_strand :: "sigma \<Rightarrow>bool" where
"Is_regular_strand s==\<not> ( Is_penetrator_strand s)"
definition nodes::"graph \<Rightarrow> node set" where
"nodes b== fst b"
definition edges::"graph \<Rightarrow> edge set" where
"edges b == snd b"
inductive_set bundles :: "graph set" where
Nil[intro!] : "({},{}):bundles" |
Add_positive1[intro!]: "\<lbrakk> b \<in> bundles;
(node_sign n2) = +;
n2 \<in> Domain;
n2 \<notin> (nodes b);
0 < index n2 ;
n1 \<in> nodes b;
n1\<Rightarrow> n2
\<rbrakk>\<Longrightarrow>
({n2} \<union> (nodes b), {(n1, n2)} \<union> (edges b)) \<in> bundles" |
Add_positive2[intro!]: "\<lbrakk> b \<in> bundles;
node_sign n2=+;
n2 \<notin> (nodes b);
n2 \<in> Domain;
index n2=0
\<rbrakk>
\<Longrightarrow>
({n2} \<union> nodes b, edges b) \<in> bundles" |
Add_negtive1[intro!]: "\<lbrakk> b \<in> bundles;
node_sign n2=-;
n2 \<notin> nodes b;
((strand n1 \<noteq> strand n2)\<and> (n1 \<rightarrow> n2) \<and> (n1 \<in> nodes b) \<and> (\<forall> n3. ( (n3 \<in> nodes b)\<longrightarrow> (n1,n3) \<notin> edges b)) );
0 < index n2 ;
n1' \<in> nodes b;
n1'\<Rightarrow>n2
\<rbrakk> \<Longrightarrow>
({n2} \<union> nodes b, {(n1, n2), (n1' , n2)} \<union> edges b) \<in> bundles" |
Add_negtive2: "\<lbrakk> b \<in> bundles;
node_sign n2= -;
n2 \<notin> nodes b;
((strand n1 \<noteq> strand n2)\<and> (n1 \<rightarrow> n2) \<and> (n1 \<in> nodes b) \<and> (\<forall> n3. ( (n3 \<in> nodes b)\<longrightarrow> (n1,n3) \<notin> edges b)) );
index n2=0
\<rbrakk> \<Longrightarrow>
({n2} \<union> nodes b, {(n1, n2)} \<union> edges b) \<in> bundles"
lemma bundle_edge_is_anti2:
assumes A:"b \<in> bundles"
shows "y \<prec>\<^sub>b z\<longrightarrow> y\<noteq>z"
using A
proof induct
case Nil show ?case
by(unfold edges_def, auto)
next
fix b n1 n2
assume a1:"b \<in> bundles"
and IH:" (y, z) \<in> (edges b)\<^sup>+ \<longrightarrow> y \<noteq> z"
and a2:" node_sign n2 = +"
and a3:" n2 \<in> Domain"
and a4:" n2 \<notin> nodes b"
and a5:" 0 < index n2"
and a6:" n1 \<in> nodes b"
and a7:" n1 \<Rightarrow> n2"
show "(y, z) \<in> (edges ({n2} \<union> nodes b, {(n1, n2)} \<union> edges b))\<^sup>+ \<longrightarrow> y\<noteq>z"
proof
assume a8:"(y, z) \<in> (edges ({n2} \<union> nodes b, {(n1, n2)} \<union> edges b))\<^sup>+"
show "y\<noteq>z"
proof(cases "z=n2")
case True
from this
have casehyp:"z=n2" .
from a8
have a9:"(y,z):({(n1, n2)} \<union> edges b)\<^sup>+"
by(unfold edges_def, simp)
from a9
have a10:"(y,z) \<in> ((edges b)^+ Un {(a,c). (a,n1) \<in> (edges b)^* \<and> ((n2,c) \<in> (edges b)^*)})"
by (simp add:trancl_insert)
from a10
have a12:"(y,z) \<in> (edges b)^+ Un {(a,n2). (a,n1) \<in> (edges b)^* }"
proof -
show "(y, z) \<in> (edges b)\<^sup>+ \<union> {(a, c). (a, n1) \<in> (edges b)\<^sup>* \<and> (n2, c) \<in> (edges b)\<^sup>*}
\<Longrightarrow>
(y, z) \<in> (edges b)\<^sup>+ \<union> {(a, n2). (a, n1) \<in> (edges b)\<^sup>*}"
apply simp
apply(erule disjE)
apply simp
by simp
qed
from a12 and a6 and a4 and IH and casehyp and A
show ?thesis
by (metis (no_types, lifting) Un_insert_left a1 a2 a3 a5 a7 a8 bundle_is_closed bundle_is_closed1 bundles.Add_positive1 edges_def insert_iff snd_conv sup_bot.left_neutral tranclD)
next
case False
from this have casehyp:"z\<noteq>n2" .
from a8 have a9:"(y,z) \<in> ({(n1, n2)} \<union> edges b)\<^sup>+"
by (unfold edges_def,simp)
from A and a8 and casehyp and a4
have a10: "(y,z) \<in> (edges b)\<^sup>+"
proof -
show "\<lbrakk>b \<in> bundles; (y, z) \<in> (edges ({n2} \<union> nodes b, {(n1, n2)} \<union> edges b))\<^sup>+; z \<noteq> n2;
n2 \<notin> nodes b\<rbrakk> \<Longrightarrow> (y, z) \<in> (edges b)\<^sup>+ "
apply (simp add:edges_def trancl_insert)
apply(erule disjE)
apply simp
apply(erule conjE)
apply(drule_tac a="n2" and b="z" in rtranclD)
apply(fold edges_def)
apply(auto dest:bundle_is_trans_closed22)
done
from a10 and IH show ?thesis by simp
qed
qed
After I add the declare [[show_sorts]], I see that the output becomes:
proof (state)
goal (1 subgoal):
1. b ∈ bundles ⟹ y ≺⇩({n2} ∪ nodes b, {(n1, n2)} ∪ edges b) z ⟹ z ≠ n2 ⟹ n2 ∉ nodes b ⟹ y ≺⇩b z
variables:
n1, n2, y, z :: sigma × nat
b, b :: (sigma × nat) set × ((sigma × nat) × sigma × nat) set
Failed to refine any pending goal
Local statement fails to refine any pending goal
Failed attempt to solve goal by exported rule:
((b::(sigma × nat) set × ((sigma × nat) × sigma × nat) set) ∈ bundles) ⟹
((y::sigma ×
nat) ≺⇩({n2::sigma × nat} ∪ nodes b, {(n1::sigma × nat, n2)} ∪ edges b) (z::sigma × nat)) ⟹
(z ≠ n2) ⟹ (n2 ∉ nodes b) ⟹ y ≺⇩b z
I think there is no wrong, how to fix it.
Let me give some idea how to debug such cases. Assume
fix x
assume A
assume B
assume C
show D
First comment out all assumptions and remove all unused fixed variables.
fix x
(*
assume A
assume B
assume C
*)
show D
If you still have the error, then your error is in the conclusion or the type of the fixes.
If it works, great, the error comes from one of the assumptions. Add them with the fixed variables one by one until you find the faulty one. So something like:
fix x
(*
assume A
assume B
*)
assume C
show D

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.

Resources