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

Denotation of open cfgs in presence of function calls #166

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions _CoqConfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ theories/Basics/CategoryTheory.v
theories/Basics/CategoryFacts.v
theories/Basics/CategorySub.v
theories/Basics/CategoryFunctor.v
theories/Basics/Applicative.v
theories/Basics/Functor.v
theories/Basics/Monad.v
theories/Basics/MonadId.v
theories/Basics/MonadState.v
theories/Basics/MonadEither.v
theories/Basics/MonadWriter.v
theories/Basics/CategoryKleisli.v
theories/Basics/CategoryKleisliFacts.v
theories/Basics/Function.v
Expand Down
9 changes: 9 additions & 0 deletions theories/Basics/Applicative.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Class Applicative@{d c} (T : Type@{d} -> Type@{c}) :=
{ pure : forall {A : Type@{d}}, A -> T A
; ap : forall {A B : Type@{d}}, T (A -> B) -> T A -> T B
}.

Module ApplicativeNotation.
Notation "f <*> x" := (ap f x) (at level 52, left associativity).
End ApplicativeNotation.

225 changes: 115 additions & 110 deletions theories/Basics/Basics.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@ From Coq Require
From Coq Require Import
RelationClasses.

From ExtLib Require Import
Structures.Functor
Structures.Monad
Data.Monads.StateMonad
Data.Monads.ReaderMonad
Data.Monads.OptionMonad
Data.Monads.EitherMonad.

Import MonadNotation.
Local Open Scope monad.
(* end hide *)

(** ** Parametric functions *)
Expand Down Expand Up @@ -103,48 +93,63 @@ Section ProdRelInstances.

End ProdRelInstances.


(** ** Common monads and transformers. *)

Module Monads.

Definition identity (a : Type) : Type := a.

Definition stateT (s : Type) (m : Type -> Type) (a : Type) : Type :=
s -> m (prod s a).
Definition state (s a : Type) := s -> prod s a.

Definition readerT (r : Type) (m : Type -> Type) (a : Type) : Type :=
r -> m a.
Definition reader (r a : Type) := r -> a.

Definition writerT (w : Type) (m : Type -> Type) (a : Type) : Type :=
m (prod w a).
Definition writer := prod.

Instance Functor_stateT {m s} {Fm : Functor m} : Functor (stateT s m)
:= {|
fmap _ _ f := fun run s => fmap (fun sa => (fst sa, f (snd sa))) (run s)
|}.

Instance Monad_stateT {m s} {Fm : Monad m} : Monad (stateT s m)
:= {|
ret _ a := fun s => ret (s, a)
; bind _ _ t k := fun s =>
sa <- t s ;;
k (snd sa) (fst sa)
|}.

End Monads.

(** ** Loop operator *)

(** [iter]: A primitive for general recursion.
Iterate a function updating an accumulator [I], until it produces
an output [R].
*)
Polymorphic Class MonadIter (M : Type -> Type) : Type :=
iter : forall {R I: Type}, (I -> M (I + R)%type) -> I -> M R.
(* Module Monads. *)

(* Definition identity (a : Type) : Type := a. *)

(* Definition eitherT (exc : Type) (m: Type -> Type) (a: Type) : Type := *)
(* m (sum exc a). *)
(* Definition either (exc : Type) (a : Type) : Type := *)
(* sum exc a. *)

(* Definition stateT (s : Type) (m : Type -> Type) (a : Type) : Type := *)
(* s -> m (prod s a). *)
(* Definition state (s a : Type) := s -> prod s a. *)

(* Definition readerT (r : Type) (m : Type -> Type) (a : Type) : Type := *)
(* r -> m a. *)
(* Definition reader (r a : Type) := r -> a. *)

(* Definition writerT (w : Type) (m : Type -> Type) (a : Type) : Type := *)
(* m (prod w a). *)
(* Definition writer := prod. *)

(* Instance Functor_stateT {m s} {Fm : Functor m} : Functor (stateT s m) *)
(* := {| *)
(* fmap _ _ f := fun run s => fmap (fun sa => (fst sa, f (snd sa))) (run s) *)
(* |}. *)

