如何规范总是减小输入大小的重写规则?

时间:2018-09-09 13:03:04

标签: agda

注意以下数据类型:

data AB : Set where
  A : AB -> AB
  B : AB -> AB
  C : AB

rwt : AB -> AB
rwt (B (A ab)) = rwt ab
rwt (A ab)     = A (rwt ab)
rwt (B ab)     = B (rwt ab)
rwt C          = C

ab : AB
ab = rwt (rwt (B (B (A (A (A (A (B (B (A (B C)))))))))))

在这里,rwt旨在用B (A x)替换所有出现的x。但是,编写方式并不能保证结果是正常形式,这可以从以下事实看出:我们需要两个rwt的应用程序才能到达A (A (B (B x))),这不能进一步重写。

是否有任何方法可以在Agda中写入reduce : AB -> AB并返回与重复调用rewrite相同的结果,直到没有B (A x)为止?而且,我们还能得到证明吗(也许reduce : (input : AB) -> Σ AB (λ output . is-reduction-of input && is-in-nf output)?

尝试:

下面的程序将始终返回正常形式的ab

reduce : AB -> ℕ -> AB
reduce (A ab) (suc n) = reduce ab n
reduce (A ab) zero    = A (reduce ab zero)
reduce (B ab) n       = reduce ab (suc n)
reduce C      (suc n) = B (reduce C n)
reduce C      zero    = C

但是我们如何证明它实际上返回了一个没有“ redexes”的术语,并且它等同于rwt (rwt (rwt ... ab))?我问是因为我希望有流行的技术来解决这种情况。

1 个答案:

答案 0 :(得分:2)

您可以归纳定义重写,然后说一个普通术语对任何东西都不能重写。然后,证明reduce是正确的并且返回正常形式。

open import Data.Empty
open import Data.Nat
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary

data AB : Set where
  A : AB -> AB
  B : AB -> AB
  C : AB

-- 1-step rewrite
infix 3 _~>_
data _~>_ : AB → AB → Set where
  BA : ∀ {x} → B (A x) ~> x
  A  : ∀ {x y} → x ~> y → A x ~> A y
  B  : ∀ {x y} → x ~> y → B x ~> B y

-- reflexive-transitive closure
infixr 5 _◅_
data Star {A : Set}(R : A → A → Set) : A → A → Set where
  ε   : ∀ {x} → Star R x x
  _◅_ : ∀ {x y z} → R x y → Star R y z → Star R x z

-- n-step rewrite
infix 3 _~>*_ 
_~>*_ : AB → AB → Set
_~>*_ = Star _~>_

normal : AB → Set
normal ab = ∀ {ab'} → ¬ (ab ~> ab')

-- TODO
reduceSound  : ∀ ab → ab ~>* reduce ab 0
reduceNormal : ∀ ab → normal (reduce ab 0)

对于reduceSound以外的其他情况,您需要归纳reduceNormal0。否则,两者都可以通过直接归纳来证明,因此我不认为通过任何特定的技术都可以使两者更容易。