Pending sort hypotheses - isabelle

What could be the reason for the following error message:
Pending sort hypotheses: trelations
Here,
trelations is a class type
the error is generated when proving a collection of subgoals by contradiction. Subgoals are of the form: "premise1 ==> premise2 ==> False"
the proof state says "No subgoals!", though.
the assumptions of trelations are consistent to me (https://lists.cam.ac.uk/pipermail/cl-isabelle-users/2012-July/msg00023.html)
Thanks.

The error arises because Isabelle can't know for sure that your assumptions are consistent. Here's a contrived example (from Brian Huffman):
class impossible =
assumes impossible: "∃x. x ≠ x"
lemma False: "False"
proof -
obtain x :: "'a::impossible" where "x ≠ x"
using impossible ..
then show "False" by simp
qed
Clearly, the system must reject this proof, because the impossible sort is empty. The technical reason why it is rejected is that the system doesn't know any instance of impossible.
There are two ways to prevent this from happening:
Before doing any proofs over classes, register an instance.
Add a "sort constraint" as an assumption for your lemma: SORT_CONSTRAINT('a::trelations). It gets automatically discharged when you use the lemma (once you've registered an instance somewhere).

Related

Proving theorem in Isar with no local assumptions

The statement n+0 = n is quite trivial to prove:
theorem add_0: "n+0 = (n::nat)"
apply(simp)
done
Upon trying to convert it to Isar however, I've noticed that it doesn't seem to require any assumption. So in the this attempt:
theorem add_0: "n+0 = (n::nat)"
proof -
thus "True" by simp
qed
It fails, as there are "No current facts available". This second attempt also fails:
theorem add_0: "n+0 = (n::nat)"
proof -
from add_0 show "True" by simp
qed
This time with the error "Failed to refine any pending goal".
Is it possible to prove a statement that requires no assume clause in Isar? If yes, then how?
There are two problems with thus "True"
As you've noted, the proof state that you begin doesn't have any assumptions, therefore no facts in the proof state. The abbreviation thus expands to then show, as we have no facts in our proof state it doesn't make sense to use then so we should instead replace it with show.
show "True" is saying that we want to prove "True" instead we want to prove the goal of the theorem. We can use the schematic variable ?thesis to refer to the original thesis of the theorem. The error Failed to refine any pending goal is just saying that if we were to prove that True is true, it wouldn't help solve the goal of our thesis.
So we can prove our original theorem with an Isar proof using the following pattern.
theorem add_0: "n+0 = (n::nat)"
proof -
show ?thesis by simp
qed

Local assumptions in "state" mode

Frequently, when proving a statement in "prove" mode, I find myself in need of some intermediate statements that are not yet stated nor proved. To state them, I usually make use of the subgoal command, followed by proof- to change to "state" mode. In the process, however, all of the local assumptions are removed. A typical example could look like this
lemma "0 < n ⟷ ((2::nat)^n < 3^n)"
apply(auto)
subgoal
proof-
have "0<n" sorry (* here I would like to refer to the assumption from the subgoal *)
then show ?thesis sorry
qed
subgoal sorry
done
I am aware that I could state the assumptions using assume explicitly. However, this becomes quickly rather tedious when multiple assumptions are involved. Is there an easier way to simply refer to all of the assumptions? Alternatively, is there a good way to implement statements with short proofs directly in "prove" mode?
There is the syntax subgoal premises prems to bind the premises of the subgoal to the name prems (or any other name – but prems is a sensible default):
lemma "0 < n ⟷ ((2::nat)^n < 3^n)"
apply(auto)
subgoal premises prems
proof -
thm prems
There is also a method called goal_cases that automatically gives names to all the current subgoals – I find it very useful. If subgoal premises did not exist, you could do this instead:
lemma "0 < n ⟷ ((2::nat)^n < 3^n)"
apply(auto)
subgoal
proof goal_cases
case 1
By the way, looking at your example, it is considered a bad idea to do anything after auto that depends on the exact form of the proof state, such as metis calls or Isar proofs. auto is fairly brutal and might behave differently in the next Isabelle release so that such proofs break. I recommend doing a nice structured Isar proof here.
Also note that your theorem is a direct consequence of power_strict_mono and power_less_imp_less_base and can be proven in a single line:
lemma "0 < n ⟷ ((2::nat)^n < 3^n)"
by (auto intro: Nat.gr0I power_strict_mono)`

How to abort a proof in 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.

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.

Use of obtain produces a fixed type variable warning

A question is posed on the IsaUserList on how to prove this lemma:
lemma "dom (SOME b. dom b = A) = A"
As a first response, P.Lammich says that obtain needs to be used:
You have to show that there is such a beast b, ie,
proof -
obtain b where "dom b = A" ...
thus ?thesis
sledgehammer (*Should find a proof now, using the rules for SOME, probably SomeI*)
Here, I have one main question, one secondary question, and I wonder about some differences between what P.Lammich says to do, some things M.Eberl does, and the results that I got.
Q1: I get the warning Introduced fixed type variable(s): 'c in "b__" at my use of obtain, and at the use of the by statement that proves the obtain. Can I get rid of this warning?
Q2: Is there a command of three dots, ...? I assume it means, "Your proof goes here." However, it sometimes sounds like the writer is also saying, "...because, after all, the proof is really simple here." I also know that there is the command . for by this, and .. for by rule. Additionally, I entertain the idea that ... is commonly known to be some simple proof statement which I'm supposed to know, but don't.
The following source will show the warning. It could be I'm supposed to fix something. The source also shows how I had to help sledgehammer, which is that I had to put an exists statement it.
I leave the error in that's due to the schematic variable, in case anyone is interested in that.
(* I HELP SLEDGEHAMMER with an exists statement. I can delete the exists
statement after the `metis` proof is found.
The `?'c1` below causes an error, but `by` still proves the goal.
*)
lemma "dom (SOME b. dom b = A) = A"
proof-
have "? x. x = (SOME b. dom b = A)"
by(simp)
from this
obtain b where ob1: "dom b = A"
(*WARNING: Orange squiggly under `obtain`. Message: Introduced fixed type
variable(s): 'c in "b__".*)
by(metis (full_types) dom_const dom_restrict inf_top_left)
thus ?thesis
using[[show_types]]
(*Because of `show_types`, a schematic type variable `?'c1` will be part
of the proof command that `sledgehammer` provides in the output panel.*)
(*sledgehammer[minimize=smart,preplay_timeout=10,timeout=60,verbose=true,
isar_proofs=smart,provers="z3 spass remote_vampire"]*)
by(metis (lifting, full_types)
`!!thesis::bool.(!!b::'a => ?'c1 option. dom b = (A::'a set) ==> thesis)
==> thesis`
someI_ex)
(*ERROR: Illegal schematic type variable: ?'c1::type.
To get rid of the error, delete `?`, or use `ob1` as the fact.*)
qed
My Q1 and Q2 are related to what's above. As part of my wonderings, there is the issue of getting an error because of the schematic variable. I may report that as bug-type issue.
In his IsaUserList response, M.Eberl says that he got the following sledgehammer proof for the obtain. He says the proof is slow, and it is. It's about 2 seconds for me.
by(metis (lifting, full_types)
dom_const dom_restrict inf_top.left_neutral someI_ex)
The proof that sledgehammer found for me above for thus ?thesis is only 4ms.
Answer to Q1
Because of M.Eberl's comment, I made a respectable effort to figure out how to get a witness without using obtain. In the process, I answered my main question.
I got rid of the warning about introducing 'c as a type variable by using b :: "'a => 'b option", instead of b, as shown here:
lemma "dom (SOME b. dom b = A) = A"
proof-
obtain b :: "'a => 'b option" where "dom (b) = A"
by(metis (full_types) dom_const dom_restrict inf_top_left)
thus ?thesis
by(metis (lifting, full_types) exE_some)
qed
Answer to Q2
(Update 140119) I finally found Isar syntax for ..., on page 6 of isar-ref.pdf.
term ... -- the argument of the last explicitly stated result (for infix application this is the right-hand side)
The string ... is not exactly a friendly search string. Finding the meaning was a result of starting to look through chapter 1. I now see that chapters 1, 2, and 6 of isar-ref.pdf are key chapters for getting some help on how to use Isar to do proofs. (End update.)
Concerning an error due to using fix/assume as an alternate to obtain
Now, I return back to M.Eberl telling me I shouldn't use obtain, which happened to be beneficial. But it brings up that it's a major effort to try to figure out how to use the language to make the PIDE happy. The last source I show below is another example of what a hassle it is to learn how to make the PIDE happy. To a large extent, it's just using examples to try and figure out the right combination of syntax and commands.
P.Lammich says to use obtain in his answer. I also looked up the use of obtain in prog-prove.pdf page 42, which discusses it in connection with the use of a witness.
I read a few other things, and I thought it was all telling me that obtain is crucial to fixing a variable or constant with certain properties.
Anyway, I used def to create a witness, so I learned something new:
declare[[show_sorts,show_brackets]]
lemma "dom (SOME b. dom b = A) = A"
proof-
def w == "(SOME b::('a => 'b option). dom b = A)"
hence "dom w = A"
by(metis (lifting, mono_tags) dom_const dom_restrict inf_top_left someI_ex)
print_facts
thus ?thesis
by(metis (lifting, full_types) dom_option_map exE_some)
qed
But, I try to use a fix/assume combination in place def, where supposedly def is an abbreviation, and I get that mysterious and greatly infuriating message, "Failed to refine any pending goal", which makes me wonder why I want to use this language.
declare[[show_sorts,show_brackets]]
lemma "dom (SOME b. dom b = A) = A"
proof-
fix w assume w_def: "w == (SOME b::('a => 'b option). dom b = A)"
hence "dom w = A"
by(metis (lifting, mono_tags) dom_const dom_restrict inf_top_left someI_ex)
print_facts
thus ?thesis
oops
For the two proofs, when the cursor is at the line before print_facts, what I see in the output panel is exactly the same, other than the def proof shows proof (state): step 4, and the fix/assume proofs shows proof (state): step 5. The facts at print_facts are also the same.
From searches, I know that "Failed to refine any pending goal" has been a source of great pain for many. In the past, I finally figured out the trick to get rid of it for what I was doing, but it doesn't make sense here, not that it made sense to me there either.
Update 140118_0054
L.Noschinski gives the subtle tip from IsaUserList 2012-11-13:
When you use "fix" or "def" to define a
variable, they either get just generalized (i.e. turned into schematics)
(fix) or replaced by their right hand side (definitions)
when a block is closed / a show is performed.
So for the fix/assumes form of the proof, I put part of it in brackets, and for some reason, it exports the fact in the way that's needed:
lemma "dom (SOME b. dom b = A) = A"
proof-
{
fix w assume "w == (SOME b::('a => 'b option). dom b = A)"
hence "dom w = A"
by(metis (lifting, mono_tags) dom_const dom_restrict inf_top_left someI_ex)
}
thus ?thesis
by(metis (lifting, full_types) dom_option_map exE_some)
qed
I go ahead and throw in a let form of the proof. I wouldn't have known to use the schematic variable ?w without having looked at M.Eberl's proofs.
lemma "dom (SOME b. dom b = A) = A"
proof-
let ?w = "(SOME b::('a => 'b option). dom b = A)"
have "dom ?w = A"
by(metis (lifting, mono_tags) dom_const dom_restrict inf_top_left someI_ex)
thus ?thesis
by(metis (lifting, full_types) dom_option_map exE_some)
qed

Resources