1 (*---------------------------------------------------------------------------*)
3 File: mk_unity_prog.sml
7 A back-end definition for the HOL-UNITY compiler programming language.
8 =====================================================================
10 This file introduces general definitions for describing a program
13 Author: (c) Copyright 1992-2008
14 by Flemming Andersen & Kim Dam Petersen
17 Updated: March 22, 2006
18 Last Update: December 30, 2007
20 The functions below are based on the following representations:
22 type 'loc = ``program variable location''
23 type 'val = ``program value''
24 type state = ('loc -> 'val) ``program state''
26 type t xpr = state -> t ``expression of type t''
27 type t asg = t -> state -> state -> state ``assignment of type t''
28 type t var = (t xpr, t asg) ``variable of type t''
30 type atom = state -> state ``atomic (singleton action)''
31 type par = state -> state -> state ``parallel action''
32 type int = atom list ``interleaved action (program)''
33 type seq = var -> num -> (int list # num)``sequential action''
36 Description of type representation: (Added: March 22, 2006)
37 -----------------------------------------------------------
39 'loc is an atomic (location) value that identifies a variable.
40 Composite variables, such as arrays and lists has a
41 single identifier. Assignment to a composite part is
42 considered an assignment to the complete variable, that
43 doesn't change the non-assigned parts of the variable.
45 'val is a generic value type of all variables.
46 It is constructed as a union of the types of the
47 variables in the program. Each program will for each type
48 of variable define a pair of functions to respectively
49 encode and decode values of the type of the variable into
50 and from the generic type 'val.
52 state is a state that associates each variable (identified by it's
53 'loc location) with it's current value (encoded in the
54 generic type 'val of value).
55 A state represents the values of every variable at a
57 A state is implemented as a map from variable locations
58 ('loc) to the generic value ('val) of the applied
63 xpr 'val xpr - generic typed expression.
65 t xpr is an expression of some (decoded) type t.
66 An expression represents a state dependent value, ie. a
67 value that depends on the values of variables.
68 An expression is implemented as map from a state (in
69 which the value is to be interpreted) to the value of the
70 expression in that state.
72 t asg is a assignment to a variable of type t.
73 An assignment represents the change in state due to
74 assignment of some variable to a value. An assignment is
75 implemented as a map from the value to be assigned, the
76 original state and a previous state to the final state.
77 The need for two parameter states: original and previous
78 is due to the fact that assignment Consider the
79 (high-level) assignment:
84 a[a[0]], a[a[1]] := 1, 0
86 The right-hand-side expression, and the left-hand-side
87 index expression should be evaluated in the original
90 The parallel assignments of:
91 a[a[0]], a[a[1]] := 1, 0
92 must be "transformed" into a single assignment of a:
93 a := a[a[i] => 1, a[j] => 0]
94 If more variables are to be assigned we get:
95 i, j, a := 1, 0, a[a[i] => 1, a[j] => 0]
96 A parallel assignment is evaluated in sequence; it is
98 [ i := <1> ] ; [ j := <0> ] ; [ a := <a[a[i] => 1, a[j] => 0> ]
99 It should be obvious that the expression in <>-braces has
100 to be evaluated in the original state of the parallel
101 assignment, whereas the sequential assignments has to be
102 evaluated in the state that is the result of the previous
103 assignment. This explains the need for two state
108 t var is a variable of type t.
109 A variable is represented by a pair that allow read- and
110 write- access to the variable.
113 atom is an atomic action.
114 An atomic action represents the state change associated
115 with a single variable assignments. An atomic action is
116 implemented as a function, that given an initial state
117 returns the state after executing the atomic action. **
120 par is a parallel action.
121 A parallel action represents the state change associated
122 with multiple atomic actions, ex.
123 (a[0] := a[1]) || (a[1] := a[0]).
124 A parallel action is implemented as a function of an
125 original- and previous state, that return a next
126 state. The use of original- and previous state is
127 explained above under section "t asg".
130 int is an interleaved action.
131 An interleaved action represents the semantic of an
132 interleaved action. An interleaved action is implemented
133 as a funtion that given an initial state returns the
134 state after evaluating the interleaved action.
136 seq is a sequential action.
137 A sequential action is a sequence of interleaved
138 actions. Each interleaved action is identified with a
139 numeric label. A sequential action is represented as a
140 function that takes a program counter variable location,
141 a NUM -encode and -decode function and an initial label
142 for the action and returns a pair with a list of
143 interleaved actions that implements the individual
144 actions to be executed in sequence and a numeric label
145 that represents the end of the sequential action. This
146 label is used as initial label for an optional sequential
147 action that is compositionally added to the current.
149 Example: val s1 : seq = `` Computer generated seq '';
150 val s2 : seq = `` Computer generated seq '';
151 val s1s2 : seq = fn pc => mk => ds => l0 =>
152 let val (lst1, l1) = s1 pc mk ds l0 in
153 let val (lst2, l2) = s2 pc mk ds l1 in
154 (APPEND lst1 lst2, l2)
159 Whereas we leave it for now due to the otherwize need for
160 updating the compiler, assignment COULD BE CHANGED to the
161 alternative below...]
163 An alternative way of implementing multiple parallel
166 1. Introduce a parallel variable assignment operator,
167 which takes a list of locations and a list of evaluated
168 generic typed expressions and performs the
169 assignment. There will no problems with side-effects,
170 due to the fact that all values has been evaluated.
173 ParAsg ([]: 'loc list) ([] : 'val list) (s : state) : state = s
174 | ParAsg (loc::locs) (val :: vals) =
175 ParAsg locs vals (fn l => (l == loc) ? val | s l))
176 | ParAsg _ _ = raise "ParAsg: location and value list differ in length";
178 The new type of ParAsg becomes:
180 ParAsg : 'loc list -> 'val list -> state -> state
182 If we redefine the type asg we get
184 ParAsg : 'loc list -> 'val list -> asg
186 2. Introduce a list evaluation operator:
189 EvalList ([] : (state -> 'val) list) (s : state) : 'val list = []
190 | EvalList (genExp :: genExps) s = (genExp s) :: EvalList genExps s;
192 3. Compile a source parallel assignment into two lists:
193 locs of the variables being assigned, and exps of
194 component transformed expressions using decoded
195 types. This process is part of the exisiting compiler.
197 4. Prepend each expression in exps with the proper encode
198 function This produces a list genExps where every
199 element is a generic typed expression.
201 5. The final representaion can now be expressed as:
204 val locs_123 : 'loc list = [ ``Generated by compiler'' ]
205 val genExps_123 : 'val list = [ ``Generated by compiler'' ]
206 val parAsg_123 : asg = (ParAsg locs_123) o (EvalList genExps_123)
209 a) A consequence of this is that VAR parameters should be
210 represented by their 'loc location.
211 b) A variable component can not be used as argument for a
212 VAR parameter, but still be used for a value parameter.
213 c) The assignment and update funtion will be deprecated.
214 d) The write part of a variable pair has to be replaced
215 with it's 'loc location.
216 e) The representation of an atomic action should be changed
217 such that it is based on the variable locations and the
218 assigned expressions. (How do we handle components???)
221 (*---------------------------------------------------------------------------*)
226 let VAR_TP = (fun s -> mk_vartype("'"^s));;
227 let LST = (fun t -> mk_type("list",[t]));;
228 let PRD = (fun (l,r) -> mk_type("prod",[l;r]));;
229 let FUN = (fun (l,r) -> mk_type("fun",[l;r]));;
232 | (l,(r::rs)) -> FUN(l,FNC(r,rs));;
234 let LOC = VAR_TP"loc";;
235 let VAL = VAR_TP"val";;
236 let STA = FUN(LOC,VAL);;
237 let ACT = FUN(STA,STA);;
240 let XPR = (fun t -> FUN(STA,t));;
241 let ASG = (fun t -> FNC(XPR t,[STA; STA; STA]));;
242 let VAR = (fun t -> PRD(XPR t, ASG t));;
243 let PAR = FNC(STA,[STA; STA]);;
244 let SEQ = FUN(LOC, FUN(FUN(NUM,VAL), FUN(FUN(VAL,NUM), FUN(NUM, PRD(INT,NUM)))));;
246 (*---------------------------------------------------------------------------*)
248 Defining Variable extraction functions
250 (*---------------------------------------------------------------------------*)
252 let t = mk_vartype"'t";;
253 let v = mk_var("v", VAR t);;
255 new_type_abbrev("stype",
257 new_type_abbrev("vtype",
258 `:(stype->'t)#((stype->'t)->stype->stype->stype)`);;
259 new_type_abbrev("vindex_type",
260 `:(stype->'i->'t)#((stype->'i->'t)->stype->stype->stype)`);;
261 new_type_abbrev("vpair_type",
262 `:(stype->'a#'b)#((stype->'a#'b)->stype->stype->stype)`);;
263 new_type_abbrev("seq_type",
264 `:'loc->(num->'val)->('val->num)->num->(stype->stype)list#num`);;
268 * Extraction expression of a variable
270 let VAR_EXP = new_definition (`VAR_EXP (v:vtype) = FST v`);;
273 * Extraction assignment of a variable
275 let VAR_ASG = new_definition (`VAR_ASG (v:vtype) = SND v`);;
277 (*---------------------------------------------------------------------------*)
279 Location to variable translator functions
281 (*---------------------------------------------------------------------------*)
283 let loc = mk_var("loc",LOC);;
284 let s = mk_var("s", STA);;
285 let s0 = mk_var("s0", STA);;
286 let ds = mk_var("ds", FUN(VAL,t));;
287 let mk = mk_var("mk", FUN(t,VAL));;
288 let e = mk_var("e", XPR t);;
291 * Translate a location to an expression
293 let LOC_EXP = new_definition
294 (`LOC_EXP loc (ds:'val->'t) (s:stype) = ds (s loc)`);;
297 * Translate a location to an assignment
299 let LOC_ASG = new_definition
300 (`LOC_ASG loc (mk:'t->'val) (e:stype->'t)
301 (s0:stype) (s:stype) l =
302 (if (l = loc) then (mk (e s0)) else (s l))`);;
305 * Translate a location to a variable pair
307 let LOC_VAR = new_definition
308 (`LOC_VAR (loc:'loc) (mk:'t->'val) (ds:'val->'t) =
309 (LOC_EXP loc ds, LOC_ASG loc mk)`);;
311 (*---------------------------------------------------------------------------*)
313 Array (index) functions
315 (*---------------------------------------------------------------------------*)
318 * Generate index expression
320 * IndexExp [(i,v),...] a
322 let INDEX_EXP = new_definition
323 (`(INDEX_EXP (a:stype->('i->'t)) (i:stype->'i) (s:stype) =
327 * Generate updated index expression (index, exp and array are frozen)
329 * UpdIndex [(i,v),...] a
331 let UPD_INDEX = new_definition
332 (`(UPD_INDEX (i:'i) (c:'t) (a:'i->'t) j = (if (j = i) then c else (a j)))`);;
335 * Generate updated index expression (index and exp are frozen)
337 * UPD_INDEX_XPR [(i,v),...] a
339 let UPD_INDEX_EXP = new_definition
340 (`(UPD_INDEX_EXP (i:'i) (c:'t) (a:stype->'i->'t) (s:stype) =
341 UPD_INDEX i c (a s))`);;
344 * Assignment part from Index of a variable
346 let VAR_INDEX_ASG = new_definition
348 (i:stype->'i) (v:vindex_type)
349 (e:stype->'t) (s0:stype) (s:stype) =
350 VAR_ASG v (UPD_INDEX_EXP (i s0) (e s0) (VAR_EXP v)) s0 s`);;
353 * Expression part from Index of a variable
355 let VAR_INDEX_EXP = new_definition
357 (i:stype->'i) (v:vindex_type) (s:stype) =
358 (VAR_EXP v s) (i s)`);;
363 let VAR_INDEXVAR = new_definition
364 (`VAR_INDEXVAR (i:stype->'i) (v:vindex_type) =
365 (VAR_INDEX_EXP i v, VAR_INDEX_ASG i v)`);;
367 (*---------------------------------------------------------------------------*)
369 List functions (not complete)
371 (*---------------------------------------------------------------------------*)
374 * List of expressions
377 (`(LIST_EXP [] (s:stype) = []) /\
378 (LIST_EXP (CONS (e:stype->'t) t) s = (CONS (e s) (LIST_EXP t s)))`);;
379 let LIST_EXP = new_recursive_definition list_RECURSION LIST_EXP_term;;
381 (*---------------------------------------------------------------------------*)
383 Record (pair,fst,snd) functions
385 (*---------------------------------------------------------------------------*)
388 * State abstracted FST and SND
390 let s_FST = new_definition
391 (`s_FST (e:'sta->('a # 'b)) s = FST (e s)`);;
393 let s_SND = new_definition
394 (`s_SND (e:'sta->('a # 'b)) s = SND (e s)`);;
399 let UPD_FST = new_definition
400 (`UPD_FST (c:'a) (p:'sta->('a#'b)) s = (c, SND(p s))`);;
402 let UPD_SND = new_definition
403 (`UPD_SND (c:'b) (p:'sta->('a#'b)) s = (FST(p s),c)`);;
406 * Assignment to FST and SND
408 let VAR_FST_ASG = new_definition
409 (`VAR_FST_ASG (v:vpair_type) (e:stype->'a) (s0:stype) (s:stype) =
410 VAR_ASG v (UPD_FST (e s0) (VAR_EXP v)) s0 s`);;
412 let VAR_SND_ASG = new_definition
413 (`VAR_SND_ASG (v:vpair_type) (e:stype->'b) (s0:stype) (s:stype) =
414 VAR_ASG v (UPD_SND (e s0) (VAR_EXP v)) s0 s`);;
417 * Variables of FST and SND
419 let FST_VAR = new_definition
420 (`FST_VAR (v:vpair_type) = (s_FST (VAR_EXP v), VAR_FST_ASG v)`);;
422 let SND_VAR = new_definition
423 (`SND_VAR (v:vpair_type) = (s_SND (VAR_EXP v), VAR_SND_ASG v)`);;
425 (*---------------------------------------------------------------------------*)
429 (*---------------------------------------------------------------------------*)
432 * Execute two parallel actions simultaneously
434 let PAR_PAR = new_definition
435 (`(PAR_PAR (p1:stype->stype->stype)
436 (p2:stype->stype->stype)
437 (s0:stype) (s:stype) =
441 * Execute a list of parallel actions
444 (`(LIST_PAR [] (s0:stype) (s:stype) = s) /\
445 (LIST_PAR (CONS (h:stype->stype->stype) t) s0 s = LIST_PAR t s0 (h s0 s))`);;
446 let LIST_PAR = new_recursive_definition list_RECURSION LIST_PAR_term;;
449 * Translate a parallel action into an atomic action
451 let PAR_ATOM = new_definition
452 (`PAR_ATOM (p:stype->stype->stype) (s:stype) = p s s`);;
455 * Guard a parallel action
457 let WHEN_PAR = new_definition
458 (`WHEN_PAR (p:stype->stype->stype) g
459 (s0:stype) (s:stype) =
460 (if (g s0) then (p s0 s) else s)`);;
463 * Conditional parallel action
465 let IF_PAR = new_definition
466 (`IF_PAR (p1:stype->stype->stype)
467 (p2:stype->stype->stype) g
468 (s0:stype) (s:stype) =
469 (if (g s0) then (p1 s0 s) else (p2 s0 s))`);;
472 * Identity parallel action
474 let ID_PAR = new_definition (`ID_PAR (s0:stype) (s:stype) = s`);;
477 * Iterated parallel assignment
480 (`(ITER_PAR0 (low:num) 0 (f:num->bool)
481 (fi:num->stype->stype->stype) = ID_PAR) /\
482 (ITER_PAR0 low (SUC n) f fi =
483 (if (f low) then PAR_PAR (fi low) (ITER_PAR0 (SUC low) n f fi)
484 else (ITER_PAR0 (SUC low) n f fi)))`);;
485 let ITER_PAR0 = new_recursive_definition num_RECURSION ITER_PAR0_term;;
487 let ITER_PAR = new_definition
488 (`ITER_PAR low high (f:num->bool)
489 (fi:num->stype->stype->stype) =
490 (ITER_PAR0 low ((1+high)-low) f fi)`);;
492 (*---------------------------------------------------------------------------*)
496 (*---------------------------------------------------------------------------*)
499 * Translate a parallel action into an atomic action
503 K and S are removed from HOL Light.
504 I and o are defined in trivia.ml
506 So I introduce K myself
508 let K_DEF = new_definition (`K x y = x`);;
510 let ASG_ACT = new_definition
511 (`ASG_ACT (par:stype->stype->stype)
512 (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
514 (WHEN_PAR (LIST_PAR [par; LOC_ASG pc mk (K (SUC l0))])
515 (LOC_EXP pc ds =* (K l0)))`);;
520 let TST_ACT = new_definition
521 (`TST_ACT (g:stype->bool)
522 (l:num) (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
523 (PAR_ATOM (WHEN_PAR (LOC_ASG pc mk ((g =>* K(SUC l0)) (K l)))
524 (LOC_EXP pc ds =* K l0)))`);;
529 let GTO_ACT = new_definition
530 (`GTO_ACT (l:num) (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
531 PAR_ATOM (WHEN_PAR (LOC_ASG pc mk (K l))
532 (LOC_EXP pc ds =* K l0))`);;
534 (*---------------------------------------------------------------------------*)
538 (*---------------------------------------------------------------------------*)
541 * Translate parallel to sequential action
543 let PAR_SEQ = new_definition
544 (`PAR_SEQ (par:stype->stype->stype)
545 (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
546 ([ASG_ACT par pc mk ds l0], SUC l0)`);;
549 * Identity sequential action
551 let ID_SEQ = new_definition
552 (`ID_SEQ (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
556 * Execute two sequential actions in a row
558 let SEQ_SEQ = new_definition
559 (`SEQ_SEQ (s1:seq_type) (s2:seq_type)
560 (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
561 let b1 = s1 pc mk ds l0 in
562 let b2 = s2 pc mk ds (SND b1) in
563 (APPEND (FST b1) (FST b2), (SND b2))`);;
566 * Iterated sequential actions
569 (`(ITER_SEQ0 (low:num) 0 (f:num->bool) (fi:num->seq_type) = ID_SEQ) /\
570 (ITER_SEQ0 low (SUC n) f fi =
571 (if (f low) then (SEQ_SEQ (fi low) (ITER_SEQ0 (SUC low) n f fi))
572 else (ITER_SEQ0 (SUC low) n f fi)))`);;
573 let ITER_SEQ0 = new_recursive_definition num_RECURSION ITER_SEQ0_term;;
575 let ITER_SEQ = new_definition
576 (`ITER_SEQ low high (f:num->bool) (fi:num->seq_type) =
577 ITER_SEQ0 low ((1+high)-low) f fi`);;
580 * List of sequential actions
583 (`(LIST_SEQ [] (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) = ([], l0)) /\
584 (LIST_SEQ (CONS (sa:seq_type) sas) pc mk ds l0 =
585 let b1 = sa pc mk ds l0 in
586 let bs = LIST_SEQ sas pc mk ds (SND b1) in
587 (APPEND (FST b1) (FST bs), (SND bs)))`);;
588 let LIST_SEQ = new_recursive_definition list_RECURSION LIST_SEQ_term;;
591 * Conditional sequential actions
593 let IF1_SEQ = new_definition
594 (`(IF1_SEQ (g:stype->bool)
595 (sa:seq_type) (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
596 let b1 = sa pc mk ds (SUC l0) in
597 let a1 = TST_ACT g (SND b1) pc mk ds l0 in
598 (CONS a1 (FST b1), (SND b1)))`);;
601 * Conditional (else) sequential actions
603 let IF2_SEQ = new_definition
604 (`(IF2_SEQ (g:stype->bool) (sa1:seq_type) (sa2:seq_type)
605 (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
606 let b1 = sa1 pc mk ds (SUC l0) in
607 let b2 = sa2 pc mk ds (SUC (SND b1)) in
608 let a1 = TST_ACT g (SUC (SND b1)) pc mk ds l0 in
609 let a2 = GTO_ACT (SND b2) pc mk ds (SND b1) in
610 (APPEND (CONS a1 (FST b1))
611 (CONS a2 (FST b2)), (SND b2)))`);;
614 * While loop sequential actions
616 let WHL_SEQ = new_definition
617 (`(WHL_SEQ (g:stype->bool) (sa:seq_type)
618 (pc:'loc) (mk:num->'val) (ds:'val->num) (l0:num) =
619 let b1 = sa pc mk ds (SUC l0) in
620 let a1 = TST_ACT g (SUC (SND b1)) pc mk ds l0 in
621 let a2 = GTO_ACT l0 pc mk ds (SND b1) in
622 (APPEND (CONS a1 (FST b1)) [a2], (SUC(SND b1))))`);;
624 (*---------------------------------------------------------------------------*)
628 (*---------------------------------------------------------------------------*)
631 * Translate a parallel action into an interleaved action
633 let PAR_INT = new_definition
634 (`PAR_INT (par:stype->stype->stype) = [PAR_ATOM par]`);;
637 * Composition of two interleaved actions
639 let INT_INT = new_definition
640 (`INT_INT (i1:(stype->stype)list) i2 = APPEND i1 i2`);;
643 * Translate a list of interleaved action into a single interleaved action
646 (`(LIST_INT [] = ([]:(stype->stype)list)) /\
647 (LIST_INT (CONS (h:(stype->stype)list) t) =
648 (APPEND h (LIST_INT t)))`);;
649 let LIST_INT = new_recursive_definition list_RECURSION LIST_INT_term;;
652 * Translate a parallel action into an interleaved action
654 let ID_INT = new_definition
655 (`ID_INT = ([]:(stype->stype)list)`);;
658 (*########################################################################
660 # Iterated interleaving #
662 # << i : 1 <= i <= N :: Pr[i] >> #
666 # IteratedINTerleaving low n Pr[.] --> #
667 # Pr[low] [] ... [] Pr[low+n-1] #
669 ########################################################################*)
672 * Iterated interleaved assignment
675 (`(ITER_INT0 (low:num) 0 (f:num->bool) (fi:num->(stype->stype)list) = ID_INT) /\
676 (ITER_INT0 low (SUC n) f fi =
677 (if (f low) then (INT_INT (fi low) (ITER_INT0 (SUC low) n f fi))
678 else (ITER_INT0 (SUC low) n f fi)))`);;
679 let ITER_INT0 = new_recursive_definition num_RECURSION ITER_INT0_term;;
681 let ITER_INT = new_definition
682 (`ITER_INT low high (f:num->bool) (fi:num->(stype->stype)list) =
683 ITER_INT0 low ((1+high)-low) f fi`);;
685 (*#######################################################################
687 # Absolute and relative Label predicates #
689 # AT,AFTER : At first, first following action #
690 # IN : Inside action #
691 # BEFORE,FOLLOW : Strictly before,following action #
693 ########################################################################*)
695 let AT_LBL = new_definition
696 (`AT_LBL ds pc (label:num#num) =
697 (LOC_EXP pc ds:stype->num) =* K (FST label)`);;
699 let AFTER_LBL = new_definition
700 (`AFTER_LBL ds pc (label:num#num) =
701 (LOC_EXP pc ds:stype->num) =* K (SND label)`);;
703 let BEFORE_LBL = new_definition
704 (`BEFORE_LBL ds pc (label:num#num) =
705 (LOC_EXP pc ds:stype->num) <* K (FST label)`);;
707 let INSIDE_LBL = new_definition
708 (`INSIDE_LBL ds pc (label:num#num) =
709 ((LOC_EXP pc ds:stype->num) >=* K (FST label)) /\*
710 ((LOC_EXP pc ds:stype->num) <* K (SND label))`);;
712 let FOLLOW_LBL = new_definition
713 (`FOLLOW_LBL ds pc (label:num#num) =
714 (LOC_EXP pc ds:stype->num) >=* K (SND label)`);;
716 (* Absolute label handler *)
717 let AT_ABS = new_definition
718 (`AT_ABS (pc:stype->num) (l:num) (u:num) = (pc =* K l)`);;
720 let AT_REL = new_definition
721 (`AT_REL (pc:(stype->num)#((stype->num)->stype->stype->stype))
723 VAR_EXP pc =* K (FST label)`);;
725 let AFTER_ABS = new_definition
726 (`AFTER_ABS (pc:stype->num) (l:num) (u:num) = (pc =* K u)`);;
728 let AFTER_REL = new_definition
729 (`AFTER_REL (pc:(stype->num)#((stype->num)->stype->stype->stype))
731 VAR_EXP pc =* K (SND label)`);;
733 let BEFORE_ABS = new_definition
734 (`BeforeAbs (pc:stype->num) (l:num) (u:num) = (pc <* K l)`);;
736 let BEFORE_REL = new_definition
737 (`BEFORE_REL (pc:(stype->num)#((stype->num)->stype->stype->stype))
739 VAR_EXP pc <* K (FST label)`);;
741 let INSIDE_ABS = new_definition
742 (`INSIDE_ABS (pc:stype->num) (l:num) (u:num) =
743 (pc >=* K l) /\* (pc <* K u)`);;
745 let INSIDE_REL = new_definition
746 (`INSIDE_REL (pc:(stype->num)#((stype->num)->stype->stype->stype))
748 (VAR_EXP pc >=* K (FST label)) /\*
749 (VAR_EXP pc <* K (SND label))`);;
751 let FOLLOW_ABS = new_definition
752 (`FollowAbs (pc:stype->num) (l:num) (u:num) = (pc >=* K l)`);;
754 let FOLLOW_REL = new_definition
755 (`FOLLOW_REL (pc:(stype->num)#((stype->num)->stype->stype->stype))
757 VAR_EXP pc >=* K (SND label)`);;
759 (*########################################################################
761 # Restricted UNLESS #
763 # (p UNLESS{valid} q) Pr #
767 # RESTRICTED_UNLESS valid p q Pr = #
768 # {p /\ valid /\ ~q)} Pr {p \/ q} #
770 ########################################################################*)
772 let RESTRICTED_UNLESS_STMT = new_definition
773 (`RESTRICTED_UNLESS_STMT v p q st =
774 (!s:'state. p s /\ v s /\ ~(q s) ==> p (st s) \/ q (st s))`);;
776 let RESTRICTED_UNLESS_term =
777 (`(RESTRICTED_UNLESS (v:'state->bool) p q [] = T) /\
778 (RESTRICTED_UNLESS (v:'state->bool) p q (CONS st Pr) =
779 (RESTRICTED_UNLESS_STMT v p q st /\ RESTRICTED_UNLESS v p q Pr))`);;
780 let RESTRICTED_UNLESS =
781 new_recursive_definition list_RECURSION RESTRICTED_UNLESS_term;;
783 (*#######################################################################
785 # RESTRICTED STABLE #
787 # (p STABLE{valid} q) Pr #
791 # RESTRICTED_STABLE valid p q Pr = #
792 # {p /\ valid} Pr {p} #
794 ########################################################################*)
795 let RESTRICTED_STABLE_STMT = new_definition
796 (`RESTRICTED_STABLE_STMT v p st =
797 (!s:'state. p s /\ v s ==> p (st s))`);;
799 let RESTRICTED_STABLE_term =
800 (`(RESTRICTED_STABLE (v:'state->bool) p [] = T) /\
801 (RESTRICTED_STABLE (v:'state->bool) p (CONS st Pr) =
802 (RESTRICTED_STABLE_STMT v p st /\ RESTRICTED_STABLE v p Pr))`);;
803 let RESTRICTED_STABLE =
804 new_recursive_definition list_RECURSION RESTRICTED_STABLE_term;;
806 (*########################################################################
808 # RESTRICTED EXISTS_TRANSITION #
810 # (p EXISTS_TRANSITION{valid} q) Pr #
814 # RESTRICTED_EXISTS_TRANSITION valid p q Pr = #
815 # ?st In Pr. {p /\ valid /\ ~q} Pr {q} #
817 ########################################################################*)
818 let RESTRICTED_EXISTS_TRANSITION_STMT = new_definition
819 (`RESTRICTED_EXISTS_TRANSITION_STMT v p q st =
820 (!s:'state. p s /\ v s /\ ~(q s) ==> q (st s))`);;
822 let RESTRICTED_EXISTS_TRANSITION_term =
823 (`(RESTRICTED_EXISTS_TRANSITION (v:'state->bool) p q [] = F) /\
824 (RESTRICTED_EXISTS_TRANSITION (v:'state->bool) p q (CONS st Pr) =
825 (RESTRICTED_EXISTS_TRANSITION_STMT v p q st \/
826 RESTRICTED_EXISTS_TRANSITION v p q Pr))`);;
827 let RESTRICTED_EXISTS_TRANSITION =
828 new_recursive_definition list_RECURSION RESTRICTED_EXISTS_TRANSITION_term;;
830 (*########################################################################
832 # RESTRICTED ENSURES #
834 # (p ENSURES{valid} q) Pr #
838 # RESTRICTED_ENSURES valid p q Pr = #
839 # RESTRICTED_UNLESS valid p q Pr /\ #
840 # RESTRICTED_EXISTS_TRANSITION valid p q Pr #
842 ########################################################################*)
843 let RESTRICTED_ENSURES = new_definition
844 (`RESTRICTED_ENSURES (v:'state->bool) p q Pr =
845 (RESTRICTED_UNLESS v p q Pr /\
846 RESTRICTED_EXISTS_TRANSITION v p q Pr)`);;
848 (*########################################################################
850 # RESTRICTED LEADSTO #
852 # (p LEADSTO{valid} q) Pr #
856 # RESTRICTED_LEADSTO valid p q Pr = #
857 # (p /\ valid p) LEADSTO q Pr /\ #
859 ########################################################################*)
860 let RESTRICTED_LEADSTO = new_definition
861 (`RESTRICTED_LEADSTO (v:'state->bool) p q Pr =
862 (((p /\* v) LEADSTO q) Pr)`);;
864 (*########################################################################
875 ########################################################################*)
876 let VALID = new_definition
877 (`VALID (p:'state->bool) = !s. p s`);;
880 (`(TRIPLE (p:'state->bool) q [] = T) /\
881 (TRIPLE p q (CONS (st:'state->'state) Pr) =
882 ((!s. p s ==> q(st s)) /\ TRIPLE p q Pr))`);;
883 let RESTRICTED_TRIPLE =
884 new_recursive_definition list_RECURSION TRIPLE_term;;
886 (*########################################################################
888 # SUMMA lwb len filter body = #
889 # Body(lwb) + ... Body(i) ... + Body(lwb+len-1) , when filter(i)#
891 # SUMMA lwb 0 f b = 0 #
892 # SUMMA lwb (SUC n) f b = (f lwb => b lwb | 0) + SUMMA lwb n f b #
894 ########################################################################*)
896 (`(SUMMA0 lwb 0 f b = 0) /\
897 (SUMMA0 lwb (SUC n) f b =
898 ((if (f lwb) then (b lwb) else 0) + (SUMMA0 (SUC lwb) n f b)))`);;
899 let SUMMA0 = new_recursive_definition num_RECURSION SUMMA0_term;;
901 let SUMMA = new_definition
902 (`SUMMA lwb upb f b = SUMMA0 lwb ((1 + upb)-lwb) f b`);;
904 let SUMMA_S = new_definition
905 (`SUMMA_S lwb upb f b (s:'state) =
906 SUMMA (lwb s) (upb s) (\i. f i s) (\i. b i s)`);;
908 (*########################################################################
910 # MULTA lwb len filter body = #
911 # Body(lwb) * ... Body(i) ... * Body(lwb+len-1) , when filter(i)#
913 # MULTA lwb 0 f b = 1 #
914 # MULTA lwb (SUC n) f b = (f lwb => b lwb | 1) * MULTA lwb n f b #
916 ########################################################################*)
918 (`(MULTA0 lwb 0 f b = 1) /\
919 (MULTA0 lwb (SUC n) f b =
920 ((if (f lwb) then (b lwb) else 1) * (MULTA0 (SUC lwb) n f b)))`);;
921 let MULTA0 = new_recursive_definition num_RECURSION MULTA0_term;;
923 let MULTA = new_definition
924 (`MULTA lwb upb f b = MULTA0 lwb ((1 + upb)-lwb) f b`);;
926 let MULTA_S = new_definition
927 (`MULTA_S lwb upb f b (s:'state) =
928 MULTA (lwb s) (upb s) (\i. f i s) (\i. b i s)`);;
930 (*########################################################################
932 # CONJA lwb len filter body = #
933 # Body(lwb) & ... Body(i) ... & Body(lwb+len-1) , when filter(i)#
935 # CONJA lwb 0 f b = T #
936 # CONJA lwb (SUC n) f b = (f lwb => b lwb | 1) & CONJA lwb n f b #
938 ########################################################################*)
940 (`(CONJA0 lwb 0 f b = T) /\
941 (CONJA0 lwb (SUC n) f b =
942 ((if (f lwb) then (b lwb) else T) /\ (CONJA0 (SUC lwb) n f b)))`);;
943 let CONJA0 = new_recursive_definition num_RECURSION CONJA0_term;;
945 let CONJA = new_definition
946 (`CONJA lwb upb f b = CONJA0 lwb ((1 + upb)-lwb) f b`);;
948 let CONJA_S = new_definition
949 (`CONJA_S lwb upb f b (s:'state) =
950 CONJA (lwb s) (upb s) (\i. f i s) (\i. b i s)`);;
952 (*########################################################################
954 # DISJA lwb len filter body = #
955 # Body(lwb) | ... Body(i) ... | Body(lwb+len-1) , when filter(i)#
957 # DISJA lwb 0 f b = F #
958 # DISJA lwb (SUC n) f b = (f lwb => b lwb | 1) | DISJA lwb n f b #
960 ########################################################################*)
962 (`(DISJA0 lwb 0 f b = F) /\
963 (DISJA0 lwb (SUC n) f b =
964 ((if (f lwb) then (b lwb) else F) \/ (DISJA0 (SUC lwb) n f b)))`);;
965 let DISJA0 = new_recursive_definition num_RECURSION DISJA0_term;;
967 let DISJA = new_definition
968 (`DISJA lwb upb f b = DISJA0 lwb ((1 + upb)-lwb) f b`);;
970 let DISJA_S = new_definition
971 (`DISJA_S lwb upb f b (s:'state) =
972 DISJA (lwb s) (upb s) (\i. f i s) (\i. b i s)`);;
974 (*---------------------------------------------------------------------------*)
978 (*---------------------------------------------------------------------------*)
980 * Test for list membership
983 (`(MEMBER (x:'a) [] = F) /\
984 (MEMBER x (CONS h t) = ((x=h) \/ (MEMBER x t)))`);;
985 let MEMBER = new_recursive_definition list_RECURSION MEMBER_term;;
988 * Test for unique elements in list
992 (UNIQUE (CONS (h:'a) t) = ((~(MEMBER h t)) /\ UNIQUE t))`);;
993 let UNIQUE = new_recursive_definition list_RECURSION UNIQUE_term;;