Skip to content

Commit 6265785

Browse files
committed
Merge branch 'outputs_pre'
2 parents b73e4a8 + 509c7c2 commit 6265785

12 files changed

+221
-127
lines changed

ROOT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
session "Z_Machines" = "ITree_UTP" +
1+
session "Z_Machines" = "ITree_VCG" +
22
options [timeout = 600, document = false]
33
sessions
44
Explorer

Z_Animator.thy

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ removeSubstr :: String -> String -> String;
2222
removeSubstr w "" = "";
2323
removeSubstr w s@(c:cs) = (if w `isPrefixOf` s then Prelude.drop (Prelude.length w) s else c : removeSubstr w cs);
2424
25-
data EventCont p = InputEvtCont [(String, p)] | OutEvtCont (String, p)
25+
data EventCont p = MultiEvtCont [(String, p)] | SingleEvtCont (String, p)
2626
2727
showEventCont :: (String, EventCont p) -> String
28-
showEventCont (n, InputEvtCont _) = n
29-
showEventCont (n, OutEvtCont (v, _)) = n ++ " " ++ v
28+
showEventCont (n, MultiEvtCont _) = n
29+
showEventCont (n, SingleEvtCont (v, _)) = n ++ " " ++ v
3030
3131
eventHierarchy :: [(String, p)] -> [(String, EventCont p)]
3232
eventHierarchy m = map (\c -> (c,
33-
(\es -> if length es == 1 then OutEvtCont (head es) else InputEvtCont es)
33+
(\es -> if length es == 1 then SingleEvtCont (head es) else MultiEvtCont es)
3434
$ map (\(e, p) -> (tail (dropWhile (\x -> x /= ' ') e), p))
3535
$ filter (isPrefixOf (c ++ " ") . fst) m)) chans
3636
where
@@ -48,30 +48,35 @@ animate_cnt n (Sil p) =
4848
animate_cnt n (Vis (Pfun_of_alist [])) = putStrLn "Deadlocked.";
4949
animate_cnt n t@(Vis (Pfun_of_alist m)) =
5050
do { putStrLn ("Operations:" ++ concat (map (\(n, e) -> " (" ++ show n ++ ") " ++ e ++ ";") (zip [1..] (map showEventCont eh))));
51+
putStr ("Choose [1-" ++ show (length eh) ++ "]: ");
5152
e <- getLine;
5253
if (e == "q" || e == "Q") then
5354
putStrLn "Animation terminated"
5455
else
5556
case (reads e) of
56-
[] -> do { putStrLn "No parse"; animate_cnt n t }
57-
[(v, _)] -> if (v > length eh)
58-
then do { putStrLn "Rejected"; animate_cnt n t }
59-
else case (snd (eh !! (v - 1))) of
60-
InputEvtCont opts ->
61-
do { putStrLn ("Parameters:" ++ concat (map (\(n, e) -> " (" ++ show n ++ ") " ++ e ++ ";") (zip [1..] (map fst opts))))
62-
; e <- getLine
63-
; case (reads e) of
64-
[] -> do { putStrLn "No parse"; animate_cnt n t }
65-
[(v, _)] -> if (v > length opts)
66-
then do { putStrLn "Rejected"; animate_cnt n t }
67-
else animate_cnt 0 (snd (opts !! (v - 1)))
68-
69-
}
70-
OutEvtCont (_, p) -> animate_cnt 0 p
57+
[] -> do { putStrLn "Invalid choice, try again."; animate_cnt n t }
58+
[(v, _)] ->
59+
if (v > length eh)
60+
then do { putStrLn "Rejected"; animate_cnt n t }
61+
else case (snd (eh !! (v - 1))) of
62+
MultiEvtCont opts ->
63+
do { putStrLn ("Parameters:" ++ concat (map (\(n, e) -> " (" ++ show n ++ ") " ++ e ++ ";") (zip [1..] (map fst opts))))
64+
; putStr ("Choose [1-" ++ show (length opts) ++ "]: ")
65+
; e <- getLine
66+
; case (reads e) of
67+
[] -> do { putStrLn "No parse"; animate_cnt n t }
68+
[(v, _)] -> if (v > length opts)
69+
then do { putStrLn "Rejected"; animate_cnt n t }
70+
else case snd (opts !! (v - 1)) of
71+
Vis (Pfun_of_alist [(e, p')]) ->
72+
do { putStrLn ("Response: " ++ show e); putStrLn ""; animate_cnt 0 p' }
73+
74+
}
75+
SingleEvtCont (_, Vis (Pfun_of_alist [(e, p')])) -> do { putStrLn ("Response: " ++ show e); putStrLn ""; animate_cnt 0 p' }
7176
}
7277
where eh = eventHierarchy (map (\(e, p) -> (Prelude.show e, p)) m);
7378
animate :: (Eq e, Prelude.Show e, Prelude.Show s) => Itree e s -> Prelude.IO ();
74-
animate p = do { hSetBuffering stdout NoBuffering; putStrLn ""; putStrLn "Starting Animation..."; animate_cnt 0 p }
79+
animate p = do { hSetBuffering stdout NoBuffering; putStrLn ""; putStrLn "Starting Animation..."; putStrLn ""; animate_cnt 0 p }
7580
\<close>
7681

7782
ML \<open>

Z_Machine.ML

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ structure Z_Machine = struct
55
type param = string * string
66

77
datatype operation_body =
8-
OperDefn of {params: param list, pre: string list, update: string, guard: string list} |
9-
OperComp of {params: param list, body: string} |
8+
OperDefn of {params: param list, pre: string list, update: string, output: string} |
9+
OperComp of {params: param list, pre: string list, body: string} |
1010
OperProm of {promop: string, plens: string} |
1111
OperEmit of {emit: string}
1212

@@ -52,7 +52,7 @@ fun mk_chan_show_fun tname ops ctx =
5252
let val typ = Syntax.read_typ ctx tname in
5353
Function_Fun.add_fun
5454
[(Binding.name ("show_" ^ tname), SOME (typ --> @{typ "String.literal"}), NoSyn)]
55-
(map (fn n => ((Binding.empty_atts, mk_chan_show_eq n ctx), [], [])) ops)
55+
(map (fn n => ((Binding.empty_atts, mk_chan_show_eq n ctx), [], [])) (ops @ map (fn n => n ^ "_Out") ops))
5656
(Function_Fun.fun_config) ctx
5757
end
5858

@@ -72,25 +72,23 @@ fun zop_update n = n ^ "_update"
7272

7373
(* FIXME: Guard ~> Precondition, Postcondition ~> Guard *)
7474

75+
fun gen n ty term ctx = snd (Local_Theory.define
76+
((Binding.name n, NoSyn)
77+
, ((Binding.name (n ^ "_def")
78+
, @{attributes [code_unfold, z_defs]})
79+
, Syntax.check_term ctx (Type.constraint ty term))) ctx);
80+
7581
fun def_zop n set st body ctx =
7682
let open Syntax; open HOLogic; open Local_Theory
7783
val parm = dest_setT (range_type (Term.type_of (check_term ctx set)))
7884
in
7985
(* Generate the type of the operation (i.e. the set of possible parameter values *)
80-
snd (define
81-
((Binding.name (zop_type n), NoSyn)
82-
, ((Binding.name (zop_type n ^ "_def")
83-
, @{attributes [code_unfold, z_defs]})
84-
, check_term ctx set)) ctx) |>
85-
(* Generate the precondition *)
86-
snd o define
87-
((Binding.name n, NoSyn)
88-
, ((Binding.name (n ^ "_def")
89-
(* It would be better if we could mark these as "code" rather than "code_unfold" to retain
90-
the structure in the language target. For now, code_unfold is required to ensure that
91-
the semantics of enumerated inputs is correctly calculated *)
92-
, @{attributes [code_unfold, z_defs]})
93-
, check_term ctx (Type.constraint (parm --> st --> dummyT) body)))
86+
gen (zop_type n) dummyT (check_term ctx set) ctx |>
87+
(* Generate the operation body *)
88+
(* It would be better if we could mark these as "code" rather than "code_unfold" to retain
89+
the structure in the language target. For now, code_unfold is required to ensure that
90+
the semantics of enumerated inputs is correctly calculated *)
91+
gen n (parm --> st --> dummyT) body
9492
end
9593

9694
fun mk_zinit (Init {name = n, state = s, update = upd}) ctx =
@@ -103,30 +101,30 @@ fun mk_zinit (Init {name = n, state = s, update = upd}) ctx =
103101
, check_term ctx (Type.constraint (st --> st) (parse_term ctx upd)))) ctx)
104102
end;
105103

106-
fun mk_zop (Operation {name = n, state = s, body = OperDefn {params = ps, pre = pre, update = upd, guard = g}}) ctx =
104+
fun mk_zop (Operation {name = n, state = s, body = OperDefn {params = ps, pre = pre, update = upd, output = ot}}) ctx =
107105
let open Syntax; open Library; open Logic; open HOLogic; open Lift_Expr
108106
val pss = (map (fn (p, t) => (p, lift_expr ctx ((parse_term ctx t)))) ps)
109107
val pset = params_set (map snd pss)
110108
val set = SEXP $ pset
111109
val parm = dest_setT (range_type (Term.type_of (check_term ctx set)))
112110
val st = read_typ ctx s
113111
val ppat = mk_tuple (map (free o fst) pss)
112+
114113
val ppre =
115-
lambda (free state_id)
116-
(mk_lift_expr ctx (foldr1 mk_conj ((map (parse_term ctx) pre))) $ Bound 0)
117-
val pguard =
118114
lambda (free state_id)
119115
(mk_conj (const @{const_name Set.member} $ ppat $ (pset $ Bound 0)
120-
, mk_lift_expr ctx (foldr1 mk_conj ((map (parse_term ctx) g))) $ Bound 0))
121-
116+
, mk_lift_expr ctx (foldr1 mk_conj ((map (parse_term ctx) pre))) $ Bound 0))
117+
val poutput =
118+
lambda (free state_id)
119+
((mk_lift_expr ctx (parse_term ctx ot)) $ Bound 0)
122120
val body = (
123121
(Const (@{const_name "mk_zop"}, (parm --> st --> dummyT) --> dummyT)
124122
$ tupled_lambda ppat (SEXP $ ppre))
125123
$ tupled_lambda ppat (Type.constraint (st --> st) (parse_term ctx upd))
126-
$ tupled_lambda ppat (SEXP $ pguard)
124+
$ tupled_lambda ppat (SEXP $ poutput)
127125
)
128-
129-
in def_zop n set st body ctx
126+
in def_zop n set st body ctx
127+
|> gen (zop_pre n) (parm --> st --> dummyT) (tupled_lambda ppat (SEXP $ ppre))
130128
end |
131129
(*
132130
(* Generate the precondition *)
@@ -144,36 +142,56 @@ mk_zop (Operation {name = n, state = s, body = OperProm {promop = opr, plens = l
144142
let open Syntax; open Lift_Expr
145143
val opr' = read_term ctx opr;
146144
val pn = fst (dest_Const opr');
147-
val opr_type = const (pn ^ "_type");
145+
val opr_type = const (zop_type pn);
146+
val opr_pre = const (zop_pre pn);
148147
val lens' = parse_term ctx lens
149148
val st = read_typ ctx s
150149
val set = check_term ctx (const @{const_name "promoted_type"} $ lens' $ const @{const_name collection_lens} $ opr_type)
150+
val ppre = check_term ctx (const @{const_name "promote_pre"} $ lens' $ const @{const_name collection_lens} $ opr_pre)
151151
val body = const @{const_name "promote_operation"} $ lens' $ const @{const_name collection_lens} $ const pn
152152
in def_zop n set st body ctx
153+
|> gen (zop_pre n) (dummyT --> st --> dummyT) ppre
153154
end |
154-
mk_zop (Operation {name = n, state = s, body = OperComp {params = ps, body = bdy}}) ctx =
155+
mk_zop (Operation {name = n, state = s, body = OperComp {params = ps, pre = pre, body = bdy}}) ctx =
155156
let open Syntax; open Library; open Logic; open HOLogic; open Lift_Expr
156157
val pss = (map (fn (p, t) => (p, lift_expr ctx ((parse_term ctx t)))) ps)
157158
val pset = params_set (map snd pss)
158159
val set = SEXP $ pset
160+
val parm = dest_setT (range_type (Term.type_of (check_term ctx set)))
159161
val st = read_typ ctx s
160162
val ppat = mk_tuple (map (free o fst) pss)
163+
val ppre =
164+
lambda (free state_id)
165+
(mk_lift_expr ctx (foldr1 mk_conj ((map (parse_term ctx) pre))) $ Bound 0)
161166
val body = tupled_lambda ppat (Type.constraint (st --> dummyT) (parse_term ctx bdy))
162167
in def_zop n set st body ctx
168+
|> gen (zop_pre n) (parm --> st --> dummyT) (tupled_lambda ppat (SEXP $ ppre))
163169
end |
164170
mk_zop (Operation {name = n, state = s, body = OperEmit {emit = e}}) ctx =
165171
let open Syntax; open HOLogic; open Lift_Expr
166172
val set = mk_lift_expr ctx (mk_set dummyT [parse_term ctx e])
167173
val st = read_typ ctx s
174+
val parm = dest_setT (range_type (Term.type_of (check_term ctx set)))
168175
val body = const @{const_abbrev emit_op}
169-
in def_zop n set st body ctx
176+
in def_zop n set st body ctx
177+
(* Generate precondition *)
178+
|> gen (zop_pre n) (parm --> st --> dummyT) (Abs ("p", parm, SEXP $ lambda (free state_id) @{term True}))
170179
end;
171180

172181
fun get_zop_ptype n ctx =
173182
case Proof_Context.read_const {proper = false, strict = false} ctx n of
174183
Const (_, Type (@{type_name fun}, [a, _])) => a |
175184
_ => raise Match;
176-
185+
186+
fun get_zop_outtype n ctx =
187+
case Proof_Context.read_const {proper = false, strict = false} ctx n of
188+
Const (_, Type (@{type_name fun},
189+
[_, Type (@{type_name fun},
190+
[_, Type (@{type_name itree},
191+
[_, Type (@{type_name prod}, [a, _])])])])) => a |
192+
_ => raise Match;
193+
194+
177195
fun read_const_name ctx n =
178196
case Proof_Context.read_const {proper = false, strict = false} ctx n of
179197
Const (n', _) => n' |
@@ -184,7 +202,12 @@ fun zmachine_body_sem n st init inve ops ends ctx =
184202
let open Syntax; open HOLogic; open Proof_Context
185203
val oplist =
186204
mk_list dummyT
187-
(map (fn n => const @{const_name zop_event} $ read_const {proper = false, strict = false} ctx (firstLower n) $ const (read_const_name ctx (zop_type n)) $ const (read_const_name ctx n)) ops)
205+
(map (fn n => const @{const_name zop_event}
206+
$ read_const {proper = false, strict = false} ctx (firstLower n)
207+
$ const (read_const_name ctx (zop_type n))
208+
$ const (read_const_name ctx (zop_pre n))
209+
$ read_const {proper = false, strict = false} ctx (firstLower n ^ "_Out")
210+
$ const (read_const_name ctx n)) ops)
188211
in snd (Local_Theory.define
189212
((Binding.name n, NoSyn)
190213
, ((Binding.name (n ^ "_def")
@@ -196,7 +219,8 @@ fun chantype_name n = n ^ "_chan"
196219

197220
fun zmachine_sem (ZMachine {name = n, state = s, init = i, inv = inv, operations = ops, ends = e}) ctx =
198221
let open Syntax; open HOLogic; open Lift_Expr
199-
val cs = map (fn n => (firstLower n, YXML.content_of (string_of_typ ctx (get_zop_ptype n ctx)))) ops
222+
val cs = map (fn n => (firstLower n, YXML.content_of (string_of_typ ctx (get_zop_ptype n ctx)))) ops @
223+
map (fn n => (firstLower n ^ "_Out", YXML.content_of (string_of_typ ctx (get_zop_outtype n ctx)))) ops
200224
val st = read_typ ctx s
201225
val inve = mk_lift_expr ctx (parse_term ctx inv)
202226
val init = parse_term ctx i
@@ -216,14 +240,15 @@ val parse_operdefn =
216240
((Scan.optional (@{keyword "params"} |-- repeat1 parse_param) []) --
217241
(Scan.optional (@{keyword "pre"} |-- repeat1 term) ["True"]) --
218242
(Scan.optional (@{keyword "update"} |-- term) "[\<leadsto>]") --
219-
(Scan.optional (@{keyword "where"} |-- repeat1 term) ["True"])
220-
>> (fn (((ps, g), upd), post) => OperDefn {params = ps, pre = g, update = upd, guard = post}))
243+
(Scan.optional (@{keyword "output"} |-- term) "()")
244+
>> (fn (((ps, g), upd), ot) => OperDefn {params = ps, pre = g, update = upd, output = ot}))
221245
end
222246

223247
val parse_opercomp =
224248
let open Scan; open Parse in
225249
((@{keyword "params"} |-- repeat1 parse_param) --
226-
(@{keyword "is"} |-- term)) >> (fn (ps, bdy) => OperComp {params = ps, body = bdy})
250+
(Scan.optional (@{keyword "pre"} |-- repeat1 term) ["True"]) --
251+
(@{keyword "is"} |-- term)) >> (fn ((ps, pre), bdy) => OperComp {params = ps, pre = pre, body = bdy})
227252
end
228253

229254
val parse_operprom =

0 commit comments

Comments
 (0)