Hello,
Should you only use erule
when the rule does not change the goal? In other words, should it be used as a method to split the state of the assumptions or can it be used to perform a forward and backward step at once while splitting the goal cases?
A bit of background. Many elimination rules are set up to apply to arbitrary goal states. E.g.: conjE
:
P ∧ Q ⟹ (P ⟹ Q ⟹ R) ⟹ R
Here is the line in question:
apply (erule inv_maintained) (* or *) apply (rule inv_maintained) apply assumption (* or *) apply (rule inv_maintained, assumption) (* What is a good stylistic choice? *)
Here is the full example:
context
fixes P Q P1 P2 P3 P4 P5 P6 P7 P8 Q1 Q2 Q3 Q4 Q5
and P_inv
and Q_inv::"('a × 'a) ⇒ bool"
and f::"('a × 'a) ⇒ ('a × 'a)"
and g::"'a ⇒ 'a"
assumes PD: "P x ⟹ P_inv x"
"P x ⟹ P3 x"
"P x ⟹ P4 x"
"P x ⟹ P5 x"
"P x ⟹ P6 x"
"P x ⟹ P7 x"
"P x ⟹ P8 x"
and P_invD: "P_inv x ⟹ P1 x"
"P_inv x ⟹ P2 x"
and Q_invI: "Q1 x ⟹ Q2 x ⟹ Q_inv x"
and QI: "Q_inv x ⟹ Q3 x ⟹ Q4 x ⟹ Q5 x ⟹ Q x"
begin
lemma provable_trivial:
assumes "fst x = fst x'"
shows
"P1 x ⟹ Q1 x'"
"P2 x ⟹ Q2 x'"
sorry
lemma provable_non_trivial:
"P1 x ⟹ Q1 (f x)"
"P2 x ⟹ Q2 (f x)"
"P3 x ⟹ P4 x ⟹ Q3 (f x)"
"P4 x ⟹ P5 x ⟹ Q4 (f x)"
"P6 x ⟹ P7 x ⟹ P8 x ⟹ Q5 (f x)"
sorry
lemma PE:
assumes "P x"
and "P_inv x ⟹ P3 x ⟹ P4 x ⟹ P5 x ⟹ P6 x ⟹ P7 x ⟹ P8 x ⟹ thesis"
shows thesis
using assms PD P_invD by auto
lemma P_invE:
assumes "P_inv x"
and "P1 x ⟹ P2 x ⟹ thesis"
shows thesis using P_invD assms by auto
lemma goal: "P x ⟹ Q (f x)"
apply (rule QI)
apply (rule Q_invI)
subgoal
apply (erule PE)
apply (erule P_invE)
by (rule provable_non_trivial)
subgoal
apply (erule PE)
apply (erule P_invE)
by (rule provable_non_trivial)
subgoal
apply (erule PE)
by (rule provable_non_trivial)
subgoal
apply (erule PE)
by (rule provable_non_trivial)
subgoal
apply (erule PE)
apply (rule provable_non_trivial)
by simp+
done
lemma inv_maintained:
assumes "P_inv x"
and "P1 x ⟹ Q1 x'"
"P2 x ⟹ Q2 x'"
shows "Q_inv x'"
using P_invD Q_invI assms by blast
lemma goal':
assumes fa: "f = (λ(x, y). (x, g y))"
shows "P x ⟹ Q (f x)"
apply (rule QI)
subgoal
apply (drule PD(1))
apply (erule inv_maintained) (* or *) apply (rule inv_maintained) apply assumption (* or *) apply (rule inv_maintained, assumption) (* What is a good stylistic choice? *)
subgoal apply (rule provable_trivial[rotated], assumption) (* okay *)
apply (cases x)
by (simp add: fa)+
subgoal apply (erule provable_trivial[rotated]) (* probably not clean *)
apply (cases x)
by (simp add: fa)+
done
subgoal
apply (frule PD(2))
apply (drule PD(3))
by (rule provable_non_trivial)
subgoal
apply (frule PD(3))
apply (drule PD(4))
by (rule provable_non_trivial)
subgoal
apply (frule PD(5))
apply (frule PD(6))
apply (drule PD(7))
by (rule provable_non_trivial)
done
end
Another stylistic note. The following is also a possibility for proving the subgoals of goal'
. Is it bad practice to use defer
and prefer
?
subgoal apply (rule provable_trivial)
prefer 2
apply assumption
apply (cases x)
by (simp add: fa)+
The better version is to go to Isar...
Otherwise, I would prefer erule
as it is more precise on the meaning
Mathias Fleury said:
The better version is to go to Isar...
I agree that Isar can make some proofs more readable.
To use apply scripts is a deliberate choice in this case. Some terms in the actual (non-example) theories became very large and were related to some other terms. Binding variables and adding assumptions in context blocks helped to some extent, but assumptions became hard to keep track of.
Mathias Fleury said:
But eventually I will need to port some of that old Isabelle code/projects to current versions. Is there any documentation about how to do that? What to expect, pitfalls, ...?
Depending on the proof style:
- <5 years (not a math development), sledgehammer your way through
- <5 years (math development like relying on HOL-Analysis), then you probably need to know what changed since that. There is a global NEWS file
- <5 years (apply style) or >= 5 years: cheaper to redo and generalize than to port
After seeing this, the previous answer about apply scripts makes more sense.
Last updated: Jun 21 2025 at 01:46 UTC