Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions mathics/builtin/combinatorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ def apply(self, values, evaluation):
return result


class _NoBoolVector(Exception):
pass


class _BooleanDissimilarity(Builtin):
@staticmethod
def _to_bool_vector(u):
class NoBoolVector(Exception):
pass

def generate():
for leaf in u.leaves:
Expand All @@ -115,21 +117,21 @@ def generate():
if val in (0, 1):
yield val
else:
raise NoBoolVector
raise _NoBoolVector
elif isinstance(leaf, Symbol):
name = leaf.name
if name == 'System`True':
yield 1
elif name == 'System`False':
yield 0
else:
raise NoBoolVector
raise _NoBoolVector
else:
raise NoBoolVector
raise _NoBoolVector

try:
return [x for x in generate()]
except NoBoolVector:
except _NoBoolVector:
return None

def apply(self, u, v, evaluation):
Expand Down
15 changes: 8 additions & 7 deletions mathics/builtin/exptrig.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,10 @@ def _fold(self, state, steps, math):
yield x, y, phi


class _IllegalStepSpecification(Exception):
pass


class AnglePath(Builtin):
"""
<dl>
Expand Down Expand Up @@ -1072,28 +1076,25 @@ def _compute(x0, y0, phi0, steps, evaluation):
if not steps:
return Expression('List')

class IllegalStepSpecification(Exception):
pass

if steps[0].get_head_name() == 'System`List':
def parse(step):
if step.get_head_name() != 'System`List':
raise IllegalStepSpecification
raise _IllegalStepSpecification
arguments = step.leaves
if len(arguments) != 2:
raise IllegalStepSpecification
raise _IllegalStepSpecification
return arguments
else:
def parse(step):
if step.get_head_name() == 'System`List':
raise IllegalStepSpecification
raise _IllegalStepSpecification
return None, step

try:
fold = AnglePathFold(parse)
leaves = [Expression('List', x, y) for x, y, _ in fold.fold((x0, y0, phi0), steps)]
return Expression('List', *leaves)
except IllegalStepSpecification:
except _IllegalStepSpecification:
evaluation.message('AnglePath', 'steps', Expression('List', *steps))

def apply(self, steps, evaluation):
Expand Down
44 changes: 34 additions & 10 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,10 @@ def get_match_count(self, vars={}):
return range


class _StopGeneratorExcept(StopGenerator):
pass


class Except(PatternObject):
"""
<dl>
Expand Down Expand Up @@ -558,34 +562,32 @@ def init(self, expr):
self.p = Pattern.create(Expression('Blank'))

def match(self, yield_func, expression, vars, evaluation, **kwargs):
class StopGenerator_Except(StopGenerator):
pass

def except_yield_func(vars, rest):
raise StopGenerator_Except(Symbol("True"))
raise _StopGeneratorExcept(True)

try:
self.c.match(except_yield_func, expression, vars, evaluation)
except StopGenerator_Except:
except _StopGeneratorExcept:
pass
else:
self.p.match(yield_func, expression, vars, evaluation)


class _StopGeneratorMatchQ(StopGenerator):
pass


class Matcher(object):
def __init__(self, form):
self.form = Pattern.create(form)

def match(self, expr, evaluation):
class StopGenerator_MatchQ(StopGenerator):
pass

def yield_func(vars, rest):
raise StopGenerator_MatchQ(Symbol("True"))
raise _StopGeneratorMatchQ(True)

try:
self.form.match(yield_func, expr, {}, evaluation)
except StopGenerator_MatchQ:
except _StopGeneratorMatchQ:
return True
return False

Expand Down Expand Up @@ -1332,3 +1334,25 @@ def _match(leaf):
return (leaf.has_form(('Rule', 'RuleDelayed'), 2) or
leaf.has_form('List', None))
return [leaf for leaf in leaves if _match(leaf)]


class _StopGeneratorBaseExpressionIsFree(StopGenerator):
pass


def item_is_free(item, form, evaluation):
# for vars, rest in form.match(self, {}, evaluation, fully=False):
def yield_match(vars, rest):
raise _StopGeneratorBaseExpressionIsFree(False)
# return False

try:
form.match(yield_match, item, {}, evaluation, fully=False)
except _StopGeneratorBaseExpressionIsFree as exc:
return exc.value

if item.is_atom():
return True
else:
return item_is_free(item.head, form, evaluation) and all(
item_is_free(leaf, form, evaluation) for leaf in item.leaves)
11 changes: 6 additions & 5 deletions mathics/builtin/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,10 @@ def apply(self, string, evaluation):
return from_python(codes)


class _InvalidCodepointError(ValueError):
pass


class FromCharacterCode(Builtin):
"""
<dl>
Expand Down Expand Up @@ -1667,9 +1671,6 @@ def apply(self, n, evaluation):
"FromCharacterCode[n_]"
exp = Expression('FromCharacterCode', n)

class InvalidCodepointError(ValueError):
pass

def convert_codepoint_list(l, encoding=None):
if encoding is not None:
raise NotImplementedError
Expand All @@ -1681,7 +1682,7 @@ def convert_codepoint_list(l, encoding=None):
evaluation.message(
'FromCharacterCode', 'notunicode',
Expression('List', *l), Integer(i + 1))
raise InvalidCodepointError
raise _InvalidCodepointError
s += unichr(pyni)

return s
Expand Down Expand Up @@ -1710,7 +1711,7 @@ def convert_codepoint_list(l, encoding=None):
return evaluation.message(
'FromCharacterCode', 'intnm', exp, Integer(1))
return String(convert_codepoint_list([n]))
except InvalidCodepointError:
except _InvalidCodepointError:
return

assert False, "can't get here"
Expand Down
20 changes: 2 additions & 18 deletions mathics/core/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,24 +312,8 @@ def format(self, evaluation, form):
return result

def is_free(self, form, evaluation):
from mathics.core.pattern import StopGenerator

class StopGenerator_BaseExpression_is_free(StopGenerator):
pass

# for vars, rest in form.match(self, {}, evaluation, fully=False):
def yield_match(vars, rest):
raise StopGenerator_BaseExpression_is_free(False)
# return False
try:
form.match(yield_match, self, {}, evaluation, fully=False)
except StopGenerator_BaseExpression_is_free as exc:
return exc.value
if self.is_atom():
return True
else:
return self.head.is_free(form, evaluation) and all(
leaf.is_free(form, evaluation) for leaf in self.leaves)
from mathics.builtin.patterns import item_is_free
return item_is_free(self, form, evaluation)

def is_inexact(self):
return self.get_precision() is not None
Expand Down