File: debt-red.mod

package info (click to toggle)
cafeobj 1.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 19,900 kB
  • sloc: lisp: 85,055; sh: 659; makefile: 437; perl: 147
file content (159 lines) | stat: -rw-r--r-- 4,176 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
-- FILE: /home/diacon/LANG/Cafe/prog/debt-red.mod
-- CONTENTS: RWL specification of a debt reduction algorithm featuring
--           execution of algorithms in RWL,
--           execution modulo axioms, and 
--           formal verification of algorithm in RWL
-- AUTHOR: Razvan Diaconescu with some proofs by Michihiro Matsumoto
-- corrected by sawada@sra.co.jp
-- DIFFICULTY: **

set tram path brute .

in integer

-- specification of a system of debts data type
mod! DEBT (X :: DINT) {
  protecting(QID * { sort Qid -> Agent })

  [ Debt < Debt* ]

  op ___ : Agent DInt Agent -> Debt
  op nil : -> Debt*
  op __ : Debt* Debt* -> Debt* { assoc comm }

  vars a b c : Agent
  var n : DInt

-- the whole debt in the system
  op global-debt : Debt* -> DInt

  eq global-debt(nil) = 0 .
  ceq global-debt(a n b) = n   if 0 <= n .
  ceq global-debt(a n b) = - n if n <= 0 .
  eq global-debt(d1:Debt* d2:Debt*) = global-debt(d1) + global-debt(d2) .

-- individual balance for each agent
  op balance : Agent Debt* -> DInt

  eq balance(a, nil) = 0 .
  ceq balance(a, (b n c)) = 0   if  ((b =/= a) and (c =/= a)) or
                                    ( (b == a) and (c == a) ) . 
  ceq balance(a, (a n b)) = - n if b =/= a .
  ceq balance(a, (b n a)) = n   if b =/= a .
  eq balance(a, d1:Debt* d2:Debt*) = balance(a, d1) + balance(a, d2) . 
}

-- specification of the reduction algorithm
mod! DEBT-REDUCE {
  protecting(DEBT)

  var S : Debt*
  vars m n : DInt 
  vars !A !B !C : Agent

  eq nil S = S .

  ceq !A m !B = !B - m !A if (m < 0) .
  eq  !A 0 !B = nil .
  eq (!A m !B) (!A n !B) = !A (m + n) !B .
  eq !A m !A = nil .

  ctrans (!A m !B) (!B n !C) => (!A m !C) (!B (n - m) !C)
                                        if (m <= n) and (0 < m) and (0 < n) .
  ctrans (!A m !B) (!B n !C) => (!A (m - n) !B) (!A n !C)
                                        if (n <= m) and (0 < m) and (0 < n) .
}


-- ----------------------------------------------
-- some testing
-- ----------------------------------------------
view dint-int from DINT to INT {
  sort DInt -> Int,
  sort DNat -> Nat,
  op s X:DNat -> X:Nat + 1, 
  op p Y:DInt -> Y:Int - 1, 
  op 0 -> 0 
}

** need normalizations, setting `exec normalize on'. <- now this is obsolete switch
** system does normalize always.
-- set exec normalize on

open DEBT-REDUCE(dint-int) .
-- -------------------------------
let A = ('a -2 'b) ('a 3 'c) ('c 4 'b) .
red global-debt(A) .
red balance('b, A) .
exec A .
red A ==> ('a 1 'b) ('c 1 'b) .
-- -------------------------------
let B = ('a 4 'b) ('b 2 'c) ('d -4 'c) ('d 5 'b) ('a -1 'e)
        ('b 4 'e) ('b 3 'a) ('e 3 'd) .
set always memo on
-- tram exec B .
exec B .
--> this needs much time to perform ... please be patient
clean memo
-- eof
red B ==> 'c 2 'd .
**
-- eof

-- -------------------------------
--> the problem is NOT confluent: both of the following are normal forms
red ('c 3 'a) ('d 1 'a) ('a 2 'b) ==> ('d 1 'a) ('c 2 'b) ('c 1 'a) .
red ('c 3 'a) ('d 1 'a) ('a 2 'b) ==> ('c 2 'a) ('d 1 'b) ('c 1 'b) .
close

-- ------------------------------------------------------------
-- proof by induction in RWL 
-- global-debt(sys2) <= global-debt(sys1)   if sys1 ==> sys2
-- ------------------------------------------------------------

-- BASE CASE 
-- no transition:
open DEBT-REDUCE .
  ops sys1 sys2 : -> Debt* .
  eq sys2 = sys1 .
red global-debt(sys2) <= global-debt(sys1) .
close

mod* BASE { 
  pr(DEBT-REDUCE)

  ops a b c : -> Agent
  ops m n k : -> DNat

  eq 0 < m = true .
  eq 0 < n = true .
  eq 0 < k = true .
}

-- m < n
open BASE .
  eq k + m = n .
red global-debt((a m c) (b k c)) <= global-debt((a m b) (b n c)) .
close
-- m = n
open BASE .
  eq n = m .
red global-debt((a m c) (b 0 c)) <= global-debt((a m b) (b n c)) .
close
-- n < m
open BASE .
  eq n + k = m .
red global-debt((a k c) (b n c)) <= global-debt((a m b) (b n c)) .
close

-- INDUCTION STEP
open DEBT-REDUCE .
  ops sys1 sys2 a b : -> Debt* .
  eq global-debt(sys1) <= global-debt(sys2) = true .
  eq global-debt(a) <= global-debt(b) = true .
red global-debt(sys1 a) <= global-debt(sys2 b) .
close
--
eof
--
$Id: debt-red.mod,v 1.2 2010-08-04 04:37:34 sawada Exp $