Limit of c^n (with ¦c¦<1) is 0 (Isabelle) - isabelle

Does anyone know a rule for showing
"¦c¦<1 ==> (λn. c^n) ---> 0"
in the reals?
I have found the following rules using the 'query' panel:
Limits.LIMSEQ_rabs_realpow_zero2: ¦?c¦ < 1 ⟹ op ^ ?c ---> 0
Limits.LIMSEQ_rabs_realpow_zero: ¦?c¦ < 1 ⟹ op ^ ¦?c¦ ---> 0
Limits.LIMSEQ_realpow_zero: 0 ≤ ?x ⟹ ?x < 1 ⟹ op ^ ?x ---> 0
although I am a little confused by what op means.

The lemma you are trying to prove is precisely LIMSEQ_rabs_realpow_zero2. You can therefore prove your goal with apply (rule LIMSEQ_rabs_realpow_zero2).
E.g. try term "λx y. x + y" or term "λx. 1 + x" in Isabelle. The output will be op + and op + 1, respectively.
The op ^ is simply a shorthand for λx y. x ^ y. In general, op in Isabelle is syntax for turning a binary infix operator into a function with two arguments (a bit like in ML).

Related

Using `defines` with induction

Consider following lemma which should be easily provable:
lemma
fixes n m::nat
defines "m ≡ n - 1"
shows "m ≤ n"
proof(induction n)
case 0
then show ?case unfolding m_def
(* Why does «n» appear here? *)
next
case (Suc n)
then show ?case sorry
qed
However after unfolding m, the goal becomes n - 1 ≤ 0 instead of 0 - 1 ≤ 0 rendering the goal unprovable since n = 2 is a counterexample.
Is this a bug in Isabelle? How can I unfold the definition correctly?
I think a useful explanation could be the following: Recall the definition of nat.induct, namely
?P 0 ⟹ (⋀n. ?P n ⟹ ?P (Suc n)) ⟹ ?P ?n
and note that ?n means that n is implicitly universally quantified, that is, the previous definition is equivalent to
⋀n. ?P 0 ⟹ (⋀n. ?P n ⟹ ?P (Suc n)) ⟹ ?P n
Now, when applying nat.induct to your example, clearly the first subgoal to prove is ?P 0, i.e., m ≤ 0. However, in that context, n is still an arbitrary but fixed nat, in particular it does not hold that n = 0, and that is the reason why after unfolding the definition of m you get n - 1 ≤ 0 as the new subgoal. With respect to your specific question, the problem is that you cannot prove your result by induction on n (but you can easily prove it using unfolding m_def by simp).
As Javier pointed out, the n defined in the lemma head is different from the n created by induction. In other words, any facts from "outside" that reference n are not directly usable within the proof (induction n) environment.
However, Isabelle does offer a way to "inject" such facts, by piping them into induction:
lemma
fixes n m::nat
defines "m ≡ n - 1"
shows "m ≤ n"
using m_def (* this allows induction to use this fact *)
proof(induction n)
case 0
then show ?case by simp
next
case (Suc n)
then show ?case by simp
qed
using assms will work just as well in this case.
Note that direcly referring to m_def is no longer necessary, since a version of it is included for each case (in 0.hyps and Suc.hyps; use print_cases inside the proof for more information).

How to generate code for less_eq operation

