Isabelle中的变函数

Isabelle中的变函数,isabelle,Isabelle,是否有可能使用Isabelle证明助手定义一个涉及变量数函数的理论 例如,我想定义arity n的所有谓词的理论,它们通过循环置换保持不变。 给定一个类型T和一个整数n, 我想定义arity n的所有谓词的理论,例如:pa_1,。。。A_n P A_n A_2,…,A_n-1 在Coq中,可以使用依赖类型,我想知道是否有一种方法可以使用Isabelle来表达这一点?Isabelle/HOL在某种程度上支持具有任意但固定算术性的函数。标准技巧是将函数在其类型中的arity编码为类型的基数。因此,实

是否有可能使用Isabelle证明助手定义一个涉及变量数函数的理论

例如,我想定义arity n的所有谓词的理论,它们通过循环置换保持不变。 给定一个类型T和一个整数n, 我想定义arity n的所有谓词的理论,例如:pa_1,。。。A_n P A_n A_2,…,A_n-1


在Coq中,可以使用依赖类型,我想知道是否有一种方法可以使用Isabelle来表达这一点?

Isabelle/HOL在某种程度上支持具有任意但固定算术性的函数。标准技巧是将函数在其类型中的arity编码为类型的基数。因此,实际上只有一个参数包含固定数量的值。当然,函数的所有变量arity参数必须取自同一类型。在您的示例中,周期性要求已经强制了这一点

例如,您可以定义arity n的不变谓词的类型,如下所示

  typedef ('n :: "{one, plus}", 'a) inv_pred 
    = "{P :: ('n ⇒ 'a) ⇒ bool. ∀f. P f ⟷ P (λn. f (n + 1))}"
    morphisms apply_ip Abs_inv_pred
    by blast
在这里,我们将变量arity谓词建模为从索引集
'n
到元素类型
'a
的函数谓词。
'n
上的排序约束确保类型定义了用于指定移位的操作
+
1
。我们可以假设当溢出发生时,
+
会自动结束,但这也可以在以后使用引理中的类型类约束来完成

理论
数词类型
(在
~/src/HOL/Library
的分布中)定义了有限基数的类型,这些类型被写为文字数字。如果发生溢流,则在其上添加的内容会自动结束。因此,人们可以写作

typ "(5, int) inv_pred"
表示整数上有5个参数的谓词类型,这些参数在循环置换下是不变的。类似地,类型
(100,nat)inv_pred
包含所有这样的arity 100谓词

如果使用普通函数对变量arity参数进行编码,则没有好的语法将函数应用于给定的参数列表。理论
~/src/HOL/multivariable\u Analysis/Finite\u Cartesian\u Product
定义了一种向量类型
('n',a)vec
,在这里也可以使用。不过,您必须为此定义自己的语法,比如说
apply_ip P[:x1,x2,x3,x4:][/code>,并编写适当的解析器和漂亮的打印机

但是,在类型检查期间,Isabelle无法在类型级别进行计算。因此,您将很难键入以下术语

apply_ip P ([: x1, x2 :] ++ [: x3, x4 :])

因为
2+2
与Isabelle/HOL中的
4
类型不同。

执行
n
元函数的类似方法如下:首先,我们定义正自然数的类型:

theory foo
imports Main "~~/src/HOL/Library/Cardinality" "~~/src/Tools/Adhoc_Overloading"
begin

typedef num1 = "UNIV :: unit set"
  by (rule UNIV_witness)

typedef 'n suc = "UNIV :: ('n::finite) option set"
  by (rule UNIV_witness)

instance num1 :: finite
proof
  show "finite (UNIV :: num1 set)"
    unfolding type_definition.univ[OF type_definition_num1]
    using finite by (rule finite_imageI)
qed

instance suc :: (finite) finite
proof
  show "finite (UNIV :: ('n::finite) suc set)"
    unfolding type_definition.univ[OF type_definition_suc]
    using finite by (rule finite_imageI)
qed

setup_lifting type_definition_num1
现在我们定义了
n
元函数的类型,这些函数接受
n
类型
'a
的值,并返回a
'b
作为从
'n获取函数的类型⇒ 'a
并返回a
'b
,以及这些函数的提取和应用:

