datatype form = VAR "num"
| FALSE
| DISJ "form" "form"
| NOT "form"
| DIAM "form"
fun demodalize :: "form ⇒ form"
where
"demodalize FALSE = FALSE"
| "demodalize (VAR p) = VAR p"
| "demodalize (DISJ form1 form2) = DISJ (demodalize form1) (demodalize form2)"
| "demodalize (NOT form) = NOT (demodalize form)"
| "demodalize (DIAM form) = demodalize form"
fun propform :: "form ⇒ bool"
where
"propform FALSE = True"
| "propform (VAR p) = True"
| "propform (DISJ f1 f2) = (propform f1 ∧ propform f2)"
| "propform (NOT f) = propform f"
| "propform (DIAM f) = False"
Problem is:
lemma propform_demodalize : "propform (demodalize f)"
proof (induct rule:form.induct)
case (VAR x)
then show ?case by simp
next
case FALSE
then show ?case by simp
next
case (DISJ x1a x2)
then show ?case by simp
next
case (NOT x)
then show ?case by simp
next
case (DIAM x)
then show ?case sorry
qed
"propform" says a modal formula is a propositional formula. "demodalize" discards all modal operators "DIAM" of a formula.
It seems like it does not understand the definition of demodalize because it thinks I should prove:
image.png
It seems to completely ignore the "demodalize", and asks to prove every formula is propositional. Here is the goal list generated:
image.png
It should not happen and may be my stupid, but I do not see now.
Specify the variable you are doing induction on instead of letting Isabelle guessing it (which sometimes like here goes wrong)…
Actually ah no(induction rule: demodalize.induct)
is probably the most natural induction principle and then the guess is correct…
But here is only one variable? What does it guess?
Mathias Fleury said:
Actuallyah no(induction rule: demodalize.induct)
is probably the most natural induction principle and then the guess is correct…
Why no ... Let me try.
it still picks the wrong thing
If I write "(induct f rule:form.induct)" instead, it does work!
I am just curious why it can even make a wrong guess.
Small list of stupid thinks to induce on:
apply (induction "demodalize f")
apply (induction "propform f")
apply (induction "propform (demodalize f)")
apply (induction "demodalize (demodalize f)")
all of these inductions are possible
and the induction has some heuristics to pick the right one
Ah? I told it to use rule: form.induct.
Yeah and? form.induct works on everything of type form
So Isabelle is not doing unification with the theorem in the screenshot?!
sure it does
but there are many possible P
P is the whole goal, right? I am proving by induction on propform (demodalize f)
.
Take P = %_. propform (demodalize f)
then you are doing induction on a variable that is not in the goal
Oh it then thinks the f is a fixed free variable... And want to unify with "!x. propform (demodalize f)"?
That is exactly why you can specify the variable with (induction f rule: form.induct)
. Avoid confusing
Mathias Fleury said:
then you are doing induction on a variable that is not in the goal
That's awful... I wonder if there exists a case of "inducting on a variable that is not in the goal" to be useful.
Never which is why induction did not pick that ;-)
Mathias Fleury said:
That is exactly why you can specify the variable with
(induction f rule: form.induct)
. Avoid confusing
Given the situation, surely I will from now on...
instead it decided to generalize the demodalize f
to form
and do induction on that
Although in general induction f rule: demodalize.induct
is better here as you pick the version adapted to demodalize
Mathias Fleury said:
instead it decided to generalize the
demodalize f
toform
and do induction on that
Ah? So what happens is that it is proving !f. f = demodalize form ==> propform (demodalize form)?
Try this silly version of the definition to see what happens:
fun propform :: "form ⇒ bool"
where
"propform FALSE = True"
| "propform (VAR p) = True"
| "propform (DISJ (VAR f1) f2) = (propform f2)"
| "propform (DISJ f1 f2) = (propform f1 ∧ propform f2)"
| "propform (NOT f) = propform f"
| "propform (DIAM f) = False"
Yiming Xu said:
Mathias Fleury said:
instead it decided to generalize the
demodalize f
toform
and do induction on thatAh? So what happens is that it is proving !f. f = demodalize form ==> propform (demodalize form)?
No, as you though it is proving that propform form
(do not ask me why, I have no interest to check the code of the induction tactic)
I won't. I will just try your example and I may check later...
Mathias Fleury said:
Yiming Xu said:
Mathias Fleury said:
instead it decided to generalize the
demodalize f
toform
and do induction on thatAh? So what happens is that it is proving !f. f = demodalize form ==> propform (demodalize form)?
No, as you though it is proving that
propform form
I will remember, this is an impressive design...
Mathias Fleury said:
Try this silly version of the definition to see what happens:
fun propform :: "form ⇒ bool" where "propform FALSE = True" | "propform (VAR p) = True" | "propform (DISJ (VAR f1) f2) = (propform f2)" | "propform (DISJ f1 f2) = (propform f1 ∧ propform f2)" | "propform (NOT f) = propform f" | "propform (DIAM f) = False"
You mean use this and use induction f rule: demodalize.induct?
Take that definition and compare:
lemma propform_demodalize : "propform (demodalize f)"
apply (induction f rule: form.induct)
apply auto
oops
lemma propform_demodalize : "propform (demodalize f)"
apply (induction f rule: demodalize.induct)
apply auto
oops
ah no sorry wait
fun demodalize :: "form ⇒ form"
where
"demodalize FALSE = FALSE"
| "demodalize (VAR p) = VAR p"
| "demodalize (DISJ (VAR form1) form2) = DISJ (VAR form1) (demodalize form2)"
| "demodalize (DISJ form1 form2) = DISJ (demodalize form1) (demodalize form2)"
| "demodalize (NOT form) = NOT (demodalize form)"
| "demodalize (DIAM form) = demodalize form"
fun propform :: "form ⇒ bool"
where
"propform FALSE = True"
| "propform (VAR p) = True"
| "propform (DISJ f1 f2) = (propform f1 ∧ propform f2)"
| "propform (NOT f) = propform f"
| "propform (DIAM f) = False"
thm form.induct
lemma propform_demodalize : "propform (demodalize f)"
apply (induction f rule: demodalize.induct)
apply auto
oops
lemma propform_demodalize : "propform (demodalize f)"
apply (induction f rule: form.induct)
apply auto
oops
I think this is what I expected? Identical to HOL4.
Oh I see.
If the definition of demodalize is changed, than if we induct on formula, we need to do case splitting on DISJ case.
But if we just induct on demodalize, then the IH does the case splitting.
Yes I agree! In that case, inducting with demodalize will be better.
I am not confident enough to claim "it works better <=> the inductive definition of a constructor of the datatype requires a case splitting". But so far I believe.
Last updated: Dec 21 2024 at 16:20 UTC