I need to generate a code calculating all values greater or equal to some value:
datatype ty = A | B | C
instantiation ty :: order
begin
fun less_ty where
"A < x = (x = C)"
| "B < x = (x = C)"
| "C < x = False"
definition "(x :: ty) ≤ y ≡ x = y ∨ x < y"
instance
apply intro_classes
apply (metis less_eq_ty_def less_ty.elims(2) ty.distinct(3) ty.distinct(5))
apply (simp add: less_eq_ty_def)
apply (metis less_eq_ty_def less_ty.elims(2))
using less_eq_ty_def less_ty.elims(2) by fastforce
end
instantiation ty :: enum
begin
definition [simp]: "enum_ty ≡ [A, B, C]"
definition [simp]: "enum_all_ty P ≡ P A ∧ P B ∧ P C"
definition [simp]: "enum_ex_ty P ≡ P A ∨ P B ∨ P C"
instance
apply intro_classes
apply auto
by (case_tac x, auto)+
end
lemma less_eq_code_predI [code_pred_intro]:
"Predicate_Compile.contains {z. x ≤ z} y ⟹ x ≤ y"
(* "Predicate_Compile.contains {z. z ≤ y} x ⟹ x ≤ y"*)
by (simp_all add: Predicate_Compile.contains_def)
code_pred [show_modes] less_eq
by (simp add: Predicate_Compile.containsI)
values "{x. A ≤ x}"
(* values "{x. x ≤ C}" *)
It works fine. But the theory looks over-complicated. Also I can't calculate values less or equal to some value. If one will uncoment the 2nd part of less_eq_code_predI lemma, then less_eq will have only one mode i => i => boolpos.
Is there a simpler and more generic approach?
Can less_eq support i => o => boolpos and o => i => boolpos at the same time?
Is it possible not to declare ty as an instance of enum class? I can declare a function returning a set of elements greater or equal to some element:
fun ge_values where
"ge_values A = {A, C}"
| "ge_values B = {B, C}"
| "ge_values C = {C}"
lemma ge_values_eq_less_eq_ty:
"{y. x ≤ y} = ge_values x"
by (cases x; auto simp add: dual_order.order_iff_strict)
This would allow me to remove enum and code_pred stuff. But in this case I will not be able to use this function in the definition of other predicates. How to replace (≤) by ge_values in the following definition?
inductive pred1 where
"x ≤ y ⟹ pred1 x y"
code_pred [show_modes] pred1 .
I need pred1 to have at least i => o => boolpos mode.
The predicate compiler has an option inductify that tries to convert functional definitions into inductive ones. It is somewhat experimental and does not work in every case, so use it with care. In the above example, the type classes make the whole situation a bit more complicated. Here's what I managed to get working:
case_of_simps less_ty_alt: less_ty.simps
definition less_ty' :: "ty ⇒ ty ⇒ bool" where "less_ty' = (<)"
declare less_ty_alt [folded less_ty'_def, code_pred_def]
code_pred [inductify, show_modes] "less_ty'" .
values "{x. less_ty' A x}"
The first line convertes the pattern-matching equations into one with a case expression on the right. It uses the command case_of_simps from HOL-Library.Simps_Case_Conv.
Unfortunately, the predicate compiler seems to have trouble with compiling type class operations. At least I could not get it to work.
So the second line introduces a new constant for (<) on ty.
The attribute code_pred_def tells the predicate compiler to use the given theorem (namely less_ty_alt with less_ty' instead of (<)) as the "defining equation".
code_pred with the inductify option looks at the equation for less_ty' declared by code_pred_def and derives an inductive definition out of that. inductify usually works well with case expressions, constructors and quantifiers. Everything beyond that is at your own risk.
Alternatively, you could also manually implement the enumeration similar to ge_values and register the connection between (<) and ge_values with the predicate compiler. See the setup block at the end of the Predicate_Compile theory in the distribution for an example with Predicate.contains. Note however that the predicate compiler works best with predicates and not with sets. So you'd have to write ge_values in the predicate monad Predicate.pred.

Ignoring a case to prove a goal through elimination

I have the following lemma to show the derivative of f at x is D.
lemma lm1:
assumes "(∀h. (f (x + h) - f x) = D*h)"
shows "DERIV f x :> D"
proof cases
assume notzero: "∀h. h ≠ 0"
have cs1: "(λh. (f (x + h) - f x) / h) -- 0 --> D" using assms notzero by auto
from this DERIV_def show ?thesis by auto
From the assumptions, I can easily prove the lemma by taking the limit then using DERIV_def. For this I have to assume that h ≠ 0. Continuing with the proof by cases I have to show that even when h = 0, the goal is true, however this can't be done when h = 0 as the assumption becomes 0 = 0. The lemma becomes trivial.
Is there a way I can prove the goal, which is this case is that f has derivative D at x, without the additional assumption that h ≠ 0?
edit: After further research, I came across the use of elimination rules in Isabelle which may be helpful. Also, I understand that the lemma is correct as the if the function is continuous, then the derivative at 0 also exists.
I have been searching for the correct use and implementation of the the above information. How can I improve my search, and where should I be looking?

How to use obtain in existential proofs?

I tried to prove an existential theorem
lemma "∃ x. x * (t :: nat) = t"
proof
obtain y where "y * t = t" by (auto)
but I could not finish the proof. So I have the necessary y but how can I feed it into the original goal?
Soundness of natural deduction requires that you get hold of the witness before you open the existential quantifier. This is why you are not allowed to use obtained variables in show statements. In your example, the proof step implicitly applies the rule exI. This turns the existentially quantified variable x into the schematic variable ?x, which can be instantiated later, but the instantiation may only refer to variables that have been in scope when ?x came into place. In the low-level proof state, obtained variables are meta-quantified (!!) and the instantiations for ?x can only refer to such variables that appear as a parameter to ?x.
Therefore, you have to switch the order in your proof:
lemma "∃ x. x * (t :: nat) = t"
proof - (* method - does not change the goal *)
obtain y where "y * t = t" by (auto)
then show ?thesis by(rule exI)
qed
You can give the witness (i.e. the element you want to put in for x) in the show clause:
lemma "∃ x. x * (t :: nat) = t"
proof
show "1*t = t" by simp
qed
Alternatively, when you already know the witness (1 or Suc 0 here), you can explicitly instantiate the rule exI to introduce the existential term:
lemma "∃ x. x * (t :: nat) = t"
by (rule exI[where x = "Suc 0"], simp)
Here, the existential quantifier introduction rule thm exI is
?P ?x ⟹ ∃x. ?P x
you can explore and instantiate it gradually with the answer.
thm exI[where x = "Suc 0"] is:
?P (Suc 0) ⟹ ∃x. ?P x
and exI[where P = "λ x. x * t = t" and x = "Suc 0"] is
Suc 0 * t = t ⟹ ∃x. x * t = t
And Suc 0 * t = t is only one simplification (simp) away. But the system can figure out the last instantiation P = "λ x. x * t = t" via unification, so it isn't really necessary.
Related:
Instantiating theorems in Isabelle

Isabelle: Predecessor function

I am not sure, but I think sometimes my proofs would be easier if I had a predecessor function, e.g., in case a variable is known not to be zero.
I don't know a good example, but perhaps here: { fix n have "(n::nat) > 0 ⟹ (∑i<n. f i) = Predecessor n" sorry }
Possibly because it is not a good idea, there is no predecessor function in the library.
Is there a way to simulate a predecessor function or similar?
I have thought of this example:
theorem dummy:
shows "1=1" (* dummy *)
proof-
(* Predecessor function *)
def pred == "λnum::nat. (∑i∈{ i . Suc i = num}. i)"
{fix n :: nat
from pred_def have "n>0 ⟹ Suc (pred n) = n"
apply(induct n)
by simp_all
}
show ?thesis sorry
qed
Your definition is unnecessarily complicated. Why do you not just write
def pred ≡ "λn::nat. n - 1"
Then you can have
have [simp]: "⋀n. n > 0 ⟹ Suc (pred n) = n" by (simp add: pred_def)
In the case of 0, the pred function then simply returns 0 and Suc (pred 0) = 0 obviously doesn't hold. You could also define pred ≡ "λn. THE n'. Suc n' = n". That would return the unique natural number whose successor is n if such a number exists (i.e. if n > 0) and undefined (i.e. some natural number you know nothing about) otherwise. However, I would argue that in this case, it is much easier and sensible to just do pred ≡ λn::nat. n - 1.
I would suspect that in most cases, you can simply forgo the pred function and write n - 1; however, I do know that it is sometimes good to have the - 1 “protected” by a definition. In these cases, I usually def a variable n' as n - 1 and prove Suc n' = n – basically the same thing. In my opinion, seeing as proving this takes only one line, it does not really merit a definition of its own, such as this pred function, but one could make a reasonable case for it, I guess.
Another thing: I've noticed you use lemma "1 = 1" as some kind of dummy environment to do Isar proofs in. I would like to point out the existence of notepad, which exists precisely for that use case and that can be used as follows:
notepad
begin
have "some fact" by something
end

Resources