17 (* global variables declarations *)
20 (* variables type declarations *)
24 type or_integer_float = Integer mm_integer | Real mm_float
25 type list_or_integer_float = list or_integer_float
27 (* exceptions type declarations *)
28 type return_type = (int, real)
30 (* exceptions declarations *)
31 exception BreakLoop return_type
34 (* logical definitions of type tests *)
35 function type_test_or_integer_float_to_integer (x: or_integer_float) : bool =
37 | Integer mm_integer -> True
38 | Real mm_float -> False
41 function type_test_or_integer_float_to_float (x: or_integer_float) : bool =
43 | Integer mm_integer -> False
44 | Real mm_float -> True
47 (* auxiliary definitions and declarations *)
48 function get_nth (i: int) (l: list_or_integer_float) : or_integer_float =
54 axiom def_nth0: forall i: int, l: list_or_integer_float. 0 <= i < length(l) -> nth i l <> None
56 (*axiom def_length0: forall l: list_or_integer_float. length(l) > 0*)
58 (* logical type conversion functions *)
59 function or_integer_float_to_integer (e: or_integer_float) : mm_integer =
61 | Integer mm_integer -> mm_integer
65 function or_integer_float_to_float (e: or_integer_float) : mm_float =
67 | Integer mm_integer -> 1.0
68 | Real mm_float -> mm_float
71 (* logical auxiliary functions for specification *)
72 function add0 (e: list_or_integer_float) (i: int) (j: int) : mm_integer =
76 | Cons h t -> if type_test_or_integer_float_to_integer (h) = True then
77 or_integer_float_to_integer (h) + add0 (t) (i+1) (j)
84 function add1 (e: list_or_integer_float) (i: int) (j: int) : mm_float =
88 | Cons h t -> if type_test_or_integer_float_to_float (h) = True then
89 or_integer_float_to_float (h) +. add1 (t)(i+1)(j)
96 (* logical translation of procedure "sum (l: list(Or(integer, float)):[integer, float]" *)
97 let sum (l: list_or_integer_float) : (int, real) =
103 let x = ref (any or_integer_float) in
104 for i = 0 to length(l)-1 do
105 invariant { !status >= 0 && (!si = add0(l)(0)(i) && !sf = add1(l)(0)(i) &&
106 (forall i0: int . 0 <= i0 < i -> ( type_test_or_integer_float_to_integer (get_nth i0 l) = True ->
107 or_integer_float_to_integer (get_nth i0 l) <> 0 ) )
108 && (forall i0: int . 0 <= i0 < i -> ( type_test_or_integer_float_to_float (get_nth i0 l) = True ->
109 or_integer_float_to_float (get_nth i0 l) >=. 0.5 ) ) )}
112 if type_test_or_integer_float_to_integer (!x) = True then
113 if or_integer_float_to_integer (!x) = 0 then
114 raise (BreakLoop (!si,!sf))
116 si := !si + or_integer_float_to_integer (!x)
118 if type_test_or_integer_float_to_float (!x) = True then
119 if or_integer_float_to_float (!x) <. 0.5 then
120 raise (BreakLoop (!si,!sf))
122 sf := !sf +. or_integer_float_to_float (!x)
126 with BreakLoop excp ->
128 | (a0, a1) -> (a0, a1)
132 let (si0, sf0) = result in
134 && si0 = add0(l)(0)(length(l))
135 && sf0 = add1(l)(0)(length(l))
136 && (forall i0: int . 0 <= i0 < length(l) -> ( type_test_or_integer_float_to_integer (get_nth i0 l) = True ->
137 or_integer_float_to_integer (get_nth i0 l) <> 0 ) )
138 && (forall i0: int . 0 <= i0 < length(l) -> ( type_test_or_integer_float_to_float (get_nth i0 l) = True ->
139 or_integer_float_to_float (get_nth i0 l) >=. 0.5 ) )
142 ( 0 <= !status < length(l)
143 && si0 = add0(l)(0)(!status)
144 && sf0 = add1(l)(0)(!status)
145 && ( (type_test_or_integer_float_to_integer (get_nth !status l) = True
146 && or_integer_float_to_integer (get_nth !status l) = 0)
148 (type_test_or_integer_float_to_float (get_nth !status l) = True
149 && or_integer_float_to_float (get_nth !status l) <. 0.5)
151 && (forall i0: int . 0 <= i0 < !status -> ( type_test_or_integer_float_to_integer (get_nth i0 l) = True ->
152 or_integer_float_to_integer (get_nth i0 l) <> 0 ) )
153 && (forall i0: int . 0 <= i0 < !status -> ( type_test_or_integer_float_to_float (get_nth i0 l) = True ->
154 or_integer_float_to_float (get_nth i0 l) >=. 0.5 ) )
159 let l = Cons (Integer 5) (Cons (Real 3.3) (Cons (Integer 8) (Cons (Real 1.4) (Cons (Integer 9) Nil)))) in
160 let (s,f) = sum (l) in
161 assert { !status = -1 };