10
10
"""
11
11
12
12
from itertools import product
13
- from typing import Optional
13
+ from typing import Optional , Union
14
14
15
15
import numpy as np
16
16
import sympy
@@ -2251,7 +2251,7 @@ def eval(self, eqs, vars, evaluation: Evaluation):
2251
2251
return
2252
2252
all_var_tuples = list (zip (vars , vars_sympy ))
2253
2253
2254
- def cut_var_dimension (expressions : Expression | list [Expression ]):
2254
+ def cut_var_dimension (expressions : Union [ Expression , list [Expression ] ]):
2255
2255
'''delete unused variables to avoid SymPy's PolynomialError
2256
2256
: Not a zero-dimensional system in e.g. Solve[x^2==1&&z^2==-1,{x,y,z}]'''
2257
2257
if not isinstance (expressions , list ):
@@ -2266,7 +2266,7 @@ def cut_var_dimension(expressions: Expression | list[Expression]):
2266
2266
subset_vars_sympy .add (var_sympy )
2267
2267
return subset_vars , subset_vars_sympy
2268
2268
2269
- def solve_sympy (equations : Expression | list [Expression ]):
2269
+ def solve_sympy (equations : Union [ Expression , list [Expression ] ]):
2270
2270
if not isinstance (equations , list ):
2271
2271
equations = [equations ]
2272
2272
equations_sympy = []
@@ -2287,10 +2287,11 @@ def solve_sympy(equations: Expression | list[Expression]):
2287
2287
equation_sympy = left - right
2288
2288
equation_sympy = sympy .together (equation_sympy )
2289
2289
equation_sympy = sympy .cancel (equation_sympy )
2290
+ equations_sympy .append (equation_sympy )
2290
2291
numer , denom = equation_sympy .as_numer_denom ()
2291
2292
denoms_sympy .append (denom )
2292
2293
try :
2293
- results = sympy .solve (equations_sympy , subset_vars_sympy , dict = True ) # no transform needed with dict=True
2294
+ results = sympy .solve (equations_sympy , subset_vars_sympy , dict = True ) # no transform_dict needed with dict=True
2294
2295
# Filter out results for which denominator is 0
2295
2296
# (SymPy should actually do that itself, but it doesn't!)
2296
2297
results = [
@@ -2314,21 +2315,21 @@ def solve_recur(expression: Expression):
2314
2315
but including the translation from Mathics to sympy
2315
2316
2316
2317
returns:
2317
- solutions: a list of sympy solution dictionaries
2318
+ solutions: a list of sympy solution dictionarys
2318
2319
conditions: a sympy condition object
2319
2320
2320
2321
note:
2321
2322
for And and List, should always return either (solutions, None) or ([], conditions)
2322
- for Or, all combinations are possible. if Or is root, should be handled outside'''
2323
+ for Or, all combinations are possible. if Or is root, this should be handled outside'''
2323
2324
head = expression .get_head_name ()
2324
- if head in (" System`And" , " System`List" ):
2325
+ if head in (' System`And' , ' System`List' ):
2325
2326
solutions = []
2326
2327
equations : list [Expression ] = []
2327
2328
inequations = []
2328
2329
for child in expression .elements :
2329
2330
if child .has_form ("Equal" , 2 ):
2330
2331
equations .append (child )
2331
- elif child .get_head_name () in (" System`And" , " System`Or" ):
2332
+ elif child .get_head_name () in (' System`And' , ' System`Or' ):
2332
2333
sub_solution , sub_condition = solve_recur (child )
2333
2334
solutions .extend (sub_solution )
2334
2335
if sub_condition is not None :
@@ -2339,14 +2340,14 @@ def solve_recur(expression: Expression):
2339
2340
conditions = sympy .And (* inequations )
2340
2341
result = [sol for sol in solutions if conditions .subs (sol )]
2341
2342
return result , None if solutions else conditions
2342
- else : # should be System`Or then
2343
- assert head == " System`Or"
2343
+ else : # assume should be System`Or
2344
+ assert head == ' System`Or'
2344
2345
solutions = []
2345
2346
conditions = []
2346
2347
for child in expression .elements :
2347
2348
if child .has_form ("Equal" , 2 ):
2348
2349
solutions .extend (solve_sympy (child ))
2349
- elif child .get_head_name () in (" System`And" , " System`Or" ): # List wouldn't be in here
2350
+ elif child .get_head_name () in (' System`And' , ' System`Or' ): # I don't believe List would be in here
2350
2351
sub_solution , sub_condition = solve_recur (child )
2351
2352
solutions .extend (sub_solution )
2352
2353
if sub_condition is not None :
@@ -2360,17 +2361,20 @@ def solve_recur(expression: Expression):
2360
2361
2361
2362
if eqs .get_head_name () in ("System`List" , "System`And" , "System`Or" ):
2362
2363
solutions , conditions = solve_recur (eqs )
2363
- # non True conditions are only accepted in subtrees, not root
2364
+ # non True conditions are only accepted in subtrees only , not root
2364
2365
if conditions is not None :
2365
2366
evaluation .message ("Solve" , "fulldim" )
2366
- return ListExpression (ListExpression ())
2367
2367
else :
2368
2368
if eqs .has_form ("Equal" , 2 ):
2369
2369
solutions = solve_sympy (eqs )
2370
2370
else :
2371
2371
evaluation .message ("Solve" , "fulldim" )
2372
2372
return ListExpression (ListExpression ())
2373
2373
2374
+ if solutions is None :
2375
+ evaluation .message ("Solve" , "ivars" )
2376
+ return ListExpression (ListExpression ())
2377
+
2374
2378
if any (
2375
2379
sol and any (var not in sol for var in vars_sympy ) for sol in solutions
2376
2380
):
@@ -2381,7 +2385,7 @@ def solve_recur(expression: Expression):
2381
2385
ListExpression (
2382
2386
* (
2383
2387
Expression (SymbolRule , var , from_sympy (sol [var_sympy ]))
2384
- for var , var_sympy in zip ( vars , all_var_tuples )
2388
+ for var , var_sympy in all_var_tuples
2385
2389
if var_sympy in sol
2386
2390
),
2387
2391
)
0 commit comments