MCPcopy Create free account
hub / github.com/ElementsProject/elements / simplicity_analyseBounds

Function simplicity_analyseBounds

src/simplicity/eval.c:588–745  ·  view source on GitHub ↗

:TODO: Document extraFrameBound in the Tech Report (and implement it in Haskell) */ Given a well-typed dag representing a Simplicity expression, compute the memory and CPU requirements for evaluation. * * If 'malloc' fails, then returns SIMPLICITY_ERR_MALLOC. * When maxCells < UBOUNDED_MAX, if the bounds on the number of cells needed for evaluation of 'dag' on an idealized Bit Machine exceeds m

Source from the content-addressed store, hash-verified

586 * and if maxCells < UBOUNDED_MAX then '*frameBound' bounds the number of stack frames needed during execution of 'dag'.
587 */
588simplicity_err simplicity_analyseBounds( ubounded *cellsBound, ubounded *UWORDBound, ubounded *frameBound, ubounded *costBound
589 , ubounded maxCells, ubounded minCost, ubounded maxCost, const dag_node* dag, const type* type_dag, const size_t len) {
590 static_assert(DAG_LEN_MAX <= SIZE_MAX / sizeof(boundsAnalysis), "bound array too large.");
591 static_assert(1 <= DAG_LEN_MAX, "DAG_LEN_MAX is zero.");
592 static_assert(DAG_LEN_MAX - 1 <= UINT32_MAX, "bound array index does not fit in uint32_t.");
593 simplicity_assert(1 <= len);
594 simplicity_assert(len <= DAG_LEN_MAX);
595 boundsAnalysis* bound = simplicity_malloc(len * sizeof(boundsAnalysis));
596 if (!bound) return SIMPLICITY_ERR_MALLOC;
597
598 /* Sum up the total costs.
599 * The computations for extraCells and cost are clipped at UBOUNDED_MAX,
600 * so a result of UBOUNDED_MAX means "UBOUNDED_MAX or larger".
601 *
602 * The extraUWORD computation may produce unsigned overflow.
603 * However the extraUWORD true value is less than the true value of extraCells.
604 * As long as extraCells is strictly less than UBOUNDED_MAX, extraUWORD will be too.
605 *
606 * The extraFrame computation is bounded by DAG_LEN, and cannot overflow.
607 */
608 for (size_t i = 0; i < len; ++i) {
609 switch (dag[i].tag) {
610 case ASSERTL:
611 case ASSERTR:
612 case CASE:
613 bound[i].extraCellsBound[0] = bounded_max( bound[dag[i].child[0]].extraCellsBound[0]
614 , bound[dag[i].child[1]].extraCellsBound[0] );
615 bound[i].extraCellsBound[1] = bounded_max( bound[dag[i].child[0]].extraCellsBound[1]
616 , bound[dag[i].child[1]].extraCellsBound[1] );
617
618 bound[i].extraUWORDBound[0] = bounded_max( bound[dag[i].child[0]].extraUWORDBound[0]
619 , bound[dag[i].child[1]].extraUWORDBound[0] );
620 bound[i].extraUWORDBound[1] = bounded_max( bound[dag[i].child[0]].extraUWORDBound[1]
621 , bound[dag[i].child[1]].extraUWORDBound[1] );
622
623 bound[i].extraFrameBound[0] = bounded_max( bound[dag[i].child[0]].extraFrameBound[0]
624 , bound[dag[i].child[1]].extraFrameBound[0] );
625 bound[i].extraFrameBound[1] = bounded_max( bound[dag[i].child[0]].extraFrameBound[1]
626 , bound[dag[i].child[1]].extraFrameBound[1] );
627 bound[i].cost = bounded_add(overhead, bounded_max( bound[dag[i].child[0]].cost
628 , bound[dag[i].child[1]].cost ));
629 break;
630 case DISCONNECT:
631 bound[i].extraCellsBound[1] = type_dag[DISCONNECT_W256A(dag, type_dag, i)].bitSize;
632 bound[i].extraCellsBound[0] = bounded_max(
633 bounded_add( type_dag[DISCONNECT_BC(dag, type_dag, i)].bitSize
634 , bounded_max( bounded_add(bound[i].extraCellsBound[1], bound[dag[i].child[0]].extraCellsBound[1])
635 , bounded_max(bound[dag[i].child[0]].extraCellsBound[0], bound[dag[i].child[1]].extraCellsBound[1]))),
636 bound[dag[i].child[1]].extraCellsBound[0]);
637 bound[i].extraUWORDBound[1] = (ubounded)ROUND_UWORD(type_dag[DISCONNECT_W256A(dag, type_dag, i)].bitSize);
638 bound[i].extraUWORDBound[0] = bounded_max(
639 (ubounded)ROUND_UWORD(type_dag[DISCONNECT_BC(dag, type_dag, i)].bitSize) +
640 bounded_max( bound[i].extraUWORDBound[1] + bound[dag[i].child[0]].extraUWORDBound[1]
641 , bounded_max(bound[dag[i].child[0]].extraUWORDBound[0], bound[dag[i].child[1]].extraUWORDBound[1])),
642 bound[dag[i].child[1]].extraUWORDBound[0]);
643
644 bound[i].extraFrameBound[1] = bounded_max( bound[dag[i].child[0]].extraFrameBound[1] + 1
645 , bound[dag[i].child[1]].extraFrameBound[1]);

Callers 4

test_hashBlockFunction · 0.85
test_programFunction · 0.85
exactBudget_testFunction · 0.85

Calls 7

bounded_maxFunction · 0.85
bounded_addFunction · 0.85
DISCONNECT_W256AFunction · 0.85
DISCONNECT_BCFunction · 0.85
DISCONNECT_BFunction · 0.85
COMP_BFunction · 0.85
IDEN_AFunction · 0.85

Tested by 3

test_hashBlockFunction · 0.68
test_programFunction · 0.68
exactBudget_testFunction · 0.68