我需要定义两个版本的操作,其定义略有不同。这是一系列涉及Nat指数的成分。
open import Data.Nat
data Hom : ℕ → ℕ → Set where
id : (m : ℕ) → Hom m m
_∘_ : ∀ {m n k} → Hom n k → Hom m n → Hom m k
p : (n : ℕ) → Hom (suc n) n
p1 : (m n : ℕ) → Hom (m + n) n
p1 zero n = id n
p1 (suc m) n = p1 m n ∘ p (m + n)
p2 : (m n : ℕ) → Hom (m + n) n
p2 zero n = id n
p2 (suc m) n = {!!} -- p n ∘ p2 m (1 + n)
-- Goal: Hom (suc (m + n)) n
-- Have: Hom (m + suc n) n
我想定义p1
和p2
,并能够互换使用它们。这可行吗?
答案 0 :(得分:4)
您可以使用here描述的技巧,通过p2
直接递归(无subst
或重写)来定义_+_
。看起来像这样:
record Homable (H : ℕ → ℕ → Set) : Set where
field
id-able : (m : ℕ) → H m m
_∘-able_ : ∀ {m n k} → H n k → H m n → H m k
p-able : (n : ℕ) → H (suc n) n
suc-homable : ∀ {H} → Homable H → Homable (λ m n -> H (suc m) (suc n))
suc-homable homable = record
{ id-able = λ m → id-able (suc m)
; _∘-able_ = _∘-able_
; p-able = λ m → p-able (suc m)
} where open Homable homable
p2-go : ∀ {H} → Homable H → (m : ℕ) → H m 0
p2-go homable zero = id-able 0 where
open Homable homable
p2-go homable (suc m) = p-able 0 ∘-able p2-go (suc-homable homable) m where
open Homable homable
plus-homable-hom : ∀ k → Homable (λ m n → Hom (m + k) (n + k))
plus-homable-hom k = record
{ id-able = λ n → id (n + k)
; _∘-able_ = _∘_
; p-able = λ n → p (n + k)
}
p2 : (m n : ℕ) → Hom (m + n) n
p2 m n = p2-go (plus-homable-hom n) m
成本是你需要维护那些有点乏味的Homable
记录,但根据我的经验证明这种方式定义的函数的事情比根据subst
或更高版本定义的函数更简单_+′_
(当然,除非你绝不想强迫_+′_
加入_+_
。)
答案 1 :(得分:2)
嗯,你提供的值的类型等于洞的类型,但是Agda没有看到这个事实。更正式地说,这两种类型在命题上是平等的,但在判断上并不相同。问题是由索引m + suc n
引起的,由于定义了加法,索引suc m + n
在命题上但在判断上不等于open import Data.Nat
open import Data.Nat.Properties
open import Relation.Binary.PropositionalEquality
data Hom : ℕ → ℕ → Set where
id : (m : ℕ) → Hom m m
_∘_ : ∀ {m n k} → Hom n k → Hom m n → Hom m k
p : (n : ℕ) → Hom (suc n) n
p1 : (m n : ℕ) → Hom (m + n) n
p1 zero n = id n
p1 (suc m) n = p1 m n ∘ p (m + n)
p2 : (m n : ℕ) → Hom (m + n) n
p2 zero n = id n
p2 (suc m) n = subst (λ k → Hom k n) (+-suc m n) (p n ∘ p2 m (suc n))
。解决问题的一种方法是手动向Agda解释两种类型相同:
p2 (suc m) n
然而,这种方法并非没有缺点,因为_+′_ : ℕ → ℕ → ℕ
zero +′ n = n
suc m +′ n = m +′ suc n
p2′ : (m n : ℕ) → Hom (m +′ n) n
p2′ zero n = id n
p2′ (suc m) n = p n ∘ p2′ m (suc n)
现在在判断上不等于你的预期定义,而是上面涉及subst的表达式。
这个问题似乎与你要做的事情有关:IIUC,p1和p2实际上是可证明相等的,但使用不同的递归结构定义。那很好,但是结果类型的索引应该遵循相同的递归结构,即你应该使用不同版本的 + 来定义p2,它以适当的方式递归p2:
p1
然而,这有另一个缺点,即p2′
和_+_
的类型不再在判断上相等(但仍然在命题上相等)。
你可以尝试的另一件事是使用Agda的重写规则来使public class StatusUpdateHook implements Hook {
private static final Logger LOGGER = LoggerFactory.getLogger(StatusUpdateHook.class);
@Override
public boolean hook(HttpServerExchange exchange, RequestContext context, BsonValue args, BsonDocument confArgs) {
LOGGER.info("Hook is Called");
return true;
}
@Override
public boolean doesSupportRequests(RequestContext rc) {
return true;
}
}
满足额外的判断平等,但这很危险,因为它可能会打破一些Agda作为逻辑的理想品质。在这种情况下,我怀疑它很好,但我必须检查。
总之,你可以尝试很多东西,但没有一个没有缺点。哪个是您最好的选择取决于您尝试使用它的目的。