typedef ('a,'n,'b) nary_fun = "UNIV :: (('n::finite ⇒ 'a) ⇒ 'b) set"
  by (rule UNIV_witness)

setup_lifting type_definition_suc
setup_lifting type_definition_nary_fun

lift_definition nary_fun_apply_1 :: "('a,num1,'b) nary_fun ⇒ 'a ⇒ 'b" 
  is "λf x. f (λ_. x)" .  

lift_definition nary_fun_apply_suc :: "('a,('n::finite) suc,'b) nary_fun ⇒ 'a ⇒ ('a,'n,'b) nary_fun" 
  is "λ(f::('n option ⇒ 'a) ⇒ 'b) (x::'a) (y::'n ⇒ 'a). f (case_option x y)" .  

lift_definition nary_fun_abs_1 :: "('a ⇒ 'b) ⇒ ('a,num1,'b) nary_fun" 
  is "λf x. f (x ())" .

lift_definition nary_fun_abs_suc :: "('a ⇒ ('a,'n::finite,'b) nary_fun) ⇒ ('a,'n suc,'b) nary_fun" 
  is "λf x. f (x None) (λn. x (Some n))" .

lemma nary_fun_1_beta [simp]: "nary_fun_apply_1 (nary_fun_abs_1 f) x = f x"
  by (simp add: nary_fun_abs_1_def nary_fun_apply_1_def Abs_nary_fun_inverse)

lemma nary_fun_suc_beta [simp]: "nary_fun_apply_suc (nary_fun_abs_suc f) x = f x"
  by (simp add: nary_fun_abs_suc_def nary_fun_apply_suc_def Abs_nary_fun_inverse 
                Abs_suc_inverse Rep_nary_fun_inverse)
添加一些合成糖:

consts nary_fun_apply :: "('a,('n::finite),'b) nary_fun ⇒ 'a ⇒ 'c" (infixl "$" 90)

adhoc_overloading nary_fun_apply nary_fun_apply_1 nary_fun_apply_suc

syntax
  "_nary_fun_abs" :: "pttrns ⇒ 'b ⇒ ('a,'n,'b) nary_fun"    ("χ (_). _" 10)

translations
  "χ x y. e" == "CONST nary_fun_abs_suc (λx. (χ y. e))"
  "χ x. e" == "CONST nary_fun_abs_1 (λx. e)"

syntax
  "_NumeralType" :: "num_token => type"  ("_")
  "_NumeralType1" :: type ("1")

translations
  (type) "1" == (type) "num1"

parse_translation {*
  let
    fun mk_numtype n =
      if n = 1 then Syntax.const @{type_syntax num1}
      else if n < 0 then raise TERM ("negative type numeral", [])
      else Syntax.const @{type_syntax suc} $ mk_numtype (n - 1)

    fun numeral_tr [Free (str, _)] = mk_numtype (the (Int.fromString str))
      | numeral_tr ts = raise TERM ("numeral_tr", ts);

  in [(@{syntax_const "_NumeralType"}, K numeral_tr)] end;
*}

print_translation {*
  let
    fun int_of (Const (@{type_syntax num1}, _)) = 1
      | int_of (Const (@{type_syntax suc}, _) $ t) = 1 + int_of t
      | int_of t = raise TERM ("int_of", [t]);

    fun suc_tr' [t] =
          let
            val num = string_of_int (int_of t + 1) handle TERM _ => raise Match;
          in
            Syntax.const @{syntax_const "_NumeralType"} $ Syntax.free num
          end
      | suc_tr' _ = raise Match;
  in
   [(@{type_syntax suc}, K suc_tr')]
  end;
*}

syntax 
  "_nary_fun_type" :: "type ⇒ type ⇒ type ⇒ type" ("(_ ^/ _ ⇒/ _)" [15, 16, 15] 15)

translations
  (type) "'a ^ 'n ⇒ 'b" == (type) "('a,'n,'b) nary_fun"
我想,我的安德烈亚斯公式是否对你们更方便,取决于你们想对你们的函数做什么

lemma "(χ x y. (x, y)) $ 1 $ 2 = (1,2)" by simp

term "(χ x y z. (x, y + z))"
(* "χ x y z. (x, y + z)" :: "'a ^ 3 ⇒ 'a × 'a" *)