elements/eval.h
Russell O'Connor f502c24196 Squashed 'src/simplicity/' content from commit 86ac0f92c4
git-subtree-dir: src/simplicity
git-subtree-split: 86ac0f92c4b2b6d694dca85dce3b6909aed25894
2024-10-07 14:38:29 -04:00

82 lines
5.1 KiB
C

/* This module provides functions for evaluating Simplicity programs and expressions.
*/
#ifndef SIMPLICITY_EVAL_H
#define SIMPLICITY_EVAL_H
#include "bounded.h"
#include "dag.h"
typedef unsigned char flags_type;
#define CHECK_NONE 0
#define CHECK_EXEC 0x10
#define CHECK_CASE 0x60
#define CHECK_ALL ((flags_type)(-1))
/* 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 maxCells,
* then return SIMPLICITY_ERR_EXEC_MEMORY.
* When maxCost < UBOUNDED_MAX, if the bounds on the dag's CPU cost exceeds 'maxCost', then return SIMPLICITY_ERR_EXEC_BUDGET.
* Otherwise returns SIMPLICITY_NO_ERR.
*
* Precondition: NULL != cellsBound
* NULL != UWORDBound
* NULL != frameBound
* NULL != costBound
* dag_node dag[len] and 'dag' is well-typed with 'type_dag'.
* Postcondition: if the result is 'SIMPLICITY_NO_ERR'
* then if maxCost < UBOUNDED_MAX then '*costBound' bounds the dag's CPU cost measured in milli weight units
* and if maxCells < UBOUNDED_MAX then '*cellsBound' bounds the number of cells needed for evaluation of 'dag' on an idealized Bit Machine
* and if maxCells < UBOUNDED_MAX then '*UWORDBound' bounds the number of UWORDs needed for the frames during evaluation of 'dag'
* and if maxCells < UBOUNDED_MAX then '*frameBound' bounds the number of stack frames needed during execution of 'dag'.
*/
simplicity_err simplicity_analyseBounds( ubounded *cellsBound, ubounded *UWORDBound, ubounded *frameBound, ubounded *costBound
, ubounded maxCells, ubounded maxCost, const dag_node* dag, const type* type_dag, const size_t len);
/* Run the Bit Machine on the well-typed Simplicity expression 'dag[len]' of type A |- B.
* If bitSize(A) > 0, initialize the active read frame's data with 'input[ROUND_UWORD(bitSize(A))]'.
*
* If malloc fails, returns 'SIMPLICITY_ERR_MALLOC'.
* When a budget is given, if static analysis results determines the bound on cpu requirements exceed the allowed budget, returns 'SIMPLICITY_ERR_EXEC_BUDGET'
* If static analysis results determines the bound on memory allocation requirements exceed the allowed limits, returns 'SIMPLICITY_ERR_EXEC_MEMORY'
* If during execution some jet execution fails, returns 'SIMPLICITY_ERR_EXEC_JET'.
* If during execution some 'assertr' or 'assertl' combinator fails, returns 'SIMPLICITY_ERR_EXEC_ASESRT'.
*
* If none of the above conditions fail and bitSize(B) > 0, then a copy the final active write frame's data is written to 'output[roundWord(bitSize(B))]'.
*
* If 'anti_dos_checks' includes the 'CHECK_EXEC' flag, and not every non-HIDDEN dag node is executed, returns 'SIMPLICITY_ERR_ANTIDOS'
* If 'anti_dos_checks' includes the 'CHECK_CASE' flag, and not every case node has both branches executed, returns 'SIMPLICITY_ERR_ANTIDOS'
*
* Otherwise 'SIMPLICITY_NO_ERROR' is returned.
*
* Precondition: dag_node dag[len] and 'dag' is well-typed with 'type_dag' for an expression of type A |- B;
* bitSize(A) == 0 or UWORD input[ROUND_UWORD(bitSize(A))];
* bitSize(B) == 0 or UWORD output[ROUND_UWORD(bitSize(B))];
* if NULL != budget then *budget <= BUDGET_MAX
* if 'dag[len]' represents a Simplicity expression with primitives then 'NULL != env';
*/
simplicity_err simplicity_evalTCOExpression( flags_type anti_dos_checks, UWORD* output, const UWORD* input
, const dag_node* dag, type* type_dag, size_t len, const ubounded* budget, const txEnv* env
);
/* Run the Bit Machine on the well-typed Simplicity program 'dag[len]'.
*
* If malloc fails, returns 'SIMPLICITY_ERR_MALLOC'.
* When a budget is given, if static analysis results determines the bound on cpu requirements exceed the allowed budget, returns 'SIMPLICITY_ERR_EXEC_BUDGET'
* If static analysis results determines the bound on memory allocation requirements exceed the allowed limits, returns 'SIMPLICITY_ERR_EXEC_MEMORY'
* If during execution some jet execution fails, returns 'SIMPLICITY_ERR_EXEC_JET'.
* If during execution some 'assertr' or 'assertl' combinator fails, returns 'SIMPLICITY_ERR_EXEC_ASESRT'.
* If not every non-HIDDEN dag node is executed, returns 'SIMPLICITY_ERR_ANTIDOS'
* If not every case node has both branches executed, returns 'SIMPLICITY_ERR_ANTIDOS'
*
* Otherwise 'SIMPLICITY_NO_ERROR' is returned.
*
* Precondition: dag_node dag[len] and 'dag' is well-typed with 'type_dag' for an expression of type ONE |- ONE;
* if NULL != budget then *budget <= BUDGET_MAX
* if 'dag[len]' represents a Simplicity expression with primitives then 'NULL != env';
*/
static inline simplicity_err evalTCOProgram(const dag_node* dag, type* type_dag, size_t len, const ubounded* budget, const txEnv* env) {
return simplicity_evalTCOExpression(CHECK_ALL, NULL, NULL, dag, type_dag, len, budget, env);
}
#endif