Agda 从参数的顺序解释这种奇怪的效果(如果可能的话,提供一种解决方法)

Agda 从参数的顺序解释这种奇怪的效果(如果可能的话,提供一种解决方法),agda,Agda,在试图为我提出的一个问题找到一个解决方案时,我发现(Agda)refl-proof的可接受性以一种奇怪的方式取决于方程一侧调用的函数的参数顺序 在下面的代码中,请参阅如何使用refl证明除一个定理之外的所有4个定理。需要注意的是,join和join'仅在参数顺序上有所不同。相应地,我认为调用它们的thms应该被等价地证明,但显然不是这样 为什么会有差异?这是否代表Agda中的错误?如何证明剩余定理(thm1) 如果我试图用refl证明thm1,我会得到以下错误: proj₁ (join (1#

在试图为我提出的一个问题找到一个解决方案时,我发现(Agda)refl-proof的可接受性以一种奇怪的方式取决于方程一侧调用的函数的参数顺序

在下面的代码中,请参阅如何使用refl证明除一个定理之外的所有4个定理。需要注意的是,
join
join'
仅在参数顺序上有所不同。相应地,我认为调用它们的
thm
s应该被等价地证明,但显然不是这样

为什么会有差异?这是否代表Agda中的错误?如何证明剩余定理(
thm1

如果我试图用refl证明
thm1
,我会得到以下错误:

proj₁ (join (1# , tl) tr ∼+) != 0# of type ℕ₂
when checking that the expression refl has type
join (1# , tl) tr ∼+ ≡ (0# , node tl tr ∼0)
注意:这是使用Agda 2.4.2.3和相同版本的stdlib(从github中提取)。

您可以编写

thm1  : ∀ {h : ℕ} (tl : Tree (suc h)) (tr : Tree (suc h)) → join (1# , tl) tr ∼+ ≡ (0# , node tl tr ∼0)
thm1 (node tl (node tl₁ tl₂ bal) ∼+) tr = refl
thm1 (node tl  leaf              ∼0) tr = refl
thm1 (node tl (node tl₁ tl₂ bal) ∼0) tr = refl
thm1 (node tl  leaf              ∼-) tr = refl
thm1 (node tl (node tl₁ tl₂ bal) ∼-) tr = refl

thm1
中,Agda强制第一个参数(
tl
)在WHNF中,即使该子句可以通过查看
join
的第三个参数,然后查看第一个参数来确定。

您如何知道将第一个参数、第一个参数的第二个参数和第三个参数进行case拆分,而不必将第一个参数的第一个参数和第二个参数进行拆分?这只是尝试吗还有错误?啊,我明白了。这是从
join
@m0davis定义的结构(左侧)来看的,这是因为
join
的第一个子句中使用了模式匹配:
join(1),node t₁ (节点t₃ T₅ bal)∼+) T₇ = ...
。这里的
节点
~+
是构造函数,因此要使
连接(1#,tl)tr∼+可还原您需要在
tl
上拆分,以便在相同的位置上有构造函数。然后Agda可以继续。通过Jacques Carette(在Agda邮件列表上):“您将在底部找到一个(操作)解释。所以参数顺序(和子句顺序)重要的是,因为案例树的语义。”@m0davis,是的,我忘记了,Agda的模式匹配不仅是自上而下的,而且是从左到右的,所以Agda没有尝试统一
∼+带有
∼-
∼0
,因此不再继续。
thm1  : ∀ {h : ℕ} (tl : Tree (suc h)) (tr : Tree (suc h)) → join (1# , tl) tr ∼+ ≡ (0# , node tl tr ∼0)
thm1 (node tl (node tl₁ tl₂ bal) ∼+) tr = refl
thm1 (node tl  leaf              ∼0) tr = refl
thm1 (node tl (node tl₁ tl₂ bal) ∼0) tr = refl
thm1 (node tl  leaf              ∼-) tr = refl
thm1 (node tl (node tl₁ tl₂ bal) ∼-) tr = refl