未经证实的保证 [英] Unproven Ensures

查看:59
本文介绍了未经证实的保证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用代码合同,只是一个简单明了的例子,但确保无法证明,这是我的代码:

Hi, I'm using code contracts with a simple straightforward example, the ensures however cannot be proven, here's my code:

使用System;

使用System.Collections.Generic;

使用System.Collections;

使用System.Diagnostics.Contracts;

使用System.Text ; $


名称空间BankAccountProgram

{

   公共类BankRecord

    {

        public int accountID;

        public int amount;



        public BankRecord(int id,int amount)

        {

            Contract.Requires(金额> = 0);

            this.accountID = id;

            this.amount =金额;

        }


        [ContractInvariantMethod]

        private void Invariants()

        {

            Contract.Invariant(金额> = 0);

        }
    }


   公共类DataModel

    {

       公共列表< BankRecord>记录;
$


        public DataModel()

        {

            records = new List< BankRecord>();

        }


        [ContractInvariantMethod]

        private void Invariants()

        {

            Contract.Invariant(records!= null);

        }


        [Pure] public BankRecord findRecordByKey(int id)

        {

            for(int i = 0; i< records.Count; i ++)

            {

               if(records [i] .accountID == id)return record [i];

            }
           返回null;

        }


       ....



    }
}

----------------------------

using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics.Contracts;
using System.Text;

namespace BankAccountProgram
{
    public class BankRecord
    {
        public int accountID;
        public int amount;

        public BankRecord(int id, int amount)
        {
            Contract.Requires(amount >= 0);
            this.accountID = id;
            this.amount = amount;
        }

        [ContractInvariantMethod]
        private void Invariants()
        {
            Contract.Invariant(amount >= 0);
        }
    }

    public class DataModel
    {
        public List<BankRecord> records;

        public DataModel()
        {
            records = new List<BankRecord>();
        }

        [ContractInvariantMethod]
        private void Invariants()
        {
            Contract.Invariant(records != null);
        }

        [Pure] public BankRecord findRecordByKey(int id)
        {
            for (int i = 0; i < records.Count; i++)
            {
               if(records[i].accountID == id) return records[i];
            }
            return null;
        }

       ....

    }
}
----------------------------

使用System;

使用System.Collections.Generic;

使用System.Text;

使用System.Diagnostics 。合同;



名称空间BankAccountProgram

{

   公共部分界面IDB

    {

        int createAccount(int accountID,int amount,DataModel dm);

        void deposit(int accountID,int amount,DataModel dm);

        void withdraw(int accountID,int amount,DataModel dm);

    }


 

    #region IDB合同约束

    [ContractClass(typeof(IDBContract))]
$
   公共部分界面IDB

    {



    }


    [ContractClassFor(typeof(IDB))]
$
   公共抽象类IDBContract:IDB

    {

        #region IDB会员



        int IDB.createAccount(int accountID,int amount,DataModel dm)

        {

            Contract.Requires(金额> 0);

           

           抛出新的NotImplementedException();
$
        }


        void IDB.deposit(int accountID,int amount,DataModel dm)

        {

            Contract.Requires(金额> 0);

            Contract.Requires(dm.findRecordByKey(accountID)!= null);

            Contract.Ensures(dm.findRecordByKey(accountID).amount == Contract.OldValue(dm.findRecordByKey(accountID)。amount)+ Contract.OldValue(amount));

    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;抛出新的NotImplementedException();
$
        }
       

        void IDB.withdraw(int accountID,int amount,DataModel dm)

        {

            Contract.Requires(金额> 0);

            Contract.Requires(dm.findRecordByKey(accountID)!= null);

            Contract.Ensures(dm.findRecordByKey(accountID).amount == Contract.OldValue(dm.findRecordByKey(accountID)。amount) - Contract.OldValue(amount));

   

           抛出新的NotImplementedException();
$
        }


        #endregion

    }
    #endregion



}

----------------------- ------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics.Contracts;

namespace BankAccountProgram
{
    public partial interface IDB
    {
        int createAccount(int accountID, int amount, DataModel dm);
        void deposit(int accountID, int amount, DataModel dm);
        void withdraw(int accountID, int amount, DataModel dm);
    }

 
    #region IDB contract binding
    [ContractClass(typeof(IDBContract))]
    public partial interface IDB
    {

    }

    [ContractClassFor(typeof(IDB))]
    public abstract class IDBContract : IDB
    {
        #region IDB Members

        int IDB.createAccount(int accountID, int amount, DataModel dm)
        {
            Contract.Requires(amount > 0 );
           
            throw new NotImplementedException();
        }

        void IDB.deposit(int accountID, int amount, DataModel dm)
        {
            Contract.Requires(amount > 0 );
            Contract.Requires(dm.findRecordByKey(accountID) != null);
            Contract.Ensures(dm.findRecordByKey(accountID).amount == Contract.OldValue(dm.findRecordByKey(accountID).amount) + Contract.OldValue(amount));
            throw new NotImplementedException();
        }
       
