我需要生成一个代码,计算所有大于或等于某个值的值:
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}" *)
工作正常。但是该理论看起来过于复杂。我也不能计算小于或等于某个值的值。如果less_eq_code_predI
引理的第二部分不存在,则less_eq
将只有一种模式i => i => boolpos
。
有没有更简单,更通用的方法?
less_eq
是否可以同时支持i => o => boolpos
和o => i => boolpos
?
是否可以不将ty
声明为enum
类的实例?我可以声明一个函数,该函数返回一组大于或等于某个元素的元素:
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)
这将允许我删除enum
和code_pred
的内容。但是在这种情况下,我将无法在其他谓词的定义中使用此函数。在以下定义中,如何用(≤)
替换ge_values
?
inductive pred1 where
"x ≤ y ⟹ pred1 x y"
code_pred [show_modes] pred1 .
我需要pred1
才能拥有至少i => o => boolpos
模式。
答案 0 :(得分:1)
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}"
case_of_simps
from HOL-Library.Simps_Case_Conv
.(<)
on ty
.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
.