From 0b7d217bd026be85326db1f2ad65f3f6a7698db7 Mon Sep 17 00:00:00 2001 From: microproofs Date: Wed, 19 Apr 2023 22:25:55 -0400 Subject: [PATCH] convert acceptance test 8 --- crates/aiken-project/src/tests/gen_uplc.rs | 32 +++++++++++++++ crates/uplc/src/builder.rs | 4 ++ crates/uplc/src/optimize.rs | 7 ++-- crates/uplc/src/optimize/shrinker.rs | 47 +++++++++++++++++++++- 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index c259ed7c..bb3b8be4 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -696,3 +696,35 @@ fn acceptance_test_7_unzip() { )), ); } + +#[test] +fn acceptance_test_8_is_empty() { + let src = r#" + use aiken/builtin + + pub fn is_empty(bytes: ByteArray) -> Bool { + builtin.length_of_bytearray(bytes) == 0 + } + + test is_empty_1() { + is_empty(#"") == True + } + "#; + + assert_uplc( + src, + Term::var("is_empty") + .lambda("is_empty") + .apply( + Term::equals_integer() + .apply(Term::length_of_bytearray().apply(Term::var("bytes"))) + .apply(Term::integer(0.into())) + .lambda("bytes"), + ) + .apply(Term::byte_string(vec![])) + .delayed_if_else( + Term::bool(true), + Term::bool(true).if_else(Term::bool(false), Term::bool(true)), + ), + ); +} diff --git a/crates/uplc/src/builder.rs b/crates/uplc/src/builder.rs index 5c22c8ae..b24e0280 100644 --- a/crates/uplc/src/builder.rs +++ b/crates/uplc/src/builder.rs @@ -135,6 +135,10 @@ impl Term { Term::Builtin(DefaultFunction::SubtractInteger) } + pub fn length_of_bytearray() -> Self { + Term::Builtin(DefaultFunction::LengthOfByteString) + } + pub fn head_list() -> Self { Term::Builtin(DefaultFunction::HeadList).force() } diff --git a/crates/uplc/src/optimize.rs b/crates/uplc/src/optimize.rs index e660d1d5..307d30aa 100644 --- a/crates/uplc/src/optimize.rs +++ b/crates/uplc/src/optimize.rs @@ -19,11 +19,12 @@ pub fn aiken_optimize_and_intern(program: Program) -> Program { program .lambda_reduce() - .inline_reduce() + .inline_basic_reduce() .lambda_reduce() - .inline_reduce() + .inline_basic_reduce() .force_delay_reduce() .wrap_data_reduce() .lambda_reduce() - .inline_reduce() + .inline_basic_reduce() + .inline_direct_reduce() } diff --git a/crates/uplc/src/optimize/shrinker.rs b/crates/uplc/src/optimize/shrinker.rs index a5873ee6..60b95586 100644 --- a/crates/uplc/src/optimize/shrinker.rs +++ b/crates/uplc/src/optimize/shrinker.rs @@ -47,9 +47,20 @@ impl Program { } } - pub fn inline_reduce(self) -> Program { + pub fn inline_basic_reduce(self) -> Program { let mut term = self.term; inline_basic_reduce(&mut term); + + Program { + version: self.version, + term, + } + } + + pub fn inline_direct_reduce(self) -> Program { + let mut term = self.term; + inline_direct_reduce(&mut term); + Program { version: self.version, term, @@ -160,6 +171,40 @@ fn force_delay_reduce(term: &mut Term) { } } +fn inline_direct_reduce(term: &mut Term) { + match term { + Term::Delay(d) => { + let d = Rc::make_mut(d); + inline_direct_reduce(d); + } + Term::Lambda { + parameter_name, + body, + } => { + let body = Rc::make_mut(body); + inline_direct_reduce(body); + + if let Term::Var(name) = body { + if name.as_ref() == parameter_name.as_ref() { + *term = body.clone(); + } + } + } + Term::Apply { function, argument } => { + let func = Rc::make_mut(function); + let arg = Rc::make_mut(argument); + inline_direct_reduce(func); + + inline_direct_reduce(arg); + } + Term::Force(f) => { + let f = Rc::make_mut(f); + inline_direct_reduce(f); + } + _ => {} + } +} + fn inline_basic_reduce(term: &mut Term) { match term { Term::Delay(d) => {