我对Agda很新。我正在处理一项来自任务的问题。我已经掌握了大部分内容,但有一个目标就是我被困住了。
data Arith : Set where
Num : ℕ → Arith
Plus : Arith → Arith → Arith
Times : Arith → Arith → Arith
eval : Arith → ℕ
eval (Num x) = x
eval (Plus e1 e2) = eval e1 + eval e2
eval (Times e1 e2) = eval e1 * eval e2
data Even : ℕ → Set where
zEven : Even 0
ssEven : {n : ℕ} → Even n → Even (suc (suc n))
-- [PROBLEM 1]
plusEven : ∀ n m → Even n → Even m → Even (n + m)
plusEven zero m x x₁ = x₁
plusEven (suc zero) m () x₁
plusEven (suc (suc .0)) m (ssEven zEven) x₁ = ssEven x₁
plusEven (suc (suc ._)) m (ssEven (ssEven x)) x₁ = ssEven (ssEven (plusEven _ m x x₁ ))
-- [PROBLEM 2]
timesEven : ∀ n m → Even n → Even m → Even (n * m)
timesEven zero m x x₁ = zEven
timesEven (suc ._) zero (ssEven x) x₁ = (timesEven _ zero x x₁)
timesEven (suc ._) (suc ._) (ssEven x) (ssEven x₁) = ssEven ((λ h → {!!}) (timesEven _ _ x x₁))
我必须证明的目标是
Goal: Even (.n₁ + suc (suc (.n₁ + .n * suc (suc .n₁))))
我觉得我必须使用plusEven一些方法。但目标看起来并不那么简单。我让这个问题困难吗?还是我走在正确的轨道上?有更简单的方法吗?我不想要解决方案。但是,正确的方向推进将是值得赞赏的。我现在已经坚持了一段时间。
答案 0 :(得分:3)
如果n
是偶数,那么n * m
也是如此,所以m
是否均匀是无关紧要的,因此你应该抛弃这个约束。所以实际的定理是(我n
和m
是隐式的,因为这很方便)
timesEvenLeft : ∀ {n m} → Even n → Even (n * m)
timesEvenRight : ∀ {n m} → Even m → Even (n * m)
你可以证明n * m ≡ m * n
并从前者推导出后者定理。因此,它只是证明第一个。在递归的情况下,您需要在范围内证明Even (suc (suc n) * m)
(减少为Even (m + (m + n * m)
)Even (n * m)
(归纳假设)。为此,你还需要另一个引理:
plusDoubleEven : ∀ {n} m → Even n → Even (m + (m + n))
答案 1 :(得分:1)
我真的很喜欢这里发布的答案,他们帮助了我很多。但我不能改变作业中给出的问题。我使用发布的答案来提出解决问题的方法。它花了我一段时间,它看起来有点凌乱,但它的工作原理。我以为我也会在这里发布。
timesEven : ∀ n m → Even n → Even m → Even (n * m)
timesEven zero m x x₁ = zEven
timesEven (suc zero) m () x₁
timesEven (suc (suc n)) zero (ssEven x) x₁ = timesEven n zero x x₁
timesEven (suc (suc n)) (suc zero) x ()
timesEven (suc (suc n)) (suc (suc m)) (ssEven x) (ssEven x₁) = ssEven ((λ h → plusEven m (suc (suc (m + n * suc (suc m)))) x₁ (ssEven (plusEven m (n * suc (suc m)) x₁ h))) (timesEven n (suc (suc m)) x (ssEven x₁)))
答案 2 :(得分:0)
这可能不是你对这个家庭作业的期望,但如果没有做太多的工作,处理这些引理的干净方法,正如@ user3237465暗示的那样,重用自然数字的众所周知的属性。
从这些众所周知的属性中获取更多信息的一种方法是引入$patients = Patient::whereDoesntHave('users', function ($q) use ($vaccine_id) {
$q->where('vaccine_id', '=', $vaccine_id);
$q->with('Vaccine', 'immunizations');
})->get();
的替代定义,您可以证明它与归纳属性相当:
Even
然后,您可以使用等式推理证明data Even : ℕ → Set where
zEven : Even 0
ssEven : {n : ℕ} → Even n → Even (suc (suc n))
record Even′ (n : ℕ) : Set where
constructor mkEven′
field factor : ℕ
.equality : n ≡ factor * 2
open Even′
Even⇒Even′ : {n : ℕ} → Even n → Even′ n
(...)
Even′⇒Even : {n : ℕ} → Even′ n → Even n
(...)
和plusEven
,重用标准库中的词条。例如timesEven(Right/Left)
的证明变为:
plusEven
Here is a gist包含所有正确的导入和所有证明。