Using rc we now get code that runs much faster and

can run jpg contract with no inputs
This commit is contained in:
Kasey White 2022-08-17 05:21:40 -04:00 committed by Lucas
parent fb81955f51
commit 2bb482d9ec
11 changed files with 219 additions and 190 deletions

View File

@ -1,4 +1,4 @@
use std::fmt::Display; use std::{fmt::Display, rc::Rc};
use pallas_primitives::alonzo::PlutusData; use pallas_primitives::alonzo::PlutusData;
@ -30,8 +30,8 @@ where
/// even necessary (i.e. minting policy). /// even necessary (i.e. minting policy).
pub fn apply(&self, program: &Self) -> Self { pub fn apply(&self, program: &Self) -> Self {
let applied_term = Term::Apply { let applied_term = Term::Apply {
function: Box::new(self.term.clone()), function: Rc::new(self.term.clone()),
argument: Box::new(program.term.clone()), argument: Rc::new(program.term.clone()),
}; };
Program { Program {
@ -60,21 +60,21 @@ pub enum Term<T> {
// tag: 0 // tag: 0
Var(T), Var(T),
// tag: 1 // tag: 1
Delay(Box<Term<T>>), Delay(Rc<Term<T>>),
// tag: 2 // tag: 2
Lambda { Lambda {
parameter_name: T, parameter_name: T,
body: Box<Term<T>>, body: Rc<Term<T>>,
}, },
// tag: 3 // tag: 3
Apply { Apply {
function: Box<Term<T>>, function: Rc<Term<T>>,
argument: Box<Term<T>>, argument: Rc<Term<T>>,
}, },
// tag: 4 // tag: 4
Constant(Constant), Constant(Constant),
// tag: 5 // tag: 5
Force(Box<Term<T>>), Force(Rc<Term<T>>),
// tag: 6 // tag: 6
Error, Error,
// tag: 7 // tag: 7
@ -306,7 +306,7 @@ impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> { fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
let mut converter = Converter::new(); let mut converter = Converter::new();
let term = converter.name_to_named_debruijn(value)?; let term = converter.name_to_named_debruijn(&value)?;
Ok(term) Ok(term)
} }
@ -333,7 +333,7 @@ impl TryFrom<Term<Name>> for Term<DeBruijn> {
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> { fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
let mut converter = Converter::new(); let mut converter = Converter::new();
let term = converter.name_to_debruijn(value)?; let term = converter.name_to_debruijn(&value)?;
Ok(term) Ok(term)
} }
@ -356,7 +356,7 @@ impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
fn try_from(value: Term<NamedDeBruijn>) -> Result<Self, debruijn::Error> { fn try_from(value: Term<NamedDeBruijn>) -> Result<Self, debruijn::Error> {
let mut converter = Converter::new(); let mut converter = Converter::new();
let term = converter.named_debruijn_to_name(value)?; let term = converter.named_debruijn_to_name(&value)?;
Ok(term) Ok(term)
} }
@ -375,7 +375,7 @@ impl From<Term<NamedDeBruijn>> for Term<DeBruijn> {
fn from(value: Term<NamedDeBruijn>) -> Self { fn from(value: Term<NamedDeBruijn>) -> Self {
let mut converter = Converter::new(); let mut converter = Converter::new();
converter.named_debruijn_to_debruijn(value) converter.named_debruijn_to_debruijn(&value)
} }
} }
@ -392,7 +392,7 @@ impl From<Term<NamedDeBruijn>> for Term<FakeNamedDeBruijn> {
fn from(value: Term<NamedDeBruijn>) -> Self { fn from(value: Term<NamedDeBruijn>) -> Self {
let mut converter = Converter::new(); let mut converter = Converter::new();
converter.named_debruijn_to_fake_named_debruijn(value) converter.named_debruijn_to_fake_named_debruijn(&value)
} }
} }
@ -413,7 +413,7 @@ impl TryFrom<Term<DeBruijn>> for Term<Name> {
fn try_from(value: Term<DeBruijn>) -> Result<Self, debruijn::Error> { fn try_from(value: Term<DeBruijn>) -> Result<Self, debruijn::Error> {
let mut converter = Converter::new(); let mut converter = Converter::new();
let term = converter.debruijn_to_name(value)?; let term = converter.debruijn_to_name(&value)?;
Ok(term) Ok(term)
} }
@ -432,7 +432,7 @@ impl From<Term<DeBruijn>> for Term<NamedDeBruijn> {
fn from(value: Term<DeBruijn>) -> Self { fn from(value: Term<DeBruijn>) -> Self {
let mut converter = Converter::new(); let mut converter = Converter::new();
converter.debruijn_to_named_debruijn(value) converter.debruijn_to_named_debruijn(&value)
} }
} }
@ -449,7 +449,7 @@ impl From<Term<FakeNamedDeBruijn>> for Term<NamedDeBruijn> {
fn from(value: Term<FakeNamedDeBruijn>) -> Self { fn from(value: Term<FakeNamedDeBruijn>) -> Self {
let mut converter = Converter::new(); let mut converter = Converter::new();
converter.fake_named_debruijn_to_named_debruijn(value) converter.fake_named_debruijn_to_named_debruijn(&value)
} }
} }

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use thiserror::Error; use thiserror::Error;
use crate::ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Term, Unique}; use crate::ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Term, Unique};
@ -32,14 +34,14 @@ impl Converter {
pub fn name_to_named_debruijn( pub fn name_to_named_debruijn(
&mut self, &mut self,
term: Term<Name>, term: &Term<Name>,
) -> Result<Term<NamedDeBruijn>, Error> { ) -> Result<Term<NamedDeBruijn>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(Name { text, unique }) => Term::Var(NamedDeBruijn { Term::Var(Name { text, unique }) => Term::Var(NamedDeBruijn {
text, text: text.to_string(),
index: self.get_index(unique)?, index: self.get_index(*unique)?,
}), }),
Term::Delay(term) => Term::Delay(Box::new(self.name_to_named_debruijn(*term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.name_to_named_debruijn(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
@ -49,13 +51,13 @@ impl Converter {
let index = self.get_index(parameter_name.unique)?; let index = self.get_index(parameter_name.unique)?;
let name = NamedDeBruijn { let name = NamedDeBruijn {
text: parameter_name.text, text: parameter_name.text.to_string(),
index, index,
}; };
self.start_scope(); self.start_scope();
let body = self.name_to_named_debruijn(*body)?; let body = self.name_to_named_debruijn(body)?;
self.end_scope(); self.end_scope();
@ -63,26 +65,26 @@ impl Converter {
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name,
body: Box::new(body), body: Rc::new(body),
} }
} }
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.name_to_named_debruijn(*function)?), function: Rc::new(self.name_to_named_debruijn(function)?),
argument: Box::new(self.name_to_named_debruijn(*argument)?), argument: Rc::new(self.name_to_named_debruijn(argument)?),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.name_to_named_debruijn(*term)?)), Term::Force(term) => Term::Force(Rc::new(self.name_to_named_debruijn(term)?)),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
}; };
Ok(converted_term) Ok(converted_term)
} }
pub fn name_to_debruijn(&mut self, term: Term<Name>) -> Result<Term<DeBruijn>, Error> { pub fn name_to_debruijn(&mut self, term: &Term<Name>) -> Result<Term<DeBruijn>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(Name { unique, .. }) => Term::Var(self.get_index(unique)?), Term::Var(Name { unique, .. }) => Term::Var(self.get_index(*unique)?),
Term::Delay(term) => Term::Delay(Box::new(self.name_to_debruijn(*term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.name_to_debruijn(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
@ -93,7 +95,7 @@ impl Converter {
self.start_scope(); self.start_scope();
let body = self.name_to_debruijn(*body)?; let body = self.name_to_debruijn(body)?;
self.end_scope(); self.end_scope();
@ -101,17 +103,17 @@ impl Converter {
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name,
body: Box::new(body), body: Rc::new(body),
} }
} }
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.name_to_debruijn(*function)?), function: Rc::new(self.name_to_debruijn(function)?),
argument: Box::new(self.name_to_debruijn(*argument)?), argument: Rc::new(self.name_to_debruijn(argument)?),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.name_to_debruijn(*term)?)), Term::Force(term) => Term::Force(Rc::new(self.name_to_debruijn(term)?)),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
}; };
Ok(converted_term) Ok(converted_term)
@ -119,14 +121,14 @@ impl Converter {
pub fn named_debruijn_to_name( pub fn named_debruijn_to_name(
&mut self, &mut self,
term: Term<NamedDeBruijn>, term: &Term<NamedDeBruijn>,
) -> Result<Term<Name>, Error> { ) -> Result<Term<Name>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(NamedDeBruijn { text, index }) => Term::Var(Name { Term::Var(NamedDeBruijn { text, index }) => Term::Var(Name {
text, text: text.to_string(),
unique: self.get_unique(index)?, unique: self.get_unique(*index)?,
}), }),
Term::Delay(term) => Term::Delay(Box::new(self.named_debruijn_to_name(*term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_name(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
@ -136,52 +138,52 @@ impl Converter {
let unique = self.get_unique(parameter_name.index)?; let unique = self.get_unique(parameter_name.index)?;
let name = Name { let name = Name {
text: parameter_name.text, text: parameter_name.text.to_string(),
unique, unique,
}; };
self.start_scope(); self.start_scope();
let body = self.named_debruijn_to_name(*body)?; let body = self.named_debruijn_to_name(body)?;
self.end_scope(); self.end_scope();
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name,
body: Box::new(body), body: Rc::new(body),
} }
} }
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.named_debruijn_to_name(*function)?), function: Rc::new(self.named_debruijn_to_name(function)?),
argument: Box::new(self.named_debruijn_to_name(*argument)?), argument: Rc::new(self.named_debruijn_to_name(argument)?),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.named_debruijn_to_name(*term)?)), Term::Force(term) => Term::Force(Rc::new(self.named_debruijn_to_name(term)?)),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
}; };
Ok(converted_term) Ok(converted_term)
} }
pub fn debruijn_to_name(&mut self, term: Term<DeBruijn>) -> Result<Term<Name>, Error> { pub fn debruijn_to_name(&mut self, term: &Term<DeBruijn>) -> Result<Term<Name>, Error> {
let converted_term = match term { let converted_term = match term {
Term::Var(index) => { Term::Var(index) => {
let unique = self.get_unique(index)?; let unique = self.get_unique(*index)?;
Term::Var(Name { Term::Var(Name {
text: format!("i_{}", unique), text: format!("i_{}", unique),
unique, unique,
}) })
} }
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_name(*term)?)), Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_name(term)?)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => { } => {
self.declare_binder(); self.declare_binder();
let unique = self.get_unique(parameter_name)?; let unique = self.get_unique(*parameter_name)?;
let name = Name { let name = Name {
text: format!("i_{}", unique), text: format!("i_{}", unique),
@ -190,127 +192,127 @@ impl Converter {
self.start_scope(); self.start_scope();
let body = self.debruijn_to_name(*body)?; let body = self.debruijn_to_name(body)?;
self.end_scope(); self.end_scope();
Term::Lambda { Term::Lambda {
parameter_name: name, parameter_name: name,
body: Box::new(body), body: Rc::new(body),
} }
} }
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.debruijn_to_name(*function)?), function: Rc::new(self.debruijn_to_name(function)?),
argument: Box::new(self.debruijn_to_name(*argument)?), argument: Rc::new(self.debruijn_to_name(argument)?),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.debruijn_to_name(*term)?)), Term::Force(term) => Term::Force(Rc::new(self.debruijn_to_name(term)?)),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
}; };
Ok(converted_term) Ok(converted_term)
} }
pub fn named_debruijn_to_debruijn(&mut self, term: Term<NamedDeBruijn>) -> Term<DeBruijn> { pub fn named_debruijn_to_debruijn(&mut self, term: &Term<NamedDeBruijn>) -> Term<DeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.into()), Term::Var(name) => Term::Var(name.clone().into()),
Term::Delay(term) => Term::Delay(Box::new(self.named_debruijn_to_debruijn(*term))), Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_debruijn(term))),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.into(), parameter_name: parameter_name.clone().into(),
body: Box::new(self.named_debruijn_to_debruijn(*body)), body: Rc::new(self.named_debruijn_to_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.named_debruijn_to_debruijn(*function)), function: Rc::new(self.named_debruijn_to_debruijn(function)),
argument: Box::new(self.named_debruijn_to_debruijn(*argument)), argument: Rc::new(self.named_debruijn_to_debruijn(argument)),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.named_debruijn_to_debruijn(*term))), Term::Force(term) => Term::Force(Rc::new(self.named_debruijn_to_debruijn(term))),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
} }
} }
pub fn debruijn_to_named_debruijn(&mut self, term: Term<DeBruijn>) -> Term<NamedDeBruijn> { pub fn debruijn_to_named_debruijn(&mut self, term: &Term<DeBruijn>) -> Term<NamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.into()), Term::Var(name) => Term::Var((*name).into()),
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_named_debruijn(*term))), Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_named_debruijn(term))),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.into(), parameter_name: (*parameter_name).into(),
body: Box::new(self.debruijn_to_named_debruijn(*body)), body: Rc::new(self.debruijn_to_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.debruijn_to_named_debruijn(*function)), function: Rc::new(self.debruijn_to_named_debruijn(function)),
argument: Box::new(self.debruijn_to_named_debruijn(*argument)), argument: Rc::new(self.debruijn_to_named_debruijn(argument)),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => Term::Force(Box::new(self.debruijn_to_named_debruijn(*term))), Term::Force(term) => Term::Force(Rc::new(self.debruijn_to_named_debruijn(term))),
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
} }
} }
pub fn fake_named_debruijn_to_named_debruijn( pub fn fake_named_debruijn_to_named_debruijn(
&mut self, &mut self,
term: Term<FakeNamedDeBruijn>, term: &Term<FakeNamedDeBruijn>,
) -> Term<NamedDeBruijn> { ) -> Term<NamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.into()), Term::Var(name) => Term::Var(name.clone().into()),
Term::Delay(term) => { Term::Delay(term) => {
Term::Delay(Box::new(self.fake_named_debruijn_to_named_debruijn(*term))) Term::Delay(Rc::new(self.fake_named_debruijn_to_named_debruijn(term)))
} }
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.into(), parameter_name: parameter_name.clone().into(),
body: Box::new(self.fake_named_debruijn_to_named_debruijn(*body)), body: Rc::new(self.fake_named_debruijn_to_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.fake_named_debruijn_to_named_debruijn(*function)), function: Rc::new(self.fake_named_debruijn_to_named_debruijn(function)),
argument: Box::new(self.fake_named_debruijn_to_named_debruijn(*argument)), argument: Rc::new(self.fake_named_debruijn_to_named_debruijn(argument)),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => { Term::Force(term) => {
Term::Force(Box::new(self.fake_named_debruijn_to_named_debruijn(*term))) Term::Force(Rc::new(self.fake_named_debruijn_to_named_debruijn(term)))
} }
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
} }
} }
pub fn named_debruijn_to_fake_named_debruijn( pub fn named_debruijn_to_fake_named_debruijn(
&mut self, &mut self,
term: Term<NamedDeBruijn>, term: &Term<NamedDeBruijn>,
) -> Term<FakeNamedDeBruijn> { ) -> Term<FakeNamedDeBruijn> {
match term { match term {
Term::Var(name) => Term::Var(name.into()), Term::Var(name) => Term::Var(name.clone().into()),
Term::Delay(term) => { Term::Delay(term) => {
Term::Delay(Box::new(self.named_debruijn_to_fake_named_debruijn(*term))) Term::Delay(Rc::new(self.named_debruijn_to_fake_named_debruijn(term)))
} }
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Term::Lambda {
parameter_name: parameter_name.into(), parameter_name: parameter_name.clone().into(),
body: Box::new(self.named_debruijn_to_fake_named_debruijn(*body)), body: Rc::new(self.named_debruijn_to_fake_named_debruijn(body)),
}, },
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Term::Apply {
function: Box::new(self.named_debruijn_to_fake_named_debruijn(*function)), function: Rc::new(self.named_debruijn_to_fake_named_debruijn(function)),
argument: Box::new(self.named_debruijn_to_fake_named_debruijn(*argument)), argument: Rc::new(self.named_debruijn_to_fake_named_debruijn(argument)),
}, },
Term::Constant(constant) => Term::Constant(constant), Term::Constant(constant) => Term::Constant(constant.clone()),
Term::Force(term) => { Term::Force(term) => {
Term::Force(Box::new(self.named_debruijn_to_fake_named_debruijn(*term))) Term::Force(Rc::new(self.named_debruijn_to_fake_named_debruijn(term)))
} }
Term::Error => Term::Error, Term::Error => Term::Error,
Term::Builtin(builtin) => Term::Builtin(builtin), Term::Builtin(builtin) => Term::Builtin(*builtin),
} }
} }

