formulae v0.4.0 Formulae
A set of functions to deal with analytical formulae.
Summary
Functions
Guesses the binding this formula requires. FIXME: probably, more sophisticated way would be to analyze Macro.traverse
Revalidates the formula with bindings given
Curries the formula by substituting the known bindings into it
Evaluates normalized representation of formula
Returns a normalized representation for the formula given
Functions
Guesses the binding this formula requires. FIXME: probably, more sophisticated way would be to analyze Macro.traverse
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
Revalidates the formula with bindings given.
Examples
iex> "a > 5" |> Formulae.check([a: 6])
true
iex> "a > 5" |> Formulae.check([a: 5])
false
iex> "a > 5" |> Formulae.check([a: 3])
false
iex> "a < 5" |> Formulae.check([b: 42])
false
iex> "a > 5" |> Formulae.check([a: nil])
false
iex> "a < 5" |> Formulae.check([{:a, nil}])
false
iex> "a > 5" |> Formulae.check([{:a, 6}])
true
iex> "a > 5" |> Formulae.check([{:a, 5}])
false
iex> "a > 5" |> Formulae.check
false
Curries the formula by substituting the known bindings into it.
Example
iex> "(temp - foo * 4) > speed / 3.14"
...> |> Formulae.curry(temp: 7, speed: 3.14)
...> |> Macro.to_string()
"7 - foo * 4 > 3.14 / 3.14"
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
Returns a normalized representation for the formula given.
Example
iex> {_, {:>, _, 0}, bindings} = "(temp - time * 4) > speed / 3.14" |> Formulae.normalize
...> bindings
[:temp, :time, :speed]
iex> {_, {:<, _, 3.14}, bindings} = "hello < 3.14" |> Formulae.normalize
...> bindings
[:hello]
iex> {_, {:<, _, 3.14}, bindings} = "HELLO < 3.14" |> Formulae.normalize
...> bindings
[:hello]
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.
@todo Try to eval
rho before guards; premature optimization
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"]}}