Exun.Pattern (exun v0.5.0)
Match ASTs. Functions umatch and match try to match patter with a real expression. Rules for matching, by example:
- umatch "f", "(any valid expression)"
Will always match f => expression
Ex: umatch "f","x^2+y"
- umatch "f'x", "exp"
Match f'x as exp
Ex: umatch "f'x", "-cos(x)"
- umatch "f<op>g", "exp"
Will tray to match f and g against exp using <op>=*,+,-,/,^ on any possible combination
Ex: umatch "a+b", "2*x^2+3"
- umatch "f*f'x", "exp"
Will match if can find a product on exp of the form f ** d(f)/dx
Ex: umatch "sin(x)*cos(x)"
- umatch "f*$f,x"
Will match if can find a product on exp of the form f ** integ(f,x)
- umatch "f(x,y)", "exp"
Will match if exp is a function call and can match x and y with its arguments.
Ex: umatch "f(a,b)", "function(2*x,y^3)"
- umatch "uv'x","sin(x) cos(x)", ["v*u'x"]
Will match u and v against "sin(x)cos(x)" and checks that condition "vu'x" does not contains a symbolic integral. This case is used for integrate by parts: $uv'x,x = u*v - $vu'x,x
Link to this section Summary
Functions
TODO: External testing, function roottype returns an atom with the type of the root tuple of expression. If you want to check if an expression is a symbolic integral, roottype(expr) must not be :integ For now, it returns true if there is not :integ inside ast
Get any combination from list that supports ssets spec
Get n sets (size of abstract list) from a list of m size (expression) this produces a quasy cartesian product for all combinations between right and left lists. For example, if left and right has the same size n, we will try all possible combinations one to one. If ther is more elements on right list then we also must handle partitions (tuples) and order inside... a mess you know
take a list an generate all possible list varying order of elements list can be of tye [a, [b,c],d] but b and c cannot be lists must produce [ [a,[b,c],d], [a,[c,b],d], [a,d,[b,c]], [a,d,[c,b]], [d,a,[b,c]], [d,a,[c,b]], [[b,c],a,d], [[b,c],d,a], [[c,b],a,d], [[c,b],d,a], ]
Extract sublist of l of size sizes extract [1,2,3,4,5],[1,2,2] -> [[1],[2,3],[4,5]]
Make some expansions in east in order to match complex matching expressions. For example match "ff'x" to "2x^3" will match if it is transformed to "2xx^2" so f=x^2
deriv match in two situations: if name is yet in map, its definition must be equal to exp. If not it will match if we can integrate expr; initially we ca use symbolic integration, but if in conditions name is used without deriv, the condition will no be true if we can not integrate it.
Match a function definition as matching f(x,y) <-> "xy", so put in map the match f=xy if f is not yet defined or it is and equals x*y If we use a pattern like f(x) then x must be in the expression expr in any way. If we use f(g(x)) then g(x) must be in the expression also
Match integral, only allowed as abstract form "$f,x"
All possible matchings from l2 to l1. l2 must be equal or greater in lenght, if not there is no possible match. Caller must comlpete l2 with 'unity', this is not going to happend here. l1 is abstract, l2 a real expression. # if map holds any definition from l1, match it before generalize; if we can't, return ko # if yes, reduce l2 and l1 for that definitions. We have to substitute map values into l1 # and then perform match # For now, try direct match; sin florituras
General matching function Try to match an abstract expresion agains real expression, for example abstract expression: u(x)*v(x)'x real expression: sin(x)^2
Sets each of size group than sums number Exun.Pattern.sizesets 7,4 -> [1, 1, 4, 1], [1, 1, 3, 2], [1, 2, 3, 1], [1, 2, 2, 2]] If you have a {{:m,op}, lst} and wants to pattern match lst against an abstract sum with 'n' variables, for example match '1+2x+3x^2+6x^3' with an abstract tree like 'a^2+b+c^3' so a=sqrt(3)x, b=1+2x, c=crt(6)x we have to try all possible groupings of the sum expression
Split expression in two ast, one of them without vari x These two ast only can be {:m,sum} or {:m,:mult} for now
Expand sublists taking one lement from each and building a new list [[a], [b,c]] -> [[a,b],[a,c]] [[a,b]] -> [a,b]
Make any possible sets of size n from list without order takeany([],[1,2,3,4],3) -> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
trx1: {{:m,:mult},lst} where k={:elev, {:vari,a},{some}} in list will double matched, original and replacing k with a^(some-remain_lst)a^(remain_lst) in a try to match ff'x <- "2x^3", so also will try "2x^(3-2)x^2" == "2x*x^2" and then f==x^2
User function, try to match and prints
Find vars of an expression
Link to this section Functions
allones?(list)
check_conds(map, cnd)
TODO: External testing, function roottype returns an atom with the type of the root tuple of expression. If you want to check if an expression is a symbolic integral, roottype(expr) must not be :integ For now, it returns true if there is not :integ inside ast
checkmap(map, key, val)
combin(arg1, arg2)
Get any combination from list that supports ssets spec
combin_expand(aast, east)
Get n sets (size of abstract list) from a list of m size (expression) this produces a quasy cartesian product for all combinations between right and left lists. For example, if left and right has the same size n, we will try all possible combinations one to one. If ther is more elements on right list then we also must handle partitions (tuples) and order inside... a mess you know
iex(1)> Exun.Pattern.combin_expand {{:m,:mult},[1,2,3]},{{:m,:mult},["a","b","c"]}
[
["a", "b", "c"],
["a", "c", "b"],
["b", "a", "c"],
["b", "c", "a"],
["c", "a", "b"],
["c", "b", "a"]
]
iex(2)> Exun.Pattern.combin_expand {{:m,:mult},[1,2]},{{:m,:mult},["a","b","c"]}
[
["a", {"b", "c"}],
[{"b", "c"}, "a"],
["a", {"c", "b"}],
[{"c", "b"}, "a"],
["b", {"a", "c"}],
[{"a", "c"}, "b"],
["b", {"c", "a"}],
[{"c", "a"}, "b"],
["c", {"a", "b"}],
[{"a", "b"}, "c"],
["c", {"b", "a"}],
[{"b", "a"}, "c"]
]
concatlist(lol)
expand_order(list)
take a list an generate all possible list varying order of elements list can be of tye [a, [b,c],d] but b and c cannot be lists must produce [ [a,[b,c],d], [a,[c,b],d], [a,d,[b,c]], [a,d,[c,b]], [d,a,[b,c]], [d,a,[c,b]], [[b,c],a,d], [[b,c],d,a], [[c,b],a,d], [[c,b],d,a], ]
extract(l, sizes)
Extract sublist of l of size sizes extract [1,2,3,4,5],[1,2,2] -> [[1],[2,3],[4,5]]
listornot(plexp)
match(taast, texpr, context, tconditions \\ [], transf \\ true)
match_ast(aast, aexp, conditions \\ [], dotransforms \\ true)
Make some expansions in east in order to match complex matching expressions. For example match "ff'x" to "2x^3" will match if it is transformed to "2xx^2" so f=x^2
mderiv(dr, expr, map)
deriv match in two situations: if name is yet in map, its definition must be equal to exp. If not it will match if we can integrate expr; initially we ca use symbolic integration, but if in conditions name is used without deriv, the condition will no be true if we can not integrate it.
mfdef(acall1, acall2, mainmap)
Match a function definition as matching f(x,y) <-> "xy", so put in map the match f=xy if f is not yet defined or it is and equals x*y If we use a pattern like f(x) then x must be in the expression expr in any way. If we use f(g(x)) then g(x) must be in the expression also
minteg(itr, expr, map)
Match integral, only allowed as abstract form "$f,x"
mklist_byindex(list, indexes)
mknumber(n, list)
mlist(a1, a2, mainmap)
mmult(aast, east, mainmap)
All possible matchings from l2 to l1. l2 must be equal or greater in lenght, if not there is no possible match. Caller must comlpete l2 with 'unity', this is not going to happend here. l1 is abstract, l2 a real expression. # if map holds any definition from l1, match it before generalize; if we can't, return ko # if yes, reduce l2 and l1 for that definitions. We have to substitute map values into l1 # and then perform match # For now, try direct match; sin florituras
mmult_inner(aast, east, mainmap)
mnode(aast, expr, map)
General matching function Try to match an abstract expresion agains real expression, for example abstract expression: u(x)*v(x)'x real expression: sin(x)^2
match u(x) = sin(x) and v(x)'x= sin(x) so v(x)=-cos(x)
u and v will be return in a map: %{"u(x)"=>"sin(x)", "v(x)"=>"-cos(x)"}
return a list of tuples {:ok, matched_defs} or {:ko, matched_defs} matched_defs is a map that holds definitions
par_inspect(arg)
permute(list)
rcombin(ssets, list, presolution)
remove_dups(los)
single_expand_order(list)
sizesets(number, group)
Sets each of size group than sums number Exun.Pattern.sizesets 7,4 -> [1, 1, 4, 1], [1, 1, 3, 2], [1, 2, 3, 1], [1, 2, 2, 2]] If you have a {{:m,op}, lst} and wants to pattern match lst against an abstract sum with 'n' variables, for example match '1+2x+3x^2+6x^3' with an abstract tree like 'a^2+b+c^3' so a=sqrt(3)x, b=1+2x, c=crt(6)x we have to try all possible groupings of the sum expression
split(arg, var)
Split expression in two ast, one of them without vari x These two ast only can be {:m,sum} or {:m,:mult} for now
subpermute(list)
Expand sublists taking one lement from each and building a new list [[a], [b,c]] -> [[a,b],[a,c]] [[a,b]] -> [a,b]
takeany(prefix, l, n)
Make any possible sets of size n from list without order takeany([],[1,2,3,4],3) -> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
transform(expr, exec)
trx1(lst)
trx1: {{:m,:mult},lst} where k={:elev, {:vari,a},{some}} in list will double matched, original and replacing k with a^(some-remain_lst)a^(remain_lst) in a try to match ff'x <- "2x^3", so also will try "2x^(3-2)x^2" == "2x*x^2" and then f==x^2
umatch(taast, texpr, tconditions \\ [], transf \\ true)
User function, try to match and prints
vars_of_expr(ast)
Find vars of an expression