Few minor changes, clippy fixes, and test fixes

This commit is contained in:
microproofs 2024-08-03 01:43:43 -04:00 committed by Kasey
parent 4cf81a19b1
commit 8a461d5bd5
5 changed files with 323 additions and 263 deletions

View File

@ -4917,7 +4917,7 @@ impl<'a> CodeGenerator<'a> {
known_data_to_type(term, &tipo) known_data_to_type(term, &tipo)
}; };
if extract_constant(&term.pierce_no_inlines()).is_some() { if extract_constant(term.pierce_no_inlines()).is_some() {
let mut program: Program<Name> = Program { let mut program: Program<Name> = Program {
version: (1, 0, 0), version: (1, 0, 0),
term, term,

View File

@ -361,21 +361,21 @@ pub fn find_introduced_variables(air_tree: &AirTree) -> Vec<String> {
AirTree::PairGuard { AirTree::PairGuard {
fst_name, snd_name, .. fst_name, snd_name, ..
} => fst_name } => fst_name
.into_iter() .iter()
.cloned() .cloned()
.chain(snd_name.into_iter().cloned()) .chain(snd_name.iter().cloned())
.collect_vec(), .collect_vec(),
AirTree::PairAccessor { fst, snd, .. } => fst AirTree::PairAccessor { fst, snd, .. } => fst
.into_iter() .iter()
.cloned() .cloned()
.chain(snd.into_iter().cloned()) .chain(snd.iter().cloned())
.collect_vec(), .collect_vec(),
AirTree::PairClause { AirTree::PairClause {
fst_name, snd_name, .. fst_name, snd_name, ..
} => fst_name } => fst_name
.into_iter() .iter()
.cloned() .cloned()
.chain(snd_name.into_iter().cloned()) .chain(snd_name.iter().cloned())
.collect_vec(), .collect_vec(),
AirTree::Fn { params, .. } => params.to_vec(), AirTree::Fn { params, .. } => params.to_vec(),
AirTree::ListAccessor { names, .. } => names.clone(), AirTree::ListAccessor { names, .. } => names.clone(),

View File

@ -4071,21 +4071,11 @@ fn generic_validator_type_test() {
} }
"#; "#;
let field_b = Term::head_list().apply(Term::var("tail_1")); let otherwise_r_a_b = Term::Error.delayed_trace(Term::string("r: A<B>")).delay();
let void_check = Term::equals_integer() let otherwise_var = &Term::var("otherwise_delayed");
.apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::unconstr_data().apply(Term::var("__val"))))
.delay_true_if_then_else(
Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("__val")))
.delay_empty_choose_list(Term::unit(), Term::var("param_msg")),
Term::var("param_msg"),
);
assert_uplc( let then_delayed = Term::equals_integer()
src,
Term::equals_integer()
.apply(Term::integer(0.into())) .apply(Term::integer(0.into()))
.apply(Term::var("subject")) .apply(Term::var("subject"))
.delayed_if_then_else( .delayed_if_then_else(
@ -4111,177 +4101,168 @@ fn generic_validator_type_test() {
) )
.lambda("subject") .lambda("subject")
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("r"))) .apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("r")))
// Validator level if then else
// which is why you have [(error) (force (error))]
.delayed_if_then_else( .delayed_if_then_else(
Term::unit(), Term::unit(),
Term::Error Term::Error
.apply(Term::Error.force()) .apply(Term::Error.force())
.delayed_trace(Term::string("Validator returned false")), .delayed_trace(Term::string("Validator returned false")),
) )
.lambda("_ctx")
.lambda("_") .lambda("_")
.apply( .delay();
Term::var("__expect_A")
.lambda("__expect_A") let call_expect_b = |tail_2: Term<Name>, field_1| {
.apply( tail_2.delay_empty_choose_list(
Term::var("__expect_B_")
.apply(field_1)
.apply(Term::var("then_delayed"))
.apply(otherwise_var.clone()),
otherwise_var.clone(),
)
};
let some_a_fields_check = Term::var(CONSTR_FIELDS_EXPOSER)
.apply(Term::var("__param_0"))
.as_var("tail_id_5", |fields| {
Term::unwrap_tail_or(
fields.clone(),
|tail| {
Term::head_list()
.apply(Term::Var(fields))
.as_var("__val", |val| {
Term::choose_data_constr(
val,
|val| {
val.unwrap_void_or(
|unit| {
unit.as_var("__field_0", |_| {
tail.as_var("tail_id_6", |other_field| {
Term::unwrap_tail_or(
other_field.clone(),
|tail_2| {
Term::head_list()
.apply(Term::Var(other_field))
.as_var("__val", |val_2| {
Term::choose_data_constr(
val_2,
|field_1| {
call_expect_b(
tail_2, field_1,
)
},
otherwise_var,
)
})
},
otherwise_var,
)
})
})
},
otherwise_var,
)
},
otherwise_var,
)
})
},
otherwise_var,
)
});
let expect_a_b = Term::var(CONSTR_INDEX_EXPOSER)
.apply(Term::var("__param_0"))
.as_var("subject", |subject| {
Term::equals_integer() Term::equals_integer()
.apply(Term::integer(0.into())) .apply(Term::integer(0.into()))
.apply(Term::var("subject")) .apply(Term::Var(subject.clone()))
.delayed_if_then_else( .delayed_if_then_else(
Term::var(CONSTR_FIELDS_EXPOSER) Term::var(CONSTR_FIELDS_EXPOSER)
.apply(Term::var("param_0")) .apply(Term::var("__param_0"))
.delay_empty_choose_list(Term::unit(), Term::var("param_msg")), .delay_empty_choose_list(
Term::var("then_delayed").force(),
otherwise_var.clone(),
),
Term::equals_integer() Term::equals_integer()
.apply(Term::integer(1.into())) .apply(Term::integer(1.into()))
.apply(Term::var("subject")) .apply(Term::Var(subject))
.delay_true_if_then_else( .delay_true_if_then_else(some_a_fields_check, otherwise_var.clone()),
Term::var("r_fields")
.delay_filled_choose_list(
Term::var("param_msg"),
Term::var("tail_1")
.delay_filled_choose_list(
Term::var("param_msg"),
Term::tail_list()
.apply(Term::var("tail_1"))
.delay_empty_choose_list(
Term::unit().lambda("_").apply(
Term::var("__expect_B")
.apply(Term::var("field_B"))
.apply(Term::var(
"param_msg",
)),
),
Term::var("param_msg"),
) )
.lambda("field_B") })
.apply( .lambda("otherwise_delayed")
Term::var("__val") .lambda("then_delayed")
.choose_data( .lambda("__param_0");
Term::var("__val").delay(),
Term::var("param_msg"), let expect_b = Term::var(CONSTR_INDEX_EXPOSER)
Term::var("param_msg"), .apply(Term::var("__param_0"))
Term::var("param_msg"), .as_var("subject", |subject| {
Term::var("param_msg"),
)
.force()
.lambda("__val")
.apply(field_b),
),
)
.lambda("tail_1")
.apply(
Term::tail_list()
.apply(Term::var("r_fields")),
)
.lambda("field_0")
.apply(
Term::var("__val")
.choose_data(
void_check.clone().delay(),
Term::var("param_msg"),
Term::var("param_msg"),
Term::var("param_msg"),
Term::var("param_msg"),
)
.force()
.lambda("__val")
.apply(
Term::head_list()
.apply(Term::var("r_fields")),
),
),
)
.lambda("r_fields")
.apply(
Term::var(CONSTR_FIELDS_EXPOSER)
.apply(Term::var("param_0")),
),
Term::var("param_msg"),
),
)
.lambda("subject")
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("param_0")))
.lambda("param_msg")
.lambda("param_0"),
)
.lambda("__expect_B")
.apply(
Term::equals_integer() Term::equals_integer()
.apply(Term::integer(0.into())) .apply(Term::integer(0.into()))
.apply(Term::var("subject")) .apply(Term::Var(subject.clone()))
.delay_true_if_then_else( .delay_true_if_then_else(
Term::var("B_fields")
.delay_filled_choose_list(
Term::var("param_msg"),
Term::tail_list()
.apply(Term::var("B_fields"))
.delay_empty_choose_list(
Term::unit(),
Term::var("param_msg"),
)
.lambda("something")
.apply(
Term::var("__val")
.choose_data(
void_check.delay(),
Term::var("param_msg"),
Term::var("param_msg"),
Term::var("param_msg"),
Term::var("param_msg"),
)
.force()
.lambda("__val")
.apply(
Term::head_list()
.apply(Term::var("B_fields")),
),
),
)
.lambda("B_fields")
.apply(
Term::var(CONSTR_FIELDS_EXPOSER) Term::var(CONSTR_FIELDS_EXPOSER)
.apply(Term::var("param_0")), .apply(Term::var("__param_0"))
), .as_var("fields", |fields| {
Term::var("param_msg"), Term::unwrap_tail_or(
fields.clone(),
|tail| {
Term::head_list().apply(Term::Var(fields)).as_var(
"field_void",
|field_void| {
Term::choose_data_constr(
field_void,
|void| {
void.unwrap_void_or(
|unit| {
unit.as_var("something", |_| {
tail.delay_empty_choose_list(
Term::var("then_delayed")
.force(),
otherwise_var.clone(),
) )
.lambda("subject") })
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("param_0"))) },
.lambda("param_msg") otherwise_var,
.lambda("param_0"),
) )
.apply(Term::var("r")) },
.apply(Term::var("r:A<B>")), otherwise_var,
) )
.lambda("r") },
.apply(
Term::var("__val")
.choose_data(
Term::var("__val").delay(),
Term::var("r:A<B>"),
Term::var("r:A<B>"),
Term::var("r:A<B>"),
Term::var("r:A<B>"),
) )
.force() },
.lambda("__val") otherwise_var,
.apply(Term::var("r")),
) )
.lambda("r") }),
.apply(Term::var("r")) otherwise_var.clone(),
)
})
.lambda("otherwise_delayed")
.lambda("then_delayed")
.lambda("__param_0");
assert_uplc(
src,
Term::var("r")
.as_var("__val", |r| {
Term::choose_data_constr(
r,
|val| {
Term::var("__expect_A_B_")
.lambda("__expect_A_B_")
.apply(expect_a_b)
.lambda("__expect_B_")
.apply(expect_b)
.apply(val)
.apply(then_delayed)
.apply(Term::var("r:A<B>"))
},
&Term::var("r:A<B>"),
)
})
.lambda("r") .lambda("r")
.lambda("r:A<B>") .lambda("r:A<B>")
.apply(Term::Error.delayed_trace(Term::string("r: A<B>")).delay()) .apply(otherwise_r_a_b),
.lambda(CONSTR_FIELDS_EXPOSER)
.apply(
Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("x")))
.lambda("x"),
)
.lambda(CONSTR_INDEX_EXPOSER)
.apply(
Term::fst_pair()
.apply(Term::unconstr_data().apply(Term::var("x")))
.lambda("x"),
),
false, false,
); );
} }
@ -5043,9 +5024,21 @@ fn expect_head3_cast_data_no_tail() {
} }
"#; "#;
let otherwise_expect = &Term::var("expect[h,i,j]:List<Int>=a");
let otherwise_msg: Term<Name> = Term::Error
.delayed_trace(Term::string("expect [h, i, j]: List<Int> = a"))
.delay();
let then = Term::equals_integer() let then = Term::equals_integer()
.apply(Term::var("h")) .apply(Term::var("h"))
.apply(Term::var("h")) .apply(Term::var("h"))
.delayed_if_then_else(
Term::equals_integer()
.apply(Term::var("i"))
.apply(Term::var("i")),
Term::bool(false),
)
.delayed_if_then_else( .delayed_if_then_else(
Term::equals_integer() Term::equals_integer()
.apply(Term::var("j")) .apply(Term::var("j"))
@ -5053,61 +5046,92 @@ fn expect_head3_cast_data_no_tail() {
Term::bool(false), Term::bool(false),
); );
assert_uplc( let unwrap_third = |head, tail: Term<Name>| {
src, Term::choose_data_integer(
Term::data(Data::list(vec![ head,
|head_int| {
head_int.as_var("j", |_| {
tail.delay_empty_choose_list(then, otherwise_expect.clone())
})
},
otherwise_expect,
)
};
let unwrap_second = |head, tail: Term<Name>| {
Term::choose_data_integer(
head,
|head_int| {
head_int.as_var("i", |_| {
tail.as_var("tail_id_2", |tail| {
Term::unwrap_tail_or(
tail.clone(),
|tail2| {
Term::head_list()
.apply(Term::Var(tail))
.as_var("head2", |head2| unwrap_third(head2, tail2))
},
otherwise_expect,
)
})
})
},
otherwise_expect,
)
};
let unwrap_first = |head, tail: Term<Name>| {
Term::choose_data_integer(
head,
|head_int| {
head_int.as_var("h", |_| {
tail.as_var("tail_id_1", |tail| {
Term::unwrap_tail_or(
tail.clone(),
|tail2| {
Term::head_list()
.apply(Term::Var(tail))
.as_var("head2", |head2| unwrap_second(head2, tail2))
},
otherwise_expect,
)
})
})
},
otherwise_expect,
)
};
let data_values = Term::data(Data::list(vec![
Data::integer(1.into()), Data::integer(1.into()),
Data::integer(2.into()), Data::integer(2.into()),
Data::integer(3.into()), Data::integer(3.into()),
])) ]));
.choose_data(
Term::var("expect[h]:List<Int>=a"), assert_uplc(
Term::var("expect[h]:List<Int>=a"), src,
Term::list_values(vec![ data_values
Constant::Data(Data::integer(1.into())), .as_var("a", |a| {
Constant::Data(Data::integer(2.into())), Term::choose_data_list(
Constant::Data(Data::integer(3.into())), a,
]) |list| {
.delay_filled_choose_list( list.as_var("list", |list_var| {
Term::var("expect[h]:List<Int>=a"), Term::unwrap_tail_or(
Term::var("__var") list_var.clone(),
.choose_data( |tail| {
Term::var("expect[h]:List<Int>=a"), Term::head_list()
Term::var("expect[h]:List<Int>=a"), .apply(Term::Var(list_var))
Term::var("expect[h]:List<Int>=a"), .as_var("__val", |head| unwrap_first(head, tail))
Term::tail_list() },
.apply(Term::list_values(vec![ otherwise_expect,
Constant::Data(Data::integer(1.into())),
Constant::Data(Data::integer(2.into())),
Constant::Data(Data::integer(3.into())),
]))
.delay_filled_choose_list(
Term::var("expect[h]:List<Int>=a"),
then.lambda("__var").apply(todo!()),
) )
.lambda("h") })
.apply(Term::un_i_data().apply(Term::var("__var"))), },
Term::var("expect[h]:List<Int>=a"), otherwise_expect,
) )
.lambda("__var") })
.apply(Term::head_list().apply(Term::list_values(vec![ .lambda("expect[h,i,j]:List<Int>=a")
Constant::Data(Data::integer(1.into())), .apply(otherwise_msg),
Constant::Data(Data::integer(2.into())),
Constant::Data(Data::integer(3.into())),
])))
.delay(),
)
.delay(),
Term::var("expect[h]:List<Int>=a"),
Term::var("expect[h]:List<Int>=a"),
)
.force()
.lambda("expect[h]:List<Int>=a")
.apply(
Term::Error
.delayed_trace(Term::string("expect [h]: List<Int> = a"))
.delay(),
),
false, false,
); );
} }

View File

@ -726,7 +726,7 @@ impl Term<Name> {
/// ///
/// Note that the 'otherwise' term is expected /// Note that the 'otherwise' term is expected
/// to be a delayed term. /// to be a delayed term.
fn unwrap_tail_or<F>(var: Rc<Name>, callback: F, otherwise: &Term<Name>) -> Term<Name> pub fn unwrap_tail_or<F>(var: Rc<Name>, callback: F, otherwise: &Term<Name>) -> Term<Name>
where where
F: FnOnce(Term<Name>) -> Term<Name>, F: FnOnce(Term<Name>) -> Term<Name>,
{ {

View File

@ -0,0 +1,36 @@
type Foo {
msg: Int,
}
type Bar {
Buzz
Bazz
}
test thing() {
let data: Data = Buzz
if data is Foo {
False
} else {
True
}
}
type A<x> {
NoA
SomeA(Void, x)
}
type B {
something: Void,
}
test err_example() {
let r: Data = SomeA(Void, B(Void))
expect x: A<B> = r
when x is {
NoA -> False
SomeA(_, B(something)) -> something == Void
}
}