fix list clauses with guards and add more tests

This commit is contained in:
microproofs
2023-08-16 16:31:44 -04:00
committed by Kasey
parent f4d0f231d7
commit 2456801b17
5 changed files with 463 additions and 22 deletions

View File

@@ -4523,3 +4523,413 @@ fn list_clause_with_guard() {
false,
);
}
#[test]
fn list_clause_with_guard2() {
let src = r#"
fn do_init(self: List<Int>) -> List<Int> {
when self is {
[] -> fail @"unreachable"
[_] ->
[]
[a, x] -> {
[a]
}
[a] if a > 10 -> []
[a, b, ..c] -> {
c
}
}
}
test init_3() {
do_init([1, 3]) == [1]
}
"#;
assert_uplc(
src,
Term::equals_data()
.apply(
Term::list_data().apply(
Term::var("do_init")
.lambda("do_init")
.apply(
Term::var("self")
.delayed_choose_list(
Term::Error.trace(Term::string("unreachable")),
Term::var("tail_1")
.delayed_choose_list(
Term::empty_list(),
Term::var("tail_1")
.choose_list(
Term::var("clause_guard")
.if_else(
Term::empty_list().delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clause_guard")
.apply(
Term::less_than_integer()
.apply(Term::integer(10.into()))
.apply(Term::var("a")),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var("self")),
),
)
.delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clauses_delayed")
.apply(
Term::var("tail_2")
.delayed_choose_list(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("a")),
)
.apply(Term::empty_list())
.lambda("x")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("self"),
),
),
),
Term::var("c").lambda("c").apply(
Term::tail_list()
.apply(Term::var("tail_1"))
.lambda("b")
.apply(Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
))
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var(
"self",
)),
),
),
),
)
.lambda("tail_2")
.apply(
Term::tail_list()
.apply(Term::var("tail_1")),
)
.delay(),
),
)
.lambda("tail_1")
.apply(Term::tail_list().apply(Term::var("self"))),
)
.lambda("self"),
)
.apply(Term::list_values(vec![
Constant::Data(Data::integer(1.into())),
Constant::Data(Data::integer(3.into())),
])),
),
)
.apply(Term::data(Data::list(vec![Data::integer(1.into())]))),
false,
);
}
#[test]
fn list_clause_with_guard3() {
let src = r#"
fn do_init(self: List<Int>) -> List<Int> {
when self is {
[] -> fail @"unreachable"
[_] ->
[]
[a, x] -> {
[a]
}
[a, ..g] if a > 10 -> g
[a, b, ..c] -> {
c
}
}
}
test init_3() {
do_init([1, 3]) == [1]
}
"#;
assert_uplc(
src,
Term::equals_data()
.apply(
Term::list_data().apply(
Term::var("do_init")
.lambda("do_init")
.apply(
Term::var("self")
.delayed_choose_list(
Term::Error.trace(Term::string("unreachable")),
Term::var("tail_1")
.delayed_choose_list(
Term::empty_list(),
Term::var("self")
.choose_list(
Term::var("clause_guard")
.if_else(
Term::var("g").delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clause_guard")
.apply(
Term::less_than_integer()
.apply(Term::integer(10.into()))
.apply(Term::var("a")),
)
.lambda("g")
.apply(
Term::tail_list()
.apply(Term::var("self")),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var("self")),
),
)
.delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clauses_delayed")
.apply(
Term::var("tail_2")
.delayed_choose_list(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("a")),
)
.apply(Term::empty_list())
.lambda("x")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("self"),
),
),
),
Term::var("c").lambda("c").apply(
Term::tail_list()
.apply(Term::var("tail_1"))
.lambda("b")
.apply(Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
))
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var(
"self",
)),
),
),
),
)
.lambda("tail_2")
.apply(
Term::tail_list()
.apply(Term::var("tail_1")),
)
.delay(),
),
)
.lambda("tail_1")
.apply(Term::tail_list().apply(Term::var("self"))),
)
.lambda("self"),
)
.apply(Term::list_values(vec![
Constant::Data(Data::integer(1.into())),
Constant::Data(Data::integer(3.into())),
])),
),
)
.apply(Term::data(Data::list(vec![Data::integer(1.into())]))),
false,
);
}
#[test]
fn list_clause_with_assign() {
let src = r#"
fn do_init(self: List<Int>) -> List<Int> {
when self is {
[] -> fail @"unreachable"
[_] as a ->
a
[a, x] if x > 2 -> {
[a]
}
[a, x] -> {
[a]
}
[a, b, ..c] -> {
c
}
}
}
test init_3() {
do_init([1, 3]) == [1]
}
"#;
assert_uplc(
src,
Term::equals_data()
.apply(
Term::list_data().apply(
Term::var("do_init")
.lambda("do_init")
.apply(
Term::var("self")
.delayed_choose_list(
Term::Error.trace(Term::string("unreachable")),
Term::var("tail_1")
.delayed_choose_list(
Term::empty_list(),
Term::var("tail_2")
.choose_list(
Term::var("clause_guard")
.if_else(
Term::mk_cons()
.apply(
Term::i_data()
.apply(Term::var("a")),
)
.apply(Term::empty_list())
.delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clause_guard")
.apply(
Term::less_than_integer()
.apply(Term::integer(2.into()))
.apply(Term::var("x")),
)
.lambda("x")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var("tail_1")),
),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var("self")),
),
)
.delay(),
Term::var("clauses_delayed"),
)
.force()
.lambda("clauses_delayed")
.apply(
Term::var("tail_2")
.delayed_choose_list(
Term::empty_list()
.lambda("b")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
),
)
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list().apply(
Term::var("self"),
),
),
),
Term::var("c").lambda("c").apply(
Term::tail_list()
.apply(Term::var("tail_1"))
.lambda("b")
.apply(Term::un_i_data().apply(
Term::head_list().apply(
Term::var("tail_1"),
),
))
.lambda("a")
.apply(
Term::un_i_data().apply(
Term::head_list()
.apply(Term::var(
"self",
)),
),
),
),
)
.delay(),
)
.lambda("tail_2")
.apply(
Term::tail_list().apply(Term::var("tail_1")),
),
)
.lambda("tail_1")
.apply(Term::tail_list().apply(Term::var("self"))),
)
.lambda("self"),
)
.apply(Term::list_values(vec![
Constant::Data(Data::integer(1.into())),
Constant::Data(Data::integer(3.into())),
])),
),
)
.apply(Term::data(Data::list(vec![Data::integer(1.into())]))),
false,
);
}