I'm quite new using Isabelle. I tried to find lemma to solve this
lemma
fixes x y z k :: real
assumes "x ≠ 0"
and "⋀k. (x*(k)⇧2 + y*k + z) ≥0"
shows "discrim x y z ≤ 0"
using sledgehammer give me no results. I found Quadratic_Discriminant theory but there is not lemma proved for inequalities. So does it proved in Isabelle or not yet?
I tried this but I'm not sure if its correct:
lemma
fixes a b c x :: real
fixes p:: "real⇒real"
assumes a:"a ≠ 0"
and ag:"a>0"
and p: "⋀x. p(x) ≥0"
and x:"⋀x. x= -(b/(2*a))"
and eq:"⋀x. p(x) = (a*(x)⇧2 + b*x + c)"
shows " discrim a b c ≤ 0" using assms
by metis
Related
While doing some basic algebra, I frequently arrive at a subgoal of the following type (sometimes with a finite sum, sometimes with a finite product).
lemma foo:
fixes N :: nat
fixes a :: "nat ⇒ nat"
shows "(a 0) = (∑x = 0..N. (if x = 0 then 1 else 0) * (a x))"
This seems pretty obvious to me, but neither auto nor auto cong: sum.cong split: if_splits can handle this. What's more, sledgehammer also surrenders when called on this lemma. How can one efficiently work with finite sums and products containing if-then-else in general, and how to approach this case in particular?
My favourite way to do these things (because it is very general) is to use the rules sum.mono_neutral_left and sum.mono_neutral_cong_left and the corresponding right versions (and analogously for products). The rule sum.mono_neutral_right lets you drop arbitrarily many summands if they are all zero:
finite T ⟹ S ⊆ T ⟹ ∀i∈T - S. g i = 0
⟹ sum g T = sum g S
The cong rule additionally allows you to modify the summation function on the now smaller set:
finite T ⟹ S ⊆ T ⟹ ∀i∈T - S. g i = 0 ⟹ (⋀x. x ∈ S ⟹ g x = h x)
⟹ sum g T = sum h S
With those, it looks like this:
lemma foo:
fixes N :: nat and a :: "nat ⇒ nat"
shows "a 0 = (∑x = 0..N. (if x = 0 then 1 else 0) * a x)"
proof -
have "(∑x = 0..N. (if x = 0 then 1 else 0) * a x) = (∑x ∈ {0}. a x)"
by (intro sum.mono_neutral_cong_right) auto
also have "… = a 0"
by simp
finally show ?thesis ..
qed
Assuming the left-hand side could use an arbitrary value between 0 and N, what about adding a more general lemma
lemma bar:
fixes N :: nat
fixes a :: "nat ⇒ nat"
assumes
"M ≤ N"
shows "a M = (∑x = 0..N. (if x = M then 1 else 0) * (a x))"
using assms by (induction N) force+
and solving the original one with using bar by blast?
I am new to Isabelle and I tried to prove something like this:
lemma refl_add_help: "[| n:nat; m:nat |] ==> 0 #+ n \<le> m #+ n"
by(rule add_le_mono1, simp)
theorem mult_le_self: "[| 0 < m; n:nat; m:nat |] ==> n \<le> n #* m"
apply(case_tac m, auto)
apply(simp add: refl_add_help)
oops
I also tried to prove a lemma:
lemma "[| n:nat; m:nat |] ==> n \<le> m #+ n"
but I could not success either. Can anyone give me some advice on how to solve the problem? Thank you very much.
By the way, is it not possible to display value in ZF like
value "{m:nat. m < 5}"
I have imported the theory like this:
theory mytheory
imports ZF.Arith
I'm not very familiar with Isabelle/ZF. That said, you can prove your results as follows:
theorem mult_le_self: "⟦ 0 < m; n:nat; m:nat ⟧ ⟹ n ≤ n #* m"
apply (case_tac m, simp)
apply (frule_tac ?m="n #* x" in refl_add_help)
apply (auto simp add: add_commute)
done
lemma "⟦ n:nat; m:nat ⟧ ⟹ n ≤ m #+ n"
by (frule refl_add_help, auto)
For more information regarding the frule and frule_tac methods please refer to The Isabelle/Isar Reference Manual, sections 9.2 and 7.3 respectively. However, I encourage you to use Isabelle/Isar instead of proof scripts. For example, your lemma can be proven as follows:
lemma "⟦ n:nat; m:nat ⟧ ⟹ n ≤ m #+ n"
proof -
assume "n:nat" and "m:nat"
then show ?thesis using refl_add_help by simp
qed
Or, more compactly, as follows:
lemma
assumes "n:nat" and "m:nat"
shows "n ≤ m #+ n"
using assms and refl_add_help by simp
Regarding the value command, I think it does not work in Isabelle/ZF.
Supposing I have a set involving three conjunctions {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2}.
How can I prove in Isabelle that the cardinality of this set is 1 ? (Namely only k=6 has gcd 3 6 = 2.) I.e., how can I prove lemma a_set : "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 1" ?
Using sledgehammer (or try) again doesn't yield results - I find it very difficult to find what exactly I need to give the proof methods to make them able to to the proof. (Even removing, e.g. gcd 3 k = 2, doesn't make it amenable to auto or sledgehammer.)
Your proposition is incorrect. The set you described is actually empty, as gcd 3 6 = 3. Sledgehammer can prove that the cardinality is zero without problems, although the resulting proof is again a bit ugly, as is often the case with Sledgehammer proofs:
lemma "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 0"
by (metis (mono_tags, lifting) card.empty coprime_Suc_nat
empty_Collect_eq eval_nat_numeral(3) gcd_nat.left_idem
numeral_One numeral_eq_iff semiring_norm(85))
Let's do it by hand, just to illustrate how to do it. These sorts of proofs do tend to get a little ugly, especially when you don't know the system well.
lemma "{k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = {}"
proof safe
fix x :: nat
assume "x > 2" "x ≤ 7" "gcd 3 x = 2"
from ‹x > 2› and ‹x ≤ 7› have "x = 3 ∨ x = 4 ∨ x = 5 ∨ x = 6 ∨ x = 7" by auto
with ‹gcd 3 x = 2› show "x ∈ {}" by (auto simp: gcd_non_0_nat)
qed
Another, much simpler way (but also perhaps more dubious one) would be to use eval. This uses the code generator as an oracle, i.e. it compiles the expression to ML code, compiles it, runs it, looks if the result is True, and then accepts this as a theorem without going through the Isabelle kernel like for normal proofs. One should think twice before using this, in my opinion, but for toy examples, it is perfectly all right:
lemma "card {k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = 0"
proof -
have "{k::nat. 2<k ∧ k ≤ 7 ∧ gcd 3 k = 2} = Set.filter (λk. gcd 3 k = 2) {2<..7}"
by (simp add: Set.filter_def)
also have "card … = 0" by eval
finally show ?thesis .
qed
Note that I had to massage the set a bit first (use Set.filter instead of the set comprehension) in order for eval to accept it. (Code generation can be a bit tricky)
UPDATE:
For the other statement from the comments, the proof has to look like this:
lemma "{k::nat. 0<k ∧ k ≤ 5 ∧ gcd 5 k = 1} = {1,2,3,4}"
proof (intro equalityI subsetI)
fix x :: nat
assume x: "x ∈ {k. 0 < k ∧ k ≤ 5 ∧ coprime 5 k}"
from x have "x = 1 ∨ x = 2 ∨ x = 3 ∨ x = 4 ∨ x = 5" by auto
with x show "x ∈ {1,2,3,4}" by (auto simp: gcd_non_0_nat)
qed (auto simp: gcd_non_0_nat)
The reason why this looks so different is because the right-hand side of the goal is no longer simply {}, so safe behaves differently and generates a pretty complicated mess of subgoals (just look at the proof state after the proof safe). With intro equalityI subsetI, we essentially just say that we want to prove that A = B by proving a ∈ A ⟹ a ∈ B and the other way round for arbitrary a. This is probably more robust than safe.
I was trying to complete a proof in Isabelle which now works:
lemma axiom1: " x = y ⟹ Δ x y z = 0"
proof -
assume 1[simp]: "x = y"
have 1: "Δ x y z = Δ y z x" by (rule axiom0_a)
also have "… = Δ y z y" by simp
also have "… = Δ z y y" by (rule axiom0_a)
moreover have "Δ y y z = - Δ z y y" by (rule axiom0_b)
moreover have "⋀r. ((r::real) = - r ⟹ r = 0)" by simp
ultimately show "Δ x y z = 0" by simp
qed
However, I had to manually add the assumption to the simplifier. My question is, will the additional rule in the simplifier x=y remain local to this proof, or will it be used in other proofs (which would cause some problems)? Also, I thought the assumptions were automatically added to the simplifier: is the reason why this assumption wasn't because it would give some danger of looping?
The assumption will remain local. It can only be used where the name 1 is also valid
Assumptions are automatically used by the simplifier, but when you start the proof it is no longer an assumption in your current subgoal.
If you do a structured proof, it often works better to also write down the lemma in a structured way with assumes and shows:
lemma axiom1:
assumes 1[simp]: "x = y"
shows "Δ x y z = 0"
...
I’m trying to express that a function f is constant on a set S, with value r My first idea was
f ` S = {r}
but that does not work, as S can be empty. So I am currently working with
f ` S ⊆ {r}
and it works okish, but I have the impression that this is still not ideal for the standard automation. In particular, auto would fail leaving this goal (irrelevant facts erased)
2. ⋀xa. thunks (delete x Γ) ⊆ thunks Γ ⟹
ae ` thunks Γ ⊆ {up⋅0} ⟹
xa ∈ thunks (delete x Γ) ⟹
ae xa = up⋅0
Sledgehammer of course has no problem (metis image_eqI singletonD subsetCE), but there are a few occurrences of this. (In general, ⊆ does not seem to work with auto as good as I’d expect).
There there a better way to express this, i.e. one that can be used by auto more easily when occurring as an assumption?
I didn't try it, since I didn't have any examples handy. But you might try the following setup.
definition "const f S r ≡ ∀x ∈ S. f x = r"
Which is equivalent to your definition:
lemma
"const f S r ⟷ f ` S ⊆ {r}"
by (auto simp: const_def)
Then employ the following simp rule:
lemma [simp]:
"const f S r ⟹ x ∈ S ⟹ f x = r"
by (simp add: const_def)
The Analysis library defines
definition constant_on (infixl "(constant'_on)" 50)
where "f constant_on A \<equiv> \<exists>y. \<forall>x\<in>A. f x = y"