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

Function freeze

src/simplicity/typeInference.c:436–492  ·  view source on GitHub ↗

Set '*result' to the index within 'type_dag' that contains an instance type bound by 'var' where free variables are instantiated * at the ONE type, recursively adding new nodes to 'type_dag' as necessary. * '*type_dag_used' will be incremented by the number of new 'type_dag' nodes created. * * If it is impossible to create a required instance (due to a cycle in the bindings reachable by 'var')

Source from the content-addressed store, hash-verified

434 * Postcondition: If 'true' is returned, then type type_dag[*type_dag_used] is well-formed
435 */
436static bool freeze(size_t* result, type* type_dag, size_t* type_dag_used, unification_var* var) {
437 var = findRoot(var);
438
439 if (isFrozen(var)) {
440 *result = getFrozenIx(var);
441 return true;
442 }
443
444 /* 'var' is not frozen, and therefore it must have a non-trivial binding.
445 * Create a one item stack of unification variables 'var' to be frozen.
446 */
447 var->next = NULL;
448 simplicity_assert(!var->bound.occursCheck);
449 var->bound.occursCheck = true;
450
451 /* Attempt to freeze all variables on the stack, pushing new variables onto the stack to recursively freeze them if needed.
452 *
453 * All variables in the stack are representatives of their equivalence class and have just had their 'occursCheck' flag changed
454 * from 'false' to 'true'.
455 * Variables never change their 'occursCheck' flag back from 'true' to 'false'.
456 * Variables are only removed from the stack after being frozen.
457 * Each time we go through this loop, the stack size either increases by 1 or decreases by 1.
458 * Therefore the total number of times this loop iterates summed over all calls to 'freeze' is bounded by
459 * twice the number of unification variable (representatives) with non-trivial bindings.
460 * ("twice" because once to add the variable to the stack and once to remove the variable from the stack).
461 *
462 * Note that number of unification_variables is bound linearly in the number of nodes in the Simplicity DAG.
463 */
464 while (var) {
465 unification_var* typeArg[2] = { findRoot(var->bound.arg[0]), findRoot(var->bound.arg[1]) };
466 if (!isFrozen(typeArg[0])) {
467 /* The first type argument's representative isn't frozen. Add it to the stack and immediately attempt to freeze it. */
468 if (typeArg[0]->bound.occursCheck) return false; /* Occurs check failure. */
469 typeArg[0]->bound.occursCheck = true;
470 typeArg[0]->next = var;
471 var = typeArg[0];
472 } else if (!isFrozen(typeArg[1])) {
473 /* The second type argument's representative isn't frozen. Add it to the stack and immediately attempt to freeze it. */
474 if (typeArg[1]->bound.occursCheck) return false; /* Occurs check failure. */
475 typeArg[1]->bound.occursCheck = true;
476 typeArg[1]->next = var;
477 var = typeArg[1];
478 } else {
479 /* Both the type argument's representatives are frozen.
480 * Create a new entry in the 'type_dag' for 'var's binding and freeze 'var'.
481 */
482 *result = var->bound.frozen_ix = (*type_dag_used)++;
483 type_dag[var->bound.frozen_ix] = (type)
484 { .kind = var->bound.kind
485 , .typeArg = { getFrozenIx(typeArg[0]), getFrozenIx(typeArg[1]) }
486 };
487 var = var->next;
488 }
489 }
490
491 return true;
492}
493

Callers 1

freezeTypesFunction · 0.85

Calls 3

findRootFunction · 0.85
isFrozenFunction · 0.85
getFrozenIxFunction · 0.85

Tested by

no test coverage detected