8 type t 'a = abstract { contents: map key 'a }
10 val function create (x: 'a): t 'a
11 ensures { result.contents = const x }
13 val function ([]) (m: t 'a) (k: key): 'a
14 ensures { result = m.contents[k] }
16 val function ([<-]) (m: t 'a) (k: key) (v: 'a): t 'a
17 ensures { result.contents = m.contents[k <- v] }
28 clone Appmap with type key = int
32 predicate injective (n:int) (m:int) (a:array 'a) =
33 forall i j:int. n <= i <= m -> n <= j <= m ->
38 (* Capucine memory model *)
44 type first_free_addr = int
46 predicate valid (a:first_free_addr) (p:pointer) = p < a
48 predicate valid_array (a:first_free_addr) (n:int) (m:int) (r:array pointer) =
49 forall i:int. n <= i <= m -> valid a (r[i])
51 val alloc : ref first_free_addr
53 val new_pointer (_tt:unit) : pointer writes { alloc }
54 ensures { !alloc = old !alloc + 1 /\ result = old !alloc }
60 inv(this) { 0 <= this.mark <= 100 }
64 type student = (char_string, int)
66 predicate invStudent (this:student) =
67 let (_,m) = this in 0 <= m <= 100
72 students: array [Rstud]
78 injective(0, count-1, this.students)
80 this.sum = mark_sum(0,this.count-1,this.students)
85 type course = (region student, array pointer, int, int)
87 function markSum (region student) int int (array pointer) : int
90 forall r:region student, i j:int, a : array pointer.
91 i > j -> markSum r i j a = 0
93 axiom MarkSumNonEmpty :
94 forall r:region student, i j:int, a : array pointer.
96 let (_,mark) = r[a[j]] in
97 markSum r i j a = markSum r i (j-1) a + mark
100 lemma MarkSumFootprint:
101 forall n:int. forall s1: array(Student [R1]).
102 forall s2: array(Student [R2]).
103 (forall i:int. [0] <= [i] /\ [i] < [n] ==>
104 [!(select(s1,i) : Student[R1]).mark] =
105 [!(select(s2,i) : Student[R2]).mark])
106 ==> [MarkSum(n, s1)] = [MarkSum(n,s2)]
109 lemma MarkSum_set_array_outside :
110 forall r:region student, i j k:int, a: array pointer, p:pointer.
112 markSum r i j (a[k <- p]) = markSum r i j a
115 lemma MarkSum_set_region_outside :
116 forall r:region student, i j:int, a: array pointer, p:pointer, s:student.
117 (forall k:int. i <= k <= j -> a[k] <> p) ->
118 markSum (r[p <- s]) i j a = markSum r i j a
123 predicate invCourse (alloc:first_free_addr) (this:course) =
124 let (rStud,students,count,sum) = this in
127 valid_array alloc 0 (count - 1) students
129 injective 0 (count - 1) students
131 sum = markSum rStud 0 (count-1) students
134 fun CreateCourse(R:[Course]): [R]
138 let c = new Course [R] in
145 let createCourse (r: (ref (region course))) : pointer
146 ensures { valid !alloc result }
147 = let c = new_pointer () in
148 let (rStud,student,_count,_sum) = !r[c] in
149 let newc = (rStud,student,0,0) in
151 assert { invCourse !alloc newc };
155 fun RegisterStudent(R:[Course], c: [R], name: char_string): [R.Rstud]
160 let s = new Student[S] in
162 (adoptregion S as R.R_s);
163 assert [MarkSum(!(!c.students))] = [old(MarkSum(!(!c.students)))];
164 (focus !c.students) := add(!(!c.students), s);
165 c := (!c.students, !c.count + 1, !c.total, !c.4);
170 (r: (ref (region course))) (c:pointer) (name:char_string) : pointer
171 requires { valid !alloc c /\ invCourse !alloc !r[c] }
172 ensures { valid !alloc result }
173 = let s = new_pointer () in
174 let (rStud,student,count,sum) = !r[c] in
175 let newstud = (name,0) in
176 let newc = (rStud[s <- newstud],student[count <- s],count+1,sum) in
178 assert { invCourse !alloc newc };
183 fun SetMark(R:Course, c:[R], s: [c.Rstud], mark: int) : unit
187 unpack c (* c.Rstud^G, R^o *)
188 let region Rs:Student
189 let s' = focus s as Rs (* Rs -o c.Rstud, Rs^c, R^o *)
190 unpack s' (* Rs -o c.Rstud, Rs^o, R^o *)