Documentation

Mt.Task.Basic

def Mt.TaskM (spec : Mt.Spec) (T : Type) :
Type

Monad to describe single threaded algorithms. Tasks can be iterated step by step until they finally complete or panic.

TaskM is a monad, i.e. you can use the do-notation to write code:

import Mt.Task.Basic
open Mt

abbrev spec : Spec :={
  State := Nat,
  Reservation := UnitReservation,
  validate :=λ _ _ => True
}

def sample_task : TaskM spec Bool :=do
  if (<- TaskM.atomic_read λ n => n) > 100 then
    -- reset to 100
    TaskM.atomic_read_modify λ _ => 100
    return false
  
  TaskM.atomic_assert λ n => n < 500
  
  TaskM.atomic_read_modify λ n => n + 7
  return true 

Note: TaskM hat an associative bind operator, but it is not a lawful monad: Binding two pure cannot be simplified into a single pure, because it requires two iterations to complete.

Equations
inductive Mt.TaskM.IterationResult (spec : Mt.Spec) (T : Type) :
Type

The result of a single iteration of TaskM.

Independent of the result, the resulting shared state after the iteration can be retrieved using IterationResult.state

Instances For
    def Mt.TaskM.IterationResult.state {T : Type} {spec : Mt.Spec} :
    Mt.TaskM.IterationResult spec Tspec.State
    Equations
    • One or more equations did not get rendered due to their size.
    instance Mt.TaskM.instMonad {spec : Mt.Spec} :
    Equations
    • Mt.TaskM.instMonad = Monad.mk
    theorem Mt.TaskM.bind_assoc {spec : Mt.Spec} {U : Type} {V : Type} {W : Type} (mu : Mt.TaskM spec U) (f : UMt.TaskM spec V) (g : VMt.TaskM spec W) :
    (mu >>= fun u => f u >>= g) = mu >>= f >>= g
    def Mt.TaskM.atomic_read_modify_read {spec : Mt.Spec} {T : Type} (f : spec.StateT × spec.State) :
    Mt.TaskM spec T

    Atomic TaskM primitive with read/write-access to the shared state.

    Additional to performing a read-modify operation, it returns a value.

    Example: Compare Exchange (https://en.wikipedia.org/wiki/Compare-and-swap)

    Equations
    def Mt.TaskM.atomic_read_modify {spec : Mt.Spec} (f : spec.Statespec.State) :

    Atomic TaskM primitive to perform read-modify operations on the shared state. It does not return anything.

    Equations
    def Mt.TaskM.atomic_read {spec : Mt.Spec} {T : Type} (f : spec.StateT) :
    Mt.TaskM spec T

    Atomic TaskM primitive to perform read the shared state. It does not change anything

    Equations
    def Mt.TaskM.panic {spec : Mt.Spec} {T : Type} (msg : String) :
    Mt.TaskM spec T

    Atomic TaskM primitive which throws an exception. The current thread panics and will be removed from the system

    Equations
    def Mt.TaskM.atomic_assert {spec : Mt.Spec} (cond : spec.StateBool) :

    Atomic TaskM primitive to assert a given condition. The condition is checked atomically. If it returns false, the current thread panics.

    Equations
    def Mt.TaskM.atomic_blocking_rmr {spec : Mt.Spec} {T : Type} (block_until : spec.StateBool) (f : spec.StateT × spec.State) :
    Mt.TaskM spec T

    TaskM primitive which blocks the current thread until a given condition holds, and executes a read-modify-read operation afterwards.

    There are neither spurious wakeups nor race conditions: The system will only perform the read-modify-read operation if the provided condition holds. If it does not, the thread will block.

    Equations
    def Mt.TaskM.iterate {spec : Mt.Spec} {T : Type} :
    Mt.TaskM spec Tspec.StateMt.TaskM.IterationResult spec T

    Iterate a given thread on a given state and provides an IterationResult.

    The task may complete or panic. If it is does not, it is still running and a continuation will be provided in the result

    Equations
    • One or more equations did not get rendered due to their size.
    theorem Mt.TaskM.iterate_pure {spec : Mt.Spec} {T : Type} (s : spec.State) (t : T) :

    Iteration of pure t always completes with result t

    theorem Mt.TaskM.iterate_bind {spec : Mt.Spec} {U : Type} {V : Type} (mu : Mt.TaskM spec U) (f : UMt.TaskM spec V) (s : spec.State) :

    Iteration of a >>= f iterates a and returns a continuation.

    • If the a iteration has completed with result t, the next iteration will start work on f t
    • If the a iteration has not completed yet, the next iteration will continue.
    • If a has panicked, the exception is propagated.
    theorem Mt.TaskM.iterate_rmr {spec : Mt.Spec} {T : Type} (f : spec.StateT × spec.State) (s : spec.State) :
    Mt.TaskM.iterate (Mt.TaskM.atomic_read_modify_read f) s = let _discr := f s; match f s with | (t, s') => Mt.TaskM.IterationResult.Done s' t

    Iteration of a read-modify-read-operation will perform the read modify and complete with the computed result.

    theorem Mt.TaskM.iterate_rm {spec : Mt.Spec} (f : spec.Statespec.State) (s : spec.State) :

    Iteration of a read-modify operation will perform the read modify operation and complete with Unit.unit

    theorem Mt.TaskM.iterate_read {spec : Mt.Spec} {T : Type} (f : spec.StateT × spec.Reservation) (s : spec.State) :

    Iteration of a read operation will compute a value based on the current shared state and complete with the result

    theorem Mt.TaskM.iterate_panic {spec : Mt.Spec} {T : Type} (msg : String) (s : spec.State) :

    Iteration of a panic will fail

    theorem Mt.TaskM.iterate_assert {spec : Mt.Spec} (cond : spec.StateBool) (s : spec.State) :

    Iteration of an assertion will atomically check the condition and succeed or fail depending on the result.

    theorem Mt.TaskM.iterate_blocking_rmr {spec : Mt.Spec} {T : Type} (block_until : spec.StateBool) (f : spec.StateT × spec.State) (s : spec.State) :

    Iteration of a atomic_blocking_rmr operation will always return a continuation.

    The IterationResult contains the blocking predicate and the desired read-modify-read operation. The caller should ensure that the read-modify-operation is only iterated when the blocking predicate holds.

    inductive Mt.TaskM.is_direct_cont {spec : Mt.Spec} {T : Type} :
    Mt.TaskM spec TMt.TaskM spec TProp

    Well founded relation on TaskM fulfilled by continuations with their parents.

    It can be used to perform well founded recursion TaskM without using the implementation details of TaskM. Whenever TaskM.iterate returns a continuation, the continuation will be smaller according to this relation.

    Instances For
      theorem Mt.TaskM.is_direct_cont_wf {spec : Mt.Spec} {T : Type} :
      WellFounded Mt.TaskM.is_direct_cont

      See TaskM.is_direct_cont

      instance Mt.TaskM.instWf {spec : Mt.Spec} {T : Type} :
      Equations
      • Mt.TaskM.instWf = { rel := Mt.TaskM.is_direct_cont, wf := (_ : WellFounded Mt.TaskM.is_direct_cont) }