Initial commit

This commit is contained in:
Gabriel Tofvesson 2025-08-23 21:32:48 +02:00
commit 0706056111
4 changed files with 138 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
.idea

16
Cargo.lock generated Normal file
View File

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "bred"
version = "0.1.0"
dependencies = [
"take_mut",
]
[[package]]
name = "take_mut"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"

7
Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "bred"
version = "0.1.0"
edition = "2024"
[dependencies]
take_mut = "0.2.2"

113
src/main.rs Normal file
View File

@ -0,0 +1,113 @@
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
struct ArgCell(Rc<RefCell<Option<EitherValue>>>);
#[derive(Debug)]
struct Lambda {
arg: ArgCell,
expression: Expression
}
#[derive(Debug)]
enum EitherValue {
Lambda(Lambda),
Expression(Expression)
}
#[derive(Debug, Clone)]
enum Expression {
Valued(ArgCell),
Expression(ArgCell, ArgCell)
}
impl ArgCell {
fn lambda(value: Lambda) -> Self {
ArgCell(Rc::new(RefCell::new(Some(EitherValue::Lambda(value)))))
}
fn expression(expression: Expression) -> Self {
ArgCell(Rc::new(RefCell::new(Some(EitherValue::Expression(expression)))))
}
fn future() -> Self {
ArgCell(Rc::new(RefCell::new(None)))
}
fn copy_retain(&self) -> Self {
Self(self.0.clone())
}
}
impl Clone for ArgCell {
fn clone(&self) -> Self {
let cell = self.0.borrow();
if cell.is_some() {
Self(self.0.clone())
} else {
Self(Rc::new(RefCell::new(None)))
}
}
}
impl Lambda {
fn new(expression: impl FnOnce(ArgCell) -> Expression) -> Self {
let cell = ArgCell::future();
Self {
arg: cell.copy_retain(),
expression: expression(cell)
}
}
fn beta_reduce(self, argument: Option<EitherValue>) -> Expression {
*self.arg.0.borrow_mut() = argument;
self.expression
}
}
impl Clone for Lambda {
fn clone(&self) -> Self {
Self::new(|_| self.expression.clone())
}
}
impl EitherValue {
fn is_lambda(&self) -> bool {
matches!(*self, EitherValue::Lambda(_))
}
fn is_expression(&self) -> bool {
matches!(*self, EitherValue::Expression(_))
}
}
impl Expression {
fn new_valued(value: ArgCell) -> Self {
Self::Valued(value)
}
fn new_expression(callee: ArgCell, argument: ArgCell) -> Self {
Self::Expression(callee, argument)
}
fn can_beta_reduce(&self) -> bool {
// TODO: Clean this up
matches!(self, Self::Expression(callee, _) if callee.0.borrow().is_some() && callee.0.borrow().as_ref().unwrap().is_lambda())
}
}
// (lx.(ly.x(xy))) (lz.z)
// -> (ly.(lz.z)((lw.w)y))
// -> (ly.(lz.z)y)
// -> (ly.y)
fn main() {
// Lambda_x { Expression { Lambda_y { Expression { x(Expression(x, y)) } } } }
let func = Lambda::new(|x|
Expression::new_valued(ArgCell::lambda(Lambda::new(|y| Expression::new_expression(x.copy_retain(), ArgCell::expression(Expression::Expression(x, y))))))
);
let func_identity = Some(EitherValue::Lambda(Lambda::new(Expression::Valued)));
let reduced = func.beta_reduce(func_identity);
dbg!(reduced);
}