How to abort a proof in Isabelle? - isabelle

I was wondering if there is a way to abort a proof in Isabelle/jEdit?
I searched for commands such as "Reset", "Abort" but couldn't find it.
I know there is Sorry. But I am not sure if one uses Sorry, the theorem at hand is assumed to be true or abandoned. Also, Sorry does not seem to work in the apply..done mode.
Currently, I comment out the theorems that I can't prove. But it requires a lot of typing (four characters each in (* *)) to comment or uncomment something, which is kind of cumbersome.
So is there a standard/universal way to abort a proof in Isabelle?

First, the command is sorry and it does work (but only) in apply style:
lemma
‹False ∧ True›
apply (rule conjI)
apply auto
sorry
About the actual question, oops aborts proofs, whether in apply style or not:
lemma
‹False ∧ True›
proof -
have True
by auto
oops
An oops-ed proof cannot be referenced later.

Related

Fragile rule application in Isabelle

I was playing around with an example from the Isabelle/HOL tutorial to get a better understanding on the correspondence between Isar and Tactics proofs.
This is a version which works:
lemma rtrancl_converseD: "(x,y) ∈ (r ^-1 )^* ⟹ (y,x) ∈ r^* "
proof (induct y rule: rtrancl_induct)
case base
then show ?case ..
next case (step y z)
then have "(z, y) ∈ r" using rtrancl_converseD by simp
with `(y,x)∈ r^*` show "(z,x) ∈ r^*" using [[unify_trace_failure]]
apply (subgoal_tac "1=(1::nat)")
apply (rule converse_rtrancl_into_rtrancl)
apply simp_all
done
qed
I want to instantiate converse_rtrancl_into_rtrancl which proofs (?a, ?b) ∈ ?r ⟹ (?b, ?c) ∈ ?r^* ⟹ (?a, ?c) ∈ ?r^* .
But without the seemingly nonsensical apply (subgoal_tac "1=(1::nat)") line this errors with
Clash: r =/= Transitive_Closure.rtrancl
Failed to apply proof method⌂:
using this:
(y, x) ∈ r^*
(z, y) ∈ r
goal (1 subgoal):
1. (z, x) ∈ r^*
If I fully instantiate the rule apply (rule converse_rtrancl_into_rtrancl[of z y r x]) this becomes Clash: z__ =/= ya__.
This leaves me with three questions: Why does this specific case break? How can I fix it? And how can I figure out what went wrong in these cases since I can't really understand what the unify_trace_failure message wants to tell me.
rule-tactics are usually sensitive to the order of premises. The order of premises in converse_rtrancl_into_rtrancl and in your proof state don't match. Switching the order of premises in the proof state using rotate_tac will make them match the rule, so that you can directly apply fact like this:
... show "(z,x) ∈ r^*"
apply (rotate_tac)
apply (fact converse_rtrancl_into_rtrancl)
done
Or, if you want to include some kind of rule tactic, this would look like this:
apply (rotate_tac)
apply (erule converse_rtrancl_into_rtrancl)
apply (assumption)
(I personally don't use apply scripts ever in my everyday work. So apply-style gurus might know more elegant ways of handling this kind of situation. ;) )
Regarding your 1=(1::nat) / simp_all fix:
The whole goal can directly be solved by simp_all. So, attempts with adding stuff like 1=1 probably did not really tell you a lot about how much the other methods contributed to solving the proof.
However, the additional assumption seems to actually help Isabelle match converse_rtrancl_into_rtrancl correctly. (Don't ask me why!) So, one could indeed circumvent the problem by adding this spurious assumption and then eliminating it with refl again like:
apply (subgoal_tac "1=(1::nat)")
apply (erule converse_rtrancl_into_rtrancl)
apply (assumption)
apply (rule refl)
This does not look particularly elegant, of course.
The [[unify_trace_failure]] probably only really helps if one is familiar with the internal workings of Nipkow's higher-order unification algorithm. (I'm not.) I think the hint for the future here would really be that one must look closely at the order of premises for some tactics (rather than at the unifier debug output).
I found an explanation in the Isar reference 6.4.3 .
The with b1..bn command is equivalent to from b1..bn and this, i.e. it enters the proof chaining mode which adds them as (structured) assumptions to proof methods.
Basic proof methods (such as rule) expect multiple facts to be given
in their proper order, corresponding to a prefix of the premises of
the rule involved. Note that positions may be easily skipped using
something like from _ and a and b, for example. This involves the
trivial rule PROP ψ =⇒ PROP ψ, which is bound in Isabelle/Pure as “_”
(underscore).
Automated methods (such as simp or auto) just insert any given facts
before their usual operation. Depending on the kind of procedure
involved, the order of facts is less significant here.
Given the information about the 'with' translation and that rule expects chained facts in order, we could try to flip the chained facts. And indeed this works:
from this and `(y,x)∈ r^*` show "(z,x) ∈ r^*"
by (rule converse_rtrancl_into_rtrancl)
I think "6.4.3 Fundamental methods and attributes" is also relevant because it describes how the basic methods interact with incoming facts. Notably, the '-' noop which is sometimes used when starting proofs turns forward chaining into assumptions on the goal.
with `(y,x)∈ r^*` show "(z,x) ∈ r^*"
apply -
apply (rule converse_rtrancl_into_rtrancl; assumption)
done
This works because the first apply consumes all chained facts so the second apply is pure backwards chaining. This is also why the subgoal_tac or rotate_tac worked, but only if they are in seperate apply commands.

Why can't I make my cases explicit in Isabelle when the proof is already complete but gives a "fails to refine any pending goal" error?

I'm going through chapter 5 of concrete semantics.
I got some error while working through this toy example proof:
lemma
shows "¬ ev (Suc 0)"
I know this is more than needed (since by cases) magically solves everything & gives a finished proof, but I wanted to make explicit the cases.
I tried this:
lemma
shows "¬ ev (Suc 0)"
proof (rule notI)
assume "ev (Suc 0)"
then show False
proof (cases)
case ev0
then show ?case by blast
next
case evSS
then show ?case sorry
qed
but if I put my mouse on the ?cases I get a complaint by Isabelle's (type checker?) verifier:
proof (chain)
picking this:
Failed to refine any pending goal
Local statement fails to refine any pending goal
Failed attempt to solve goal by exported rule:
HOL.induct_true
what does this error mean?
Why can't I make the proof explicit with the case syntax here? even if it's trivial?
How question is, how do you close a case immediately?
If there are no cases to be proved you can close a proof immediately with qed.
is referenced later but I can't make it work for real proofs.
The auto-generated proof outline is sometimes just wrong. This is one such case.
The reason why cases solves your goal here is that it does some pre-simplification of the cases (as documented in §6.5.2 of the Isabelle/Isar reference manual). This is enough to make both cases disappear automatically here, since they are clearly impossible. Your proof state therefore has no proof obligations left, and Isar only allows you to prove things with show that you still have to prove. That's why you get the error message Failed to refine any pending goal: There simply are no pending goals.
You can disable the pre-simplification of cases using the (no_simp) parameter, i.e.
proof (cases (no_simp))
Note however that cases does not define the ?case variable because it does not change the goal. Just use ?thesis instead.

Is it possible to "free" top-level universally quantified variables using tactics in Isabelle?

In short, I would like to go from this:
proof (prove)
goal (1 subgoal):
1. ⋀ myVar . somePredicate myVar
to this:
proof (prove)
goal (1 subgoal):
1. somePredicate myVar
by using tactics. The only solution I can find is to write a new lemma for example:
lemma myPredicateHolds_aux : "somePredicate myVar"
sorry
and then the original ⋀ myVar . somePredicate myVar usually can be solved by writing:
using myPredicateHolds_aux by blast
but I wonder whether there is a better way (using tactics), for convenience, and because, if the property is very intricate, blast may fail.
The proof (prove) suggests you're writing a proof script, in which case you can use subgoal for myVar. The "isar-ref" manual says a little more about it, I think (though it may be a bit dense).
You can also, and I believe this is usually the "preferred" way to do it, go into structured Isar proof mode and use fix:
proof -
fix myVar
show "somePredicate myVar"
proof ...

Algebraic simplifications in Isabelle

I have been playing around with basic examples of proofs in Isabelle.
Consider the following simple proof:
lemma
fixes n::nat
shows "n*(n+1) = n^2 + n"
by simp
It seems to me that a powerful proof assistant like Isabelle should be able to prove this lemma without much guidance.
However, I was surprised to find out that Isabelle actually fails at applying the rule simp here (I also tried other "generic" rules like simp_all, auto, force, blast but the result is the same).
If I replace the last line by the following, then it works out:
by (simp add: power2_eq_square)
My concern is that I feel like I shouldn't have had to tell the system about the specific rule power2_eq_square to complete this proof.
Playing around with similar trivial examples, I found that simp is able to prove
n*(n+2)=n*n+n*2
but fails with
n*(n+3)=n*n+n*3
The last example is proven
by (simp add: distrib_left)
It is a complete mystery to me why I need to specify distrib_left in that second example, but not in the first (why is that?).
I have given these examples not for their own sake, but mainly to illustrate my main question:
Is there a way to automate the verification of routine algebraic identities such as the above in Isabelle? If there isn't, then why not? What are the technical obstacles?
Daily proof work indeed often stumbles over »routine algebraic identities«; but after some practical experience one usually develops some intuition how to solve such problems effectively. A pattern I have developed over the years, by example:
context semidom
begin
lemma "a * (b ^ 2 + c) + 2 = a * b * b + c * a + 2"
A typical explorative proof starts with
apply auto
Then associativity and commutative are considered also
apply (auto simp add: ac_simps)
Then more algebaic normalizing rules are applied
apply (auto simp add: algebra_simps)
The last gap is then easily filled by sledgehammer
apply (simp add: power2_eq_square)
After that, the proof can be compactified
by (simp add: algebra_simps power2_eq_square)
The lemma
lemma power2_eq_square: "a^2 = a * a"
is not a good rewrite rule in general, as it will easily blow up the size of terms. So it is expected that a term rewriting based automation like simp will not apply this without you telling it to.
What you want is some sort of proof search, and Isabelle provides that: After writing your lemma, you can invoke the sledgehammer tool, and it will readily and quickly find the proof for you:
Sledgehammering...
Proof found...
"z3": Try this: by (simp add: power2_eq_square) (1 ms)
"cvc4": Try this: by (simp add: power2_eq_square) (5 ms)

Why does simp "fail to apply initial proof method" where blast succeeds with the same facts?

I have modelled this calculus in Isabelle as an exercise. Here's my code so far.
I use sledgehammer to prove simple theorems which usually suggests to use blast supplemented with a subset of the rules of the calculus, e.g.:
by (blast intro: DH_bdiam2_f Fbox2_R l2)
That works fine and dandy, however if I try to use simp adding the same rules, e.g.:
by (simp only: DH_bdiam2_f Fbox2_R l2)
I get an error that none of the rules were applicable
Failed to apply initial proof method⌂:
What is going on exactly? I was expecting that simp either terminates or times out, but certainly not this. What am I missing?
This is the error message you get when a tactic failed to produce a proof step. For simp, that's the case when no rule matches (i.e. rewriting with neither DH_bdiam2_f ... is impossible). Looking at your code, these rules come from an inductive predicate. Usually, those are not suitable as rewriting (= simplification) rules. Scattered throughout Programming and Proving in Isabelle/HOL, there are hints about what are suitable simplification and introduction rules, along with explanations about what tactics are suitable.

Resources