Current section
Files
Jump to
Current section
Files
lib/exun_collect.ex
defmodule Exun.Collect do
@moduledoc """
Collect Math expression, try to simplify
"""
import Exun.Simpl
import Exun.Eq
import Exun.Fun
@doc """
Main collecting function. Try to simplify tree withou chaging its value
Gets and returns an AST, as produced by Exun.parse.
"""
def coll(tree) do
newtree =
tree
# |> IO.inspect(label: "make00, orig->mkrec")
|> mkrec()
|> expand_rec()
|> mkrec()
if eq(newtree, tree), do: newtree, else: coll(newtree)
end
@doc """
Expand mult(sum) to try collect more
"""
def expand_rec(ast) do
newast = expand(ast)
if ast == newast do
newast
else
expand_rec(newast)
end
end
defp expand({{:m, :suma}, l}), do: {{:m, :suma}, Enum.map(l, &expand(&1))}
defp expand({:deriv, f, v}), do: {:deriv, expand(f), v}
defp expand({:integ, f, v}), do: {:integ, expand(f), v}
defp expand({:fcall, f, args}), do: {:fcall, f, Enum.map(args, &expand(&1))}
defp expand({:unit, n, t}), do: {:unit, expand(n), t}
defp expand({:minus, a}), do: {:minus, expand(a)}
defp expand({:elev,a,{:numb, n}}) when n>0, do: {{:m,:mult},List.duplicate(a,n)}
defp expand({:elev, b, e}), do: {:elev, expand(b), expand(e)}
defp expand({{:m, :mult}, l}) do
tsuma = List.keyfind(l, {:m, :suma}, 0)
if tsuma != nil do
{_, lsuma} = tsuma
# Convert {:m,:mult} to {:m,:suma}
remain = {{:m, :mult}, List.delete(l, tsuma)}
{{:m, :suma}, Enum.map(lsuma, &mult(remain, &1))}
else
{{:m, :mult}, Enum.map(l, &expand(&1))}
end
end
defp expand(ast), do: ast
end