I am trying to re-write the following arg_min expression in Isabelle (2020) into the more convenient ARG_MIN syntax.
lemma "1 = arg_min (λ(x::int). x*x) ((<) 0)"
What I have so far is:
lemma "1 = (ARG_MIN ((x::int)*x). 0 < x)"
But it's giving me an "Inner syntax error".
I am just wondering what the correct way is to use ARG_MIN above.
Look at the syntax translation from ARG_MIN (found by C-click on arg_min, and looking a few lines after that definition):
translations
"ARG_MIN f x. P" ⇌ "CONST arg_min f (λx. P)"
You want to have arg_min (λ(x::int). x*x) (λx. x < 0). So matching what P, x, and f are, the notation becomes:
ARG_MIN (λ(x::int). x*x) x. (x < 0)
Related
I found this expression somewhere in Isabelle's standard library and tried to see what value does with it
value "(λ x::bool . ¬x) ≤ (λ x . x)"
It outputs False. What is the meaning of ≤ here? Ideally, where can I find the exact instantiation of it? When I Ctrl+Click on the lambda symbol, jEdit doesn't take me anywhere. Is λ part of meta logic then? Where is it defined?
This and many other things are defined in Lattices.thy theory in Main library
https://isabelle.in.tum.de/library/HOL/HOL/Lattices.html
under the following section.
subsection ‹Lattice on \<^typ>‹_ ⇒ _››
instantiation "fun" :: (type, semilattice_sup) semilattice_sup
begin
definition "f ⊔ g = (λx. f x ⊔ g x)"
lemma sup_apply [simp, code]: "(f ⊔ g) x = f x ⊔ g x"
by (simp add: sup_fun_def)
instance
by standard (simp_all add: le_fun_def)
end
Here is a sample theory:
datatype ty = A | B | C
inductive test where
"test A B"
| "test B C"
inductive test2 where
"¬(∃z. test x z) ⟹ test2 x"
code_pred [show_modes] test .
code_pred [show_modes] test2 .
values "{x. test2 A}"
The generated code tries to enumerate over ty. And so it fails.
I'm tring to define an executable version of test predicate:
definition "test_ex x ≡ ∃y. test x y"
definition "test_ex_fun x ≡
Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x))"
lemma test_ex_code [code_abbrev, simp]:
"test_ex_fun = test_ex"
apply (intro ext)
unfolding test_ex_def test_ex_fun_def Predicate.singleton_def
apply (simp split: if_split)
But I can't prove the lemma. Could you suggest a better approach?
Existential quantifiers over an argument to an inductive predicate can be made executable by introducing another inductive predicate. For example:
inductive test2_aux where "test x z ==> test2_aux x"
inductive test2 where "~ test2_aux x ==> test2 x"
with appropriate code_pred statements. The free variable z in the premise of test2_aux acts like an existential. Since this transformation is canonical, code_pred has a preprocessor to do so:
code_pred [inductify] test2 .
does the job.
Well, values complains about the fact that ty is not of sort enum. So, in this particular case it is easiest to perform this instantiation.
instantiation ty :: enum
begin
definition enum_ty :: "ty list" where
"enum_ty = [A,B,C]"
definition "enum_all_ty f = list_all f [A,B,C]"
definition "enum_ex_ty f = list_ex f [A,B,C]"
instance
proof (intro_classes)
let ?U = "UNIV :: ty set"
show id: "?U = set enum_class.enum"
unfolding enum_ty_def
using ty.exhaust by auto
fix P
show "enum_class.enum_all P = Ball ?U P"
"enum_class.enum_ex P = Bex ?U P"
unfolding id enum_all_ty_def enum_ex_ty_def enum_ty_def by auto
show "distinct (enum_class.enum :: ty list)" unfolding enum_ty_def by auto
qed
Afterwards, your values-command evaluates without problems.
I thought that the lemma is unprovable, and I should find another approach. But it can be proven as follows:
lemma test_ex_code [code_abbrev, simp]:
"Predicate.singleton (λ_. False)
(Predicate.map (λ_. True) (test_i_o x)) = (∃y. test x y)"
apply (intro ext iffI)
unfolding Predicate.singleton_def
apply (simp_all split: if_split)
apply (metis SUP1_E mem_Collect_eq pred.sel test_i_o_def)
apply (intro conjI impI)
apply (smt SUP1_E the_equality)
apply (metis (full_types) SUP1_E SUP1_I mem_Collect_eq pred.sel test_i_o_def)
done
The interesting thing is that the lemma structure and the proof structure seems to be independent of the concrete predicate. I guess there could be a general solution for any predicate.
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.
In a local proof block in Isabelle I can use the very convenient obtain command, which allows me to define a constant with given properties:
proof
...
from `∃x. P x ∧ Q x`
obtain x where "P x" and "Q x" by blast
...
What is the most convenient way to do that on the theory or locale level?
I can do it by hand using SOME, but it seems to be unnecessary complicated:
lemma ex: "∃x. P x ∧ Q x"
sorry
definition x where "x = (SOME x. P x ∧ Q x)"
lemma P_x: "P x" and Q_x: "Q x"
unfolding atomize_conj x_def by (rule someI_ex, rule ex)
Another, more direct, way seems to be specification:
consts x :: nat
specification (x) P_x: "P x" Q_x: "Q x" by (rule ex)
but it requires the somewhat low-level consts command, and worse, it does not work in a local context.
Would it be possible to have something as nice as the obtain command on the theory level?
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"