I am trying to learn how to use the THE syntax in Isabelle/HOL (2020). In the tutorial main.pdf, there is:
The basic logic: x = y, True, False, ¬ P, P ∧ Q, P ∨ Q, P −→ Q, ∀ x. P,
∃ x. P, ∃!x. P, THE x. P.
I can understand what the others mean, but not the last one "THE x. P". My best guess is "the (maybe unique) x that satisfy property P". So I tried to state a toy lemma as follows:
lemma "0 = THE x::nat. (x ≥ 0 ∧ x ≤ 0)"
, which means that the x that is both ge and le 0 is 0.
But I get an error in Isabelle/jEdit with a highlight on the "THE" word.
I tried to search with the keywords Isabelle and "THE", but obviously the word "THE" is ignored by search engines. Hence the question here.
Can someone help explain the meaning and use of the "THE" syntax, hopefully with the example here?
You need more parentheses.
lemma "0 = (THE x::nat. (x ≥ 0 ∧ x ≤ 0))"
(*the proof*)
using theI[of ‹λx::nat. (x ≥ 0 ∧ x ≤ 0)› 0]
by auto
SOME (resp. THE) is (a variant of) Hilbert's epsilon operator that returns a (the) element that respects a certain property. If none (none or more than one) exist, an underspecified element is returned.
SOME and THE are not executable. They are rarely useful for beginners.
Related
I am learning to use Isabelle to prove certain theories, but I encountered a problem. I would like to know how can I define exchange(X) to ensure that the theorem presented in the code listing below can be stated without causing an error?
theorem exchange_wp2_1:
"
preOrder(T) =X # preOrder(q) # F(S) ∧ exchange(X) ∧ q ≠ null ⟹
preOrder(T)=X # (data q) # preOrder(ltree q) # F ([rtree q] # S)
"
Error:
Type unification failed:Cash of types "_list" and "_tree" Type error
in application:incompatible operand type Operator: exchange::??
'tree⇒bool Operator: X::?? 'b list
I don't know exactly the definitions of preOrder and exchange, but it seems that preOrder returns a list, whereas exchange expects a tree as input. So, in your expression, it is unclear what type X should have: is it a tree or a list?
preOrder(T) = X (so X is list)
exchange X (so X is a tree)
this is what the error message tells you.
Consider the following minimal working example of Isabelle, where I defined two different functions, func1 and func2, that should emulate Eulers Totient function.
Oddly, the obivious definition is false and changing the definition only slightly by introducing ∈ℕ leads to correct, but yet unprovable definition.
(The exact questions I interspersed with the code, as that makes it probably clearer to what I'm referring).
theory T
imports
Complex_Main
"~~/src/HOL/Number_Theory/Number_Theory"
begin
(* Part I*)
definition func1 :: "nat ⇒ nat"
where "func1 n = card {m. m≤n ∧ coprime n m}"
lemma func1_equals : "func1 1 = 2" (* This equation is obviously false...*)
by (auto simp: func1_def)
(* Question 1: Why is this proof correct according to Isabelle? *)
(* Part II*)
definition func2 :: "nat ⇒ nat"
where "func2 n = card {m. m∈ℕ ∧ m≤n ∧(coprime n m)}"
(* Slightly changed definition by incorporating ∈ℕ*)
lemma func2_equals : "func2 1 = 1"
apply (auto simp: func2_def)
(* Unproved subgoal <<card {m ∈ ℕ. m ≤ Suc 0} = Suc >> looks more promising *)
oops
(* Question 2: Which proof method should I use to prove the last lemma?
Interestingly, sledgehammer runs out of time...*)
Question 3: Analogous to Q2 but for func2 4 = 2 ? The difference now is that
the preliminary <<apply (auto simp: func2_def)>> rewrites to a slightly
different subgoal. *)
end
Are there perhaps any more elegant ways to define the Euler totient function ?
Your two definitions are equivalent:
lemma "func1 n = func2 n"
by (simp add: func1_def func2_def Nats_def)
The reason why you get 2 instead of 1 is a subtle one and a perfect example of the kind of problems you run into when you formalise mathematical definitions: The natural numbers in Isabelle contain 0, so if you evaluate func1 1, you look at the numbers no greater than 1 – 0 and 1 – and check which of them are coprime to 1. Since gcd 0 n = n for all n, you find that both 0 and 1 are coprime to 1 and therefore the result is 2.
Euler's totient function only counts the positive integers less than n that are coprime to n, so your definition should look more like this:
definition totient :: "nat ⇒ nat" where
"totient n = card {k ∈ {0<..n}. coprime k n}"
If you want code generation to work, you can use the following code equation:
lemma totient_code [code]: "totient n = card (Set.filter (λk. coprime k n) {0<..n})"
by (simp add: totient_def Set.filter_def)
Then you can do this:
value "map (int ∘ totient) [1..<10]"
(* Output: "[1, 1, 2, 2, 4, 2, 6, 4, 6]" :: "int list" *)
Note that while I think the totient function would be very nice to have in Isabelle, I'm not sure it's the best think for a beginner to explore, since the proofs involving cardinalities of sets and these things might get a bit involved. A good way to get to know the system is the free bok Concrete Semantics by Nipkow and Klein. The examples and exercises in that book are more computer science/programming-oriented, but the material is more geared towards beginners and more amenable to interactive theorem proving in the sense that the proofs tend to get less messy and require less experience with the system.
And, by the way, the reason why sledgehammer fails to prove func2 1 = 1 is because the result is 2 and not 1. You can prove that by unfolding the definition of ℕ (which, for natural numbers, is basically just UNIV) as I did above, either by doing unfolding Nats_def or adding Nats_def to the simp set with simp add:.
Can you prove using reflexivity that f(n) equals big Theta(f(n))? It seems straight forward when thinking about it because f(n) is bounded above and below by itself. But how will I write this down? And does this apply to big Omega and big O
I believe what you are intending to ask is (w.r.t. #emory:s answer) is something along the lines:
"For some function f(n), is it true that f ∈ ϴ(f(n))?"
If you emanate from the formal definition of Big-ϴ notation, it is quite apparent that this holds.
f ∈ ϴ(g(n))
⇨ For some positive constants c1, c2, and n0, the following holds:
c1 · |g(n)| ≤ |f(n)| ≤ c2 · |g(n)|, for all n ≥ n0 (+)
Let f(n) be some arbitrary real-valued function. Set g(n) = f(n) and choose, e.g., c1=0.5, c2=2, and n0 = 1. Then, naturally, (+) holds:
0.5 · |f(n)| ≤ |f(n)| ≤ 2 · |f(n)|, for all n ≥ 1
Hence, f ∈ ϴ(f(n)) holds.
No we can not because it is not true. ϴ(f(n)) is a set. f(n) is a member of that set. f(n)+1 is also a member of that set.
Why does the second lemma's "auto" proving hangs? The second lemma is a special case of the first one.
primrec ListSumTAux :: "nat list ⇒ nat ⇒ nat" where
"ListSumTAux [] n = n" |
"ListSumTAux (x#xs) n = ListSumTAux xs (n+x)"
lemma ListSumTAux_1 : " ∀a b. ListSumTAux xs (a+b) = a + ListSumTAux xs b"
apply (induct xs)
apply (auto) (* Works fine *)
done
lemma ListSumTAux_2 : "∀ a. ListSumTAux xs a = a + ListSumTAux xs 0 "
apply (induct xs)
apply (auto) (* Hangs on this *)
oops
First of all: it is inconvenient to state goals with the HOL universal quantifier ∀. Free variables in goals are implicitly universally quantified anyway, so you can simply leave out the ∀. You will, however, tell the induction command to universally quantify these variables in the induction step using arbitrary:
lemma ListSumTAux_1 : "ListSumTAux xs (a+b) = a + ListSumTAux xs b"
apply (induct xs arbitrary: a b)
apply (auto)
done
Now, to answer your question: auto gets stuck because your induction hypothesis has the form
⋀a. ListSumTAux xs a = a + ListSumTAux xs 0
auto uses Isabelle's simplifier, which takes this as a rewrite rule. However, you will notice that the left-hand side of this rule matches the right-hande side of this loop, which leads to the infinite rewrite sequence
ListSumTAux xs a → a + ListSumTAux xs 0 → a + (0 + ListSumTAux xs 0) →
a + (0 + (0 + ListSumTAux xs 0))
When these situations occur, there are several things you can do:
you can do a structured Isar proof and do things by hand
you can try to flip the equation in question, i.e. write the goal as a + ListSumTAux xs 0 = ListSumTAux xs a. Then the left-hand side does not match the right-hand side anymore.
you can introduce an additional premise like a ≠ 0 to the equation that prevents the simplifier from looping.
In any case, you will not be able to prove your goal this way, because it is too specific: if you state your goal as ListSumTAux xs a = a + ListSumTAux xs 0, then you will have a 0 in the induction hypothesis as well, but of course, your accumulator will not always be 0.
It is a frequent problem in inductive proofs, especially when accumulators are involved, that you need to generalise your statement in order to strengthen the induction hypothesis before the proof works – like you did in the first statement of the lemma, ListSumTAux_1.
I was reading the book Introduction to Mathematical Philosophy by B.Russell and trying to formalize all the theorems described in it.
One-many relations are described by the following text (contexts on book).
One-many relations may be defined as relations such that, if x has the
relation in question to y, there is no other term x' which also has
the relation to y.
Or, again, they may be defined as follows: Given
two terms x and x', the terms to which x has the given relation and
those to which x' has it have no member in common.
Or, again, they may
be defined as relations such that the relative product of one of them
and its converse implies identity, where the “relative product” of two
relations R and S is that relation which holds between x and z when
there is an intermediate term y, such that x has the relation R to y
and y has the relation S to z.
It poses three ways of definition. I've been successfully described the first two and proved their equivalence. While I was stuck on the third, I tried to get rid of the concepts of 'relative product' and directly get to its connotation but also failed.
Here below are my definitions, did I make any mistakes?
Definition one_many {X} (R : relation X) : Prop :=
forall x y, R x y -> forall x', x <> x' -> ~(R x' y).
Definition one_many' {X} (R : relation X) : Prop :=
forall x x' y, R x y -> R x' y -> x = x'.
Inductive relative_product
{X} (R: relation X) (S: relation X) : relation X :=
| rp0 : forall x y, forall z, R x y -> S y z -> relative_product R S x z.
Inductive converse {X} (R : relation X) : relation X :=
| cv0 : forall x y, R x y -> converse R y x.
Inductive id {X} : relation X :=
| id0 : forall x, id x x.
Definition one_many'' {X} (R : relation X) : Prop :=
forall x y, relative_product R (converse R) x y <-> id x y.
Below is how I interpret the definition of the third and also I failed to prove their equivalence.
Goal forall {X} (R : relation X),
one_many'' R <-> (forall x y, R x y -> forall x', converse R y x' -> x = x').
Proof.
intros. unfold one_many''. split.
intros.
assert (relative_product R (converse R) x x' <-> id x x'). apply H.
inversion H2. apply id_eqv. apply H3.
apply rp0 with y. assumption. assumption.
intros.
split. intro.
inversion H0. subst.
apply id_eqv. apply H with y0.
assumption. assumption.
(* I'm stuck here. This subgoal is obviously not provable. *)
in which proof, id_eqv is Lemma id_eqv : forall {X} (x:X) (y:X), x = y <-> id x y, easily proved in advance.
Can somebody help me to figure out or give me a hint about where I went wrong? Thanks in advance.
I think you've mistranslated the third definition. The original text says:
Or, again, they may be defined as relations such that the relative product of one of them and its converse implies identity
(emphasis mine). That would translate as:
forall x y, relative_product R (converse R) x y -> id x y
That is, it should be a straight implication, rather than the equivalence you've asserted. You can't hope to prove your third statement from either of the others, since it's not equivalent: consider the empty relation on a nonempty set. That's certainly a one-to-many relation, but the relative product with its converse is also empty, so is not the full identity relation.
Wild guess, but you might need R to be reflexive or not empty. Using your script I end up having to prove
1 subgoal
X : Type
R : relation X
H : forall x y : X, R x y -> forall x' : X, converse R y x' -> x = x'
y : X
______________________________________(1/1)
relative_product R (converse R) y y
So you have a relation R, and one inhabitant y:X. To prove your goal, you need to have a witness z such that R y z and R z y. Without any other information, I guess your only shot is to have R to be reflexive and z be y.