If the Simplicity DAG, 'dag', has a principal type (including constraints due to sharing of subexpressions), * then allocate a well-formed type DAG containing all the types needed for all the subexpressions of 'dag', * with all free type variables instantiated at ONE, and set '*type_dag' to this allocation, * and update the '.sourceType' and '.targetType' fields within each node of the 'dag' 't
| 559 | * if the return value is not 'SIMPLICITY_NO_ERROR' then 'NULL == *type_dag' |
| 560 | */ |
| 561 | simplicity_err simplicity_mallocTypeInference(type** type_dag, simplicity_callback_mallocBoundVars mallocBoundVars, dag_node* dag, const uint_fast32_t len, const combinator_counters* census) { |
| 562 | *type_dag = NULL; |
| 563 | static_assert(DAG_LEN_MAX <= SIZE_MAX / sizeof(unification_arrow), "arrow array too large."); |
| 564 | static_assert(1 <= DAG_LEN_MAX, "DAG_LEN_MAX is zero."); |
| 565 | static_assert(DAG_LEN_MAX - 1 <= UINT32_MAX, "arrow array index does not fit in uint32_t."); |
| 566 | simplicity_assert(1 <= len); |
| 567 | simplicity_assert(len <= DAG_LEN_MAX); |
| 568 | unification_arrow* arrow = simplicity_malloc(len * sizeof(unification_arrow)); |
| 569 | unification_var* bound_var = NULL; |
| 570 | size_t word256_ix, extra_var_start; |
| 571 | const size_t orig_bindings_used = mallocBoundVars(&bound_var, &word256_ix, &extra_var_start, max_extra_vars(census)); |
| 572 | size_t bindings_used = orig_bindings_used; |
| 573 | |
| 574 | static_assert(1 <= NUMBER_OF_TYPENAMES_MAX, "NUMBER_OF_TYPENAMES_MAX is zero."); |
| 575 | simplicity_assert(orig_bindings_used <= NUMBER_OF_TYPENAMES_MAX - 1); |
| 576 | |
| 577 | simplicity_err result = arrow && bound_var ? SIMPLICITY_NO_ERROR : SIMPLICITY_ERR_MALLOC; |
| 578 | if (IS_OK(result)) { |
| 579 | result = typeInference(arrow, dag, len, bound_var + extra_var_start, bound_var, word256_ix, &bindings_used); |
| 580 | } |
| 581 | if (IS_OK(result)) { |
| 582 | /* :TODO: constrain the root of the dag to be a Simplicity program: ONE |- ONE */ |
| 583 | static_assert(TYPE_DAG_LEN_MAX <= SIZE_MAX / sizeof(type), "type_dag array too large."); |
| 584 | static_assert(1 <= TYPE_DAG_LEN_MAX, "TYPE_DAG_LEN_MAX is zero."); |
| 585 | static_assert(TYPE_DAG_LEN_MAX - 1 <= UINT32_MAX, "type_dag array index does not fit in uint32_t."); |
| 586 | /* 'bindings_used' is at most 4*len plus the initial value of 'bindings_used' set by 'mallocBoundVars'. */ |
| 587 | simplicity_assert(bindings_used <= orig_bindings_used + 4*len); |
| 588 | *type_dag = simplicity_malloc((1 + bindings_used) * sizeof(type)); |
| 589 | result = *type_dag ? SIMPLICITY_NO_ERROR : SIMPLICITY_ERR_MALLOC; |
| 590 | if (IS_OK(result)) { |
| 591 | result = freezeTypes(*type_dag, dag, arrow, len); |
| 592 | } |
| 593 | if (!IS_OK(result)) { |
| 594 | simplicity_free(*type_dag); |
| 595 | *type_dag = NULL; |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | simplicity_free(arrow); |
| 600 | simplicity_free(bound_var); |
| 601 | return result; |
| 602 | } |