(* Instance Monad_stateT {m s} {Fm : Monad m} : Monad (stateT s m) *)
(* := {| *)
(* ret _ a := fun s => ret (s, a) *)
(* ; bind _ _ t k := fun s => *)
(* sa <- t s ;; *)
(* k (snd sa) (fst sa) *)
(* |}. *)

(* Instance Functor_eitherT {m exc} {Fm : Functor m} : Functor (eitherT exc m) *)
(* := {| *)
(* fmap _ _ f := fmap (fun ma => match ma with *)
(* | inl e => inl e *)
(* | inr a => inr (f a) *)
(* end) *)
(* |}. *)

(* Program Instance Monad_eitherT {m exc} {Fm : Monad m} : Monad (eitherT exc m) *)
(* := {| *)
(* ret _ a := ret (inr a) *)
(* ; bind _ _ t k := *)
(* bind (m := m) t *)
(* (fun ma => *)
(* match ma with *)
(* | inl e => ret (inl e) *)
(* | inr a => k a *)
(* end) *)
(* |}. *)

(* End Monads. *)

(** *** Transformer instances *)

Expand All @@ -153,66 +158,66 @@ Polymorphic Class MonadIter (M : Type -> Type) : Type :=
Quite easily in fact, no [Monad] assumption needed.
*)

