这是对this question的跟进。多亏了Kwartz,我现在有了一个命题状态,如果b除以a,然后b除以* c表示任意整数c,即:
alsoDividesMultiples : (a, b, c : Integer) ->
DivisibleBy a b ->
DivisibleBy (a * c) b
现在,目标是证明这一说法。我意识到我不了解如何对依赖对进行操作。我尝试了一个更简单的问题,该问题表明每个数字都可以被1整除。经过可耻的思考,我想到了 我想出了一个解决方案:
-- All numbers are divisible by 1.
DivisibleBy a 1 = let n = a in
(n : Integer ** a = 1 * n)
这可以编译,但是我怀疑它是否有效。为了确认我错了,将其略微更改为:
-- All numbers are divisible by 1.
DivisibleBy a 1 = let n = a in
(n : Integer ** a = 2 * n)
这也会编译,这意味着我的“英语”解释肯定是不正确的,因为我会将其解释为“所有数字都可以被一个整数整除,因为每个数字都是另一个整数的两倍”。因此,我不能完全确定我要用那句话说明什么。因此,我回过头来尝试了一种更常规的方式来说明问题:
oneDividesAll : (a : Integer) ->
(DivisibleBy a 1)
oneDividesAll a = ?sorry
对于oneDividesAll
的实现,我不太确定如何“注入” (n = a)
的事实。例如,我将这种证明写成(英文):
我们希望证明1 |一种。如果是这样,则
a = 1 * n
会持续大约n。让n = a
,然后a = a * 1
,根据身份,这是正确的。
我不确定该如何说:“考虑n = a
的时间”。据我了解,rewrite
策略需要证明n = a
。
我试图改编我的谬论:
oneDividesAll : (a : Integer) ->
(DivisibleBy a 1)
oneDividesAll a = let n = a in (n : Integer ** a = b * n)
但这给出了:
|
12 | oneDividesAll a = let n = a in (n : Integer ** a = b * n)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When checking right hand side of oneDividesAll with expected type
DivisibleBy a 1
Type mismatch between
Type (Type of DPair a P)
and
(n : Integer ** a = prim__mulBigInt 1 n) (Expected type)
任何帮助/提示将不胜感激。
答案 0 :(得分:2)
首先,如果要证明数字的性质,则应使用Nat
(或其他归纳类型)。 Integer
使用的原语中,参数不能比prim__mulBigInt : Integer -> Integer -> Integer
争论得更远;您传递两个Integer
来获得一个。编译器不知道任何内容,结果Integer
的样子如何,因此它无法证明其内容。
所以我将继续使用Nat
:
DivisibleBy : Nat -> Nat -> Type
DivisibleBy a b = (n : Nat ** a = b * n)
同样,这是一个命题,而不是证明。 DivisibleBy 6 0
是有效类型,但找不到proof : Divisible 6 0
。所以你说对了
oneDividesAll : (a : Nat) ->
(DivisibleBy a 1)
oneDividesAll a = ?sorry
这样,您可以生成oneDividesAll a : DivisibleBy a 1
形式的证明。那么,?sorry
漏洞是什么? :t sorry
给了我们sorry : (n : Nat ** a = plus n 0)
(在DivisibleBy a 1
看来,依德里斯可以解决)。您对这对的右侧感到困惑:x = y
是一种类型,但是现在我们需要一个值-这是您最后一次错误隐式错误消息提示所基于的内容。 =
只有一个构造函数Refl : x = x
。因此,我们需要使相等的两边都具有相同的值,因此结果看起来像(n ** Refl)
。
如您所想,我们需要将n
设置为a
:
oneDividesAll a = (a ** ?hole)
对于所需的重写策略,我们签出:search plus a 0 = a
,并查看plusZeroRightNeutral
的类型正确。
oneDividesAll a = (a ** rewrite plusZeroRightNeutral a in ?hole)
现在:t hole
给了我们hole : a = a
,所以我们可以自动完成到Refl
:
oneDividesAll a = (a ** rewrite plusZeroRightNeutral a in Refl)
Idris Doc中有一个很好的定理证明教程(其中还解释了为什么plus a Z
不减少)。