muro-lang.dev / docs
Streams
In brief: μ descends (match on Nat). ν is a greatest fixed point. Stream is ν X. A × X. Only a run Stream becomes an Elixir Stream. A non-productive unfold is rejected.
ν Stream
There is one ν former. The block is required for shape, then dropped — Stream is primitive.
ν Stream (A : Type) : Type where
uncons : Stream A → A × Stream A
ASCII: nu Stream (A : Type) : Type where uncons : Stream A -> A * Stream A.
uncons splits a stream into a head and a tail. head and tail are sugar for fst (uncons s) and snd (uncons s).
unfold
A ν value must be an unfold.
unfold seed (λ (s : S) → (head, next_seed))
The body is a pair. Productivity: in run and evidence, the self-name of the definition must not occur in the pair’s head. The tail may continue the stream. Spec does not run this check.
+ is still only for Data. You may write (+ k : Nat) in an unfold step when the seed is Nat.
zeros
def zeros : run Stream Nat :=
unfold 0 (λ (_ : Nat) → (0, 0))
(examples/zeros.muro.) Head is 0. The next seed is 0 again. head-zeros is {head zeros ≡ 0 : Nat} by refl.
natsFrom
def natsFrom : run Π (n : Nat) → Stream Nat :=
λ (n : Nat) →
unfold n (λ (+ k : Nat) → (k, suc k))
(examples/nats.muro.) Each step reuses k because Nat is Data.
{:ok, src} = Muro.emit_file("examples/nats.muro", Muro.Nats)
Code.eval_string(src)
Muro.Nats.natsFrom(0) |> Stream.take(3) |> Enum.to_list()
# [0, {:suc, 0}, {:suc, {:suc, 0}}]
Emit of a checked run Stream is Stream.unfold/2. The pair is {head, next_seed}. uncons becomes two replayable views (Enum.take/2 and Stream.drop/2); affinity was already checked.
Always
Always P s is the coinductive family “P holds at every head.” Same former as Stream: ν Y. P (head s) × Y.
def zeros-always-zero : evidence Always Nat (λ (_ : Nat) → {0 ≡ 0 : Nat}) zeros :=
unfold tt (λ (_ : Unit) → (refl, tt))
(examples/always.muro.) Surface: Always A P s. This is evidence. It is omitted at emit.
Bisimulation
σ ~ τ (ASCII bisim σ τ) is a coinductive family on two streams: heads equal, tails related. After J.J.M.M. Rutten, Elements of Stream Calculus, ENTCS 45 (2001), Theorem 2.1.
def zeros-bisim : evidence zeros ~ zeros' :=
unfold tt (λ (_ : Unit) → (refl, tt))
def nats-tail-bisim : evidence Π (n : Nat) → tail (natsFrom n) ~ natsFrom (suc n) :=
λ (n : Nat) →
unfold tt (λ (_ : Unit) → (refl, tt))
(examples/bisim.muro.) Always, ~, and their inhabitants are evidence (or live in evidence). They are not Elixir streams.
There are no user-defined ν-predicates. See Limits.
Next: Either and Dec.
Source on GitHub
· fetched from murolang/muro manual/