首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自然数的基本运算(+/*),并证明它们的交换性和结合性- Dafny

自然数的基本运算(+/*),并证明它们的交换性和结合性- Dafny
EN

Stack Overflow用户
提问于 2021-10-12 11:49:55
回答 1查看 75关注 0票数 0

学习Dafny我想在自然数(作为代数数据类型)上定义自然数的和和乘法,并证明它们的交换性和结合性。

我成功地做到了:

加法

代码语言:javascript
复制
datatype Nat = Zero | Succ(Pred: Nat)

function add(m: Nat, n: Nat) : Nat
decreases m
{
    match m
    case Zero => n
    case Succ(m') => Succ(add(m', n))
}

乘法

代码语言:javascript
复制
function multiply(m: Nat, n: Nat) : Nat
decreases n
{
    match n
    case Zero => Zero
    case Succ(Zero) => m
    case Succ(p) => add(m, multiply(m, p))
}

加法交换性

代码语言:javascript
复制
lemma CommAdd(m: Nat, n: Nat)
ensures add(m,n) == add(n, m)
{
    match m
    case Zero => Add1(n);
    case Succ(m') => CommAdd(m', n);
}

我被卡住的地方:

乘法交换性,结合性,这是我尝试过的,但没有得到“验证”。

代码语言:javascript
复制
// Neutral element
lemma Multiply1(m: Nat)
decreases m
// ensures multiply(m, Zero) == Zero
ensures multiply(m, Succ(Zero)) == m
{
//
}


// Commutativity of Multiplication - DRAFT, NOT VERIFIED
lemma CommMult(m: Nat, n: Nat)
ensures multiply(m, n) == multiply(n, m)
{
    match m
    case Zero => Zero
    case Succ(Zero) => Multiply1(n)
    case Succ(m') => CommMult(m', n)
}
EN

回答 1

Stack Overflow用户

发布于 2021-10-12 15:31:47

注意,您对multiply模式的定义与第二个参数相匹配,而作为证明,CommMult模式与第一个参数相匹配。虽然可以使用任何一种方法来证明,但如果双方都同意,就会容易得多。

代码语言:javascript
复制
function multiply(m: Nat, n: Nat): Nat
  decreases m
{
  match m
    case Zero => Zero
    case Succ(Zero) => n
    case Succ(p) => add(n, multiply(p, n))
}
lemma CommMult(m: Nat, n: Nat)
  ensures multiply(m, n) == multiply(n, m)
{
  match m
    case Zero => {}
    case Succ(Zero) => Multiply1(n);
    case Succ(m') => CommMult(m', n);
}

现在Succ(Zero)分支不会抛出验证错误。进一步注意,它是与匹配表达式不同的匹配语句。在Zero情况下,dafny能够自动验证,原因语句为空。在Succ(Zero)情况下,引理Multiply1(n)足以证明后置条件。Succ(m')分支需要进一步的引理/语句来证明。CommMult(m', n)给出了multiply(m', n) == multiply(n, m'),但它也需要乘法对加法的分配性质来完成证明。

代码语言:javascript
复制
   m * n 
== S m' * n
== n + m' * n
{ using CommMulti property}
== n + n * m'
{ using distributive property }
== n * (1 + m')
== n * m

dafny以calc的形式支持这种计算风格的证明

代码语言:javascript
复制
lemma CommMult(m: Nat, n: Nat)
  ensures multiply(m, n) == multiply(n, m)
{
  match m
    case Zero => {}
    case Succ(Zero) => Multiply1(n);
    case Succ(m') => {
      calc {
        multiply(Succ(m'), n);
        // defintion of multiply
        add(n, multiply(m', n));
        { CommMult(m', n); }
        add(n, multiply(n, m'));
        { Multiply1(n); }
        add(multiply(n, Succ(Zero)), multiply(n, m'));
        // TODO use distributive law
      }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69540013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档