diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 4dbcf578..c828994c 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -3786,10 +3786,25 @@ impl<'a> CodeGenerator<'a> { let fields = Term::empty_list(); - let term = Term::constr_data() + let mut term = Term::constr_data() .apply(Term::integer(constr_index.try_into().unwrap())) .apply(fields); + let mut program: Program = Program { + version: (1, 0, 0), + term, + }; + + let mut interner = Interner::new(); + + interner.program(&mut program); + + let eval_program: Program = program.try_into().unwrap(); + + let evaluated_term: Term = + eval_program.eval(ExBudget::default()).result().unwrap(); + term = evaluated_term.try_into().unwrap(); + arg_stack.push(term); } } diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index a7b534ca..5bf10a8c 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -193,7 +193,7 @@ mod test { use uplc::{ ast::{self as uplc_ast, Constant, Name}, machine::cost_model::ExBudget, - optimize, BigInt, PlutusData, + optimize, BigInt, Constr, PlutusData, }; use super::{ @@ -368,11 +368,8 @@ mod test { term: expected, }; - println!("EXP BEFORE {}", expected.to_pretty()); - let expected = optimize::aiken_optimize_and_intern(expected); - println!("EXP AFTER {}", expected.to_pretty()); let expected: Program = expected.try_into().unwrap(); assert_eq!(debruijn_program.to_pretty(), expected.to_pretty()); @@ -804,6 +801,65 @@ mod test { ); } + #[test] + fn acceptance_test_5_head_not_empty() { + let src = r#" + use aiken/builtin.{head_list} + + pub fn head(xs: List) -> Option { + when xs is { + [] -> None + _ -> Some(head_list(xs)) + } + } + + test head_1() { + head([1, 2, 3]) == Some(1) + } + "#; + + assert_uplc( + src, + Term::equals_data() + .apply( + Term::var("head") + .lambda("head") + .apply( + Term::var("xs") + .delayed_choose_list( + Term::Constant( + Constant::Data(PlutusData::Constr(Constr { + tag: 122, + any_constructor: None, + fields: vec![], + })) + .into(), + ), + Term::constr_data().apply(Term::integer(0.into())).apply( + Term::mk_cons() + .apply(Term::head_list().apply(Term::var("xs"))) + .apply(Term::empty_list()), + ), + ) + .lambda("xs"), + ) + .apply(Term::list_values(vec![ + Constant::Data(PlutusData::BigInt(BigInt::Int(1.into()))), + Constant::Data(PlutusData::BigInt(BigInt::Int(2.into()))), + Constant::Data(PlutusData::BigInt(BigInt::Int(3.into()))), + ])), + ) + .apply(Term::Constant( + Constant::Data(PlutusData::Constr(Constr { + tag: 121, + any_constructor: None, + fields: vec![PlutusData::BigInt(BigInt::Int(1.into()))], + })) + .into(), + )), + ); + } + #[test] fn mint_parameterized() { assert_validator( diff --git a/crates/uplc/src/optimize/shrinker.rs b/crates/uplc/src/optimize/shrinker.rs index f1299271..a5873ee6 100644 --- a/crates/uplc/src/optimize/shrinker.rs +++ b/crates/uplc/src/optimize/shrinker.rs @@ -236,46 +236,20 @@ fn wrap_data_reduce(term: &mut Term) { return; }; + wrap_data_reduce(Rc::make_mut(inner_arg)); + match (first_action, second_action) { - (DefaultFunction::UnIData, DefaultFunction::IData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::IData, DefaultFunction::UnIData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::BData, DefaultFunction::UnBData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::UnBData, DefaultFunction::BData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::ListData, DefaultFunction::UnListData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::UnListData, DefaultFunction::ListData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::MapData, DefaultFunction::UnMapData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::UnMapData, DefaultFunction::MapData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::UnConstrData, DefaultFunction::ConstrData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); - } - (DefaultFunction::ConstrData, DefaultFunction::UnConstrData) => { - *term = argument.as_ref().clone(); - wrap_data_reduce(term); + (DefaultFunction::UnIData, DefaultFunction::IData) + | (DefaultFunction::IData, DefaultFunction::UnIData) + | (DefaultFunction::BData, DefaultFunction::UnBData) + | (DefaultFunction::UnBData, DefaultFunction::BData) + | (DefaultFunction::ListData, DefaultFunction::UnListData) + | (DefaultFunction::UnListData, DefaultFunction::ListData) + | (DefaultFunction::MapData, DefaultFunction::UnMapData) + | (DefaultFunction::UnMapData, DefaultFunction::MapData) + | (DefaultFunction::UnConstrData, DefaultFunction::ConstrData) + | (DefaultFunction::ConstrData, DefaultFunction::UnConstrData) => { + *term = inner_arg.as_ref().clone(); } _ => {} } diff --git a/examples/acceptance_tests/005/lib/tests.ak b/examples/acceptance_tests/005/lib/tests.ak index a9d723ad..ce9644a7 100644 --- a/examples/acceptance_tests/005/lib/tests.ak +++ b/examples/acceptance_tests/005/lib/tests.ak @@ -2,10 +2,8 @@ use aiken/builtin.{head_list} pub fn head(xs: List) -> Option { when xs is { - [] -> - None - _ -> - Some(head_list(xs)) + [] -> None + _ -> Some(head_list(xs)) } }