View File

@ -1,4 +1,4 @@
use std::{collections::VecDeque, fmt::Debug}; use std::{collections::VecDeque, fmt::Debug, rc::Rc};
use flat_rs::{ use flat_rs::{
de::{self, Decode, Decoder}, de::{self, Decode, Decoder},
@ -164,18 +164,18 @@ where
fn decode(d: &mut Decoder) -> Result<Self, de::Error> { fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
match decode_term_tag(d)? { match decode_term_tag(d)? {
0 => Ok(Term::Var(T::decode(d)?)), 0 => Ok(Term::Var(T::decode(d)?)),
1 => Ok(Term::Delay(Box::new(Term::decode(d)?))), 1 => Ok(Term::Delay(Rc::new(Term::decode(d)?))),
2 => Ok(Term::Lambda { 2 => Ok(Term::Lambda {
parameter_name: T::binder_decode(d)?, parameter_name: T::binder_decode(d)?,
body: Box::new(Term::decode(d)?), body: Rc::new(Term::decode(d)?),
}), }),
3 => Ok(Term::Apply { 3 => Ok(Term::Apply {
function: Box::new(Term::decode(d)?), function: Rc::new(Term::decode(d)?),
argument: Box::new(Term::decode(d)?), argument: Rc::new(Term::decode(d)?),
}), }),
// Need size limit for Constant // Need size limit for Constant
4 => Ok(Term::Constant(Constant::decode(d)?)), 4 => Ok(Term::Constant(Constant::decode(d)?)),
5 => Ok(Term::Force(Box::new(Term::decode(d)?))), 5 => Ok(Term::Force(Rc::new(Term::decode(d)?))),
6 => Ok(Term::Error), 6 => Ok(Term::Error),
7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)), 7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)),
x => Err(de::Error::Message(format!( x => Err(de::Error::Message(format!(

View File

@ -16,8 +16,8 @@ use self::{cost_model::CostModel, runtime::BuiltinRuntime};
enum MachineStep { enum MachineStep {
Return(Rc<Context>, Value), Return(Rc<Context>, Value),
Compute(Rc<Context>, Vec<Value>, Term<NamedDeBruijn>), Compute(Rc<Context>, Rc<Vec<Value>>, Rc<Term<NamedDeBruijn>>),
Done(Term<NamedDeBruijn>), Done(Rc<Term<NamedDeBruijn>>),
} }
impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> { impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> {
@ -25,7 +25,7 @@ impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> {
fn try_from(value: Option<MachineStep>) -> Result<Self, Error> { fn try_from(value: Option<MachineStep>) -> Result<Self, Error> {
match value { match value {
Some(MachineStep::Done(term)) => Ok(term), Some(MachineStep::Done(term)) => Ok(Rc::as_ref(&term).clone()),
_ => Err(Error::MachineNeverReachedDone), _ => Err(Error::MachineNeverReachedDone),
} }
} }
@ -59,8 +59,11 @@ impl Machine {
self.spend_budget(startup_budget)?; self.spend_budget(startup_budget)?;
self.stack self.stack.push(Compute(
.push(Compute(Rc::new(Context::NoFrame), vec![], term.clone())); Rc::new(Context::NoFrame),
Rc::new(vec![]),
Rc::new(term.clone()),
));
while let Some(step) = self.stack.pop() { while let Some(step) = self.stack.pop() {
match step { match step {
@ -84,10 +87,10 @@ impl Machine {
fn compute( fn compute(
&mut self, &mut self,
context: Rc<Context>, context: Rc<Context>,
env: Vec<Value>, env: Rc<Vec<Value>>,
term: Term<NamedDeBruijn>, term: Rc<Term<NamedDeBruijn>>,
) -> Result<(), Error> { ) -> Result<(), Error> {
match term { match term.as_ref() {
Term::Var(name) => { Term::Var(name) => {
self.step_and_maybe_spend(StepKind::Var)?; self.step_and_maybe_spend(StepKind::Var)?;
@ -98,8 +101,10 @@ impl Machine {
Term::Delay(body) => { Term::Delay(body) => {
self.step_and_maybe_spend(StepKind::Delay)?; self.step_and_maybe_spend(StepKind::Delay)?;
self.stack self.stack.push(MachineStep::Return(
.push(MachineStep::Return(context, Value::Delay(*body, env))); context,
Value::Delay(Rc::clone(body), env),
));
} }
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
@ -110,8 +115,8 @@ impl Machine {
self.stack.push(MachineStep::Return( self.stack.push(MachineStep::Return(
context, context,
Value::Lambda { Value::Lambda {
parameter_name, parameter_name: parameter_name.clone(),
body: *body, body: Rc::clone(body),
env, env,
}, },
)); ));
@ -120,15 +125,20 @@ impl Machine {
self.step_and_maybe_spend(StepKind::Apply)?; self.step_and_maybe_spend(StepKind::Apply)?;
self.stack.push(MachineStep::Compute( self.stack.push(MachineStep::Compute(
Rc::new(Context::FrameApplyArg(env.clone(), *argument, context)), Rc::new(Context::FrameApplyArg(
Rc::clone(&env),
Rc::clone(argument),
context,
)),
env, env,
*function, Rc::clone(function),
)); ));
} }
Term::Constant(x) => { Term::Constant(x) => {
self.step_and_maybe_spend(StepKind::Constant)?; self.step_and_maybe_spend(StepKind::Constant)?;
self.stack.push(MachineStep::Return(context, Value::Con(x))); self.stack
.push(MachineStep::Return(context, Value::Con(x.clone())));
} }
Term::Force(body) => { Term::Force(body) => {
self.step_and_maybe_spend(StepKind::Force)?; self.step_and_maybe_spend(StepKind::Force)?;
@ -136,18 +146,22 @@ impl Machine {
self.stack.push(MachineStep::Compute( self.stack.push(MachineStep::Compute(
Rc::new(Context::FrameForce(context)), Rc::new(Context::FrameForce(context)),
env, env,
*body, Rc::clone(body),
)); ));
} }
Term::Error => return Err(Error::EvaluationFailure), Term::Error => return Err(Error::EvaluationFailure),
Term::Builtin(fun) => { Term::Builtin(fun) => {
self.step_and_maybe_spend(StepKind::Builtin)?; self.step_and_maybe_spend(StepKind::Builtin)?;
let runtime: BuiltinRuntime = (fun).into(); let runtime: BuiltinRuntime = (*fun).into();
self.stack.push(MachineStep::Return( self.stack.push(MachineStep::Return(
context, context,
Value::Builtin { fun, term, runtime }, Value::Builtin {
fun: *fun,
term,
runtime,
},
)); ));
} }
}; };
@ -164,7 +178,7 @@ impl Machine {
self.stack.push(MachineStep::Compute( self.stack.push(MachineStep::Compute(
Rc::new(Context::FrameApplyFun(value, ctx.to_owned())), Rc::new(Context::FrameApplyFun(value, ctx.to_owned())),
arg_var_env.to_owned(), arg_var_env.to_owned(),
arg.to_owned(), Rc::clone(arg),
)); ));
} }
Context::FrameForce(ctx) => self.force_evaluate(ctx.to_owned(), value)?, Context::FrameForce(ctx) => self.force_evaluate(ctx.to_owned(), value)?,
@ -182,68 +196,70 @@ impl Machine {
Ok(()) Ok(())
} }
fn discharge_value(&mut self, value: Value) -> Term<NamedDeBruijn> { fn discharge_value(&mut self, value: Value) -> Rc<Term<NamedDeBruijn>> {
match value { match value {
Value::Con(x) => Term::Constant(x), Value::Con(x) => Rc::new(Term::Constant(x)),
Value::Builtin { term, .. } => term, Value::Builtin { term, .. } => term,
Value::Delay(body, env) => self.discharge_value_env(env, Term::Delay(Box::new(body))), Value::Delay(body, env) => self.discharge_value_env(env, Rc::new(Term::Delay(body))),
Value::Lambda { Value::Lambda {
parameter_name, parameter_name,
body, body,
env, env,
} => self.discharge_value_env( } => self.discharge_value_env(
env, env,
Term::Lambda { Rc::new(Term::Lambda {
parameter_name: NamedDeBruijn { parameter_name: NamedDeBruijn {
text: parameter_name.text, text: parameter_name.text,
index: 0.into(), index: 0.into(),
}, },
body: Box::new(body), body,
}, }),
), ),
} }
} }
fn discharge_value_env( fn discharge_value_env(
&mut self, &mut self,
env: Vec<Value>, env: Rc<Vec<Value>>,
term: Term<NamedDeBruijn>, term: Rc<Term<NamedDeBruijn>>,
) -> Term<NamedDeBruijn> { ) -> Rc<Term<NamedDeBruijn>> {
fn rec( fn rec(
lam_cnt: usize, lam_cnt: usize,
t: Term<NamedDeBruijn>, t: Rc<Term<NamedDeBruijn>>,
this: &mut Machine, this: &mut Machine,
env: &[Value], env: Rc<Vec<Value>>,
) -> Term<NamedDeBruijn> { ) -> Rc<Term<NamedDeBruijn>> {
match t { match t.as_ref() {
Term::Var(name) => { Term::Var(name) => {
let index: usize = name.index.into(); let index: usize = name.index.into();
if lam_cnt >= index { if lam_cnt >= index {
Term::Var(name) Rc::new(Term::Var(name.clone()))
} else { } else {
env.get::<usize>(env.len() - (index - lam_cnt)) env.get::<usize>(env.len() - (index - lam_cnt))
.cloned() .cloned()
.map_or(Term::Var(name), |v| this.discharge_value(v)) .map_or(Rc::new(Term::Var(name.clone())), |v| {
this.discharge_value(v)
})
} }
} }
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => Term::Lambda { } => Rc::new(Term::Lambda {
parameter_name, parameter_name: parameter_name.clone(),
body: Box::new(rec(lam_cnt + 1, *body, this, env)), body: rec(lam_cnt + 1, Rc::clone(body), this, env),
}, }),
Term::Apply { function, argument } => Term::Apply { Term::Apply { function, argument } => Rc::new(Term::Apply {
function: Box::new(rec(lam_cnt, *function, this, env)), function: rec(lam_cnt, Rc::clone(function), this, Rc::clone(&env)),
argument: Box::new(rec(lam_cnt, *argument, this, env)), argument: rec(lam_cnt, Rc::clone(argument), this, env),
}, }),
Term::Delay(x) => Term::Delay(Box::new(rec(lam_cnt, *x, this, env))), Term::Delay(x) => Rc::new(Term::Delay(rec(lam_cnt, Rc::clone(x), this, env))),
Term::Force(x) => Term::Force(Box::new(rec(lam_cnt, *x, this, env))), Term::Force(x) => Rc::new(Term::Force(rec(lam_cnt, Rc::clone(x), this, env))),
rest => rest, rest => Rc::new(rest.clone()),
} }
} }
rec(0, term, self, &env) rec(0, term, self, env)
} }
fn force_evaluate(&mut self, context: Rc<Context>, value: Value) -> Result<(), Error> { fn force_evaluate(&mut self, context: Rc<Context>, value: Value) -> Result<(), Error> {
@ -258,7 +274,7 @@ impl Machine {
term, term,
mut runtime, mut runtime,
} => { } => {
let force_term = Term::Force(Box::new(term)); let force_term = Rc::new(Term::Force(term));
if runtime.needs_force() { if runtime.needs_force() {
runtime.consume_force(); runtime.consume_force();
@ -269,7 +285,9 @@ impl Machine {
Ok(()) Ok(())
} else { } else {
Err(Error::BuiltinTermArgumentExpected(force_term)) Err(Error::BuiltinTermArgumentExpected(
force_term.as_ref().clone(),
))
} }
} }
rest => Err(Error::NonPolymorphicInstantiation(rest)), rest => Err(Error::NonPolymorphicInstantiation(rest)),
@ -283,12 +301,13 @@ impl Machine {
argument: Value, argument: Value,
) -> Result<(), Error> { ) -> Result<(), Error> {
match function { match function {
Value::Lambda { body, env, .. } => { Value::Lambda { body, mut env, .. } => {
let mut e = env; let e = Rc::make_mut(&mut env);
e.push(argument); e.push(argument);
self.stack.push(MachineStep::Compute(context, e, body)); self.stack
.push(MachineStep::Compute(context, Rc::new(e.clone()), body));
Ok(()) Ok(())
} }
@ -299,10 +318,10 @@ impl Machine {
} => { } => {
let arg_term = self.discharge_value(argument.clone()); let arg_term = self.discharge_value(argument.clone());
let t = Term::<NamedDeBruijn>::Apply { let t = Rc::new(Term::<NamedDeBruijn>::Apply {
function: Box::new(term), function: term,
argument: Box::new(arg_term), argument: arg_term,
}; });
if runtime.is_arrow() && !runtime.needs_force() { if runtime.is_arrow() && !runtime.needs_force() {
runtime.push(argument)?; runtime.push(argument)?;
@ -313,7 +332,7 @@ impl Machine {
Ok(()) Ok(())
} else { } else {
Err(Error::UnexpectedBuiltinTermArgument(t)) Err(Error::UnexpectedBuiltinTermArgument(t.as_ref().clone()))
} }
} }
rest => Err(Error::NonFunctionalApplication(rest)), rest => Err(Error::NonFunctionalApplication(rest)),
@ -323,7 +342,7 @@ impl Machine {
fn eval_builtin_app( fn eval_builtin_app(
&mut self, &mut self,
fun: DefaultFunction, fun: DefaultFunction,
term: Term<NamedDeBruijn>, term: Rc<Term<NamedDeBruijn>>,
runtime: BuiltinRuntime, runtime: BuiltinRuntime,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
if runtime.is_ready() { if runtime.is_ready() {
@ -337,10 +356,10 @@ impl Machine {
} }
} }
fn lookup_var(&mut self, name: NamedDeBruijn, env: Vec<Value>) -> Result<Value, Error> { fn lookup_var(&mut self, name: &NamedDeBruijn, env: Rc<Vec<Value>>) -> Result<Value, Error> {
env.get::<usize>(env.len() - usize::from(name.index)) env.get::<usize>(env.len() - usize::from(name.index))
.cloned() .cloned()
.ok_or(Error::OpenTermEvaluated(Term::Var(name))) .ok_or_else(|| Error::OpenTermEvaluated(Term::Var(name.clone())))
} }
fn step_and_maybe_spend(&mut self, step: StepKind) -> Result<(), Error> { fn step_and_maybe_spend(&mut self, step: StepKind) -> Result<(), Error> {
@ -387,7 +406,7 @@ impl Machine {
#[derive(Clone)] #[derive(Clone)]
enum Context { enum Context {
FrameApplyFun(Value, Rc<Context>), FrameApplyFun(Value, Rc<Context>),
FrameApplyArg(Vec<Value>, Term<NamedDeBruijn>, Rc<Context>), FrameApplyArg(Rc<Vec<Value>>, Rc<Term<NamedDeBruijn>>, Rc<Context>),
FrameForce(Rc<Context>), FrameForce(Rc<Context>),
NoFrame, NoFrame,
} }
@ -395,15 +414,15 @@ enum Context {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Value { pub enum Value {
Con(Constant), Con(Constant),
Delay(Term<NamedDeBruijn>, Vec<Value>), Delay(Rc<Term<NamedDeBruijn>>, Rc<Vec<Value>>),
Lambda { Lambda {
parameter_name: NamedDeBruijn, parameter_name: NamedDeBruijn,
body: Term<NamedDeBruijn>, body: Rc<Term<NamedDeBruijn>>,
env: Vec<Value>, env: Rc<Vec<Value>>,
}, },
Builtin { Builtin {
fun: DefaultFunction, fun: DefaultFunction,
term: Term<NamedDeBruijn>, term: Rc<Term<NamedDeBruijn>>,
runtime: BuiltinRuntime, runtime: BuiltinRuntime,
}, },
} }

View File

@ -19,8 +19,8 @@ impl ExBudget {
impl Default for ExBudget { impl Default for ExBudget {
fn default() -> Self { fn default() -> Self {
ExBudget { ExBudget {
mem: 14000000, mem: 14000000000000,
cpu: 10000000000, cpu: 10000000000000000,
} }
} }
} }

View File

@ -1,4 +1,4 @@
use std::str::FromStr; use std::{rc::Rc, str::FromStr};
use crate::{ use crate::{
ast::{Constant, Name, Program, Term}, ast::{Constant, Name, Program, Term},
@ -67,7 +67,7 @@ peg::parser! {
rule lambda() -> Term<Name> rule lambda() -> Term<Name>
= "(" _* "lam" _+ parameter_name:name() _+ t:term() _* ")" { = "(" _* "lam" _+ parameter_name:name() _+ t:term() _* ")" {
Term::Lambda { parameter_name, body: Box::new(t) } Term::Lambda { parameter_name, body: Rc::new(t) }
} }
#[cache_left_rec] #[cache_left_rec]
@ -76,16 +76,16 @@ peg::parser! {
terms terms
.into_iter() .into_iter()
.fold(initial, |lhs, rhs| Term::Apply { .fold(initial, |lhs, rhs| Term::Apply {
function: Box::new(lhs), function: Rc::new(lhs),
argument: Box::new(rhs) argument: Rc::new(rhs)
}) })
} }
rule delay() -> Term<Name> rule delay() -> Term<Name>
= "(" _* "delay" _* t:term() _* ")" { Term::Delay(Box::new(t)) } = "(" _* "delay" _* t:term() _* ")" { Term::Delay(Rc::new(t)) }
rule force() -> Term<Name> rule force() -> Term<Name>
= "(" _* "force" _* t:term() _* ")" { Term::Force(Box::new(t)) } = "(" _* "force" _* t:term() _* ")" { Term::Force(Rc::new(t)) }
rule error() -> Term<Name> rule error() -> Term<Name>
= "(" _* "error" _* ")" { Term::Error } = "(" _* "error" _* ")" { Term::Error }

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use std::{collections::HashMap, rc::Rc};
use crate::ast::{Name, Program, Term, Unique}; use crate::ast::{Name, Program, Term, Unique};
@ -22,20 +22,20 @@ impl Interner {
pub fn term(&mut self, term: &mut Term<Name>) { pub fn term(&mut self, term: &mut Term<Name>) {
match term { match term {
Term::Var(name) => name.unique = self.intern(&name.text), Term::Var(name) => name.unique = self.intern(&name.text),
Term::Delay(term) => self.term(term), Term::Delay(term) => self.term(Rc::make_mut(term)),
Term::Lambda { Term::Lambda {
parameter_name, parameter_name,
body, body,
} => { } => {
parameter_name.unique = self.intern(&parameter_name.text); parameter_name.unique = self.intern(&parameter_name.text);
self.term(body); self.term(Rc::make_mut(body));
} }
Term::Apply { function, argument } => { Term::Apply { function, argument } => {
self.term(function); self.term(Rc::make_mut(function));
self.term(argument); self.term(Rc::make_mut(argument));
} }
Term::Constant(_) => (), Term::Constant(_) => (),
Term::Force(term) => self.term(term), Term::Force(term) => self.term(Rc::make_mut(term)),
Term::Error => (), Term::Error => (),
Term::Builtin(_) => (), Term::Builtin(_) => (),
} }

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use crate::ast::{Name, Term}; use crate::ast::{Name, Term};
use crate::program_builder::WithTerm; use crate::program_builder::WithTerm;
@ -30,8 +32,8 @@ impl<T: WithTerm> WithTerm for ApplyBuilderArgument<T> {
fn next(self, term: Term<Name>) -> Self::Next { fn next(self, term: Term<Name>) -> Self::Next {
let term = Term::Apply { let term = Term::Apply {
function: Box::new(self.function), function: Rc::new(self.function),
argument: Box::new(term), argument: Rc::new(term),
}; };
self.outer.next(term) self.outer.next(term)
} }

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use crate::ast::{Name, Term}; use crate::ast::{Name, Term};
use crate::program_builder::WithTerm; use crate::program_builder::WithTerm;
@ -9,7 +11,7 @@ impl<T: WithTerm> WithTerm for DelayBuilder<T> {
type Next = T::Next; type Next = T::Next;
fn next(self, term: Term<Name>) -> Self::Next { fn next(self, term: Term<Name>) -> Self::Next {
let term = Term::Delay(Box::new(term)); let term = Term::Delay(Rc::new(term));
self.outer.next(term) self.outer.next(term)
} }

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use crate::ast::{Name, Term}; use crate::ast::{Name, Term};
use crate::program_builder::WithTerm; use crate::program_builder::WithTerm;
@ -9,7 +11,7 @@ impl<T: WithTerm> WithTerm for ForceBuilder<T> {
type Next = T::Next; type Next = T::Next;
fn next(self, term: Term<Name>) -> Self::Next { fn next(self, term: Term<Name>) -> Self::Next {
let term = Term::Force(Box::new(term)); let term = Term::Force(Rc::new(term));
self.outer.next(term) self.outer.next(term)
} }

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use crate::ast::{Name, Term}; use crate::ast::{Name, Term};
use crate::program_builder::WithTerm; use crate::program_builder::WithTerm;
@ -12,7 +14,7 @@ impl<T: WithTerm> WithTerm for LambdaBuilder<T> {
fn next(self, term: Term<Name>) -> Self::Next { fn next(self, term: Term<Name>) -> Self::Next {
let term = Term::Lambda { let term = Term::Lambda {
parameter_name: self.parameter_name, parameter_name: self.parameter_name,
body: Box::new(term), body: Rc::new(term),
}; };
self.outer.next(term) self.outer.next(term)
} }