Herbie's input format is designed for expressing mathematical functions, which Herbie can then search for accurate implementations of. It also allows specifying the distribution that Herbie draws inputs from when evaluating the accuracy of an expression.

Herbie uses the FPCore format for its input expression, which looks like this:

(FPCore (inputs ...)properties ...expression)

Each input is a variable, like `x`

, which can be used
in the expression, whose accuracy Herbie will try to improve.
Properties are described below.

The expression is written in prefix form, with every function call
parenthesized, as in Lisp. For example, the formula for the
hypotenuse of a triangle with legs *a* and *b* is

(FPCore (a b) (sqrt (+ (* a a) (* b b))))

We recommend the `.fpcore`

file extension for Herbie input files.

Herbie supports all functions from math.h with floating-point-only inputs and outputs. The best supported functions, far from the full list, include:

`+`

,`-`

,`*`

,`/`

,`fabs`

- The usual arithmetic functions
`-`

is both negation and subtraction `sqrt`

,`cbrt`

- Square and cube roots
`pow`

,`exp`

,`log`

- Various exponentiations and logarithms
`sin`

,`cos`

,`tan`

- The trigonometric functions
`asin`

,`acos`

,`atan`

,`atan2`

- The inverse trigonometric functions
`sinh`

,`cosh`

,`tanh`

- The hyperbolic functions
`asinh`

,`acosh`

,`atanh`

- The inverse hyperbolic functions
`fma`

,`expm1`

,`log1p`

,`hypot`

- Specialized numeric functions

Herbie also supports the constants `PI`

and `E`

.

Herbie links against `libm`

to ensure that every
function has the same behavior in Herbie as in your code. However,
on Windows platforms some functions are not available in the
system `libm`

. In these cases Herbie will use a fallback
implementation and print a warning; turning off the
the `precision:fallback` option
disables those functions instead.

FPCore uses `if`

for conditional expressions:

(ifcondif-trueif-false)

An `if`

epxression evaluates the
conditional `cond`

and returns either `if-true`

if
it is true or `if-false`

if it is not. Conditionals may use:

`==`

,`!=`

,`<`

,`>`

,`<=`

,`>=`

- The usual comparison operators
`and`

,`or`

,`not`

- The usual logical operators
`TRUE`

,`FALSE`

- The two boolean values

Note that unlike the arithmetic operators, the comparison functions can take any number of arguments.

Intermediate variables can be defined using `let`

:

(let ([variablevalue]...)body)

In a `let`

expression, all the values are evaluated
first, and then are bound to their variables in the body. This
means that the value of one variable can't refer to another
variable in the same `let`

block; nest `let`

constructs if you want to do that.

Note that Herbie treats intermediate values only as a notational convenience, and inlines their values before improving the formula's accuracy. Using intermediate variables will not help Herbie improve a formula's accuracy or speed up its run-time.

Herbie includes experimental support for complex numbers; however, this support is currently limited to the basic arithmetic operations. Some of Herbie's internal mechanisms for improving expression accuracy also do not yet support complex-number expressions.

All input parameters are real numbers; complex numbers must be
constructed with `complex`

. The
functions `+`

, `-`

, `*`

, `/`

, `re`

, `im`

,
and `conj`

are available on complex numbers. Note that
complex and real operations use the same syntax; however, complex
and real arithmetic cannot be mixed: ```
(+ (complex 1 2)
1)
```

is not valid. A type checker will report such errors.

Complex operations use the Racket implementation, so results may differ (slightly) for the complex library used in your language, especially for non-finite complex numbers. Unfortunately, complex number arithmetic is not as standardized as float-point arithmetic.

In the future, we hope to support complex-number arguments and fully support all complex-number operations.

Herbie also allows several FPCore properties specified on inputs for additional meta-data:

`:name`

`string`- Herbie uses this name in its output
`:pre`

`test`- Herbie samples only points that pass the test in the reals

Several additional properties can be found in the benchmark suite and are used for testing, but are not supported and can change without warning.

Herbie's output uses custom FPCore properties in its output to provide meta-data about the Herbie improvement process:

`:herbie-status`

`status`- Describes whether Herbie successfully improved the accuracy of the input;
`status`is one of`success`

,`timeout`

,`error`

, or`crash`

. `:herbie-time`

`ms`- The time, in milliseconds, used by Herbie to find a more accurate formula.
`:herbie-bits-used`

`bits`- The precision used to find accurate outputs from the formula.
`:herbie-error-input ([`

`pts``err`] ...)- The computed average error of the input program, evaluated on
`pts`points. Multiple entries correspond to multiple training or test sets. `:herbie-error-output ([`

`pts2``err1`] [`pts2``err2`])- The computed average error of the output program, like above.

Herbie's output also passes through any `:name`

and `:pre`

properties on its inputs.

Herbie 0.9 used a different input
format, which is not supported Herbie 1.0 and later. To
simplify the transition, the `infra/convert.rkt`

script
converts from the old to the new format.

To use the conversion tool, run:

racket infra/convert.rktfile.rkt>file.fpcore