Есть несколько проблем с текущим кодом. Например, следующий случай не работает:
case+ pf1 of
| MULbas() => MULbas()
, потому что abc == 0 еще не доказано. Это можно легко исправить следующим образом:
case+ pf1 of
| MULbas() => let prval MULbas() = pf3 in MULbas() end
Я бы не советовал продолжать с текущим кодом доказательства.
В общем, если вы хотите доказать теоремы, касающиеся MUL, из первого принципа, тогда вам почти всегда нужны следующие две проверочные функции:
extern
prfun
mul_is_tot
{a,b:int}() : [c:int] MUL(a, b, c)
extern
prfun
mul_is_fun
{a,b,c1,c2:int}
( pf1: MUL(a, b, c1)
, pf2: MUL(a, b, c2)): [c1==c2] void
Кстати, следующая реализация mul_assoc проходит проверку типов:
extern
prfun
mul_is_tot
{a,b:int}() : [c:int] MUL(a, b, c)
extern
prfun
mul_is_fun
{a,b,c1,c2:int}
( pf1: MUL(a, b, c1)
, pf2: MUL(a, b, c2)): [c1==c2] void
extern
prfun
mul_distrib
{a,b,c,ac,bc:int}
( MUL(a, c, ac)
, MUL(b, c, bc)): MUL(a+b, c, ac+bc)
extern
prfun
mul_assoc
{a,b,c,ab,bc,abc:int}
( pf1: MUL(a, b, ab),
pf2: MUL(b, c, bc),
pf3: MUL(ab, c, abc)): MUL(a, bc, abc)
extern
prfun
mul_neg_1
{m,n,p:int}(MUL(m, n, p)): MUL(~m, n, ~p)
primplmnt
mul_assoc
{a,b,c
,ab,bc,abc:int}
(pf1, pf2, pf3) =
(
sif
(a >= 0)
then
mul_assoc1(pf1, pf2, pf3)
else
mul_neg_1(mul_assoc1(mul_neg_1(pf1), pf2, mul_neg_1(pf3)))
) where
{
prfun
mul_assoc1
{a:nat
;b,c,ab,bc,abc:int} .<a>.
( pf1: MUL(a, b, ab),
pf2: MUL(b, c, bc),
pf3: MUL(ab, c, abc)): MUL(a, bc, abc) =
(
case+ pf1 of
| MULbas() =>
let
prval MULbas() = pf3 in MULbas()
end
| MULind(pf1') => // a = a'+1 // ab = a'b + b
let
prval pf3' = mul_is_tot() // (a'*b)*c
prval res' = mul_assoc1(pf1', pf2, pf3') // (a'*b)*c = a'*(b*c)
prval ( ) = mul_is_fun(pf3, mul_distrib(pf3', pf2))
in
MULind(res')
end
)
} (* end of [mul_assoc] *)