use std::marker::PhantomData;
pub mod mu_types {
use super::*;
pub trait Protocol {
type StartSet: ActiveSet;
type EndSet: ActiveSet;
}
pub struct Mu<P: Protocol>(PhantomData<P>);
impl<P: Protocol> Protocol for Mu<P>
where
P: Protocol<EndSet = <P as Protocol>::StartSet>, {
type StartSet = P::StartSet;
type EndSet = P::EndSet;
}
pub struct End<S: ActiveSet>(PhantomData<S>);
impl<S: ActiveSet> Protocol for End<S> {
type StartSet = S;
type EndSet = S;
}
pub struct Seq<P1: Protocol, P2: Protocol>(PhantomData<(P1, P2)>);
impl<P1, P2> Protocol for Seq<P1, P2>
where
P1: Protocol,
P2: Protocol<StartSet = P1::EndSet>,
{
type StartSet = P1::StartSet;
type EndSet = P2::EndSet;
}
}
pub mod uniform_iteration {
use super::*;
pub struct UniformLoop<S: ActiveSet, const N: usize> {
_marker: PhantomData<S>,
}
impl<S: ActiveSet, const N: usize> UniformLoop<S, N> {
pub fn new() -> Self {
UniformLoop {
_marker: PhantomData,
}
}
pub fn execute<F>(self, mut warp: Warp<S>, mut body: F) -> Warp<S>
where
F: FnMut(&mut Warp<S>, usize),
{
for i in 0..N {
body(&mut warp, i);
}
warp
}
}
pub trait UniformLoopProtocol {
type ActiveSet: ActiveSet;
const ITERATIONS: usize;
fn body(warp: &mut Warp<Self::ActiveSet>, iteration: usize);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_uniform_loop() {
let loop_5: UniformLoop<All, 5> = UniformLoop::new();
let warp: Warp<All> = Warp::new();
let mut count = 0;
let result = loop_5.execute(warp, |_w, _i| {
count += 1;
});
assert_eq!(count, 5);
let _: Warp<All> = result; }
}
}
pub mod convergent_iteration {
use super::*;
pub struct ConvergentLoop<S: ActiveSet> {
_marker: PhantomData<S>,
max_iterations: usize,
}
impl<S: ActiveSet> ConvergentLoop<S> {
pub fn new(max_iterations: usize) -> Self {
ConvergentLoop {
_marker: PhantomData,
max_iterations,
}
}
pub fn execute<F, P>(
self,
warp: Warp<S>,
mut body: F,
mut converged: P,
) -> (Warp<S>, bool, usize)
where
F: FnMut(&Warp<S>), P: FnMut(&Warp<S>) -> bool, {
for i in 0..self.max_iterations {
if converged(&warp) {
return (warp, true, i);
}
body(&warp);
}
(warp, converged(&warp), self.max_iterations)
}
}
pub trait ConvergentProtocol {
type ActiveSet: ActiveSet;
fn body(warp: &Warp<Self::ActiveSet>);
fn converged(warp: &Warp<Self::ActiveSet>) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_convergent_loop() {
use std::cell::Cell;
let conv_loop: ConvergentLoop<All> = ConvergentLoop::new(100);
let warp: Warp<All> = Warp::new();
let iteration = Cell::new(0);
let (result, converged, iters) = conv_loop.execute(
warp,
|_w| {
iteration.set(iteration.get() + 1);
},
|_w| iteration.get() >= 5, );
assert!(converged);
assert_eq!(iters, 5);
let _: Warp<All> = result;
}
}
}
pub mod reducing_iteration {
use super::*;
pub struct ReducingLoop<S: ActiveSet> {
_marker: PhantomData<S>,
max_iterations: usize,
}
impl<S: ActiveSet> ReducingLoop<S> {
pub fn new(max_iterations: usize) -> Self {
ReducingLoop {
_marker: PhantomData,
max_iterations,
}
}
pub fn execute<F, P>(self, warp: Warp<S>, mut body: F, mut any_active: P) -> Warp<S>
where
F: FnMut(u32, usize), P: FnMut() -> bool, {
for i in 0..self.max_iterations {
if !any_active() {
break;
}
body(0, i); }
warp }
}
pub struct PhasedReducingLoop<S: ActiveSet> {
_marker: PhantomData<S>,
}
impl<S: ActiveSet> PhasedReducingLoop<S> {
pub fn execute<W, L, P>(
warp: Warp<S>,
mut warp_phase: W,
mut lane_phase: L,
mut done: P,
max_iters: usize,
) -> Warp<S>
where
W: FnMut(&Warp<S>), L: FnMut(u32), P: FnMut() -> bool, {
for _ in 0..max_iters {
warp_phase(&warp); lane_phase(0); if done() {
break;
}
}
warp
}
}
}
pub mod recursive_diverge {
use super::*;
pub trait RecursiveTreeProtocol {
fn visit_node(warp: &Warp<All>, depth: usize);
fn has_left(lane: u32) -> bool;
fn has_right(lane: u32) -> bool;
}
pub fn bounded_tree_traversal<P: RecursiveTreeProtocol>(
warp: Warp<All>,
max_depth: usize,
) -> Warp<All> {
fn go<P: RecursiveTreeProtocol>(warp: Warp<All>, depth: usize, max: usize) -> Warp<All> {
if depth >= max {
return warp;
}
P::visit_node(&warp, depth);
go::<P>(warp, depth + 1, max)
}
go::<P>(warp, 0, max_depth)
}
pub struct BalancedRecursion;
}
pub mod fold_unfold {
use super::*;
pub struct Rec<P>(PhantomData<P>);
pub struct Unfolded<P>(PhantomData<P>);
pub trait RecBody {
type ActiveSet: ActiveSet;
fn body<F: FnOnce(Warp<Self::ActiveSet>) -> Warp<Self::ActiveSet>>(
warp: Warp<Self::ActiveSet>,
recurse: F,
) -> Warp<Self::ActiveSet>;
}
pub fn execute_rec<P: RecBody>(
warp: Warp<P::ActiveSet>,
max_unfolds: usize,
) -> Warp<P::ActiveSet> {
fn go<P: RecBody>(warp: Warp<P::ActiveSet>, remaining: usize) -> Warp<P::ActiveSet> {
if remaining == 0 {
warp } else {
P::body(warp, |w| go::<P>(w, remaining - 1))
}
}
go::<P>(warp, max_unfolds)
}
#[cfg(test)]
mod tests {
use super::*;
struct CountingProtocol;
impl RecBody for CountingProtocol {
type ActiveSet = All;
fn body<F>(warp: Warp<All>, recurse: F) -> Warp<All>
where
F: FnOnce(Warp<All>) -> Warp<All>,
{
recurse(warp)
}
}
#[test]
fn test_fold_unfold() {
let warp: Warp<All> = Warp::new();
let result = execute_rec::<CountingProtocol>(warp, 10);
let _: Warp<All> = result; }
}
}
pub mod decidability {
pub struct DecidabilityConditions;
pub fn protocol_equivalent<P1, P2>() -> bool
where
P1: super::mu_types::Protocol + 'static,
P2: super::mu_types::Protocol + 'static,
{
std::any::TypeId::of::<P1>() == std::any::TypeId::of::<P2>()
}
}
pub mod summary {
pub struct Recommendations;
}
pub mod language_integration {
pub struct Example;
}
pub trait ActiveSet: Copy + Clone + 'static {
const MASK: u32;
}
#[derive(Copy, Clone)]
pub struct All;
impl ActiveSet for All {
const MASK: u32 = 0xFFFFFFFF;
}
#[derive(Copy, Clone)]
pub struct Even;
impl ActiveSet for Even {
const MASK: u32 = 0x55555555;
}
#[derive(Copy, Clone)]
pub struct Warp<S: ActiveSet> {
_marker: PhantomData<S>,
}
impl<S: ActiveSet> Warp<S> {
pub fn new() -> Self {
Warp {
_marker: PhantomData,
}
}
}
#[cfg(test)]
mod tests {
use super::convergent_iteration::*;
use super::reducing_iteration::*;
use super::uniform_iteration::*;
use super::*;
#[test]
fn test_uniform_preserves_type() {
let warp: Warp<All> = Warp::new();
let loop_10: UniformLoop<All, 10> = UniformLoop::new();
let result: Warp<All> = loop_10.execute(warp, |_w, _i| {});
let _ = result;
}
#[test]
fn test_convergent_preserves_type() {
use std::cell::Cell;
let warp: Warp<All> = Warp::new();
let conv: ConvergentLoop<All> = ConvergentLoop::new(100);
let i = Cell::new(0);
let (result, _, _): (Warp<All>, _, _) = conv.execute(
warp,
|_w| {
i.set(i.get() + 1);
},
|_w| i.get() >= 10,
);
let _ = result;
}
#[test]
fn test_reducing_preserves_type() {
use std::cell::Cell;
let warp: Warp<All> = Warp::new();
let red: ReducingLoop<All> = ReducingLoop::new(100);
let count = Cell::new(0);
let result: Warp<All> = red.execute(
warp,
|_lane, _iter| {
count.set(count.get() + 1);
},
|| count.get() < 10,
);
let _ = result;
}
#[test]
fn test_protocol_types_compile() {
use mu_types::*;
type SimpleRec = Mu<End<All>>;
fn check_protocol<P: Protocol>() {}
check_protocol::<SimpleRec>();
}
#[test]
fn test_bounded_recursion() {
struct DummyTree;
impl recursive_diverge::RecursiveTreeProtocol for DummyTree {
fn visit_node(_warp: &Warp<All>, _depth: usize) {}
fn has_left(_lane: u32) -> bool {
false
}
fn has_right(_lane: u32) -> bool {
false
}
}
let warp: Warp<All> = Warp::new();
let result = recursive_diverge::bounded_tree_traversal::<DummyTree>(warp, 5);
let _: Warp<All> = result;
}
}