You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.8 KiB
94 lines
2.8 KiB
use std::{collections::HashMap, rc::Rc};
|
|
|
|
use crate::{
|
|
exec::{DeBrujinAst as DBAst, builtin_definitions::AddOp},
|
|
parse::{Ast, Constant},
|
|
types::{PrimitiveType, Type},
|
|
};
|
|
|
|
use super::builtins::Builtin;
|
|
|
|
#[test]
|
|
fn to_de_brujin_ast_simple() {
|
|
let input = Ast::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::Primitive(PrimitiveType::Nat).into()),
|
|
Box::new(Ast::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::Primitive(PrimitiveType::Nat).into()),
|
|
Box::new(Ast::Variable("x".to_string())),
|
|
)),
|
|
);
|
|
let de_brujin: DBAst = input.into();
|
|
assert_eq!(
|
|
de_brujin,
|
|
DBAst::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::Primitive(PrimitiveType::Nat).into()),
|
|
Box::new(DBAst::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::Primitive(PrimitiveType::Nat).into()),
|
|
Box::new(DBAst::BoundVariable(1))
|
|
))
|
|
)
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn de_brujin_beta_reduce() {
|
|
let input = Ast::Application(
|
|
Box::new(Ast::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::arrow(PrimitiveType::Nat, PrimitiveType::Nat).into()),
|
|
Box::new(Ast::Application(
|
|
Box::new(Ast::Variable("x".to_string())),
|
|
Box::new(Ast::Constant(Constant::Nat(5))),
|
|
)),
|
|
)),
|
|
Box::new(Ast::Variable("y".to_string())),
|
|
);
|
|
let dbast: DBAst = input.into();
|
|
let reduced = dbast.beta_reduce();
|
|
assert_eq!(
|
|
reduced,
|
|
DBAst::Application(
|
|
Box::new(DBAst::FreeVariable("y".to_string())),
|
|
Box::new(DBAst::Constant(Constant::Nat(5))),
|
|
),
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn to_and_from_de_brujin_is_id() {
|
|
let input = Ast::Application(
|
|
Box::new(Ast::Abstraction(
|
|
"x".to_string(),
|
|
Some(Type::arrow(PrimitiveType::Nat, PrimitiveType::Nat).into()),
|
|
Box::new(Ast::Application(
|
|
Box::new(Ast::Variable("x".to_string())),
|
|
Box::new(Ast::Constant(Constant::Nat(5))),
|
|
)),
|
|
)),
|
|
Box::new(Ast::Variable("y".to_string())),
|
|
);
|
|
let dbast: DBAst = input.clone().into();
|
|
let output: Ast = dbast.into();
|
|
assert_eq!(input, output);
|
|
}
|
|
|
|
#[test]
|
|
fn reduce_add() {
|
|
let input: DBAst = Ast::Application(
|
|
Box::new(Ast::Application(
|
|
Box::new(Ast::Variable("add".to_string())),
|
|
Box::new(Ast::Constant(Constant::Nat(5))),
|
|
)),
|
|
Box::new(Ast::Constant(Constant::Nat(5))),
|
|
)
|
|
.into();
|
|
let mut builtins: HashMap<String, Rc<dyn Builtin>> = HashMap::new();
|
|
builtins.insert("add".to_string(), Rc::new(AddOp));
|
|
let output = input.reduce_builtins(&builtins);
|
|
assert_eq!(output, DBAst::Constant(Constant::Nat(10)));
|
|
}
|