formulae v0.5.0 Formulae

A set of functions to deal with analytical formulae.

Link to this section Summary

Functions

Returns the binding this formula requires.

Revalidates the formula with bindings given. Returns true if the formula strictly evaluates to true, false otherwise. Compiles the formula before evaluation if needed.

Compiles the formula into module.

Checks whether the formula was already compiled into module.

Curries the formula by substituting the known bindings into it.

Evaluates the formula returning the result back.

Evaluates normalized representation of formula.

normalize(input) deprecated

Returns a normalized representation for the formula given.

Produces the normalized representation of formula. If the rho is an instance of Integer or Float, it’s left intact, otherwise it’s moved to the left side with negation.

Link to this section Types

Link to this type

t()

t() :: %atom(){
  formula: binary(),
  ast: nil | tuple(),
  module: nil | atom(),
  variables: nil | [atom()],
  eval: nil | (keyword() -> any())
}

Link to this section Functions

Link to this function

bindings?(formula, bindings \\ [])

bindings?(formula :: Formulae.t() | binary(), binding :: keyword()) :: keyword()
This function is deprecated. Use `Formulae.compile/1` and `%Formulae{}.variables` or `Formula.curry/2` instead.

Returns the binding this formula requires.

Examples

iex> "a > 5" |> Formulae.bindings?
~w|a|a

iex> ":math.sin(a / (3.14 * b)) > c" |> Formulae.bindings?
~w|a b c|a

iex> "a + b * 4 - :math.pow(c, 2) / d > 1.0 * e" |> Formulae.bindings?
~w|a b c d e|a
Link to this function

check(string, bindings \\ [])

check(string :: binary(), bindings :: keyword()) :: boolean()
This function is deprecated. Use `Formulae.eval/2` instead.

Revalidates the formula with bindings given. Returns true if the formula strictly evaluates to true, false otherwise. Compiles the formula before evaluation if needed.

Link to this function

compile(input)

compile(Formulae.t() | binary()) :: Formulae.t()

Compiles the formula into module.

Examples:

iex> f = Formulae.compile("rem(a, 5) - b == 0")
iex> f.formula
"rem(a, 5) - b == 0"
iex> f.variables
[:a, :b]
iex> f.module
:"Elixir.Formulae.rem(a, 5) - b == 0"
iex> f.module.eval(a: 12, b: 2)
true

iex> f = Formulae.compile("rem(a, 5) - b == 0")
iex> f.eval.(a: 11, b: 1)
true
iex> f.eval.(a: 12, b: 1)
false
Link to this function

compiled?(input)

compiled?(binary() | Formulae.t()) :: boolean()

Checks whether the formula was already compiled into module.

Examples:

iex> Formulae.compiled?("foo > 42")
false
iex> Formulae.compile("foo > 42")
iex> Formulae.compiled?("foo > 42")
true
Link to this function

curry(input, binding \\ [], opts \\ [])

curry(input :: Formulae.t() | binary(), binding :: keyword(), opts :: keyword()) ::
  Formulae.t()

Curries the formula by substituting the known bindings into it.

Example

iex> Formulae.curry("(temp - foo * 4) > speed / 3.14", temp: 7, speed: 3.14).formula
"7 - foo * 4 > 3.14 / 3.14"
Link to this function

eval(string, bindings \\ [])

eval(string :: binary(), bindings :: keyword()) :: term()

Evaluates the formula returning the result back.

Examples:

iex> Formulae.eval("rem(a, 5) + rem(b, 4) == 0", a: 20, b: 20)
true
iex> Formulae.eval("rem(a, 5) == 0", a: 21)
false
iex> Formulae.eval("rem(a, 5) + rem(b, 4)", a: 21, b: 22)
3
Link to this function

evaluate(input, binding \\ [], opts \\ [])

This function is deprecated. Use `Formulae.eval/2` instead.

Evaluates normalized representation of formula.

Examples

iex> Formulae.evaluate(Formulae.unit("3 > 2"))
true

iex> Formulae.evaluate(Formulae.unit("3 < 2"))
false

iex> Formulae.evaluate(Formulae.unit("a < 2"), [a: 1])
true

iex> Formulae.evaluate(Formulae.unit("a > 2"), [a: 1])
false

iex> Formulae.evaluate(Formulae.unit("a < 2"), [])
** (Formulae.RunnerError) Formula failed to run (compile): incomplete binding to evaluate a formula, lacking: [:a].

iex> Formulae.evaluate(Formulae.unit("a + 2 = 3"), [a: 1])
true

iex> Formulae.evaluate(Formulae.unit("a + 2 = 3"), [a: 2])
false

iex> Formulae.evaluate(Formulae.unit(~S|a = "3"|), [a: "3"])
true

iex> Formulae.evaluate(Formulae.unit(~S|a = "3"|), [a: 3])
false

iex> Formulae.evaluate(Formulae.unit(~S|a = "3"|), [a: "hello"])
false

iex> Formulae.evaluate("a + 2 = 3", [a: 2])
false

iex> Formulae.evaluate(~S|a = "3"|, [a: "3"])
true

iex> Formulae.evaluate(Formulae.unit("a_b_c_490000 > 2"), [a_b_c_490000: 3])
true
Link to this function

normalize(input)

This function is deprecated. Use `Formulae.compile/1` and `%Formulae{}.variables` instead.

Returns a normalized representation for the formula given.

Link to this function

unit(input, env \\ [])

This function is deprecated. Use `Formulae.eval/2` instead.

Produces the normalized representation of formula. If the rho is an instance of Integer or Float, it’s left intact, otherwise it’s moved to the left side with negation.

Examples

iex> Formulae.unit("3 > 2")
{"3 > 2", {:>, [], [3, 2]}}

iex> Formulae.unit("3 - a > 2")
{"3 - a > 2", {:>, [], [{:-, [line: 1], [3, {:a, [line: 1], nil}]}, 2]}}

iex> Formulae.unit("3 > A + 2")
{"3 > a + 2",
  {:>, [],
    [{:-, [context: Formulae, import: Kernel],
      [3, {:+, [line: 1], [{:a, [line: 1], nil}, 2]}]}, 0]}}

iex> Formulae.unit("3 >= a + 2")
{"3 >= a + 2",
  {:>=, [],
    [{:-, [context: Formulae, import: Kernel],
      [3, {:+, [line: 1], [{:a, [line: 1], nil}, 2]}]}, 0]}}

iex> Formulae.unit("3 a > A + 2")
** (Formulae.SyntaxError) Formula [3 a > A + 2] syntax is incorrect (parsing): syntax error before: “a”.

iex> Formulae.unit("a + 2 = 3")
{"a + 2 = 3", {:==, [], [{:+, [line: 1], [{:a, [line: 1], nil}, 2]}, 3]}}

iex> Formulae.unit(~S|A = "3"|)
{"a = \"3\"", {:==, [], [{:a, [line: 1], nil}, "3"]}}