Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Globals (pre-cursor to Compilation Units) #30

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bedrock2/src/BasicC64Semantics.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ Instance parameters : parameters := {|
(* TODO: faster maps *)
mem := UnorderedList.map {| UnorderedList.key_eqb a b := if Word.weq a b then true else false |};
locals := UnorderedList.map {| UnorderedList.key_eqb := String.eqb |};
funname_eqb := String.eqb;
word_eqb := @Word.weqb 64
|}.
2 changes: 1 addition & 1 deletion bedrock2/src/BasicC64Syntax.v
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Definition to_c_parameters : ToCString.parameters := {|
| eq => e1++"=="++e2
end%string;
c_var := id;
c_fun := id;
c_glob := id;
c_act := ToCString.c_call;

varname_eqb := String.eqb;
Expand Down
104 changes: 104 additions & 0 deletions bedrock2/src/CompilationUnit.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
Require Import Coq.Strings.String.
Require Import Coq.ZArith.BinIntDef.
Require Import bedrock2.Macros bedrock2.Notations bedrock2.Map.
Require Import bedrock2.Syntax.
Require Import bedrock2.Semantics.

(* Compilation units should be fairly simple
* - the basic idea is that you have "externals", "internals", and "exports"
* - definitions can call externals and internals
* - exports must be a subset of external and internal
* - in the module-level semantics, one type of interaction needs to be
* external call.
* - note(gmm): we don't have to support recursive linking if we want to keep
* the terminating semantics.
*)

Module module.
Section with_parameters.
Context {p : Syntax.parameters}.

Variant data : Set :=
| Data (_ : list Z).

Variant definition : Type :=
| X (_ : list data)
| Function (_ : list varname * list varname * Syntax.cmd).


(* note(gmm): this could be made more uniform with the rest of the development
* if we used `map`.
*)
Record module : Type :=
{ imports : list globname
; internal : list globname
; exports : list globname
; definitions : list (globname * definition)
}.

End with_parameters.
End module.

(* the meaning of a module is a function of the meaning of the imports to the
* meaning of the outputs.
* note(gmm): an alternative way to represent this to treat calls to imports
* as actions.
*)

Require Import bedrock2.WeakestPrecondition.

Section module_semantics.
Variable p : Semantics.parameters.
Variable resolver : globname -> option word.

Definition func_meaning : Type :=
(trace -> Prop) ->
(trace -> Prop) ->
(trace -> trace -> Prop) ->
trace ->
mem ->
list word ->
(trace -> mem -> list word -> Prop) -> Prop.

Variables (mod : module.module)
(denoteImports : globname -> func_meaning).

Definition functions : list _ :=
(fix functions ls :=
match ls with
| nil => nil
| cons (a, module.Function b) ls =>
match resolver a with
| Some a => cons (a,b) (functions ls)
| None => functions ls
end
| cons _ ls => functions ls
end) mod.(module.definitions).

Definition module_definitions (g : globname)
: func_meaning.
refine (fun rely guarantee progress t mem args post =>
exists body, List.In (g, body) mod.(module.definitions) /\
match body with
| module.Function body =>
exists n,
WeakestPrecondition.func rely guarantee progress resolver
(fun w t mem args post =>
exists g, resolver g = Some w /\
(List.In g mod.(module.imports) /\
denoteImports g rely guarantee progress t mem args post)
\/ call_rec rely guarantee progress resolver
functions n w t mem args post)
body
t mem args post
| _ => False
end).
Defined.

Definition module (g : globname)
: func_meaning :=
fun rely guarantee progress t mem args post =>
List.In g mod.(module.exports) /\
module_definitions g rely guarantee progress t mem args post.

End module_semantics.
60 changes: 44 additions & 16 deletions bedrock2/src/Examples/Swap.v
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,44 @@ end.

Context (__A : map.ok Semantics.mem).
Lemma swap_ok :
forall a_addr a b_addr b (m:map.rep (value:=@Semantics.byte _)) R t,
forall l a_addr a b_addr b (m:map.rep (value:=@Semantics.byte _)) R t,
(sep (ptsto 1 a_addr a) (sep (ptsto 1 b_addr b) R)) m ->
WeakestPrecondition.func
(fun _ => True) (fun _ => False) (fun _ _ => True) (fun _ _ _ _ _ => False)
(fun _ => True) (fun _ => False) (fun _ _ => True) l (fun _ _ _ _ _ => False)
(@swap BasicC64Syntax.params) t m (a_addr::b_addr::nil)
(fun t' m' rets => t=t' /\ (sep (ptsto 1 a_addr b) (sep (ptsto 1 b_addr a) R)) m' /\ rets = nil).
Proof.
intros. rename H into Hm.
repeat t.
Qed.

Lemma skipn_here : forall {T} (l : list T), List.skipn 0 l = l.
Proof. reflexivity. Qed.
Lemma skipn_next : forall {T} n l (ls ls' : list T), List.skipn n ls = ls' -> List.skipn (S n) (l :: ls) = ls'.
Proof. intros. subst. reflexivity. Qed.

Ltac find_in_list :=
repeat first [ apply skipn_here
| apply skipn_next ].

Lemma wp_call_resolve : forall r g p l funcs addr t m args post i body rest,
List.skipn i funcs = (addr, body) :: rest ->
WeakestPrecondition.func r g p l (WeakestPrecondition.call r g p l rest) body t m args post ->
WeakestPrecondition.call r g p l funcs addr t m args post.
Proof.
Admitted.


Lemma swap_swap_ok :
forall a_addr a b_addr b (m:map.rep (value:=@Semantics.byte _)) R t,
forall l swap_addr a_addr a b_addr b (m:map.rep (value:=@Semantics.byte _)) R t,
l "swap" = Some swap_addr ->
(sep (ptsto 1 a_addr a) (sep (ptsto 1 b_addr b) R)) m ->
WeakestPrecondition.func
(fun _ => True) (fun _ => False) (fun _ _ => True) (WeakestPrecondition.call (fun _ => True) (fun _ => False) (fun _ _ => True) [("swap", (@swap BasicC64Syntax.params))])
(fun _ => True) (fun _ => False) (fun _ _ => True) l (WeakestPrecondition.call (fun _ => True) (fun _ => False) (fun _ _ => True) l [(swap_addr, (@swap BasicC64Syntax.params))])
(@swap_swap BasicC64Syntax.params) t m (a_addr::b_addr::nil)
(fun t' m' rets => t=t' /\ (sep (ptsto 1 a_addr a) (sep (ptsto 1 b_addr b) R)) m' /\ rets = nil).
Proof.
intros. rename H into Hm.
intros. rename H0 into Hm.
eexists.
eexists.
eexists.
Expand All @@ -121,11 +139,17 @@ Proof.
eexists.
eexists.
eexists.
intros. eapply WeakestPreconditionProperties.Proper_func.
6: eapply swap_ok.
1,2,3,4,5 : cbv [Morphisms.pointwise_relation trace Basics.flip Basics.impl Morphisms.respectful]; try solve [typeclasses eauto with core].
1,2: cycle 1.
refine ((?[sep]:@Lift1Prop.impl1 mem _ _) m Hm). reflexivity. (* TODO: ecancel *)
eexists.
eexists. eassumption.
intros.
eapply wp_call_resolve.
find_in_list.
eapply WeakestPreconditionProperties.Proper_func.
7: eapply swap_ok.
all: try reflexivity.
cbv [Morphisms.pointwise_relation trace Basics.flip Basics.impl Morphisms.respectful]; try solve [typeclasses eauto with core].
tauto.
2: refine ((?[sep]:@Lift1Prop.impl1 mem _ _) m Hm); reflexivity. (* TODO: ecancel *)
intros ? m' ? (?&Hm'&?).
clear Hm.
clear m.
Expand All @@ -142,11 +166,16 @@ Proof.
eexists.
eexists.
eexists.
intros. eapply WeakestPreconditionProperties.Proper_func.
6: eapply swap_ok.
1,2,3,4,5 : cbv [Morphisms.pointwise_relation trace Basics.flip Basics.impl Morphisms.respectful]; try solve [typeclasses eauto with core].
1,2: cycle 1.
refine ((?[sep]:@Lift1Prop.impl1 mem _ _) m Hm). reflexivity. (* TODO: ecancel *)
eexists.
eexists; [ eassumption | ].
eapply wp_call_resolve.
find_in_list.
eapply WeakestPreconditionProperties.Proper_func.
7: eapply swap_ok.
all: try reflexivity.
cbv [Morphisms.pointwise_relation trace Basics.flip Basics.impl Morphisms.respectful]; try solve [typeclasses eauto with core]; tauto.
2: refine ((?[sep]:@Lift1Prop.impl1 mem _ _) m Hm); reflexivity. (* TODO: ecancel *)
cbv [Morphisms.pointwise_relation trace Basics.flip Basics.impl Morphisms.respectful]; try solve [typeclasses eauto with core].
intros ? m' ? (?&Hm'&?).
clear Hm.
clear m.
Expand All @@ -163,4 +192,3 @@ Proof.
eassumption.
eexists.
Qed.

