如何定义列表的半格?

时间:2018-10-19 10:22:21

标签: isabelle

我正在尝试定义上半格:

A ≺ B
... ≺ C [B,B,B] ≺ C [B,B] ≺ C [B] ≺ B
C [A] ≺ C [B]
C [A,A] ≺ C [A,B] ≺ C [B,B]
C [A,A] ≺ C [B,A] ≺ C [B,B]
C [A,A,A] ≺ C [A,A,B] ≺ C [A,B,B] ≺ C [B,B,B]
C [A,A,A] ≺ C [A,B,A] ≺ C [A,B,B] ≺ C [B,B,B]
C [A,A,A] ≺ C [A,A,B] ≺ C [B,A,B] ≺ C [B,B,B]
C [A,A,A] ≺ C [B,A,A] ≺ C [B,A,B] ≺ C [B,B,B]
C [A,A,A] ≺ C [A,B,A] ≺ C [B,B,A] ≺ C [B,B,B]
C [A,A,A] ≺ C [B,A,A] ≺ C [B,B,A] ≺ C [B,B,B]
and so on...

我需要禁止以下形式的直接关系:

C [A,A] ≺ C [B,B]
C [A,A,B] ≺ C [B,B,B]
and so on...

只有一个元素必须与前面的元素不同。我将这种间接关系定义为传递闭包。

我试图将其定义如下:

datatype t = A | B | C "t list"

definition "only_one p xs ys ≡
  let xys = zip xs ys in
  length xs = length ys ∧
  list_all (λ(x, y). x = y ∨ p x y) xys ∧
  length xs =
    length (takeWhile (λ(x, y). x = y) xys) +
    length (takeWhile (λ(x, y). x = y) (rev xys)) + 1"

inductive prec_t ("_ ≺ _" [65, 65] 65) where
  "A ≺ B"
| "C [B] ≺ B"
| "C (xs@[B]) ≺ C xs"
| "only_one (λx y. x ≺ y) xs ys ⟹
   C xs ≺ C ys"

但是出现以下错误:

Proof failed.
 1. ⋀x y xa xb xs ys.
       x (?x47 x y xa xb xs ys) (?x48 x y xa xb xs ys) ⟶
       y (?x47 x y xa xb xs ys) (?x48 x y xa xb xs ys) ⟹
       only_one x xs ys ⟶ only_one y xs ys
The error(s) above occurred for the goal statement⌂:
mono
 (λp x1 x2.
     x1 = A ∧ x2 = B ∨
     x1 = C [B] ∧ x2 = B ∨
     (∃xs. x1 = C (xs @ [B]) ∧ x2 = C xs) ∨ (∃xs ys. x1 = C xs ∧ x2 = C ys ∧ only_one p xs ys))

您能建议如何解决它吗?


更新

我重新定义了条件检查器,如下所示。但这无济于事。

primrec only_one' :: "bool ⇒ ('a ⇒ 'a ⇒ bool) ⇒ 'a list ⇒ 'a list ⇒ bool" where
  "only_one' found p xs [] = (case xs of [] ⇒ found | _ ⇒ False)"
| "only_one' found p xs (y # ys) = (case xs of [] ⇒ False | z # zs ⇒
    if z = y then only_one' found p zs ys else
    let found' = p z y in
    if found ∧ found' then False else only_one' found' p zs ys)"

abbreviation "only_one ≡ only_one' False"

更新2

归纳定义也无济于事:

inductive only_one :: "bool ⇒ ('a ⇒ 'a ⇒ bool) ⇒ 'a list ⇒ 'a list ⇒ bool" where
  "only_one True p [] []"
| "x = y ⟹
   only_one found p xs ys ⟹
   only_one found p (x#xs) (y#ys)"
| "p x y ⟹
   found = False ⟹
   only_one True p xs ys ⟹
   only_one found p (x#xs) (y#ys)"

1 个答案:

答案 0 :(得分:1)

您的归纳定义不被接受,因为Isabelle不知道only_one是单调的。

因此,归纳定义前面的以下代码应该可以解决您的问题。

lemma only_one_mono: "(⋀ x y. x ∈ set xs ⟹ y ∈ set ys ⟹ p x y ⟶ q x y) ⟹ 
  only_one p xs ys ⟶ only_one q xs ys" sorry

declare only_one_mono[mono]

最好,雷内(René)