Commit 9802562f authored by Adam Blank's avatar Adam Blank
Browse files

Initial commit

parents
No related merge requests found
Showing with 1437 additions and 0 deletions
+1437 -0
{
"python.testing.pytestArgs": [
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
\ No newline at end of file
from support.parsing import parse
from support.canonicalize import simplify
from support.to_string import expr_to_string
import readline
def eval(expr):
result_parens = expr_to_string(simplify(parse(expr)), use_parens=True)
print(result_parens)
while True:
try:
expr = input("minimathematica$ ")
if expr in ['quit', 'quit()', 'exit', 'exit()']:
break
except EOFError:
print()
break
except KeyboardInterrupt:
print()
continue
eval(expr)
from support.expr_types import *
from functools import cache
from support.canonicalize import simplify
@cache
def evaluate_diff(expr, var):
"""
Relevant Expression Types (and fields):
- BinaryOperation b: b.left, b.right
- Function f: f.name, f.arguments
- SummationOperation s: s.values
- ProductOperation p: p.values
Variable types for below:
- OP_CHAR in ['+', '-', '*', '/', '^']
- FUNC_NAME in ['e', 'arctan']
- expr : Expression
- x : Expression
- y : Expression
- var : str
- xs : List[expr]
Available/Useful functions:
- is_constant(expr, var)
- is_op(expr, OP_CHAR)
- is_function(expr, FUNC_NAME)
- is_product(expr)
- is_summation(expr)
- Plus(x, y)
- Minus(x, y)
- Mul(x, y)
- Pow(x, y)
- Div(x, y)
- Summation(xs)
- Product(xs)
- Func(expr, xs)
- evaluate_diff(expr, var)
Differentation Rules to Handle:
- var
- constant w.r.t. var
- sum rule
- subtraction rule
- product rule
- division rule: DO THIS AS A RE-WRITE to multiplication, do not use division rule directly
- power rule for numerical exponent
- e^x rule (e^x is represented as a function e(x))
- arctan(x) rule
- sum rule for SummationOperation([x1, x2, x3, ...])
- product rule for ProductOperation([x1, x2, x3, ...])
"""
if is_constant(expr, var):
return None
if expr == var:
return None
if is_op(expr, '+'):
return None
# Uh oh...lots of cases are missing and the ones above seem wrong. :(
raise Exception("not implemented: " + str(expr))
from support.expr_types import *
from functools import cache
from support.canonicalize import *
from src.differentiation import evaluate_diff
from fractions import Fraction
EPSILON = 10**(-5)
MAX_ITER = 1000
INFINITY = 10**(1000)
ZERO = 10**(-1000)
@cache
def newton(f, x0, var):
"""
The goal of Newton's method is to find a zero of the provided function f w.r.t. the variable var.
It works by iteratively making guesses (with an initial guess of x0) until it's close enough to
a correct answer.
Some useful functions:
- abs(x): Takes the absolute value of x
- coerce_float(x): Converts any number (int, Fraction, Decimal, float) to a float for
comparison with other floats.
- evaluate_diff(expr, var): This is the function you wrote in the previous part!
- eval_expr(expr, {v1: val1, v2:, val2, ...}): Plugs in val1 for v1, val2 for v2, etc. into expr
and simplifies as much of expr as possible.
Algorithm:
Until we've tried MAX_ITER times...
Our current estimate is x_0.
Calculate f(x_0) and f'(x_0).
If both are at least INFINITY, assume we've failed.
If f'(x_0) is at most ZERO, assume we've failed.
Calculate a new estimate, x_1, where x_1 = x_0 - (f(x_0)/f'(x_0))
If we've converged on a value (x_0 and x_1 are close enough with tolerance EPSILON)...
If f(x_1) is close enough to 0 with tolerance EPSILON, we've found a zero! Return it!
Otherwise, assume we've failed.
"""
return None
\ No newline at end of file
from math import floor
import support.parsing
from support.canonicalize import *
from src.newton import newton
from src.differentiation import evaluate_diff
from math import factorial, ceil
N = 10
@cache
def nth_derivative(func, n):
return None
@cache
def taylor(func, x):
return None
def taylor_at(func, b, f_at_b):
return None
def max_error(func, a, x, n=N):
return None
@cache
def estimate(func, x, a, func_at_a):
return None
PI = 3.14159265358979323846264338327950288419716939937510582097494
def arctan(x):
if x == 0:
return 0, 0
elif x == 1:
return PI/4, Decimal(10**-16)
a = 0
total_error = Decimal(0)
prev_value = 0
while a + 1 <= x:
prev_value = estimate('arctan', a + 1, a, prev_value)
total_error += max_error('arctan', a, a + 1)
a += 1
print(total_error)
return estimate('arctan', x, floor(x), prev_value), total_error + max_error('arctan', floor(x), x)
if __name__ == "__main__":
for i in range(0, 4):
for j in range(10):
x = i + j/10
v, e = arctan(Decimal(x))
print('arctan(' + str(x) + ') =', v, '(error <= ' + str(e) + ')')
from support.parsing import parse
from math import prod
from support.expr_types import *
from collections import Counter
import copy
from support.to_string import expr_to_string
import fractions
import numbers
from functools import cache
from decimal import *
getcontext().prec = 20
EPSILON = 10**(-3)
@cache
def create_comm(expr, l, r, op):
is_com_of_vals = is_add_of_values if op == '+' else is_mul_of_values
Op = SumOperation if op == '+' else ProductOperation
if is_com_of_vals(expr):
expr = Op(tuple([l, r]))
elif isinstance(l, BinaryOperation) and l.op == op:
expr = Op(tuple([l.left, l.right, r]))
elif isinstance(r, BinaryOperation) and r.op == op:
expr = Op(tuple([l, r.left, r.right]))
elif isinstance(l, Op) and isinstance(r, Op):
expr = Op(tuple(l.values + r.values))
elif isinstance(l, Op) and (is_value(r) or is_com_of_vals(r)):
expr = Op(tuple(l.values + tuple([r])))
elif isinstance(r, Op) and (is_value(l) or is_com_of_vals(l)):
expr = Op(tuple([l]) + r.values)
else:
return expr
return collapse_comm(expr.values, op, Op)
@cache
def is_monomial(m):
return isinstance(m, Number) or isinstance(m, str) or (isinstance(m, Term) and is_monomial(m.right)) or\
(isinstance(m, BinaryOperation) and (\
(m.op == '^' and is_monomial(m.left) == 1 and isinstance(m.right, Number)) or\
(m.op == '*' and (\
is_monomial(m.right) and isinstance(m.left, Number) or
is_monomial(m.left) and isinstance(m.right, Number)\
))
)
)
@cache
def get_monomial_coefficient(m):
if isinstance(m, str):
return 1
if isinstance(m, Number):
return m
if isinstance(m, Term):
return m.left
if isinstance(m, BinaryOperation):
if is_monomial(m.left) and m.op == '^' and isinstance(m.right, Number):
return 1
if is_monomial(m.left) and m.op == '*' and isinstance(m.right, Number):
return m.right
if is_monomial(m.right) and m.op == '*' and isinstance(m.left, Number):
return m.left
raise Exception("not a monomial")
@cache
def get_monomial_power(m):
if isinstance(m, str):
return 1
if isinstance(m, Number):
return 0
if isinstance(m, Term) and is_monomial(m.right):
return get_monomial_power(m.right)
if isinstance(m, BinaryOperation):
if is_monomial(m.left) and m.op == '^' and isinstance(m.right, Number):
return m.right
if is_monomial(m.left) and m.op == '*' and isinstance(m.right, Number):
return get_monomial_power(m.left)
if is_monomial(m.right) and m.op == '*' and isinstance(m.left, Number):
return get_monomial_power(m.right)
raise Exception("not a monomial")
@cache
def get_monomial_base(m, op):
if isinstance(m, str):
return m
if isinstance(m, Number):
return 1
if isinstance(m, Term) and is_monomial(m.right):
return get_monomial_base(m.right, op)
if isinstance(m, BinaryOperation):
if is_monomial(m.left) and m.op == '^' and isinstance(m.right, Number):
return m.left if op == '*' else m
if is_monomial(m.left) and m.op == '*' and isinstance(m.right, Number):
return get_monomial_base(m.left, op)
if is_monomial(m.right) and m.op == '*' and isinstance(m.left, Number):
return get_monomial_base(m.right, op)
raise Exception("not a monomial")
@cache
def get_base(a, op):
if isinstance(a, Number):
return 1
if is_monomial(a):
return get_monomial_base(a, op)
if isinstance(a, BinaryOperation) and a.op == '^' and isinstance(a.left, Number):
return a.left
return a
def coerce_float(x):
if x is None:
return Decimal('Infinity')
if is_int(x): x = Decimal(x)
if isinstance(x, fractions.Fraction): x = Decimal(x.numerator)/Decimal(x.denominator)
if isinstance(x, float): x = Decimal(x)
return x
@cache
def collect_likes(terms, op):
by_var = {}
for t in terms:
s = simplify(t)
v = frozenset(collect_variables(s))
if v not in by_var:
by_var[v] = []
by_var[v].append(s)
result = []
for varset in by_var:
exprs = by_var[varset]
by_func = {}
for a in exprs:
f = get_base(a, op)
if f not in by_func:
by_func[f] = []
by_func[f].append(a)
for func in by_func:
funcset = by_func[func]
if op == '*':
coeff = 1
power = 0
col = []
rest = []
for f in funcset:
if isinstance(f, Number):
if int(f) == f:
f = int(f)
if int(coeff) == coeff:
coeff = int(coeff)
if isinstance(coeff, Decimal) or isinstance(f, Decimal) or isinstance(coeff, float) or isinstance(f, float):
coeff = coerce_float(coeff)
f = coerce_float(f)
coeff *= f
elif is_monomial(f):
coeff *= get_monomial_coefficient(f)
power += get_monomial_power(f)
elif isinstance(f, BinaryOperation) and f.op == '^' and isinstance(f.left, Number) and len(collect_variables(f.right)) > 0:
col.append(simplify(f.right))
else:
rest.append(simplify(f))
if is_monomial(f) or isinstance(f, Number):
result.append(simplify(Term(coeff, BinaryOperation('^', func, power))))
elif len(col) > 0:
result.append(simplify(BinaryOperation('^', func, SumOperation(tuple(col)))))
result += tuple(rest)
elif op == '+':
coeff = 0
for f in funcset:
if isinstance(f, Number):
if int(f) == f:
f = int(f)
if int(coeff) == coeff:
coeff = int(coeff)
if isinstance(coeff, Decimal) or isinstance(f, Decimal) or isinstance(coeff, float) or isinstance(f, float):
coeff = coerce_float(coeff)
f = coerce_float(f)
coeff += f
elif is_monomial(f):
coeff += get_monomial_coefficient(f)
else:
result.append(simplify(f))
if coeff == 1:
result.append(func)
elif func is None:
result.append(coeff)
elif coeff != 0:
result.append(simplify(Term(coeff, func)))
return tuple(result)
@cache
def collapse_comm(vals, op, Op):
recs = [tuple(x.values) for x in vals if isinstance(x, Op)]
vals = [x for x in vals if not isinstance(x, Op)]
for vs in recs:
vals += vs
vals = tuple([simplify(x) for x in vals])
vals = collect_likes(vals, op)
vals = [simplify(x) for x in vals]
if op == '*':
t = None
const = None
expr = Op(tuple(vals))
if len(expr.values) == 1:
return expr.values[0]
if len(expr.values) == 0:
return 0 if op == '+' else 1
return expr
@cache
def evaluate_function(f):
if f.name == 'diff':
from src.differentiation import evaluate_diff
x = simplify(evaluate_diff(simplify(f.arguments[0]), f.arguments[1]))
if is_constant(x, f.arguments[1]):
return (True, x)
return (False, x)
elif f.name == 'arctan':
return (False, Function(f.name, tuple([simplify(f.arguments[0])])))
elif f.name == 'e':
if f.arguments[0] == 0:
return (True, 1)
else:
return (False, f)
elif f.name == 'sqrt':
return (False, f)
elif f.name == 'newton':
from src.newton import newton
return (True, newton(*f.arguments))
raise Exception("function not implemented")
@cache
def replace_in_expr(expr, x, y):
if isinstance(expr, Number):
return expr
if isinstance(expr, Variable) and expr == x:
return y
if isinstance(expr, Variable) and expr != x:
return expr
if isinstance(expr, BinaryOperation):
return BinaryOperation(expr.op, replace_in_expr(expr.left, x, y), replace_in_expr(expr.right, x, y))
if isinstance(expr, Function):
f = Function(expr.name, tuple([replace_in_expr(a, x, y) for a in expr.arguments]))
if f.name == 'sqrt':
from src.newton import newton
x = newton(Minus(Pow('x', 2), f.arguments[0]), 2, 'x')
return x
return f
if isinstance(expr, Term):
return Term(expr.left, replace_in_expr(expr.right, x, y))
if isinstance(expr, SumOperation):
return SumOperation(tuple([replace_in_expr(z, x, y) for z in expr.values]))
if isinstance(expr, ProductOperation):
return ProductOperation(tuple([replace_in_expr(z, x, y) for z in expr.values]))
raise Exception("replace not implemented for: " + str(expr))
def eval_expr(expr, args):
return _eval_expr(expr, tuple(args.items()))
@cache
def _eval_expr(expr, args):
try:
for x, y in args:
expr = simplify(replace_in_expr(expr, x, y))
return expr
except (ZeroDivisionError, OverflowError):
return None
def _simplify(expr):
expr = reduce_expr(expr)
if isinstance(expr, SumOperation):
expr = collapse_comm(tuple([simplify(x) for x in expr.values]), '+', SumOperation)
if isinstance(expr, ProductOperation) and len(expr.values) == 2 and isinstance(expr.values[0], Number):
expr = Term(simplify(expr.values[0]), simplify(expr.values[1]))
if isinstance(expr, ProductOperation) and len(expr.values) == 2 and isinstance(expr.values[1], Number):
expr = Term(simplify(expr.values[1]), simplify(expr.values[0]))
if isinstance(expr, ProductOperation):
expr = collapse_comm(tuple([simplify(x) for x in expr.values]), '*', ProductOperation)
if isinstance(expr, Term):
r = simplify(expr.right)
if isinstance(r, Number):
expr = simplify(BinaryOperation('*', expr.left, r))
elif isinstance(expr.right, Term):
a = expr.left
b = expr.right.left
if is_int(a): a = int(a)
if is_int(b): b = int(b)
if isinstance(a, Decimal) or isinstance(b, Decimal):
a = coerce_float(a)
b = coerce_float(b)
expr = Term(simplify(a*b), simplify(expr.right.right))
else:
expr = Term(expr.left, simplify(expr.right))
if isinstance(expr, BinaryOperation):
l_is_const, l = _simplify(expr.left)
r_is_const, r = _simplify(expr.right)
if l_is_const and r_is_const:
if is_int(l): l = int(l)
if is_int(r): r = int(r)
if isinstance(l, Decimal) or isinstance(r, Decimal) or isinstance(l, float) or isinstance(r, float):
l = coerce_float(l)
r = coerce_float(r)
if expr.op == '/':
if isinstance(l, Decimal) or isinstance(r, Decimal) or isinstance(l, float) or isinstance(r, float):
if abs(r) < EPSILON:
raise ZeroDivisionError()
return (True, l / r)
return (True, fractions.Fraction(l, r))
elif expr.op == '+': return (True, l + r)
elif expr.op == '-': return (True, l - r)
elif expr.op == '*': return (True, l * r)
elif expr.op == '^': return (True, l ** r)
raise Exception("binary op not handled: " + str(expr.op))
old_expr = expr
expr = BinaryOperation(old_expr.op, l, r)
if old_expr.op == '+': expr = create_comm(expr, l, r, '+')
elif old_expr.op == '*': expr = create_comm(expr, l, r, '*')
if isinstance(expr, fractions.Fraction):
if expr.denominator == 1:
return (True, expr.numerator)
return (True, expr)
elif isinstance(expr, Number) and int(expr) == expr:
return (True, int(expr))
elif isinstance(expr, Number) and isinstance(expr, Decimal):
return (True, Decimal(expr))
elif isinstance(expr, Number):
return (True, expr)
if isinstance(expr, Function):
return evaluate_function(expr)
return (False, expr)
def reduce_expr(expr):
expr = distribute(expr)
expr = addition_reductions(expr)
expr = division_reductions(expr)
expr = multiplication_reductions(expr)
expr = power_reductions(expr)
return expr
@cache
def simplify(expr):
if isinstance(expr, fractions.Fraction):
if expr.denominator == 1:
return expr.numerator
return expr
elif isinstance(expr, Number) and int(expr) == expr:
return int(expr)
elif isinstance(expr, Number) and isinstance(expr, Decimal):
return Decimal(expr)
elif isinstance(expr, Number):
return expr
old = None
while expr != old:
old = copy.copy(expr)
v, expr = _simplify(expr)
if v is None:
return expr
return expr
# a * (x + y)
def distribute(expr):
if isinstance(expr, BinaryOperation) and expr.op == '*':
if isinstance(expr.left, BinaryOperation) and expr.left.op in set(['+', '-']):
expr = BinaryOperation(expr.left.op, BinaryOperation('*', left=expr.left.left, right=expr.right), BinaryOperation('*', left=expr.left.right, right=expr.right))
elif isinstance(expr.right, BinaryOperation) and expr.right.op in set(['+', '-']):
expr = BinaryOperation(expr.right.op, BinaryOperation('*', left=expr.left, right=expr.right.left), BinaryOperation('*', left=expr.left, right=expr.right.right))
elif isinstance(expr.left, SumOperation):
expr = SumOperation(tuple([BinaryOperation('*', left=expr.right, right=x) for x in expr.left.values]))
elif isinstance(expr.right, SumOperation):
expr = SumOperation(tuple([BinaryOperation('*', left=expr.left, right=x) for x in expr.right.values]))
if isinstance(expr, ProductOperation):
sums = []
rest = []
for x in expr.values:
if (isinstance(x, BinaryOperation) and x.op == '+') or isinstance(x, SumOperation):
sums.append(x)
else:
rest.append(x)
if len(sums) > 0:
while len(rest) > 0:
x = rest.pop()
sums[0] = BinaryOperation('*', x, sums[0])
expr = ProductOperation(tuple(sums + rest))
return expr
def power_reductions(expr):
if isinstance(expr, BinaryOperation) and expr.op == '^':
if isinstance(expr.left, Number):
if expr.left == 0:
return 0
if expr.left == 1:
return 1
if isinstance(expr.right, Number):
if expr.right == 0:
return 1
if expr.right == 1:
return expr.left
if isinstance(expr, Term) and isinstance(expr.right, BinaryOperation) and expr.right.op == '^':
if isinstance(expr.right.right, Number):
if expr.right.right == 0:
return expr.left
if expr.right.right == 1:
return simplify(Term(expr.left, expr.right.left))
return expr
def addition_reductions(expr):
if isinstance(expr, BinaryOperation) and expr.op == '+':
if isinstance(expr.left, Number):
if expr.left == 0:
return expr.right
if isinstance(expr.right, Number):
if expr.right == 0:
return expr.left
if isinstance(expr, BinaryOperation) and expr.op == '-':
if isinstance(expr.left, Number):
if expr.right == 0:
return expr.left
return BinaryOperation('+', simplify(expr.left), simplify(BinaryOperation('*', -1, expr.right)))
return expr
def division_reductions(expr):
if isinstance(expr, BinaryOperation) and expr.op == '/':
if expr.right == 1:
return expr.left
if is_monomial(expr.left) and is_monomial(expr.right):
l = get_monomial_base(expr.left, '*'), get_monomial_power(expr.left), get_monomial_coefficient(expr.left)
r = get_monomial_base(expr.right, '*'), get_monomial_power(expr.right), get_monomial_coefficient(expr.right)
if l[0] == r[0] and isinstance(l[2], numbers.Rational) and isinstance(r[2], numbers.Rational):
x = simplify(BinaryOperation('*', fractions.Fraction(l[2], r[2]), BinaryOperation('^', l[0], BinaryOperation('-', l[1], r[1]))))
return x
if isinstance(expr.left, Term) and isinstance(expr.right, Term):
return Term(simplify(fractions.Fraction(expr.left.left, expr.right.left)), simplify(BinaryOperation('/', expr.left.right, expr.right.right)))
if len(collect_variables(expr.left)) > 0 and isinstance(expr.right, Number):
return BinaryOperation('*', simplify(fractions.Fraction(1, expr.right)), expr.left)
if len(collect_variables(expr.right)) > 0 and isinstance(expr.left, Number):
result = BinaryOperation('*', expr.left, BinaryOperation('/', 1, expr.right))
if expr.right == 1:
return expr.left
return expr
def multiplication_reductions(expr):
if isinstance(expr, BinaryOperation) and expr.op == '*':
if isinstance(expr.left, Number):
if expr.left == 0:
return 0
elif expr.left == 1:
return expr.right
if isinstance(expr.right, Number):
if expr.right == 0:
return 0
elif expr.right == 1:
return expr.left
if isinstance(expr, Term):
if expr.left == 0:
return 0
elif expr.left == 1:
return expr.right
if isinstance(expr, ProductOperation):
expr = ProductOperation(tuple([simplify(x) for x in expr.values if x != 1]))
if len(expr.values) == 1:
expr = expr.values[0]
return expr
import numbers
from collections import namedtuple
from functools import cache
Variable = str
Number = numbers.Number
BinaryOperation = namedtuple('BinaryOperation', ['op', 'left', 'right'])
SumOperation = namedtuple('SumOperation', ['values'])
ProductOperation = namedtuple('ProductOperation', ['values'])
Function = namedtuple('Function', ['name', 'arguments'])
Term = namedtuple('Term', ['left', 'right'])
from support.to_string import expr_to_string
BinaryOperation.__str__ = expr_to_string
SumOperation.__str__ = expr_to_string
ProductOperation.__str__ = expr_to_string
Function.__str__ = expr_to_string
Term.__str__ = expr_to_string
def is_constant(expr, var):
return var not in collect_variables(expr) and 'e' not in collect_variables(expr)
def is_int(expr):
try:
return isinstance(expr, Number) and int(expr) == expr
except OverflowError:
return False
def is_value(expr):
return isinstance(expr, Variable) or isinstance(expr, Number) or isinstance(expr, Term)
def is_add_of_values(expr):
return isinstance(expr, BinaryOperation) and expr.op == '+' and is_value(expr.left) and is_value(expr.right)
def is_mul_of_values(expr):
return isinstance(expr, BinaryOperation) and expr.op == '*' and is_value(expr.left) and is_value(expr.right)
@cache
def collect_variables(expr):
if isinstance(expr, Number):
return frozenset()
if isinstance(expr, Variable):
return frozenset([expr])
elif isinstance(expr, BinaryOperation):
return collect_variables(expr.left) | collect_variables(expr.right)
elif isinstance(expr, Term):
return collect_variables(expr.right)
elif isinstance(expr, Function):
result = frozenset()
for x in expr.arguments:
result |= collect_variables(x)
return result
elif isinstance(expr, SumOperation) or isinstance(expr, ProductOperation):
result = frozenset()
for x in expr.values:
result |= collect_variables(x)
return result
raise Exception("unimplemented collect: " + str(expr))
def is_op(expr, op):
return isinstance(expr, BinaryOperation) and expr.op == op or\
isinstance(expr, Term) and op == '*'
def is_product(expr):
return isinstance(expr, ProductOperation)
def is_summation(expr):
return isinstance(expr, SumOperation)
def is_function(expr, func):
return isinstance(expr, Function) and expr.name == func
def Mul(x, y):
return BinaryOperation('*', x, y)
def Plus(x, y):
return BinaryOperation('+', x, y)
def Minus(x, y):
return BinaryOperation('-', x, y)
def Pow(x, y):
return BinaryOperation('^', x, y)
def Div(x, y):
return BinaryOperation('/', x, y)
def Product(xs):
from support.canonicalize import simplify
return simplify(ProductOperation(values=tuple(xs)))
def Summation(xs):
from support.canonicalize import simplify
return simplify(SumOperation(values=tuple(xs)))
def Func(f, args):
if isinstance(args, str):
args = [args]
from support.canonicalize import simplify
return simplify(Function(f, tuple(args)))
import enum
import re
from support.expr_types import *
class TokenType(enum.Enum):
T_NUM = 0
T_PLUS = 1
T_MINUS = 2
T_MULT = 3
T_DIV = 4
T_LPAR = 5
T_RPAR = 6
T_END = 7
T_VAR = 8
T_POW = 9
T_FUN = 10
T_COMMA = 11
T_GT = 12
T_ARROW = 13
class Node:
def __init__(self, token_type, value=None, charno=-1):
self.token_type = token_type
self.value = value
self.charno = charno
self.children = []
def __str__(self):
if self.token_type in [TokenType.T_NUM, TokenType.T_VAR]:
return str(self.value)
elif self.token_type == TokenType.T_ARROW:
return str(self.children[0]) + " -> " + str(self.children[1])
elif self.token_type == TokenType.T_FUN:
return self.value[0] + "(" + str(self.value[1]) + ")"
else:
return str(self.value) + (("(" + ", ".join([str(x) for x in self.children]) + ")") if len(self.children) > 0 else "")
def __repr__(self):
return str(self)
mappings = {
'+': TokenType.T_PLUS,
'-': TokenType.T_MINUS,
'*': TokenType.T_MULT,
'/': TokenType.T_DIV,
'^': TokenType.T_POW,
'(': TokenType.T_LPAR,
')': TokenType.T_RPAR
}
rev_map = {}
for k in mappings:
rev_map[mappings[k]] = k
def lexical_analysis(s):
tokens = []
for i, c in enumerate(s):
if re.match(r'>', c):
token = Node(TokenType.T_GT)
elif c in mappings:
token_type = mappings[c]
token = Node(token_type, value=c, charno=i)
elif re.match(r',', c):
token = Node(TokenType.T_COMMA)
elif re.match(r'[0-9.]', c):
token = Node(TokenType.T_NUM, value=c, charno=i)
elif re.match(r'[a-z]', c):
token = Node(TokenType.T_VAR, value=c, charno=i)
elif re.match(r'\s', c):
continue
else:
raise Exception('Invalid token: {}'.format(c))
if len(tokens) > 0 and token.token_type == tokens[-1].token_type and token.token_type in [TokenType.T_NUM, TokenType.T_VAR]:
tokens[-1].value += token.value
else:
tokens.append(token)
tokens.append(Node(TokenType.T_END))
return tokens
def match(tokens, token):
if tokens[0].token_type == token:
return tokens.pop(0)
else:
print(tokens)
raise Exception('Invalid syntax on token {}'.format(tokens[0].token_type))
def parse_e(tokens):
left_node = parse_e2(tokens)
while tokens[0].token_type in [TokenType.T_PLUS, TokenType.T_MINUS]:
node = tokens.pop(0)
if node.token_type == TokenType.T_MINUS and tokens[0].token_type == TokenType.T_GT:
_ = tokens.pop(0)
node = Node(TokenType.T_ARROW)
node.children.append(left_node)
node.children.append(parse_e2(tokens))
left_node = node
return left_node
def parse_e2(tokens):
left_node = parse_e3(tokens)
while tokens[0].token_type in [TokenType.T_MULT, TokenType.T_DIV]:
node = tokens.pop(0)
node.children.append(left_node)
node.children.append(parse_e3(tokens))
left_node = node
return left_node
def parse_e3(tokens):
left_node = parse_e4(tokens)
while tokens[0].token_type in [TokenType.T_POW]:
node = tokens.pop(0)
node.children.append(left_node)
node.children.append(parse_e4(tokens))
left_node = node
return left_node
def parse_e4(tokens):
if tokens[0].token_type in [TokenType.T_NUM]:
return tokens.pop(0)
elif tokens[0].token_type in [TokenType.T_VAR]:
if len(tokens) == 1 or tokens[1].token_type != TokenType.T_LPAR:
return tokens.pop(0)
else:
f = tokens.pop(0)
match(tokens, TokenType.T_LPAR)
if tokens[0].token_type == TokenType.T_RPAR:
expressions = []
else:
expressions = [parse_e(tokens)]
while tokens[0].token_type == TokenType.T_COMMA:
match(tokens, TokenType.T_COMMA)
expressions.append(parse_e(tokens))
match(tokens, TokenType.T_RPAR)
return Node(TokenType.T_FUN, value=(f.value, expressions), charno=f.charno)
elif tokens[0].token_type == TokenType.T_MINUS:
tokens.pop(0)
node = Node(TokenType.T_MINUS)
node.children = [parse_e(tokens)]
return node
match(tokens, TokenType.T_LPAR)
expression = parse_e(tokens)
match(tokens, TokenType.T_RPAR)
return expression
def _convert_ast(ast):
if ast.token_type in rev_map:
# Assuming this is unary negation for now....
if len(ast.children) == 1:
return BinaryOperation('*', -1, _convert_ast(ast.children[0]))
return BinaryOperation(rev_map[ast.token_type], _convert_ast(ast.children[0]), _convert_ast(ast.children[1]))
elif ast.token_type == TokenType.T_ARROW:
return BinaryOperation('->', _convert_ast(ast.children[0]), _convert_ast(ast.children[1]))
elif ast.token_type == TokenType.T_FUN:
return Function(ast.value[0], tuple([_convert_ast(x) for x in ast.value[1]]))
elif ast.token_type == TokenType.T_NUM:
try:
return int(ast.value)
except:
return float(ast.value)
else:
return ast.value
def parse(inputstring):
tokens = lexical_analysis(inputstring)
ast = parse_e(tokens)
match(tokens, TokenType.T_END)
ast = _convert_ast(ast)
return ast
from support.expr_types import *
from decimal import Decimal
def expr_to_string(expr, use_parens=True, use_spaces=True):
from support.canonicalize import simplify
expr = simplify(expr)
if expr is None:
return "?"
if isinstance(expr, Number) or isinstance(expr, Variable):
if (isinstance(expr, float) or isinstance(expr, Decimal)) and float(expr).is_integer():
return str(int(float((expr))))
if isinstance(expr, Decimal):
return str(float(expr))
return str(expr)
elif isinstance(expr, SumOperation):
return("(" if use_parens else "") + " + ".join([expr_to_string(x, use_parens=False, use_spaces=False) for x in expr.values]) + (")" if use_parens else "")
elif isinstance(expr, ProductOperation):
return " * ".join([expr_to_string(x) for x in expr.values])
# Commutative binary operations...
elif isinstance(expr, BinaryOperation):
use_parens = True
return ("(" if use_parens else "") + expr_to_string(expr.left) + (" " if use_spaces else "") + expr.op + (" " if use_spaces else "") + expr_to_string(expr.right) + (")" if use_parens else "")
elif isinstance(expr, Term):
return (str(expr.left) if expr.left != 1 else "") + "*" + expr_to_string(expr.right, use_spaces=False, use_parens=False)
elif isinstance(expr, Function):
return expr.name + "(" + ", ".join([expr_to_string(x, use_parens=False) for x in expr.arguments]) + ")"
else:
raise Exception(expr)
from sympy import series, atan, oo, nsimplify, poly, diff
from sympy.calculus.util import Interval, maximum
from sympy.abc import x
import math
from src.taylor import arctan
from decimal import Decimal
import pytest
def term(N, xval, a):
ivl = Interval(xval - 0.001, a + 0.001) + Interval(a - 0.001, xval + 0.001)
d = diff(f, x, N + 1)
M = maximum(d, x, ivl)
return nsimplify(abs(((M * ((x - a)**(N + 1))/math.factorial(N + 1)).subs(x, xval))))
f = atan(x)
def approx_atan(N, xval, a):
return nsimplify(series(f, x=x, x0=a, n=N+1).removeO().subs(x, xval).doit()), term(N, xval, a)
xval = 0.2
for q in range(0, 20):
xval = q / 10
result, error = approx_atan(11, xval, 0)
#print(xval, float(error), abs(math.atan(xval) - result) <= float(error))
v, e = arctan(Decimal(xval))
#print(xval, float(error), abs(math.atan(xval) - float(v)) <= float(error))
print(xval, float(e), abs(math.atan(xval) - float(v)), abs(math.atan(xval) - float(v)) <= float(e))
import pytest
from sympy import sympify, simplify, expand, nsimplify, Eq, solve
from fractions import Fraction
from termcolor import colored
from support.parsing import parse
from support.to_string import expr_to_string
from support.canonicalize import simplify as oursimplify
from support.canonicalize import collect_variables
from random import seed, uniform, shuffle
from tests.helpers.tests import cases, cases_extend
from tests.helpers.tests2 import cases2, cases2_extend
seed(1000)
def us_to_sympy(expr):
return expr.replace("^", "**").replace("e(", "exp(").replace("arctan(", "atan(")
def sympy_to_us(expr):
return expr.replace("**", "^").replace("exp(", "e(").replace("atan(", "arctan(")
def pprint(expr, pr=True):
orig = expr_to_string(expr)
result = expr_to_string(oursimplify(expr), use_parens=False)
result_parens = expr_to_string(oursimplify(expr), use_parens=True)
ref = nsimplify(expand(sympify(us_to_sympy(orig))))
if pr:
print(orig, end=" ")
print(colored("=", 'yellow'), end=" ")
print(result, end=" ")
print(colored("?=", 'yellow'), end=" ")
print(str(ref))
assert(nsimplify(expand(sympify(us_to_sympy(result)))) == ref)
from src.newton import newton
x0s = [x/10 for x in range(-50, 50)] + [x/50 for x in range(-10, 10)] + [3.35, 1200]
@pytest.mark.parametrize('expr', cases + cases2)
def test_newton(expr):
orig = expr_to_string(oursimplify(parse(expr)))
ref = solve(Eq(expand(sympify(us_to_sympy(orig))), 0))
ref = [float(x) for x in ref if x.is_real]
if not len(ref):
ref = None
expr = oursimplify(parse(expr))
var = list(collect_variables(expr))
if not var:
us = None
else:
us = newton(expr, 1, var[0])
if ref is None or us is not None:
assert ref == us if ref is None else any([pytest.approx(float(us), 0.001) == x for x in ref])
else:
for x in x0s:
try:
us = newton(expr, x, var[0])
if us is not None:
assert any([pytest.approx(float(us), 0.001) == x for x in ref])
break
except ZeroDivisionError:
continue
else:
assert False
import pytest
from sympy import sympify, simplify, expand, nsimplify, Eq, solve
from fractions import Fraction
from termcolor import colored
from support.parsing import parse
from support.to_string import expr_to_string
from support.canonicalize import simplify as oursimplify
from support.canonicalize import collect_variables
from random import seed, uniform, shuffle
from tests.helpers.tests import cases, cases_extend
from tests.helpers.tests2 import cases2, cases2_extend
seed(1000)
def us_to_sympy(expr):
return expr.replace("^", "**").replace("e(", "exp(").replace("arctan(", "atan(")
def sympy_to_us(expr):
return expr.replace("**", "^").replace("exp(", "e(").replace("atan(", "arctan(")
def pprint(expr, pr=True):
orig = expr_to_string(expr)
result = expr_to_string(oursimplify(expr), use_parens=False)
result_parens = expr_to_string(oursimplify(expr), use_parens=True)
ref = nsimplify(expand(sympify(us_to_sympy(orig))))
if pr:
print(orig, end=" ")
print(colored("=", 'yellow'), end=" ")
print(result, end=" ")
print(colored("?=", 'yellow'), end=" ")
print(str(ref))
assert(nsimplify(expand(sympify(us_to_sympy(result)))) == ref)
@pytest.mark.parametrize('expr', [
"diff(x + 1, x)",
"3*diff((4*x)^2 + 1, x)",
])
def test_basic_differentiation(expr):
pprint(parse(expr), False)
@pytest.mark.parametrize('expr', cases + cases_extend)
def test_more_differentiation(expr):
pprint(parse(('diff(' + expr + ', x)')), False)
@pytest.mark.parametrize('expr', cases2 + cases2_extend)
def test_moremore_differentiation(expr):
pprint(parse(('diff(' + expr + ', x)')), False)
@pytest.mark.parametrize('expr', cases + cases_extend)
def test_moremoremore_differentiation(expr):
pprint(parse(('diff(diff(' + expr + ', x), x)')), False)
@pytest.mark.parametrize('expr', cases2 + cases2_extend)
def test_moremoremore_differentiation(expr):
pprint(parse(('diff(diff(' + expr + ', x), x)')), False)
\ No newline at end of file
import pytest
from sympy import sympify, simplify, expand, nsimplify, Eq, solve
from fractions import Fraction
from termcolor import colored
from support.parsing import parse
from support.to_string import expr_to_string
from support.canonicalize import simplify as oursimplify
from support.canonicalize import collect_variables
from random import seed, uniform, shuffle
from tests.helpers.tests import cases, cases_extend
from tests.helpers.tests2 import cases2, cases2_extend
seed(1000)
def us_to_sympy(expr):
return expr.replace("^", "**").replace("e(", "exp(").replace("arctan(", "atan(")
def sympy_to_us(expr):
return expr.replace("**", "^").replace("exp(", "e(").replace("atan(", "arctan(")
def pprint(expr, pr=True):
orig = expr_to_string(expr)
result = expr_to_string(oursimplify(expr), use_parens=False)
result_parens = expr_to_string(oursimplify(expr), use_parens=True)
ref = nsimplify(expand(sympify(us_to_sympy(orig))))
if pr:
print(orig, end=" ")
print(colored("=", 'yellow'), end=" ")
print(result, end=" ")
print(colored("?=", 'yellow'), end=" ")
print(str(ref))
assert(nsimplify(expand(sympify(us_to_sympy(result)))) == ref)
@pytest.mark.parametrize('expr', [
"x + (1.5 + 2) + x+24",
"x + 2*x*(1.5+2)+x+24",
"x*2*x + 2*x*(1.5+2)+x+24",
"(x + 1) * (x + - 1)",
"x *3*( (x + 1) * (x + - 1))",
"x *3*( (2*x + 1) * (x/4 + - 1))",
"2^x *3*( (2*x + 1) * (x/4 + - 1))",
"(3*x + 5)/(2 * x^2 - 5*x - 3)",
])
def test_simplification(expr):
pprint(parse(expr), False)
@pytest.mark.parametrize('expr', cases + cases_extend)
def test_simplification2(expr):
pprint(parse(expr), False)
@pytest.mark.parametrize('expr', cases2 + cases2_extend)
def test_simplification3(expr):
pprint(parse(expr), False)
\ No newline at end of file
UNARIES = ["-%s", "e(%s)", "arctan(%s)"]
BINARIES = ["%s + %s", "%s - %s", "%s * %s", "%s / %s", "%s ^ %s"]
PROB_PARENTHESES = 0.3
PROB_BINARY = 0.8
def generate_expressions(scope, num_exp, num_ops):
scope = list(scope)
for _ in range(num_ops):
if random() < PROB_BINARY:
op = choice(BINARIES)
args = None
while not args or ('/' in op and args[1] == '0'):
args = (choice(scope), choice(scope))
ex = op % args
if random() < PROB_PARENTHESES:
ex = "(%s)" % ex
scope.append(ex)
else:
scope.append(choice(UNARIES) % choice(scope))
return scope[-num_exp:]
for x in generate_expressions(["0", "1", "2", "10", "100", "x"], 1000, 100):
print('"' + x + '"')
for x in generate_expressions(["0", "1", "2", "10", "100", "x"], 100, 100):
pprint(parse('diff(' + x + ', x)'))
cases = [
"((10 / x) / 1 / 1 + 100) + (2 * 100)",
"((10 / x) / 1 / 1 + 100) ^ (-(10 + 2) + 1 / 1 + 1 / 1)",
"((10 / x) / 1 / 1 + 100)",
"((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10)",
"(-(10 + 2) + 1 / 1 + 1 / 1)",
"(-1 * (10 / x) / 1 / 1 + (10 + 2))",
"(-2 + -100)",
"(1 - (10 / x) / 1 / 1 + (10 + 2))",
"(1 / 1 + 1 / 1 + (10 + 2) / 100 * (10 + 2) / (10 + 2) - (10 / x)) / 10 - x * (10 / x) / -1",
"(1 / 1 + 1 / 1 + (10 + 2) / 100 * (10 + 2) / (10 + 2) - (10 / x)) ^ (2 * 5) * -1 ^ 10",
"(1 / 1 + 1 / 1 + (10 + 2) / 100 * (10 + 2) / (10 + 2) - (10 / x))",
"(1 / 1 + 1 / 1 + 2 / 1 ^ 10 * (2 * 100) - --1)",
"(1 / 1 + 2 + 1) * 0",
"(1 / 1 + 2 + 1)",
"(1 / 1 + 2 - 10 - x * (10 / x) - (10 / x))",
"(1 / 1 + 2 / ((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10)) ^ -1 ^ 10",
"(1 / 1 + 2 / ((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10))",
"(1 ^ 10 ^ (10 + 2) - (10 / x))",
"(10 + (1 / 1 + 1 / 1 + (10 + 2) / 100 * (10 + 2) / (10 + 2) - (10 / x)))",
"(10 + 2) - (10 / x)",
"(10 + 2) - -1",
"(10 + 2)",
"(10 - x * (10 / x) - (10 / x) * -1)",
"(10 / x) * 10 - x * (10 / x) - (10 / x)",
"(10 / x) - 2",
"(10 / x) / 1 / 1 + (10 + 2) / (2 * 100) / -2 / (10 / x) / 1 / 1 + (10 + 2)",
"(10 / x) / 1 / 1 + (10 + 2) / (2 * 100)",
"(10 / x) / 1 / 1 + (10 + 2)",
"(10 / x) / 1 / 1 ^ (10 / x) - 2 / (10 + 2) / -10 - x",
"(10 / x) / 1 / 1 ^ (10 / x) - 2 / (10 + 2)",
"(10 / x) / 1 / 1 ^ (10 / x) - 2",
"(10 / x) / 1 / 1",
"(10 / x)",
"(2 * 100) * -1 ^ 10",
"(2 * 100)",
"(x ^ -10 * 100)",
"-((10 / x) / 1 / 1 + 100)",
"-(10 + 2)",
"--1 - (1 / 1 + 2 / ((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10))",
"--1",
"--2",
"-0 / 1 / 1 + 1 / 1 + 2",
"-1 - (1 / 1 + 2 / ((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10)) - (2 * 100)",
"-1 - (1 / 1 + 2 / ((10 / x) / 1 / 1 ^ (10 / x) - 2 - 1 ^ 10))",
"-1 / 1 + 1 / 1 + 2",
"-1 / 1 + 2",
"-1 ^ 10",
"-1",
"-10 * 100",
"-10",
"-100 - 1 / 1 + 1 / 1 + (10 + 2) - 10 - x * (10 / x) / -1 / (10 / x) / 1 / 1 ^ (10 / x) - 2 / (10 + 2)",
"-100 - 1 / 1 + 1 / 1 + (10 + 2)",
"-100",
"-2 / (10 / x) / 1 / 1 + (10 + 2)",
"-2",
"0 / 1 / 1 + 1 / 1 + 2",
"0",
"1 / 1 + 1 / 1 + (10 + 2) / (10 / x) / 1 / 1 + (10 + 2) / (2 * 100)",
"1 / 1 + 1 / 1 + (10 + 2)",
"1 / 1 + 1 / 1 + 2 / (10 / x) * 10 - x * (10 / x) - (10 / x)",
"1 / 1 + 1 / 1 + 2 / 1 ^ 10 * (2 * 100)",
"1 / 1 + 1 / 1 + 2 / 1 ^ 10 + (10 / x) / 1 / 1 + (10 + 2) / (2 * 100)",
"1 / 1 + 1 / 1 + 2 / 1 ^ 10",
"1 / 1 + 1 / 1 + 2",
"1 / 1 + 1 / 1 / 10 - x * (10 / x) / -1 + (10 + (1 / 1 + 1 / 1 + (10 + 2) / 100 * (10 + 2) / (10 + 2) - (10 / x)))",
"1 / 1 + 1 / 1 / 10 - x * (10 / x) / -1",
"1 / 1 + 1 / 1",
"1 / 1 + 2",
"1 / 1",
"1 ^ 10",
"1",
"10 - x * (10 / x) - (10 / x)",
"10 - x * (10 / x) / -1 / (10 / x) / 1 / 1 ^ (10 / x) - 2 / (10 + 2)",
"10 - x * (10 / x) / -1",
"10 - x * (10 / x)",
"10",
"100 * (10 + 2) / (10 + 2) - (10 / x)",
"100 * (10 + 2)",
"100",
"2 + -10 * 100 + 10 - x * (10 * x) - (10 * x)",
"2 + -10 * 100",
"2",
"x^3 - x - 2",
"(x - 1)*(x - 3)",
"(x - 4)*(x - 5)*(x - 6)",
"(x - 7)*(x - 8)*(x - 9)*(x - 10)",
"(x - 1)*(x - 3)",
"x^3 - x^2 + 2*x",
"x^3 - x + 2",
"x^2 -13",
"(x + 4)^2 - 16",
"-2* w^2 -6*sqrt(3)*w + 108",
"(y + 4)^ - 1225",
"(v-2)^2 - 1764",
"q^2 - 9*q + 20",
"-2*m^2 + 10*m - 12",
"4*q^2 - 24*q + 20",
"x^2 - 8",
"-5*a^2 - 30*sqrt(7) * a - 280",
"x^2 - 20",
"-2*n^2 + 12 * n - 18",
"-4 * x^2 - 32 * sqrt(3) * x - 8",
"4 * x^2 - 24 * x + 32",
"(x-3)^2 - 4",
]
cases_extend = [
"(10 + 2) - (10 / x) ^ 100 * (10 + 2) / (10 + 2) - (10 / x)",
"-1 / 1 + 2 ^ 10 - x",
"-10 - x",
"10 - x",
"x",
"100 * (10 + 2) + (x ^ -10 * 100)",
"100 * (10 + 2) / (10 + 2) - (10 / x) / (1 / 1 + 2 - 10 - x * (10 / x) - (10 / x))",
]
cases2 = [
"0",
"1",
"2",
"10",
"100",
"(10 + 2)",
"1 / 1",
"(10 / x)",
"1 / 1 + 2",
"(10 / x) / 1 / 1",
"(10 / x) - 2",
"(2 * 100)",
"((10 / x) / 1 / 1 + 100)",
"1 ^ 10",
"-1 / 1 + 2",
"10 - x * (10 / x)",
"-1",
"1 / 1 + 1 / 1 + 2",
"100 * (10 + 2)",
"(10 / x) / 1 / 1 ^ (10 / x) - 2",
"(10 / x) / 1 / 1 ^ (10 / x) - 2 / (10 + 2)",
"1 / 1 + 1 / 1",
"10 - x * (10 / x) / -1",
"1 / 1 + 1 / 1 + 2 / 1 ^ 10",
"(1 / 1 + 2 + 1)",
"(10 / x) / 1 / 1 + (10 + 2)",
"10 - x * (10 / x) - (10 / x)",
"1 / 1 + 1 / 1 + (10 + 2)",
"(-1 * (10 / x) / 1 / 1 + (10 + 2))",
"(10 + 2) - (10 / x)",
"(1 / 1 + 2 - 10 - x * (10 / x) - (10 / x))",
"(1 / 1 + 2 + 1) * 0",
"((10 / x) / 1 / 1 + 100) * (10 / x) / 1 / 1 ^ (10 / x) - 2",
"1 ^ 10 + ((10 / x) / 1 / 1 + 100) * (10 / x) / 1 / 1 ^ (10 / x) - 2",
"1 / 1 + 2 ^ 10 - x * (10 / x) / -1",
"(10 + 2) - (10 / x) * (10 / x) / 1 / 1 + (10 + 2)",
"-1 / 1 + 2 - -1 / 1 + 2",
"10 - x * (10 / x) - (10 / x) / 10 - x * (10 / x) - (10 / x) - 1 / 1 + 2 ^ 10 - x * (10 / x) / -1",
"-1 / 1 + 2 - -1 / 1 + 2 - (2 * 100)",
"0 / 1 / 1 + 1 / 1 + 2",
"1 / 1 + 1 / 1 + 2 / 1 ^ 10 + (10 + 2) - (10 / x) * (10 / x) / 1 / 1 + (10 + 2)",
"1 / 1 + 1 / 1 / 10 - x * (10 / x) / -1",
"--1 / 1 + 2 - -1 / 1 + 2",
"10 + -1 / 1 + 2",
"-1 / 1 + 2 - -1 / 1 + 2 - (2 * 100) + 1 ^ 10",
"(10 + 2) - (10 / x) - -1",
"10 - x * (10 / x)",
"(10 / x) / 1 / 1 + (10 + 2) - 1 / 1 + 1 / 1 + (10 + 2)",
"1 ^ 10 * (2 * 100)",
"---1 * 1 + 2 - -1 * 1 + 2",
"(1 * 1 + 1 * 1 * 10 - x * (10 * x) * -1 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1",
"(1 * 1 + 1 * 1 * 10 - x * (10 * x) * -1 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1) * 1 * 1 + 1 * 1 + 2",
"10 + -1 * 1 + 2 - 10 - x * (10 * x) - (10 * x)",
"1 * 1 + 2 ^ 10 - x * (10 * x) * -1 ^ (1 * 1 + 1 * 1 + (10 + 2) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1)",
"(1 * 1 + 1 * 1 * 10 - x * (10 * x) * -1 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 * (10 * x) - 2 * 1",
"1 * 1 + 1 * 1 + 2 * 1 ^ 10 * (2 * 100)",
"--1 * 1 + 2 - -1 * 1 + 2 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1",
"x - 10 - x * (10 * x) - (10 * x) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 * 10 - x * (10 * x) - (10 * x) - ((10 * x) * 1 * 1 + 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2",
"10 - x * (10 * x) + 10 - x * (10 * x) - (10 * x)",
"((10 * x) * 1 * 1 + (10 + 2) - 1 * 1 + 1 * 1 + (10 + 2) * 10 - x * (10 * x) + 10 - x * (10 * x) - (10 * x))",
"(10 + 2) - -1",
"10 + -1 * 1 + 2 * 10 - x * (10 * x) * -1",
"(--1 * 1 + 2 - -1 * 1 + 2 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 - (10 * x) * 1 * 1 ^ (10 * x) - 2 * 1 ^ 10 * (2 * 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2 * (10 + 2))",
]
cases2_extend = [
"((10 * x) * 1 * 1 + 100) ^ 1 * 1 + 1 * 1 + 2 * 1 ^ 10 * (2 * 100)",
"(10 * x) * 1 * 1 ^ (10 * x) - 2 * 1 ^ 10 * (2 * 100)",
"(10 * x) * 1 * 1 ^ (10 * x) - 2 * 1 ^ 10 * (2 * 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2 * (10 + 2)",
"(10 * x) * 1 * 1 ^ (10 * x) - 2 * (10 + 2) * 1 ^ 10 * (2 * 100)",
"(10 * x) * 1 * 1 ^ (10 * x) - 2 * (10 + 2) * 1 ^ 10 * (2 * 100) - ((10 * x) * 1 * 1 + 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2",
"arctan(10 - x * (10 * x) * -1)",
"10 - x * (10 * x) - (10 * x) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 * 10 - x * (10 * x) - (10 * x) - ((10 * x) * 1 * 1 + 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2",
"10 - x * (10 * x) - (10 * x) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 * (2 * 100)",
"10 - x * (10 * x) - (10 * x) - ((10 * x) * 1 * 1 + 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2",
"10 - x * (10 * x) - (10 * x) * 10 - x * (10 * x) - (10 * x) - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1 * 10 - x * (10 * x) - (10 * x) - ((10 * x) * 1 * 1 + 100) * (10 * x) * 1 * 1 ^ (10 * x) - 2 * 1 * 1 + 1 * 1 + (10 + 2) * (10 + 2) - (10 * x) * (10 * x) * 1 * 1 + (10 + 2)",
"x",
"x - 10 + -1 / 1 + 2",
"10 - x",
"(10 - x * (10 / x) + (10 / x) - 2 * 1)",
"e(e(x))",
"e(e(x)) + (10 + 2) - (10 / x)",
"(e(e(x)) * (10 / x) / 1 / 1 ^ (10 / x) - 2 * 1 ^ 10 * (2 * 100))",
"(e(e(x)) * (10 / x) / 1 / 1 ^ (10 / x) - 2 * 1 ^ 10 * (2 * 100)) + (2 * 100)",
"(e(e(x)) * 10 - x * (10 / x) + 10 - x * (10 / x) - (10 / x))",
"arctan(x / 1 / 1 + 1 / 1 + 2)",
"x - 10 - x * (10 / x) - (10 / x) / 10 - x * (10 / x) - (10 / x) - 1 / 1 + 2 ^ 10 - x * (10 / x) / -1 * 10 - x * (10 / x) - (10 / x) - ((10 / x) / 1 / 1 + 100) * (10 / x) / 1 / 1 ^ (10 / x) - 2 + arctan(x / 1 / 1 + 1 / 1 + 2)",
"(10 - x * (10 / x) / ((10 / x) / 1 / 1 + 100))",
"(1 / 1 + 1 / 1 + (10 + 2) / 10 - x * (10 / x) - (10 / x) - 1 / 1 + 2 ^ 10 - x * (10 / x) / -1)",
"100 - 1 - 1 + 2 ^ 10 - x * (10 - x) - -1",
"100 - 1 - 1 + 2 ^ 10 - x * (10 - x) - -1",
"(-1 * 1 + 2 - -1 * 1 + 2 - (2 * 100) + 1 ^ 10 * (1 * 1 + 2 - 10 - x * (10 * x) - (10 * x)))",
"1 * 1 + 1 * 1 + (10 + 2) * (10 + 2) - (10 * x) * (10 * x) * 1 * 1 + (10 + 2)",
"(1 * 1 + 1 * 1 * 10 - x * (10 * x) * -1 + 100 - 1 * 1 + 2 ^ 10 - x * (10 * x) * -1)",
"-1 * 1 + 2 - -1 * 1 + 2 - (2 * 100) + 10 - x * (10 * x)",
"-1 * 1 + 2 - -1 * 1 + 2 * (10 * x) * 1 * 1 + (10 + 2)",
"(10 * x) - 2 * 1",
"(-1 * 1 + 2 - -1 * 1 + 2 + (-1 * 1 + 2 - -1 * 1 + 2 - (2 * 100) + 1 ^ 10 * (1 * 1 + 2 - 10 - x * (10 * x) - (10 * x))))",
"arctan(0 * 1 * 1 + 1 * 1 + 2)",
"((-1 * 1 + 2 - -1 * 1 + 2 + (-1 * 1 + 2 - -1 * 1 + 2 - (2 * 100) + 1 ^ 10 * (1 * 1 + 2 - 10 - x * (10 * x) - (10 * x)))) - -1 * 1 + 2)",
"(10 - x * (10 / x) - (10 / x) * -1)",
"10 - x * (10 / x) - (10 / x) - 1 / 1 + 2 ^ 10 - x * (10 / x) / -1",
]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment