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

Adding states to exec monad natively #1

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

Conversation

Nils-Lauermann
Copy link
Contributor

No description provided.

Copy link
Collaborator

@tperami tperami left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good! If the whole Common lib doesn't build with that change, fix it, otherwise wait until tomorrow before fixing the rest of the codebase

Common/Exec.v Outdated
Proof. unfold_decide. Qed.

(** Create an execution from a set of results, e.g. to convert from pure
non-determinism to Exec *)
Definition Results {E A C} `{Elements A C} (s : C) : t E A := make (elements s) [].
Definition Results {E A C} `{Elements A C} (s : C) : res () E A := make (map ((),.) (elements s)) [].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at how this is used (in 2 places), this might be better if this was of type Exec.t St E A and forwarded the state into each result

Common/Exec.v Outdated
make (e1.(results) ++ e2.(results)) (e1.(errors) ++ e2.(errors)).
#[global] Typeclasses Opaque merge.
Arguments merge : simpl never.

(** Convert an execution into a list of results *)
Definition to_result_list `(e : t E A) : list (result E A) :=
Definition to_result_list `(e : res St E A) : list (result (St * E) (St * A)) :=
map Ok e.(results) ++ map Error e.(errors).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will generate a list (result (St * E) (St * A)), I think it would be better if it was list (St * result E A)

Common/Exec.v Outdated
#[global] Instance choose_inst {E} : MChoose (t E) :=
λ '(ChooseFin n), make (enum (fin n)) [].
#[global] Instance choose_inst {St E} : MChoose (t St E) :=
λ '(ChooseFin n) st, make (map (st,.) (enum (fin n))) [].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that this is a bit more complicated, maybe the implementation should just be Results (enum (fin n)). This would avoid duplicating the logic

UnfoldElemOf x ((f <$> e) st) (∃ st' y, P (st', y) ∧ x = (st', f y)).
Proof. tcclean. unfold elem_of, elem_of_results, fmap, fmap_inst.
destruct (e st) as [l es]. cbn. set_unfold.
cdestruct |- *** #CDestrSplitGoal; repeat eexists; eauto; naive_solver.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repeat eexists before eauto should not be necessary. Also having eauto in non-terminating position is not great. Doesn't naive_solver work alone? (It does on my machine)

Copy link
Collaborator

@tperami tperami left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except we need to think together how to update the promising part

map (λ '(st,r), (st, Ok r)) e.(results) ++ map (λ '(st,err), (st, Error err)) e.(errors).

Definition t {St E A} := St → res St E A.
Arguments t : clear implicits.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the { and the Arguments here


(** Create an execution from a set of results, e.g. to convert from pure
non-determinism to Exec *)
Definition Results {St E A C} `{Elements A C} (s : C) : t St E A := λ st, make (map (st,.) (elements s)) [].
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Column 80

#[global] Instance mbind_inst {E} : MBind (t E) :=
λ _ _ f e, foldr merge (make [] e.(errors)) (map f e.(results)).
#[global] Instance mbind_inst {St E} : MBind (t St E) :=
λ _ _ f e st, let est := e st in foldr merge (make [] est.(errors)) (map (λ '(st', r), f r st') est.(results)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Column 80

#[global] Instance throw_inst {St E} : MThrow E (t St E) := λ _ e st, make [] [(st,e)].

#[global] Instance choose_inst {St E} : MChoose (t St E) :=
λ '(ChooseFin n), @Results _ _ (Fin.t n) _ _ (enum (fin n)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use fin and not Fin.t everywhere for consistency

| MGet => λ s, (mret s : t St E St) s
end.

Lemma mdiscard_eq {St E A} : mdiscard =@{t St E A} (λ st, make [] []).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ordering remark: This should be kept close to choose_inst, because it's derived from it directly

Comment on lines +109 to +112
match eff with
| MSet s => λ _, (mret () : t St E ()) s
| MGet => λ s, (mret s : t St E St) s
end.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation should be 2 spaces here. Also, it might be nicer to have the inlined version here as this is a primitive effect of the monad e.g. λ _, make [(s, ())] [] instead of λ _, mret () s).

@@ -281,9 +281,9 @@ Module TermModels (IWA : InterfaceWithArch). (* to be imported *)
End MR.
Arguments t : clear implicits.

Definition from_exec {n} (e : Exec.t string (MState.final n)) :
Definition from_exec {St n} (e : Exec.t St string (MState.final n)) (st : St) :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the original didn't have a stateT than this should take an Exec.res rather than do the application itself

@@ -170,17 +170,17 @@ Module Gen (IWA : InterfaceWithArch) (TM : TermModelsT IWA).
set.*)
promise_select :
(* fuel *) nat -> (* tid *) nat → memoryMap → pModel.(tState) →
PromMemory.t pModel.(mEvent) → Exec.t string pModel.(mEvent);
PromMemory.t pModel.(mEvent) → Exec.t (pModel.(tState) * PromMemory.t pModel.(mEvent) * pModel.(iis)) string pModel.(mEvent);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again if there was not StateT it should become a Exec.res

Comment on lines 243 to 249
init |>
(ist ←@{(Exec.t (tState * PromMemory.t mEvent * iis prom) string)} cinterp handler sem;
λ '(ts, mem, iis),
st |> setv (tstate tid) ts
|> setv (istate tid) ist
|> setv events mem
|> λ st', (mret st' : Exec.t (tState * PromMemory.t mEvent * Gen.iis prom) string t) (ts, mem, iis)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original was horrible to read, but now it's even worse, we need to have a function to lift an Exec monad into another exec monad with a different state. I'll add the required boilerplate to the Setter set-up for that, and then we'll need to add a step function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants