cpsa-4.4.3: coq/CRun.v
(* Concrete Algebra Procedure Execution as a Function
Copyright (c) 2021 The MITRE Corporation
This program is free software: you can redistribute it and/or
modify it under the terms of the BSD License as published by the
University of California. *)
(** * Procedure Execution
This library contains a straightforward definition of the
semantics of procedure execution. The semantics is specified
using a function. The semantics of statement execution is defined
using a partial function that takes a runtime state and a list of
statements and returns the final runtime environment and a list of
terms that make up the procedure's outputs. A runtime environment
is a map from program variables to terms. A runtime state contains
- the current runtime environment,
- the current trace, and
- a list of the uniques that occur at the transmissions in the
current trace. *)
Require Import FunInd Nat Bool Preamble Monad Proc Alg CSem.
Import List.ListNotations.
Open Scope list_scope.
(** printing <- #←# *)
(** A runtime state *)
Record crun_state: Set :=
mkCRSt {
crenv: cenv;
crtr: list cevt;
cruniqs: list calg;
crs: list nat }.
(** The semantics of expressions *)
Definition crun_expr (rst: crun_state) (ex: expr):
option (crun_state * calg) :=
match ex with
| Quot_ s => Some (rst, CTg s)
| Hash_ v =>
x <- lookup v (crenv rst);;
Some (rst, CHs x)
| Pair_ u v =>
x <- lookup u (crenv rst);;
y <- lookup v (crenv rst);;
Some (rst, CPr x y)
| Encr_ u v =>
x <- lookup u (crenv rst);;
y <- lookup v (crenv rst);;
match crs rst with
| [] => Some (rst, CEn 0 x y)
| r :: rs =>
Some (mkCRSt (crenv rst)
(crtr rst)
(cruniqs rst)
rs,
CEn r x y)
end
| Frst_ v =>
x <- lookup v (crenv rst);;
match x with
| CPr y z => Some (rst, y)
| _ => None
end
| Scnd_ v =>
x <- lookup v (crenv rst);;
match x with
| CPr y z => Some (rst, z)
| _ => None
end
| Decr_ u v =>
x <- lookup u (crenv rst);;
match x with
| CEn _ y z =>
k <- lookup v (crenv rst);;
if negb (chas_enc k) && calg_eqb k (cinv z) then
Some (rst, y)
else
None
| _ => None
end
| Recv_ v =>
c <- lookup v (crenv rst);;
match crtr rst with
| CRv d x :: tr =>
match c with
| CCh n =>
if n =? d then
Some (mkCRSt (crenv rst) tr (cruniqs rst) (crs rst), x)
else
None
| _ => None
end
| _ => None
end
| Frsh_ =>
match cruniqs rst with
| u :: us =>
Some (mkCRSt (crenv rst) (crtr rst) us (crs rst), u)
| _ => None
end
end.
Lemma crun_expr_env_extends:
forall rst ex rst' val,
crun_expr rst ex = Some (rst', val) ->
crenv rst' = crenv rst.
Proof.
intros.
destruct ex; simpl in H; inv H; auto.
- apply do_some in H1.
destruct H1.
destruct H.
inv H0; auto.
- apply do_some in H1.
destruct H1.
destruct H.
apply do_some in H0.
destruct H0.
destruct H0.
inv H1; auto.
- destruct (lookup n (crenv rst)).
+ destruct (lookup n0 (crenv rst)).
* destruct (crs rst); inv H1; auto.
* inv H1.
+ inv H1.
- destruct (lookup n (crenv rst)).
+ destruct c; inv H1; auto.
+ inv H1.
- destruct (lookup n (crenv rst)).
+ destruct c; inv H1; auto.
+ inv H1.
- destruct (lookup n (crenv rst)).
+ destruct c; inv H1; auto.
destruct (lookup n0 (crenv rst)); inv H0; auto.
destruct (negb (chas_enc c) && calg_eqb c (cinv c2)); inv H1; auto.
+ inv H1.
- destruct (cruniqs rst); inv H1; auto.
- destruct (lookup n (crenv rst)); inv H1; auto.
destruct (crtr rst); inv H0; auto.
destruct c0; inv H1; auto.
destruct c; inv H0; auto.
destruct (n1 =? n0); inv H1; auto.
Qed.
(** Check that the type of [x] is compatible with [t]. *)
Definition ctype_check (x: calg) (t: type): bool :=
type_eqb t Mesg || type_eqb (ctype_of x) t.
(** The semantics of statements *)
Definition crun_stmt (rst: crun_state) (cmd: stmt): option crun_state :=
match cmd with
| Bind (v, t) exp =>
sx <- crun_expr rst exp;;
let (rst, x) := sx in
if ctype_check x t then
Some (mkCRSt
((v, x) :: crenv rst)
(crtr rst)
(cruniqs rst)
(crs rst))
else
None
| Send u v =>
match crtr rst with
| CSd d x :: tr =>
c <- lookup u (crenv rst);;
match c with
| CCh n =>
if n =? d then
y <- lookup v (crenv rst);;
if calg_eqb x y then
Some (mkCRSt (crenv rst) tr (cruniqs rst) (crs rst))
else
None
else
None
| _ => None
end
| _ => None
end
| Same u v =>
x <- lookup u (crenv rst);;
y <- lookup v (crenv rst);;
if negb (chas_enc x) && calg_eqb x y then
Some rst
else
None
| Invp u v =>
x <- lookup u (crenv rst);;
y <- lookup v (crenv rst);;
if negb (chas_enc x) && calg_eqb x (cinv y) then
Some rst
else
None
| Return _ => None
end.
Lemma crun_stmt_env_extends:
forall rst stmt rst',
crun_stmt rst stmt = Some rst' ->
exists ev, crenv rst' = ev ++ crenv rst.
Proof.
intros.
destruct stmt; simpl in H.
- inv H.
- destruct d.
alt_option_dec (crun_expr rst e) p G; rewrite G in H.
+ inv H.
+ expand_let_pairs.
destruct p.
apply crun_expr_env_extends in G.
simpl in H.
destruct (ctype_check c0 t); inv H; auto.
exists [(n, c0)]; simpl.
rewrite G.
auto.
- exists []; simpl.
destruct (crtr rst).
inv H.
destruct c.
+ destruct (lookup n (crenv rst)).
* destruct c0; try inv H.
destruct (n2 =? n1).
-- destruct (lookup n0 (crenv rst)).
++ destruct (calg_eqb c c0); inv H1; simpl; auto.
++ inv H1.
-- inv H1.
* inv H.
+ inv H.
- exists []; simpl.
destruct (lookup n (crenv rst)).
+ destruct (lookup n0 (crenv rst)).
* destruct (negb (chas_enc c) && calg_eqb c c0); inv H; simpl; auto.
* inv H.
+ inv H.
- exists []; simpl.
destruct (lookup n (crenv rst)); inv H; auto.
destruct (lookup n0 (crenv rst)); inv H1; auto.
destruct (negb (chas_enc c) && calg_eqb c (cinv c0)); inv H0; auto.
Qed.
(** The semantics of lists of statements *)
Fixpoint crun_stmts (rst: crun_state) (stmts: list stmt):
option (cenv * list calg) :=
match stmts with
| [] => None
| [Return vs] =>
match crtr rst, cruniqs rst with
| [], [] =>
xs <- map_m (fun x => lookup x (crenv rst)) vs;;
Some (crenv rst, xs)
| _, _ => None
end
| cmd :: stmts =>
rst <- crun_stmt rst cmd;;
crun_stmts rst stmts
end.
Lemma crun_stmts_env_extends:
forall rst stmts ev outs,
crun_stmts rst stmts = Some (ev, outs) ->
exists ev', ev = ev' ++ crenv rst.
Proof.
intros rst stmts.
revert rst.
induction stmts; intros.
- simpl in H.
inv H.
- destruct a; unfold crun_stmts in H; fold crun_stmts in H.
+ exists []; simpl.
destruct stmts; inv H; auto.
destruct (crtr rst); inv H1; auto.
destruct (cruniqs rst); inv H0; auto.
destruct (map_m (fun x : nat => lookup x (crenv rst)) l); inv H1; auto.
+ apply do_some in H.
repeat destruct_ex_and.
apply crun_stmt_env_extends in H.
apply IHstmts in H0.
repeat destruct_ex_and; subst.
rewrite H.
exists (x0 ++ x1).
rewrite app_assoc; auto.
+ apply do_some in H.
repeat destruct_ex_and.
apply crun_stmt_env_extends in H.
apply IHstmts in H0.
repeat destruct_ex_and; subst.
rewrite H.
exists (x0 ++ x1).
rewrite app_assoc; auto.
+ apply do_some in H.
repeat destruct_ex_and.
apply crun_stmt_env_extends in H.
apply IHstmts in H0.
repeat destruct_ex_and; subst.
rewrite H.
exists (x0 ++ x1).
rewrite app_assoc; auto.
+ apply do_some in H.
repeat destruct_ex_and.
apply crun_stmt_env_extends in H.
apply IHstmts in H0.
repeat destruct_ex_and; subst.
rewrite H.
exists (x0 ++ x1).
rewrite app_assoc; auto.
Qed.
(** Bind inputs with procedure parameters. *)
Fixpoint cbind_inputs (ds: list decl) (xs: list calg) (renv: cenv):
option cenv :=
match ds, xs with
| [], [] => Some renv
| (v, t) :: ds, x :: xs =>
if ctype_check x t then
cbind_inputs ds xs ((v, x) :: renv)
else
None
| _, _ => None
end.
(** The semantics of a procedure *)
Definition crun (p: proc) (inputs: list calg) (tr: list cevt)
(us: list calg) (rs: list nat):
option (cenv * list calg) :=
renv <- cbind_inputs (ins p) inputs [];;
crun_stmts (mkCRSt (rev renv) tr us rs) (body p).