如何针对不同的归纳谓词模式使用不同的代码引理?

时间:2018-09-23 04:21:41

标签: isabelle

(该问题与How to define an inductive predicate on fset?有关,但更具体)

这是一个简单的理论,具有2种值和一个转换谓词:

theory FSetIndTest
  imports Main "~~/src/HOL/Library/FSet"
begin

datatype val1 = A | B
datatype val2 = C | D

inductive cast_val :: "val1 ⇒ val2 ⇒ bool" where
  "cast_val A C"
| "cast_val B D"

code_pred [show_modes] cast_val .

fun cast_val_fun :: "val1 ⇒ val2" where
  "cast_val_fun A = C"
| "cast_val_fun B = D"

fun cast_val_fun_inv :: "val2 ⇒ val1" where
  "cast_val_fun_inv C = A"
| "cast_val_fun_inv D = B"

我正在尝试为fsets定义一个强制转换谓词。在i ⇒ o ⇒ bool模式下可以正常运行,但不支持o ⇒ i ⇒ bool模式:

inductive cast_fset1 :: "val1 fset ⇒ val2 fset ⇒ bool" where
  "cast_fset1 {||} {||}"
| "cast_val x y ⟹ cast_fset1 xs ys ⟹
   cast_fset1 (finsert x xs) (finsert y ys)"

lemma cast_fset1_left [code_pred_intro]:
  "fimage cast_val_fun xs = ys ⟹ cast_fset1 xs ys"
  apply (induct xs arbitrary: ys)
  apply (simp add: cast_fset1.intros(1))
  by (metis (full_types) cast_fset1.intros(2) cast_val.intros(1) cast_val.intros(2) cast_val_fun.simps(1) cast_val_fun.simps(2) fimage_finsert val1.exhaust)

lemma cast_fset1_left_inv:
  "cast_fset1 xs ys ⟹
   fimage cast_val_fun xs = ys"
  apply (induct rule: cast_fset1.induct)
  apply simp
  using cast_val.simps by auto

code_pred [show_modes] cast_fset1
  by (simp add: cast_fset1_left_inv)

values "{x. cast_fset1 {|A, B|} x}"

因此,我尝试为两个参数定义一个代码引理。结果,仅支持i ⇒ i ⇒ bool模式:

inductive cast_fset2 :: "val1 fset ⇒ val2 fset ⇒ bool" where
  "cast_fset2 {||} {||}"
| "cast_val x y ⟹ cast_fset2 xs ys ⟹
   cast_fset2 (finsert x xs) (finsert y ys)"

lemma cast_fset2_code [code_pred_intro]:
  "fimage cast_val_fun xs = ys ⟹ cast_fset2 xs ys"
  "fimage cast_val_fun_inv ys = xs ⟹ cast_fset2 xs ys"
  apply (auto)
  apply (induct xs arbitrary: ys)
  apply (simp add: cast_fset2.intros(1))
  apply (metis (full_types) cast_fset2.intros(2) cast_val.intros(1) cast_val.intros(2) cast_val_fun.simps(1) cast_val_fun.simps(2) fimage_finsert val1.exhaust)
  apply (induct ys arbitrary: xs)
  apply (simp add: cast_fset2.intros(1))
  by (smt cast_fset2.intros(2) cast_val.intros(1) cast_val.intros(2) cast_val_fun_inv.elims cast_val_fun_inv.simps(1) fimage_finsert)

lemma cast_fset2_code_inv:
  "cast_fset2 xs ys ⟹ fimage cast_val_fun xs = ys"
  "cast_fset2 xs ys ⟹ fimage cast_val_fun_inv ys = xs"
  apply (induct rule: cast_fset2.induct)
  apply simp
  apply simp
  using cast_val.simps cast_val_fun.simps(1) apply auto[1]
  using cast_val.simps by auto

code_pred [show_modes] cast_fset2
  by (simp add: cast_fset2_code_inv(1))

我正在尝试使用[code]注释而不是[code_pred_intro]

inductive cast_fset3 :: "val1 fset ⇒ val2 fset ⇒ bool" where
  "cast_fset3 {||} {||}"
| "cast_val x y ⟹ cast_fset3 xs ys ⟹
   cast_fset3 (finsert x xs) (finsert y ys)"

lemma cast_fset3_left:
  "fimage cast_val_fun xs = ys ⟹ cast_fset3 xs ys"
  apply (induct xs arbitrary: ys)
  apply (simp add: cast_fset3.intros(1))
  by (metis (full_types) cast_fset3.intros(2) cast_val.intros(1) cast_val.intros(2) cast_val_fun.simps(1) cast_val_fun.simps(2) fimage_finsert val1.exhaust)

lemma cast_fset3_left_inv:
  "cast_fset3 xs ys ⟹
   fimage cast_val_fun xs = ys"
  apply (induct rule: cast_fset3.induct)
  apply simp
  using cast_val.simps by auto

lemma cast_fset3_left_code [code]:
  "fimage cast_val_fun xs = ys ⟷
   cast_fset3 xs ys"
  using cast_fset3_left cast_fset3_left_inv by blast

但是我收到以下警告,引理完全被忽略了:

Partially applied constant "FSetIndTest.cast_val_fun" on left hand side of equation, in theorem:
cast_val_fun |`| ?xs = ?ys ≡ cast_fset3 ?xs ?ys

是否可以对归纳谓词的不同模式(i ⇒ o ⇒ boolo ⇒ i ⇒ bool)使用不同的代码引理?如何解决最后一个引理?为什么我会收到此警告?

1 个答案:

答案 0 :(得分:1)

归纳谓词的代码生成始终以相同的引入规则集为基础;但是,您总是可以随意引入现有归纳谓词的副本,并为它们配备一套不同的引入规则。

属性[code]仅用于方程式,不适用于引入规则。