Library models.DCPOSL
Require Import LogicalRelations.
Require Import OptionRel.
Require Import Category.
Require Import ConcreteCategory.
Require Import Functor.
Require Import DCPO.
Require Import EffectSignatures.
Require Import PropExtensionality.
Require Import FunctionalExtensionality.
Require Import Classical.
Require Import OptionRel.
Require Import Category.
Require Import ConcreteCategory.
Require Import Functor.
Require Import DCPO.
Require Import EffectSignatures.
Require Import PropExtensionality.
Require Import FunctionalExtensionality.
Require Import Classical.
Free dcpo-semilattice generated by a set
- pointed dcpos and strict Scott-continuous functions between them, representing spaces of potentially non-terminating computations, and
- complete (semi)lattices and sup-preserving functions, representing computation spaces featuring undefined behaviors and angelic choices.
Free dcpo
Variant outcome_le {A} : relation (outcome A) :=
| val_le a : outcome_le (val a) (val a)
| div_le x : outcome_le div x.
Global Instance outcome_le_preo A :
PreOrder (@outcome_le A).
Global Instance outcome_le_antisym A :
Antisymmetric (outcome A) eq outcome_le.
Classically speaking, the order defined above is also a dcpo:
any directed set will contain at most one of the generators,
in which case it will be the supremum. If there is no generator
in the set then the supremum must be div. However, it is not
possible to provide a dsup operator as defined in the DCPO
library without the use of classical axioms, as we would need
the generator membership condition to be decidable for a set
given in outcome A → Prop. Since we only use the construction
above as a building block, this is not an issue.
On the other side of things, the free sup-lattice generated by a
set is simply its powerset, ordered under inclusion, where suprema
are given by set unions. We may want to refactor the code to make
this explicit somewhere, though this construction is a special case
of the downset completion mechanized in lattices/Downset.v.
Per Abramsky and Jung, a dcpo-semilattice is a dcpo
which provides the join operation of a semilattice.
As a dcpo operator, the join must preserve directed sups
in each argument. In the infinitary case of the sup-lattices
we are considering, this manifests as the distributivity property
⋃i∈I · ⋁j∈Jᵢ · xi,j = ⋁f∈(∏i·Jᵢ) · ⋃i∈I · xi,f(i)
where ⋃ denotes the join operation associated with the sup-lattice
and ⋁ is the directed-sup operation (the least element can be seen
as the empty sup) associated with the dcpo structure.
Maps between dcpo-semilattices must respect both structures and
be at the time strict Scott-continuous with regards to the dcpo
and sup-preserving with regards the semilattice ordering.
Free semilattice
Free dcpo-semilattice
Carrier set
By contrast, the directed-complete structure is more subtle.
The least element is the singleton {div}. As the computation
progresses, any div outcome in the set can be replaced by a new
set of outcomes. This new set of outcomes can be empty, and could
itself include div if some of the computation's nondeterministic
are still running. However, once div has been dropped from the
set, the computation is fully terminated and can no longer be
modified by further execution.
The order described above can be defined as follows.
Record le (x y : omap A) :=
{
le_fw a : x (val a) → y (val a);
le_bw σ : y σ → x div ∨ x σ;
}.
Lemma le_div (x y : omap A) :
le x y → y div → x div.
Global Instance le_preo :
PreOrder le.
Global Instance le_antisym :
Antisymmetric _ eq le.
Under that ordering, fully terminating computations are
the maximal elements. Two computations will have an upper bound
when it is possible to extend them so that they produce the same
set of outcomes. Sups for sets of computations which are
compatible in this way can be defined as follows.
Section DSUP.
Context (D : omap A → Prop) `{HD : !Directed D}.
Definition dsup : omap A :=
fun σ ⇒
match σ with
| val a ⇒ ∃ x, D x ∧ x (val a)
| div ⇒ ∀ x, D x → x div
end.
Lemma directed_val x y a :
D x → D y → x (val a) → y div ∨ y (val a).
Lemma dsup_has_all σ :
dsup σ → ∀ x, D x → x div ∨ x σ.
Global Instance lsup_spec :
IsSup D dsup.
End DSUP.
Global Instance le_dc : DirectedComplete (omap A) :=
{
dc_po := {| models.DCPO.le := le |};
dsup D _ := dsup D;
}.
End DCPO.
Monad operations
Variant ret {A} (a : A) : omap A :=
| ret_intro : ret a (val a).
Variant bind {A B} (f : A → omap B) (x : omap A) : omap B :=
| bind_div : x div → bind f x div
| bind_val a σ : x (val a) → f a σ → bind f x σ.
Lemma bind_ret_l {A} (x : omap A) :
bind (@ret A) x = x.
Lemma bind_ret_r {A B} (f : A → omap B) (a : A) :
bind f (ret a) = f a.
Lemma bind_bind {A B C} (g : B → omap C) (f : A → omap B) (x : omap A) :
bind g (bind f x) = bind (fun a ⇒ bind g (f a)) x.
End FDSL.