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
(with one size and one uncertainty per axis when every term of the main
form has the same degree in each axis, see crate::filter_form),
exact_differences, expansions_translated, expansions_untranslated
(only when the predicate has an #[exact] form) on stack buffers, the
same two expansion forms over arena spans, expansions_translated_in and
expansions_untranslated_in, which take the exact coordinates of any
point type, 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. A stage on the stack is emitted only when its
temporaries take at most 4,096 f64; when one does not fit, staged
takes an arena and runs the stage over spans of the same form in its
place, on the exact coordinates of the explicit points. For points of
any type that implements Point, staged_in runs filter_points, the
filter with the uncertainty of the errors of the points, then
exact_stages, the exact stages of staged, when every point is
explicit, and otherwise exact_stages_in, the stages over spans on the
exact coordinates of the points, the translated form first. The module of
its checks holds exact, the main form evaluated with the exact numbers
of implicit-predicates-oracle, bound_edge_cases, pairs of inputs at
the edge of the error bound of the filter for explicit points, and, for a
per-axis filter, uncertainty_edge_cases, the same with an uncertainty.
§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:
parsenests brackets at most 32 deep, and the difference form and the degree of the#[exact]form take one pass each;crate::filter_boundkeeps its exact coefficients within2^26bits in all;crate::canonicalkeeps every expansion within2^16terms,2^16bits per coefficient and2^20units of work;- the exact plans reject temporaries of
2^32components or more, or of more than2^51operations on the stack and2^50over spans, and take a few passes over the graph for each power of two they try; the plans over spans stop each pass at the first node whose bound overflows; - 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.