Factor out common UPLC logic for converting Data to Bool.

This commit is contained in:
KtorZ 2024-08-01 10:42:43 +02:00 committed by Kasey
parent 05504b9762
commit c3a61706b5
2 changed files with 69 additions and 75 deletions

View File

@ -912,22 +912,7 @@ pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
) )
.lambda("__list_data") .lambda("__list_data")
.apply(Term::unlist_data().apply(term)), .apply(Term::unlist_data().apply(term)),
Some(UplcType::Bool) => Term::snd_pair() Some(UplcType::Bool) => Term::unwrap_bool_or(term, |result| result, &Term::Error.delay()),
.apply(Term::var("__pair__"))
.delayed_choose_list(
Term::less_than_equals_integer()
.apply(Term::integer(2.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.delayed_if_then_else(
Term::Error,
Term::equals_integer()
.apply(Term::integer(1.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__"))),
),
Term::Error,
)
.lambda("__pair__")
.apply(Term::unconstr_data().apply(term)),
Some(UplcType::Unit) => Term::equals_integer() Some(UplcType::Unit) => Term::equals_integer()
.apply(Term::integer(0.into())) .apply(Term::integer(0.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__"))) .apply(Term::fst_pair().apply(Term::var("__pair__")))
@ -956,14 +941,15 @@ pub fn softcast_data_to_type_otherwise(
) -> Term<Name> { ) -> Term<Name> {
let uplc_type = field_type.get_uplc_type(); let uplc_type = field_type.get_uplc_type();
let then = then.lambda(name);
match uplc_type { match uplc_type {
Some(UplcType::Integer) => Term::var("__val") Some(UplcType::Integer) => Term::var("__val")
.choose_data( .choose_data(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(Term::un_i_data().apply(Term::var("__val")))
.apply(Term::un_i_data().apply(Term::var("__val")))
.delay(), .delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
) )
@ -976,8 +962,7 @@ pub fn softcast_data_to_type_otherwise(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(Term::un_b_data().apply(Term::var("__val")))
.apply(Term::un_b_data().apply(Term::var("__val")))
.delay(), .delay(),
) )
.force() .force()
@ -989,8 +974,7 @@ pub fn softcast_data_to_type_otherwise(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(Term::decode_utf8().apply(Term::un_b_data().apply(Term::var("__val"))))
.apply(Term::decode_utf8().apply(Term::un_b_data().apply(Term::var("__val"))))
.delay(), .delay(),
) )
.force() .force()
@ -1000,8 +984,7 @@ pub fn softcast_data_to_type_otherwise(
Some(UplcType::List(_)) if field_type.is_map() => Term::var("__val") Some(UplcType::List(_)) if field_type.is_map() => Term::var("__val")
.choose_data( .choose_data(
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(Term::unmap_data().apply(Term::var("__val")))
.apply(Term::unmap_data().apply(Term::var("__val")))
.delay(), .delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
@ -1014,8 +997,7 @@ pub fn softcast_data_to_type_otherwise(
.choose_data( .choose_data(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(Term::unlist_data().apply(Term::var("__val")))
.apply(Term::unlist_data().apply(Term::var("__val")))
.delay(), .delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
@ -1030,8 +1012,7 @@ pub fn softcast_data_to_type_otherwise(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(
.apply(
Term::bls12_381_g1_uncompress() Term::bls12_381_g1_uncompress()
.apply(Term::un_b_data().apply(Term::var("__val"))), .apply(Term::un_b_data().apply(Term::var("__val"))),
) )
@ -1046,8 +1027,7 @@ pub fn softcast_data_to_type_otherwise(
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
then.lambda(name) then.apply(
.apply(
Term::bls12_381_g2_uncompress() Term::bls12_381_g2_uncompress()
.apply(Term::un_b_data().apply(Term::var("__val"))), .apply(Term::un_b_data().apply(Term::var("__val"))),
) )
@ -1070,16 +1050,14 @@ pub fn softcast_data_to_type_otherwise(
Term::tail_list() Term::tail_list()
.apply(Term::var("__tail")) .apply(Term::var("__tail"))
.choose_list( .choose_list(
then.lambda(name) then.apply(
.apply(
Term::mk_pair_data() Term::mk_pair_data()
.apply( .apply(
Term::head_list() Term::head_list()
.apply(Term::var("__list_data")), .apply(Term::var("__list_data")),
) )
.apply( .apply(
Term::head_list() Term::head_list().apply(Term::var("__tail")),
.apply(Term::var("__tail")),
), ),
) )
.delay(), .delay(),
@ -1105,28 +1083,13 @@ pub fn softcast_data_to_type_otherwise(
.apply(value), .apply(value),
Some(UplcType::Bool) => Term::var("__val") Some(UplcType::Bool) => Term::var("__val")
.choose_data( .choose_data(
Term::snd_pair() Term::unwrap_bool_or(
.apply(Term::var("__pair__")) Term::var("__val"),
.choose_list( |result| then.apply(result),
Term::less_than_equals_integer() &otherwise_delayed,
.apply(Term::integer(2.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.delayed_if_then_else(
otherwise_delayed.clone(),
then.lambda(name).apply(
Term::equals_integer()
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.apply(Term::integer(1.into())),
),
) )
.delay(), .delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
)
.force()
.lambda("__pair__")
.apply(Term::unconstr_data().apply(Term::var("__val")))
.delay(),
otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
@ -1143,7 +1106,7 @@ pub fn softcast_data_to_type_otherwise(
Term::snd_pair() Term::snd_pair()
.apply(Term::unconstr_data().apply(Term::var("__val"))) .apply(Term::unconstr_data().apply(Term::var("__val")))
.choose_list( .choose_list(
then.lambda(name).apply(Term::unit()).delay(), then.apply(Term::unit()).delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
) )
.force() .force()
@ -1161,11 +1124,11 @@ pub fn softcast_data_to_type_otherwise(
.lambda("__val") .lambda("__val")
.apply(value), .apply(value),
Some(UplcType::Data) => then.lambda(name).apply(value), Some(UplcType::Data) => then.apply(value),
// constr type // constr type
None => Term::var("__val") None => Term::var("__val")
.choose_data( .choose_data(
then.lambda(name).apply(Term::var("__val")).delay(), then.apply(Term::var("__val")).delay(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),
otherwise_delayed.clone(), otherwise_delayed.clone(),

View File

@ -484,4 +484,35 @@ impl Term<Name> {
.lambda("__constr_var"), .lambda("__constr_var"),
) )
} }
/// Convert an arbitrary 'term' into a bool term and pass it into a 'callback'.
/// Continue the execution 'otherwise' with a different branch.
///
/// Note that the 'otherwise' term as well as the callback's result are expected
/// to be delayed terms.
pub fn unwrap_bool_or<F>(term: Term<Name>, callback: F, otherwise: &Term<Name>) -> Term<Name>
where
F: FnOnce(Term<Name>) -> Term<Name>,
{
Term::snd_pair()
.apply(Term::var("__pair__"))
.choose_list(
Term::less_than_equals_integer()
.apply(Term::integer(2.into()))
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.delayed_if_then_else(
otherwise.clone(),
callback(
Term::equals_integer()
.apply(Term::fst_pair().apply(Term::var("__pair__")))
.apply(Term::integer(1.into())),
),
)
.delay(),
otherwise.clone(),
)
.force()
.lambda("__pair__")
.apply(Term::unconstr_data().apply(term))
}
} }