Skip to main content

generate

Function generate 

Source
pub fn generate(
    source: &str,
    file: &str,
    regenerate: &str,
) -> Result<Vec<Generated>, Error>
Expand description

Generates the code of every predicate defined in source.

file labels errors and is named in the header of the generated code, for instance predicates/orient3d.pred. regenerate tells how to regenerate the code, for instance the command that produced it; it is written in the header of every generated file after “To regenerate,”, one comment line per line of text. The command line tool passes the command it was run with.

For each predicate the module of its stages holds the constants of its filter and the ranges of its exact stages, and the functions filter, exact_differences, expansions_translated, expansions_untranslated (only when the predicate has an #[exact] form) and staged, which runs the filter and then the exact stages in the order: differences that are exact, the translated expansion form, then the #[exact] form if one is given. The order is the same for every predicate for now. The module of its checks holds exact, the main form evaluated with the exact numbers of implicit-predicates-oracle, and bound_edge_cases, pairs of inputs at the edge of the error bound of the filter.

§Errors

Returns the first problem found in the definitions: a syntax error, a main form that is not homogeneous in differences of coordinates, a degree above the 1022 that the filter accepts, a definition too large to derive the filter bound for or to expand, an #[exact] form that is a different polynomial, a main form with more than 256 distinct subexpressions, or a predicate that the exact stages cannot support.

§Work

The checks run from the cheapest to the most expensive, and each step whose work can grow faster than the size of the definition has a budget, checked before the work it limits:

  • parse nests brackets at most 32 deep, and the difference form and the degree of the #[exact] form take one pass each;
  • crate::filter_bound keeps its exact coefficients within 2^26 bits in all;
  • crate::canonical keeps every expansion within 2^16 terms, 2^16 bits per coefficient and 2^20 units of work;
  • the exact plans reject temporaries of 2^32 components or more, or of more than 2^51 operations, and take a few passes over the graph for each power of two they try;
  • the search for the edge cases of the checks, the most expensive step per node, runs only on main forms of at most 256 distinct subexpressions, and makes at most a fixed number of exact evaluations of the form.

So the work of generate is bounded for every definition, and the slowest definitions accepted take a few seconds in a debug build, most of it in the search for the edge cases; a definition beyond a budget is rejected with an error that names the limit.