注意以下数据类型:
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))
?我问是因为我希望有流行的技术来解决这种情况。
答案 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
以外的其他情况,您需要归纳reduceNormal
和0
。否则,两者都可以通过直接归纳来证明,因此我不认为通过任何特定的技术都可以使两者更容易。