我对使用数据类型的定理的形式化存在令人讨厌的问题,该数据类型具有一些其索引具有列表串联的构造函数。当我尝试使用emacs模式进行大小写分割时,Agda会返回以下错误消息:
I'm not sure if there should be a case for the constructor
o-success, because I get stuck when trying to solve the following
unification problems (inferred index ≟ expected index):
e₁ o e'' , x₁ ++ x'' ++ y₁ ≟ e o e' , x ++ x' ++ y
suc (n₂ + n'') , x₁ ++ x'' ≟ m' , p''
when checking that the expression ? has type
suc (.n₁ + .n') == .m' × .x ++ .x' == p'
由于代码的行数不止一个,我把它放在以下要点:
https://gist.github.com/rodrigogribeiro/976b3d5cc82c970314c2
任何提示都表示赞赏。
最佳,
答案 0 :(得分:3)
有类似的question。
但是,您希望xs1 ++ xs2 ++ xs3
与ys1 ++ ys2 ++ ys3
统一,但_++_
不是构造函数 - 它是一个函数,并且它不是单射的。考虑这个简化的例子:
data Bar {A : Set} : List A -> Set where
bar : ∀ xs {ys} -> Bar (xs ++ ys)
ex : ∀ {A} {zs : List A} -> Bar zs -> Bar zs -> List A
ex (bar xs) b = {!!}
b
的类型为Bar (xs ++ .ys)
,但b
不一定等于bar .xs
,因此您无法像这样进行模式匹配。这里有两个Bar
,它们具有相同的类型但值不同:
ok : ∃₂ λ (b1 b2 : Bar (tt ∷ [])) -> b1 ≢ b2
ok = bar [] , bar (tt ∷ []) , λ ()
这是因为xs1 ++ xs2 ≡ ys1 ++ ys2
一般不会暗示xs1 ≡ ys1 × xs2 ≡ ys2
。
但是可以推广一个索引。您可以在上面的链接中使用Vitus描述的技术,或者您可以使用这个简单的组合器,它会忘记索引:
generalize : ∀ {α β} {A : Set α} (B : A -> Set β) {x : A} -> B x -> ∃ B
generalize B y = , y
E.g。
ex : ∀ {A} {zs : List A} -> Bar zs -> Bar zs -> List A
ex {A} (bar xs) b with generalize Bar b
... | ._ , bar ys = xs ++ ys
毕竟,你确定你的引理是真的吗?
<强>更新强>
首先是一些评论。
您的empty
案件陈述
empty : forall x -> G :: (emp , x) => (1 , x)
empty
解析器解析整个字符串。它应该是
empty : forall x -> G :: (emp , x) => (1 , [])
如文中所述。
您对o-fail1
的定义包含此部分:
(n , fail ∷ o)
但是fail
会失败,所以它应该是(n , fail ∷ [])
。通过这种表示,您可能需要在A
上进行可判定的相等来完成引理,并且证明会很脏。用于表示可能失败的东西的干净且惯用的方式是将其包装在Maybe
monad中,所以这是我对_::_=>_
的定义:
data _::_=>_ {n} (G : Con n) : Foo n × List A -> Nat × Maybe (List A) -> Set where
empty : ∀ {x} -> G :: emp , x => 1 , just []
sym-success : ∀ {a x} -> G :: sym a , (a ∷ x) => 1 , just (a ∷ [])
sym-failure : ∀ {a b x} -> ¬ (a == b) -> G :: sym a , b ∷ x => 1 , nothing
var : ∀ {x m o} {v : Fin (suc n)}
-> G :: lookup v G , x => m , o -> G :: var v , x => suc m , o
o-success : ∀ {e e' x x' y n n'}
-> G :: e , x ++ x' ++ y => n , just x
-> G :: e' , x' ++ y => n' , just x'
-> G :: e o e' , x ++ x' ++ y => suc (n + n') , just (x ++ x')
o-fail1 : ∀ {e e' x x' y n}
-> G :: e , x ++ x' ++ y => n , nothing
-> G :: e o e' , x ++ x' ++ y => suc n , nothing
o-fail2 : ∀ {e e' x x' y n n'}
-> G :: e , x ++ x' ++ y => n , just x
-> G :: e' , x' ++ y => n' , nothing
-> G :: e o e' , x ++ x' ++ y => suc (n + n') , nothing
以下是lemma
:
postulate
cut : ∀ {α} {A : Set α} -> ∀ xs {ys zs : List A} -> xs ++ ys == xs ++ zs -> ys == zs
mutual
aux : ∀ {n} {G : Con n} {e e' z x x' y n n' m' p'}
-> z == x ++ x' ++ y
-> G :: e , z => n , just x
-> G :: e' , x' ++ y => n' , just x'
-> G :: e o e' , z => m' , p'
-> suc (n + n') == m' × just (x ++ x') == p'
aux {x = x} {x'} {n = n} {n'} r pr1 pr2 (o-success {x = x''} pr3 pr4) with x | n | lemma pr1 pr3
... | ._ | ._ | refl , refl rewrite cut x'' r with x' | n' | lemma pr2 pr4
... | ._ | ._ | refl , refl = refl , refl
aux ...
lemma : ∀ {n m m'} {G : Con n} {f x p p'}
-> G :: f , x => m , p -> G :: f , x => m' , p' -> m == m' × p == p'
lemma (o-success pr1 pr2) pr3 = aux refl pr1 pr2 pr3
lemma ...
证据进行如下:
lemma
pr3
的类型,如在Vitus&#39;回答。现在可以在pr3
上进行模式匹配。lemma'
s pr3
中的第一个解析器(pr3
中也称为aux
)产生与pr1
相同的输出。< / LI>
lemma
pr3
中的第二个解析器(pr4
中称为aux
)产生的输出与{相同{1}}。pr2
和pr1
生成相同的输出,而pr3
和pr2
生成相同的输出,pr4
和o-success pr1 pr2
会产生相同的输出,所以我们放o-success pr3 pr4
。 code。我没有证明refl , refl
和o-fail1
个案,但它们应该相似。
<强>更新强>
样板量可以减少
o-fail2
个案的定义。fail
而不是Maybe (List A)
。如果需要,您可以递归计算此Nat × Maybe (List A)
。Nat
成语而不是辅助功能。我认为没有更简单的解决方案。 code。