class Iff(recstruct('Iff', [], ['t1', 't2'])): __slots__ = () sort = Boolean @classmethod def _preprocess_(cls, t1, t2): bad_sorts = [ i for i, t in enumerate([t1, t2]) if t.sort not in (Boolean, TopS) ] if len(bad_sorts) > 0: raise SortError("Bad sorts in: Iff({}, {}) (positions: {})".format( t1, t2, bad_sorts, )) return t1, t2 def __str__(self): return 'Iff({}, {})'.format(self.t1, self.t2) def __vmt__(self): return '(= {} {})'.format(self.t1, self.t2)
class Eq(recstruct('Eq', [], ['t1', 't2'])): __slots__ = () sort = Boolean @classmethod def _preprocess_(cls, t1, t2): if type(t1.sort) == TopSort or type(t2.sort) == TopSort: pass elif t1.sort != t2.sort: raise SortError( "Cannot compare different sorts: {}:{} == {}:{}".format( t1, t1.sort, t2, t2.sort)) elif not first_order_sort(t1.sort): raise SortError("Cannot compare high order sorts: {} == {}".format( t1, t2)) return t1, t2 def __str__(self): return '({} == {})'.format(self.t1, self.t2) def __vmt__(self): return '(= {} {})'.format(self.t1, self.t2)
class Const(recstruct('Const', ['name', 'sort'], [])): __slots__ = () @classmethod def _preprocess_(cls, name, sort): # if not name or name[0].isupper(): # raise IvyError("Bad constant name: {!r}".format(name)) return name, sort def __str__(self): return self.name def __call__(self, *terms): return Apply(self, *terms) if len(terms) > 0 else self def __vmt__(self): if self.name in {'0', '__0'}: return "{}_{}".format(self.sort, self.name) if self.name in {'<', '__<', '-', '__-'}: return "{}_{}".format(self.sort.domain[0], self.name) else: return self.name
class Apply(recstruct('Apply', [], ['func', '*terms'])): __slots__ = () @classmethod def _preprocess_(cls, func, *terms): if type(func.sort) is TopSort: pass elif type(func.sort) is not FunctionSort: raise SortError("Tried to apply a non-function: {}".format(func)) elif func.sort.arity != len(terms): print func.sort.arity print func.sort raise SortError("Bad arity in: {}({})".format( str(func), ', '.join(str(t) for t in terms) )) else: bad_sorts = [i for i in range(func.sort.arity) if terms[i].sort != func.sort.domain[i] and not any(type(t) is TopSort for t in (terms[i].sort, func.sort.domain[i]))] if len(bad_sorts) > 0: raise SortError("Bad sorts in: {}({}) (positions: {})".format( str(func), ', '.join(repr(t) for t in terms), bad_sorts, )) return (func, ) + terms def __str__(self): if len(self.terms) == 0: return str(self.func) else: return '{}({})'.format( str(self.func), ', '.join(str(t) for t in self.terms) ) sort = property(lambda self: TopS if self.func.sort == TopS else self.func.sort.range)
class Exists(recstruct('Exists', ['variables'], ['body'])): __slots__ = () sort = Boolean @classmethod def _preprocess_(cls, variables, body): if len(variables) == 0: raise IvyError("Must quantify over at least one variable") if not all(type(v) is Var for v in variables): raise IvyError("Can only quantify over variables") if body.sort not in (Boolean, TopS): raise SortError("Quantified body must be Boolean: {}", body) return frozenset(variables), body def __str__(self): return '(Exists {}. {})'.format( ', '.join('{}:{}'.format(v.name, v.sort) for v in sorted(self.variables)), self.body) def __vmt__(self): return '(exists ({}) {})'.format( ' '.join('({} {})'.format(v.name, v.sort) for v in sorted(self.variables)), self.body)
class Ite(recstruct('Ite', [], ['cond', 't_then', 't_else'])): __slots__ = () @classmethod def _preprocess_(cls, cond, t_then, t_else): if cond.sort not in (Boolean, TopS): raise SortError("Ite condition must be Boolean: {}".format(body)) elif TopS in (t_then.sort, t_else.sort): pass elif t_then.sort != t_else.sort: raise SortError( "Ite then and else terms must have same sort: {}, {}".format( t_then, t_else)) elif not first_order_sort(t_then.sort): pass # TODO: should we raise the following exception? #raise SortError("Cannot apply Ite to high order sorts: {}, {}".format(t_then, t_else)) return cond, t_then, t_else def __str__(self): return 'Ite({}, {}, {})'.format(self.cond, self.t_then, self.t_else) sort = property(lambda self: self.t_then.sort if self.t_then.sort != TopS else self.t_else.sort)
class Ite(recstruct('Ite', ['sort'], ['cond', 't_then', 't_else'])): __slots__ = () def __init__(self, cond, t_then, t_else): super(Ite, self).__init__(t_then.sort, cond, t_then, t_else) @classmethod def _preprocess_(cls, sort, cond, t_then, t_else): if cond.sort not in (Boolean, TopS): raise SortError("Ite condition must be Boolean: {}".format(body)) elif isinstance(t_then.sort, TopSort) or isinstance( t_else.sort, TopSort): pass elif t_then.sort != t_else.sort: raise SortError( "Ite then and else terms must have same sort: {}, {}".format( t_then, t_else)) elif not first_order_sort(t_then.sort): pass # TODO: should we raise the following exception? #raise SortError("Cannot apply Ite to high order sorts: {}, {}".format(t_then, t_else)) return sort, cond, t_then, t_else def __str__(self): return 'Ite({}, {}, {})'.format(self.cond, self.t_then, self.t_else)
class BooleanSort(recstruct('BooleanSort', [], [])): __slots__ = () def __str__(self): return 'Boolean'
class UninterpretedSort(recstruct('UninterpretedSort', ['name'], [])): __slots__ = () def __str__(self): return self.name