10 type array 'a = A.t int 'a
12 logic injective (n:int) (m:int) (a:array 'a) =
13 forall i j:int. n <= i <= m -> n <= j <= m ->
14 A.get a i = A.get a j -> i = j
18 (* Capucine memory model *)
22 type region 'a = A.t pointer 'a
25 type first_free_addr = int
27 logic valid (a:first_free_addr) (p:pointer) = p < a
29 logic valid_array (a:first_free_addr) (n:int) (m:int) (r:array pointer) =
30 forall i:int. n <= i <= m -> valid a (A.get r i)
32 parameter alloc : ref first_free_addr
34 parameter new_pointer : tt:unit ->
38 { alloc = old alloc + 1 and result = old alloc }
46 inv(this) { 0 <= this.mark <= 100 }
50 type student = (string, int)
52 logic invStudent (this:student) =
53 let (_,m) = this in 0 <= m <= 100
58 students: array [Rstud]
64 injective(0, count-1, this.students)
66 this.sum = mark_sum(0,this.count-1,this.students)
71 type course = (region student, array pointer, int, int)
73 (* markSum(r,i,j,a) donne \sigma_{k=i,j} get(r,a[k]).mark *)
75 logic markSum (region student) int int (array pointer) : int
77 (* axiom MarkSumEmpty :
78 forall region r:Student,
79 forall i j:int, forall a:(array pointer),
80 i > j -> markSum(r,i,j,a) = 0
84 forall r:region student, i j:int, a : array pointer.
85 i > j -> markSum r i j a = 0
87 (* axiom MarkSumNonEmpty :
88 forall region r:Student,
89 forall i j:int, forall a:(array [r]),
91 let p = array_get a j in
92 markSum(r,i,j,a) = markSum(r,i,j-1,a) + get(r,p).mark
95 axiom MarkSumNonEmpty :
96 forall r:region student, i j:int, a : array pointer.
99 let (_,mark) = A.get r p in
100 markSum r i j a = markSum r i (j-1) a + mark
102 (* a essayer mais pas essentiel
103 logic markSum (r:region student) (i:int) (j:int) (a:array pointer) : int =
104 if i > j then 0 else ...
109 lemma MarkSumFootprint:
110 forall n:int. forall s1: array(Student [R1]).
111 forall s2: array(Student [R2]).
112 (forall i:int. [0] <= [i] and [i] < [n] ==>
113 [!(select(s1,i) : Student[R1]).mark] =
114 [!(select(s2,i) : Student[R2]).mark])
115 ==> [MarkSum(n, s1)] = [MarkSum(n,s2)]
120 lemma MarkSum_set_array_outside :
121 forall region r:Student. forall i j k:int, a: array [r], p:pointer.
123 markSum(r,i,j,array_set(a,k,p)) = markSum(r,i,j,a)
127 lemma MarkSum_set_array_outside :
128 forall r:region student, i j k:int, a: array pointer, p:pointer.
130 markSum r i j (A.set a k p) = markSum r i j a
134 lemma MarkSum_set_region_outside :
135 forall region r:Student. forall i j:int, a: array [r], p:pointer, s:student.
136 (forall k:int. i <= k <= j -> A.get a k <> p) ->
137 markSum (A.set r p s) i j a = markSum r i j a
140 lemma MarkSum_set_region_outside :
141 forall r:region student, i j:int, a: array pointer, p:pointer, s:student.
142 (forall k:int. i <= k <= j -> A.get a k <> p) ->
143 markSum (A.set r p s) i j a = markSum r i j a
148 logic invCourse (alloc:first_free_addr) (this:course) =
149 let (rStud,students,count,sum) = this in
152 valid_array alloc 0 (count - 1) students
154 injective 0 (count - 1) students
156 sum = markSum rStud 0 (count-1) students
159 fun CreateCourse(R:[Course]): [R]
163 let c = new Course [R] in
170 let createCourse (r: (ref (region course))) : pointer =
172 let c = new_pointer () in
173 let (rStud,student,count,sum) = A.get !r c in
174 let newc = (rStud,student,0,0) in
175 r := A.set !r c newc;
176 assert { invCourse alloc newc };
178 { valid alloc result }
181 fun RegisterStudent(R:[Course], c: [R], name: string): [R.Rstud]
186 let s = new Student[S] in
188 assert forall i:int, array_get c.students i in rStud;
189 (adoptregion S as R.R_s);
190 " assume forall p:pointer. p in old(R.R_S) -> p <> s "
191 assert [MarkSum(!(!c.students))] = [old(MarkSum(!(!c.students)))];
192 (focus !c.students) := add(!(!c.students), s);
193 c := (!c.students, !c.count + 1, !c.total, !c.4);
198 (r: (ref (region course))) (c:pointer) (name:string) : pointer =
199 { valid alloc c and invCourse alloc (A.get r c) }
200 let s = new_pointer () in
201 let (rStud,student,count,sum) = A.get !r c in
202 let newstud = (name,0) in
203 assume { forall p:pointer. in_region(p,old rStud) -> p <> s } ;
204 let newc = (A.set rStud s newstud,A.set student count s,count+1,sum) in
205 r := A.set !r c newc;
206 assert { invCourse alloc newc };
208 { valid alloc result }
212 fun SetMark(R:Course, c:[R], s: [c.Rstud], mark: int) : unit
216 unpack c (* c.Rstud^G, R^o *)
217 let region Rs:Student
218 let s' = focus s as Rs (* Rs -o c.Rstud, Rs^c, R^o *)
219 unpack s' (* Rs -o c.Rstud, Rs^o, R^o *)
231 compile-command: "unset LANG; make -C ../.. examples/programs/course"