Hi,
I wanna define a partial function. It works if I define:
definition f :: "nat ⇒ nat option"
where
"f x = (if x ∈ {1, 2, 3} then Some 0 else None)"
But I want to specify the range of the function f
is {5,6}
, so I defined:
definition f :: "nat ⇒ nat option"
where
"f x = (if x ∈ {1, 2, 3} then (Some y ∈ {5,6}) else None)"
It caused the error:
Type unification failed: No type arity option :: numeral
Type error in application: incompatible operand type
Operator: (∈) (Some y) :: ??'a option set ⇒ bool
Operand: {5, 6} :: ??'b set
I understand that it considers the return value of Some y ∈ {5,6}
is bool, right?
So, how to specify the range of the function f
?
On syntax level, you are confusing Some
and SOME y. y ∈ {5,6}
. What you have should type for Some (SOME y. y ∈ {5,6})
.
On the conceptual level, you are not defining what you intend to.
Assume you fix your definition with Some (SOME y. y ∈ {5,6})
. Your function f will be defined by:
f: 1,2, or 3 -> some value of {5, 6}, the same for 1, 2, and 3
_ -> None
And again, you cannot know if f(1)
is equal to 5 or 6. You cannot distinguish this in Isabelle. However, f(1)
, f(2)
, and f(3)
are equal to the same value.
As I understand, SOME y. y ∈ {5, 6}
means that the value is 5 or 6. So why we have to put Some
before SOME y. y ∈ {5, 6}
?
Some
is the option
constructor for your nat option
return value.
In
if x ∈ {1, 2, 3} then PLACEHOLDER else None
None has type nat option
. So PLACEHOLDER
must have the same type. SOME y. y ∈ {5, 6}
has type nat
. You need either to convert the nat
to nat option
by Some
. Or change None to something of type nat
(like undefined
or a default value)
Mathias Fleury said:
In
if x ∈ {1, 2, 3} then PLACEHOLDER else None
None has type
nat option
. SoPLACEHOLDER
must have the same type.SOME y. y ∈ {5, 6}
has typenat
. You need either to convert thenat
tonat option
bySome
. Or change None to something of typenat
(likeundefined
or a default value)
It's very clear. Thank you for your explanation.
For the function:
definition f :: "nat ⇒ nat option"
where
"f x = (if x ∈ {1, 2, 3} then Some(SOME y. y ∈ {5, 6}) else None)"
I check the range of it like this:
lemma "ran f = {5,6}"
unfolding f_def ran_def
apply auto
done
And the result is:
proof (prove)
goal (14 subgoals):
1. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
2. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
3. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
4. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
5. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
6. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
7. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
8. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
9. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
10. (SOME y. y = 5 ∨ y = 6) ≠ 5 ⟹ (SOME y. y = 5 ∨ y = 6) = 6
A total of 14 subgoals...
I think that subgoals should be proved by simp
because
P ⟹ Q ≡ ¬P ∨ Q ≡
(SOME y. y = 5 ∨ y = 6) = 5 ∨ (SOME y. y = 5 ∨ y = 6) = 6
So why this lemma cannot be proved?
using someI[of \<open>%y. y \<in> {5,6}\<close>, of 5]
It is wrong due to:
Mathias Fleury said:
f(1)
,f(2)
, andf(3)
are equal to the same value.
I think most of the conversion comes from the fact that you don't understand some. You are confusing it with non-determinism, which is the wrong way of seeing it.
Hilbert choice takes a predicate as argument. If there is no way to make the predicate true, some non-specified constant is returned. Otherwise, it returns some non-specified constant fulfilling the predicate.
What does non-specified mean? It means that you cannot know which elements is returned and the element changes every time Isabelle is restarted (roughly speaking).
What is the difference with non-determinism? Well, the returned is _always_ the same within one Isabelle execution. That means that (SOME y::nat. y = 5 ∨ y = 6)
will return the same element as (SOME y::nat. y = 5 ∨ y = 6)
, (SOME y::nat. y = 5 ∨ y = 6)
, and (SOME y::nat. y = 5 ∨ y = 6)
. This is not the same as non-determinsm, where calling the C function rand()
, rand()
, rand()
, and rand()
, can return different values [1].
What does that mean for your use case? It means that you need to do recursion to be construct the mapping and _exclude the elements mapped so far_. This is also entails that your current approach does not work.
[1] other examples include file parsing, reading environment values, looking at a thermometer, ...
So, when I use Some
, the return values of each running time are different, right?
(SOME y::nat. y = 5 ∨ y = 6) = (SOME y::nat. y = 5 ∨ y = 6)
is always true, so no.
Unlike a C version likerand() == rand()
.
Mathias Fleury said:
- you need to help simp, for example with
using someI[of \<open>%y. y \<in> {5,6}\<close>, of 5]
- your realize that your lemma is wrong, right?
After applying it, the output is:
proof (prove)
using this:
5 ∈ {5, 6} ⟹ (SOME y. y ∈ {5, 6}) ∈ {5, 6}
goal (1 subgoal):
1. {b. ∃a. (if a ∈ {1, 2, 3} then Some (SOME y. y ∈ {5, 6}) else None) = Some b} = {5, 6}
Actually, I don't know what's wrong. Can you explain it?
using someI[of \<open>%y. y \<in> {5,6}\<close>, of 5] apply simp
The output is:
proof (prove)
goal (1 subgoal):
1. (SOME y. y = 5 ∨ y = 6) = 5 ∨ (SOME y. y = 5 ∨ y = 6) = 6 ⟹
{b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{5, 6}
it equals to
{b. ∃a.(a = Suc 0 ∨ a = 2 ∨ a = 3) ∧ (SOME y. y = 5 ∨ y = 6) = b)} = {5,6}
I think it's TRUE.
No it is not.
We know that (SOME y. y = 5 ∨ y = 6)
is either 5 or 6, but let's call it N
.
your set is:
{b. ∃a.(a = Suc 0 ∨ a = 2 ∨ a = 3) ∧ N = b}
By miniscoping this is the same as:
{b. (∃a.(a = Suc 0 ∨ a = 2 ∨ a = 3) )∧ N = b}
Now, ∃a.(a = Suc 0 ∨ a = 2 ∨ a = 3)
is true. So we can simplify the set to:
{b. True ∧ N = b}
Therefore, the set is equal to
{N}
And {N}
is not equal to {5,6}
As I said before, the choice value does not change. It is always the same.
As I understand your explanation, y
should be {5}
or {6}
not {5,6}
right?
If so, it's true for the command:
"f x = (if x ∈ {1, 2, 3} then Some(SOME y. y ∈ {5, 6}) else None)"
but in the lemma, I check the range of the function. So if y = {5} or {6}
so the ran f = {5, 6}
right?
Let's be precise first: y
is 5
or 6
, not {5}
or {6}
ah yes, my bad, I'm following the set then made this mistake.
Your definition is equivalent to:
f x = (if x ∈ {1, 2, 3} then Some N else None)
The N
is constant. It has a single value. It does not change never. NEVER.
So ran f = {N}
. Either ran f = {5}
or ran f = {6}
holds. That is all you can say.
But many things don't hold: ran f = {5,6}
never holds. Same for ran f = {4}
.
Maybe this view helps you more: SOME y. y ∈ {5, 6}
is a constant. But it is constant only I (technically, the model) knows. But it is only a constant.
Mathias Fleury said:
So
ran f = {N}
. Eitherran f = {5}
orran f = {6}
holds. That is all you can say.But many things don't hold:
ran f = {5,6}
never holds. Same forran f = {4}
.
Following your explanation, I changed the lemma to:
lemma "ran f = {5} ∨ ran f = {6}"
unfolding f_def ran_def
apply simp
done
and it's still unprovable
Failed to finish proof:
goal (1 subgoal):
1. {b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{5} ∨
{b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{6}
In that case, it is provable. simp is not strong enough…
lemma
defines ‹N == (SOME y :: nat. y = 5 ∨ y = 6)›
shows
‹{b::nat. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{5} ∨
{b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{6::nat}
›
using someI[of \<open>%y::nat. y = 5 ∨ y = 6\<close>, of 5]
unfolding N_def[symmetric]
by auto
But it seems went too far from my purpose. I intend to check the range of the function f x = (if x ∈ {1, 2, 3} then Some(SOME y. y ∈ {5, 6}) else None)
.
I mean that if y
is either 5
or 6
, the range is {5,6}
Thee range is the set of all possible values from f
you have either 5 or 6, but not both
let's try to be more formal, maybe that helps.
There is a model of HOL where N is 5. In that world, ran f = {5}
.
There is another model of HOL where N is 6. In that world, ran f = {6}
.
In Isabelle you are in one of those two models (and you don't know which).
Yes, that's why I tried this lemma:
lemma "ran f = {5} ∨ ran f = {6}"
unfolding f_def ran_def
apply auto
done
It should be proved without adding defines
and shows
parts.
Generally, SOME
tends to confuse auto and make thinks more complicated
Therefore I replaced the SOME...
by N
and called auto. The defines just makes that possible
Trinh Le Khanh said:
It should be proved without adding
defines
andshows
parts.
There is no guarantee on what auto can and cannot ...
Actually you don't need the defines:
lemma
‹{b::nat. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{5} ∨
{b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{6::nat}
›
using someI[of \<open>%y::nat. y = 5 ∨ y = 6\<close>, of 5]
by auto
Maybe I still confuse about the proving process. I summary that, from the lemma:
lemma "ran f = {5} ∨ ran f = {6}"
unfolding f_def ran_def
apply simp
I got the subgoal:
goal (1 subgoal):
1. {b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{5} ∨
{b. ∃a. (a = Suc 0 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 2 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧
(a = 3 ⟶ (SOME y. y = 5 ∨ y = 6) = b) ∧ (a = Suc 0 ∨ a = 2 ∨ a = 3)} =
{6}
Then, I remove my lemma and create a lemma for this subgoal as you presented. Right?
If so, we just prove the subgoal, it doesn't mean that the lemma is proved.
lemma "ran f = {5} ∨ ran f = {6}"
unfolding f_def ran_def
using someI[of ‹λy::nat. y = 5 ∨ y = 6›, of 5]
by auto
Thank you. I also try using someI[of ‹λy::nat. y ∈ {5,6}›]
and it worked. I have one more question, how do you know what rule should be applied for the proving? For instance, someI
in this lemma.
Last updated: Dec 21 2024 at 16:20 UTC