7 changes: 3 additions & 4 deletions bedrock2/src/Semantics.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Class parameters := {
word_succ : word -> word;
word_test : word -> bool;
word_of_Z : BinNums.Z -> option word;
word_eqb : word -> word -> bool;
interp_binop : bopname -> word -> word -> word;

byte : Type;
Expand All @@ -17,14 +18,12 @@ Class parameters := {
split : nat -> word -> byte * word;

mem :> map word byte;
locals :> map varname word;

funname_eqb : funname -> funname -> bool
locals :> map varname word
}.

Section semantics.
Context {pp : unique! parameters}.

Fixpoint load_rec (sz : nat) (m:mem) (a:word) : option word :=
match sz with
| O => Some word_zero
Expand Down
2 changes: 1 addition & 1 deletion bedrock2/src/StringNamesSyntax.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Class parameters := {

Instance make (p : parameters) : Syntax.parameters := {|
Syntax.varname := string;
Syntax.funname := string;
Syntax.globname := string;

Syntax.actname := actname;
Syntax.bopname := bopname;
Expand Down
7 changes: 4 additions & 3 deletions bedrock2/src/Syntax.v
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Require Import bedrock2.Macros.

Require Import Coq.Numbers.BinNums.

Class parameters := {
varname : Set;
funname : Set;
globname : Set;
actname : Set;
bopname : Set;
}.
Expand All @@ -15,6 +15,7 @@ Module expr. Section expr.
Inductive expr : Type :=
| literal (v: Z)
| var (x: varname)
| global (_ : globname)
| load (access_size_in_bytes:Z) (addr:expr)
| op (op: bopname) (e1 e2: expr).
End expr. End expr. Notation expr := expr.expr.
Expand All @@ -28,6 +29,6 @@ Module cmd. Section cmd.
| cond (condition : expr) (nonzero_branch zero_branch : cmd)
| seq (s1 s2: cmd)
| while (test : expr) (body : cmd)
| call (binds : list varname) (function : funname) (args: list expr)
| call (binds : list varname) (function : globname) (args: list expr)
| interact (binds : list varname) (action : actname) (args: list expr).
End cmd. End cmd. Notation cmd := cmd.cmd.
9 changes: 5 additions & 4 deletions bedrock2/src/ToCString.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Class parameters := {
c_lit : Z -> String.string;
c_bop : string -> bopname -> string -> string;
c_var : varname -> String.string;
c_fun : funname -> String.string;
c_glob : globname -> String.string;
c_act : list varname -> actname -> list String.string -> string;
}.

Expand All @@ -33,6 +33,7 @@ Section ToCString.
match e with
| expr.literal v => c_lit v
| expr.var x => c_var x
| expr.global x => c_glob x
| expr.load s ea => "*(" ++ c_size s ++ "*)(" ++ c_expr ea ++ ")"
| expr.op op e1 e2 => c_bop ("(" ++ c_expr e1 ++ ")") op ("(" ++ c_expr e2 ++ ")")
end.
Expand Down Expand Up @@ -79,13 +80,13 @@ Section ToCString.
| cmd.skip =>
indent ++ "/*skip*/" ++ LF
| cmd.call args f es =>
indent ++ c_call (List.map c_var args) (c_fun f) (List.map c_expr es)
indent ++ c_call (List.map c_var args) (c_glob f) (List.map c_expr es)
| cmd.interact binds action es =>
indent ++ c_act binds action (List.map c_expr es)
end%string.

Definition c_decl (rett : string) (args : list varname) (name : funname) (retptrs : list varname) : string :=
(rett ++ " " ++ c_fun name ++ "(" ++ concat ", " (
Definition c_decl (rett : string) (args : list varname) (name : globname) (retptrs : list varname) : string :=
(rett ++ " " ++ c_glob name ++ "(" ++ concat ", " (
List.map (fun a => "uintptr_t "++c_var a) args ++
List.map (fun r => "uintptr_t* "++c_var r) retptrs) ++
")")%string.
Expand Down
3 changes: 2 additions & 1 deletion bedrock2/src/Variables.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Module expr. Section expr. Import Syntax.expr.
Context {p : unique! Syntax.parameters}.
Fixpoint vars (e : expr) : list varname :=
match e with
| literal v => nil
| literal _ => nil
| var x => cons x nil
| global _ => nil
| load _ ea => vars ea
| op _ e1 e2 => List.app (vars e1) (vars e2)
end.
Expand Down
Loading