Instance MonadIter_stateT {M S} {MM : Monad M} {AM : MonadIter M}
: MonadIter (stateT S M) :=
fun _ _ step i => mkStateT (fun s =>
iter (fun is =>
let i := fst is in
let s := snd is in
is' <- runStateT (step i) s ;;
ret match fst is' with
| inl i' => inl (i', snd is')
| inr r => inr (r, snd is')
end) (i, s)).

Polymorphic Instance MonadIter_stateT0 {M S} {MM : Monad M} {AM : MonadIter M}
: MonadIter (Monads.stateT S M) :=
fun _ _ step i s =>
iter (fun si =>
let s := fst si in
let i := snd si in
si' <- step i s;;
ret match snd si' with
| inl i' => inl (fst si', i')
| inr r => inr (fst si', r)
end) (s, i).

Instance MonadIter_readerT {M S} {AM : MonadIter M} : MonadIter (readerT S M) :=
fun _ _ step i => mkReaderT (fun s =>
iter (fun i => runReaderT (step i) s) i).

Instance MonadIter_optionT {M} {MM : Monad M} {AM : MonadIter M}
: MonadIter (optionT M) :=
fun _ _ step i => mkOptionT (
iter (fun i =>
oi <- unOptionT (step i) ;;
ret match oi with
| None => inr None
| Some (inl i) => inl i
| Some (inr r) => inr (Some r)
end) i).

Instance MonadIter_eitherT {M E} {MM : Monad M} {AM : MonadIter M}
: MonadIter (eitherT E M) :=
fun _ _ step i => mkEitherT (
iter (fun i =>
ei <- unEitherT (step i) ;;
ret match ei with
| inl e => inr (inl e)
| inr (inl i) => inl i
| inr (inr r) => inr (inr r)
end) i).
(* Instance MonadIter_stateT {M S} {MM : Monad M} {AM : MonadIter M} *)
(* : MonadIter (stateT S M) := *)
(* fun _ _ step i => mkStateT (fun s => *)
(* iter (fun is => *)
(* let i := fst is in *)
(* let s := snd is in *)
(* is' <- runStateT (step i) s ;; *)
(* ret match fst is' with *)
(* | inl i' => inl (i', snd is') *)
(* | inr r => inr (r, snd is') *)
(* end) (i, s)). *)

(* Polymorphic Instance MonadIter_stateT0 {M S} {MM : Monad M} {AM : MonadIter M} *)
(* : MonadIter (Monads.stateT S M) := *)
(* fun _ _ step i s => *)
(* iter (fun si => *)
(* let s := fst si in *)
(* let i := snd si in *)
(* si' <- step i s;; *)
(* ret match snd si' with *)
(* | inl i' => inl (fst si', i') *)
(* | inr r => inr (fst si', r) *)
(* end) (s, i). *)

(* Instance MonadIter_readerT {M S} {AM : MonadIter M} : MonadIter (readerT S M) := *)
(* fun _ _ step i => mkReaderT (fun s => *)
(* iter (fun i => runReaderT (step i) s) i). *)

(* Instance MonadIter_optionT {M} {MM : Monad M} {AM : MonadIter M} *)
(* : MonadIter (optionT M) := *)
(* fun _ _ step i => mkOptionT ( *)
(* iter (fun i => *)
(* oi <- unOptionT (step i) ;; *)
(* ret match oi with *)
(* | None => inr None *)
(* | Some (inl i) => inl i *)
(* | Some (inr r) => inr (Some r) *)
(* end) i). *)

(* Instance MonadIter_eitherT {M E} {MM : Monad M} {AM : MonadIter M} *)
(* : MonadIter (eitherT E M) := *)
(* fun _ _ step i => mkEitherT ( *)
(* iter (fun i => *)
(* ei <- unEitherT (step i) ;; *)
(* ret match ei with *)
(* | inl e => inr (inl e) *)
(* | inr (inl i) => inl i *)
(* | inr (inr r) => inr (inr r) *)
(* end) i). *)

(** And the nondeterminism monad [_ -> Prop] also has one. *)

Inductive iter_Prop {R I : Type} (step : I -> I + R -> Prop) (i : I) (r : R)
: Prop :=
| iter_done
: step i (inr r) -> iter_Prop step i r
| iter_step i'
: step i (inl i') ->
iter_Prop step i' r ->
iter_Prop step i r
.

Polymorphic Instance MonadIter_Prop : MonadIter Ensembles.Ensemble := @iter_Prop.
(* Inductive iter_Prop {R I : Type} (step : I -> I + R -> Prop) (i : I) (r : R) *)
(* : Prop := *)
(* | iter_done *)
(* : step i (inr r) -> iter_Prop step i r *)
(* | iter_step i' *)
(* : step i (inl i') -> *)
(* iter_Prop step i' r -> *)
(* iter_Prop step i r *)
(* . *)

(* Polymorphic Instance MonadIter_Prop : MonadIter Ensembles.Ensemble := @iter_Prop. *)
16 changes: 11 additions & 5 deletions theories/Basics/CategoryKleisli.v
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
From Coq Require Import
Morphisms.

From ExtLib Require Import
Structures.Monad.

From ITree Require Import
Basics.Basics
Basics.CategoryOps
Expand Down Expand Up @@ -56,7 +53,7 @@ Section Instances.

Definition map {a b c} (g:b -> c) (ab : Kleisli m a b) : Kleisli m a c :=
cat ab (pure g).

Global Instance Initial_Kleisli : Initial (Kleisli m) void :=
fun _ v => match v : void with end.

Expand All @@ -73,6 +70,15 @@ Section Instances.
fun _ _ => pure inr.

Global Instance Iter_Kleisli `{MonadIter m} : Iter (Kleisli m) sum :=
fun a b => Basics.iter.
fun a b => iter.

End Instances.

(* Convenient equation to switch perspective between the monadic and categorical view. *)
Lemma iter_monad_to_cat:
forall {M} {IM: MonadIter M} a b,
@Monad.iter M IM a b = @CategoryOps.iter Type (Kleisli M) sum _ b a.
Proof.
reflexivity.
Qed.

3 changes: 0 additions & 3 deletions theories/Basics/CategoryKleisliFacts.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ From Coq Require Import
Morphisms
RelationClasses.

From ExtLib Require Import
Structures.Monad.

From ITree Require Import
Basics.Basics
Basics.Category
Expand Down
7 changes: 7 additions & 0 deletions theories/Basics/Functor.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Polymorphic Class Functor@{d c} (F : Type@{d} -> Type@{c}) : Type :=
{ fmap : forall {A B : Type@{d}}, (A -> B) -> F A -> F B }.

Module FunctorNotation.
Notation "f <$> x" := (@fmap _ _ _ _ f x) (at level 52, left associativity).
End FunctorNotation.

Loading