formulae v0.1.2 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 ({:<, "sumOaSTS3E14CSMSb", 0}
) representation
for the formula given
Makes a valid (rigid) identifier out of AST
Checks if the given string represents the rigid identifier
Makes a string representation of a formula out of it’s rigid implementation
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
Revalidates the formula with bindings given.
Examples
iex> "a > 5" |> Formulae.check([a: 6])
true
iex> "a > 5" |> Formulae.check([a: 3])
false
iex> "a > 5" |> Formulae.check
false
Curries the formula by substituting the known bindings into it.
Example
iex> "(temp - time * 4) > speed / 3.14" |> Formulae.curry(temp: 7, speed: 3.14) |> Macro.to_string
"{7 - time * 4 - 1.0 > 0, {}}"
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
# This test issues a warning about “variable "a" does not exist and is being expanded to "a()"”
iex> Formulae.evaluate(Formulae.unit("a < 2"), [])
** (Formulae.RunnerError) Formula failed to run (compile): undefined function a/0.
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 ({:<, "sumOaSTS3E14CSMSb", 0}
) representation
for the formula given.
Example
iex> "(temp - time * 4) > speed / 3.14" |> Formulae.normalize
{:>, {"tempSMStimeSTS4SMSspeedSDS3E14", "temp - time * 4 - speed / 3.14"}, 0}
iex> "hello < 3.14" |> Formulae.normalize
{:<, {"hello", "hello"}, 3.14}
iex> "HELLO < 3.14" |> Formulae.normalize
{:<, {"hello", "HELLO"}, 3.14}
Makes a valid (rigid) identifier out of AST.
Examples
iex> “sum(a * 3.14) - b” |> Formulae.rigid! “sumOaSTS3E14CSMSb”
iex> “sum(a 3.14) - b ± 3” |> Formulae.rigid! ** (Formulae.SyntaxError) Formula [sum(a 3.14) - b ± 3] syntax is incorrect (symbols): NYI.
Checks if the given string represents the rigid identifier.
Examples
iex> Formulae.rigid?("hello")
true
iex> Formulae.rigid?("HELLO")
false
iex> Formulae.rigid?("hello world!")
false
iex> Formulae.rigid?("sum0")
true
iex> Formulae.rigid?("sum(3.14 * 42)")
false
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]}
iex> Formulae.unit("3 - a > 2")
{:>, [], [{:-, [line: 1], [3, {:a, [line: 1], nil}]}, 2]}
iex> Formulae.unit("3 > A + 2")
{:>, [],
[{:-, [context: Formulae, import: Kernel],
[3, {:+, [line: 1], [{:__aliases__, [counter: 0, line: 1], [:A]}, 2]}]}, 0]}
iex> Formulae.unit("3 >= a + 2")
** (Formulae.SyntaxError) Formula [3 >= a + 2] syntax is incorrect (operation): “>=”.
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")
{:==, [], [{:+, [line: 1], [{:a, [line: 1], nil}, 2]}, 3]}
iex> Formulae.unit(~S|A = "3"|)
{:==, [], [{:__aliases__, [counter: 0, line: 1], [:A]}, "3"]}