From 816f5e3464b9e91fa65e89013224e646f4efd9be Mon Sep 17 00:00:00 2001
From: Regis Blanc <regwblanc@gmail.com>
Date: Thu, 17 Mar 2016 15:05:43 +0100
Subject: [PATCH] banking testcases

---
 .../xlang/BankSimpleTransactions.scala        | 73 ++++++++++++++++
 .../verification/xlang/BankTransfer.scala     | 83 ++++++-------------
 2 files changed, 98 insertions(+), 58 deletions(-)
 create mode 100644 testcases/verification/xlang/BankSimpleTransactions.scala

diff --git a/testcases/verification/xlang/BankSimpleTransactions.scala b/testcases/verification/xlang/BankSimpleTransactions.scala
new file mode 100644
index 000000000..46a4d6a2b
--- /dev/null
+++ b/testcases/verification/xlang/BankSimpleTransactions.scala
@@ -0,0 +1,73 @@
+import leon.lang._
+
+object BankSimpleTransactions {
+
+  def okTransaction(): Unit = {
+    var balance: BigInt = 0
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      balance += x
+    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= balance)
+      balance -= x
+    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
+
+    deposit(35)
+    withdrawal(30)
+  }
+
+  def invalidTransaction(): Unit = {
+    var balance: BigInt = 0
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      balance += x
+    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= balance)
+      balance -= x
+    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
+
+    deposit(35)
+    withdrawal(40)
+  }
+
+
+  def internalTransfer(): Unit = {
+    var checking: BigInt = 0
+    var saving: BigInt = 0
+
+    def balance = checking + saving
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      checking += x
+    } ensuring(_ => checking == old(checking) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= checking)
+      checking -= x
+    } ensuring(_ => checking == old(checking) - x && balanceInvariant)
+
+    def checkingToSaving(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && checking >= x)
+      checking -= x
+      saving += x
+    } ensuring(_ => checking + saving == old(checking) + old(saving) && balanceInvariant)
+
+    deposit(50)
+    withdrawal(30)
+    checkingToSaving(10)
+  }
+
+}
diff --git a/testcases/verification/xlang/BankTransfer.scala b/testcases/verification/xlang/BankTransfer.scala
index c533b4e08..2044df06a 100644
--- a/testcases/verification/xlang/BankTransfer.scala
+++ b/testcases/verification/xlang/BankTransfer.scala
@@ -2,72 +2,39 @@ import leon.lang._
 
 object BankTransfer {
 
-  def okTransaction(): Unit = {
-    var balance: BigInt = 0
+  case class BankAccount(var checking: BigInt, var saving: BigInt) {
+    require(checking >= 0 && saving >= 0)
 
-    def balanceInvariant: Boolean = balance >= 0
-
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      balance += x
-    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= balance)
-      balance -= x
-    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
-
-    deposit(35)
-    withdrawal(30)
+    def balance: BigInt = checking + saving
   }
 
-  def invalidTransaction(): Unit = {
-    var balance: BigInt = 0
+  //TODO: support for map references to mutable items
+  //case class Bank(accounts: Map[BigInt, BankAccount])
 
-    def balanceInvariant: Boolean = balance >= 0
 
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      balance += x
-    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= balance)
-      balance -= x
-    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
-
-    deposit(35)
-    withdrawal(40)
-  }
+  def deposit(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0)
+    account.checking = account.checking + x
+  } ensuring(_ => account.balance == old(account).balance + x)
 
+  def withdrawal(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0 && account.checking >= x)
+    account.checking = account.checking - x
+  } ensuring(_ => account.balance == old(account).balance - x)
 
-  def internalTransfer(): Unit = {
-    var checking: BigInt = 0
-    var saving: BigInt = 0
+  def transfer(x: BigInt, a1: BankAccount, a2: BankAccount): Unit = {
+    require(x > 0 && a1.checking >= x)
+    withdrawal(x, a1)
+    deposit(x, a2)
+  } ensuring(_ => a1.balance + a2.balance == old(a1).balance + old(a2).balance &&
+                  a1.balance == old(a1).balance - x &&
+                  a2.balance == old(a2).balance + x)
 
-    def balance = checking + saving
 
-    def balanceInvariant: Boolean = balance >= 0
-
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      checking += x
-    } ensuring(_ => checking == old(checking) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= checking)
-      checking -= x
-    } ensuring(_ => checking == old(checking) - x && balanceInvariant)
-
-    def checkingToSaving(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && checking >= x)
-      checking -= x
-      saving += x
-    } ensuring(_ => checking + saving == old(checking) + old(saving) && balanceInvariant)
-
-    deposit(50)
-    withdrawal(30)
-    checkingToSaving(10)
-  }
+  def save(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0 && account.checking >= x)
+    account.checking = account.checking - x
+    account.saving = account.saving + x
+  } ensuring(_ => account.balance == old(account).balance)
 
 }
-- 
GitLab