From b5449eceedbd5d93ea4bd22e604fd972c46eda43 Mon Sep 17 00:00:00 2001 From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:44:48 -0500 Subject: Reversible Programming, html formatting changes, and css tweaks --- reversible.rs | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 reversible.rs (limited to 'reversible.rs') diff --git a/reversible.rs b/reversible.rs new file mode 100644 index 0000000..19e6f98 --- /dev/null +++ b/reversible.rs @@ -0,0 +1,158 @@ +use std::marker::PhantomData; + +pub trait Rev { + type Input; + type Output; + + fn forward(&self, i: Self::Input) -> Self::Output; + fn reverse(&self, o: Self::Output) -> Self::Input; +} + +#[derive(Clone)] +pub struct Addition { + amount: A +} +impl Rev for Addition +where + A: std::ops::Add + std::ops::Sub + Copy +{ + type Input = A; + type Output = A; + + fn forward(&self, a: A) -> A { + a + self.amount + } + + fn reverse(&self, b: A) -> A { + b - self.amount + } +} +pub fn plus(amount: A) -> Addition { + Addition { amount } +} + +// more blocks + +#[derive(Clone)] +pub struct Negate(PhantomData); +impl> Rev for Negate { + type Input = A; + type Output = A; + + fn forward(&self, a: Self::Input) -> Self::Output { + -a + } + + fn reverse(&self, b: Self::Output) -> Self::Input { + -b + } +} +pub fn neg() -> Negate { + Negate(PhantomData) +} + +#[derive(Clone)] +pub struct Multiplication { + amount: A +} +impl Rev for Multiplication +where + A: std::ops::Mul + std::ops::Div + Copy, +{ + type Input = A; + type Output = A; + + fn forward(&self, a: A) -> A { + a * self.amount + } + + fn reverse(&self, b: A) -> A { + b / self.amount + } +} +pub fn times(amount: A) -> Multiplication { + Multiplication { amount } +} + +#[derive(Clone)] +pub struct DiscreteMap(Vec<(A, B)>); +impl Rev for DiscreteMap { + type Input = A; + type Output = B; + + fn forward(&self, a: A) -> B { + for i in self.0.iter() { + if i.0 == a { + return i.1.clone() + } + } + panic!() + } + + fn reverse(&self, b: B) -> A { + for i in self.0.iter() { + if i.1 == b { + return i.0.clone() + } + } + panic!() + } +} +pub fn discrete(vec: Vec<(A, B)>) -> DiscreteMap { + DiscreteMap(vec) +} + +// combinators + +#[derive(Clone)] +pub struct Pipe(X, Y); +impl Rev for Pipe +where + X: Rev, + Y: Rev +{ + type Input = X::Input; + type Output = Y::Output; + + fn forward(&self, a: Self::Input) -> Self::Output { + self.1.forward(self.0.forward(a)) + } + + fn reverse(&self, c: Self::Output) -> Self::Input { + self.0.reverse(self.1.reverse(c)) + } +} + +#[derive(Clone)] +pub struct Inverse(X); +impl Rev for Inverse { + type Input = X::Output; + type Output = X::Input; + + fn forward(&self, a: Self::Input) -> Self::Output { + self.0.reverse(a) + } + + fn reverse(&self, b: Self::Output) -> Self::Input { + self.0.forward(b) + } +} + +pub trait RevExt: Rev + Sized { + fn then>(self, other: N) -> Pipe { + Pipe(self, other) + } + + fn inverse(self) -> Inverse { + Inverse(self) + } +} +impl RevExt for T {} + +pub fn under(op: Op, val: Val) -> impl Rev +where + Op: Rev + Clone, + Val: Rev +{ + op.clone().then(val).then(op.inverse()) +} \ No newline at end of file -- cgit v1.3.1