        void IDB.withdraw(int accountID, int amount, DataModel dm)
        {
            Contract.Requires(amount > 0);
            Contract.Requires(dm.findRecordByKey(accountID) != null);
            Contract.Ensures(dm.findRecordByKey(accountID).amount == Contract.OldValue(dm.findRecordByKey(accountID).amount) - Contract.OldValue(amount));
   
            throw new NotImplementedException();
        }

        #endregion
    }
    #endregion

}
-----------------------------------

使用System;

使用System.Collections.Generic;

使用System.Diagnostics.Contracts;

使用System.Text;
$


命名空间BankAccountProgram

{

   班级构成

    {

       静态IDB dbi;



        public static void transfer(int fromAccount,int toAccount,int amount,DataModel dm)

        {

            Contract.Requires(fromAccount!= toAccount);

            Contract.Requires(金额> 0);

            Contract.Requires(dm.findRecordByKey(fromAccount)!= null);

            Contract.Requires(dm.findRecordByKey(toAccount)!= null);

            Contract.Ensures(dm.findRecordByKey(fromAccount).amount == Contract.OldValue(dm.findRecordByKey(fromAccount)。amount) - Contract.OldValue(amount));

    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; Contract.Ensures(dm.findRecordByKey(toAccount).amount == Contract.OldValue(dm.findRecordByKey(toAccount)。amount)+ Contract.OldValue(amount));

   



            dbi.withdraw(fromAccount,amount,dm);

            dbi.deposit(toAccount,amount,dm);

        }&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP;


    }


}

------------------------ --------------

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Text;

namespace BankAccountProgram
{
    class Composition
    {
        static IDB dbi;

        public static void transfer(int fromAccount, int toAccount, int amount, DataModel dm)
        {
            Contract.Requires(fromAccount != toAccount);
            Contract.Requires(amount > 0);
            Contract.Requires(dm.findRecordByKey(fromAccount) != null);
            Contract.Requires(dm.findRecordByKey(toAccount) != null);
            Contract.Ensures(dm.findRecordByKey(fromAccount).amount == Contract.OldValue(dm.findRecordByKey(fromAccount).amount) - Contract.OldValue(amount));
            Contract.Ensures(dm.findRecordByKey(toAccount).amount == Contract.OldValue(dm.findRecordByKey(toAccount).amount) + Contract.OldValue(amount));
   

            dbi.withdraw(fromAccount, amount, dm);
            dbi.deposit(toAccount, amount, dm);
        }       
    }

}
--------------------------------------

我收到这些静态检查警告:

I'm getting these static checker warnings:

CodeContracts:确保未经证实: dm.findRecordByKey(toAccount).amount == Contract.OldValue(dm.findRecordByKey(toAccount)。amount)+ Contract.OldValue(amount)

CodeContracts: ensures unproven: dm.findRecordByKey(toAccount).amount == Contract.OldValue(dm.findRecordByKey(toAccount).amount) + Contract.OldValue(amount)

CodeContracts:确保未经证实:dm.findRecordByKey( fromAccount)。amount == Contract.OldValue(dm.findRecordByKey(fromAccount)。amount) - Contract.OldValue(amount) 


$

CodeContracts: ensures unproven: dm.findRecordByKey(fromAccount).amount == Contract.OldValue(dm.findRecordByKey(fromAccount).amount) - Contract.OldValue(amount) 

非常感谢任何帮助!

谢谢,

 

Iman

推荐答案

您好Iman,

Hi Iman,

我怀疑至少有一个问题是静态检查器并不认为
dm.findRecordByKey(fromAccount)总是返回每次调用它时都有相同的参考。 即使该方法标记为
Pure ,我也非常确定代码合同只考虑副作用的纯度,而不是纯度方面的纯度。 换句话说,您的 方法可以更改  findRecordByKey
在检索旧值的时间与检索到最新值的时间之间返回的内容,而不会影响方法的陈述"纯度"。 我不知道有任何方法可以指定合同来断言这一点。

I suspect at least one problem is that the static checker doesn't assume that dm.findRecordByKey(fromAccount) always returns the same reference each time that it's called.  Even though the method is marked Pure, I'm pretty sure that Code Contracts only considers purity in terms of side-effects, not purity in terms of determinism.  In other words, your method could change what findRecordByKey returns between the time that the old value is retrieved and the time that the latest value is retrieved, without affecting the method's stated "purity".  I don't know of any way to specify contracts to assert this.

无论如何,定义接受ID的方法,执行多次查找然后用术语定义合同似乎是不合逻辑的。查找。 为什么不只是拥有
BankRecord 参数,然后根据这些参数定义合约?

Regardless, it seems illogical to define methods that accept IDs, perform multiple lookups and then define your contracts in terms of the lookups.  Why not just have BankRecord parameters instead and then define the contracts in terms of those?

还要考虑线程安全,这是常见的代码模拟银行交易的问题。 除非您处理不可变对象或粗粒度锁定,否则您将无法使用代码合同来强制执行合同,因为
需要确保合约将在您的个别方法使用的锁之外进行评估。

Also consider thread-safety, which is a common issue for code that simulates banking transactions.  Unless you're dealing with immutable objects or coarse-grained locking, you won't be able to use Code Contracts to enforce your contracts since Requires and Ensures contracts would be evaluated outside of the locks that your individual methods use.

- Dave


这篇关于未经证实的保证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