Source code for pyidp3.idpobjects

"""
This file contains all the IDP objects.
"""

import collections.abc


[docs]class IDPObject(object): """ 'Abstract' class for all the IDP objects. Initialises idp. """ def __init__(self, idp): self.idp = idp def accept(self, vis): return vis.visit(self)
# Vocabulary objects:
[docs]class IDPVocabularyObject(IDPObject): """ Abstract class for all the objects that appear in a vocabulary. """ def __eq__(self, other): """ Two objects are equal is they have the same name. """ return self.typedName() == other.typedName() def __init__(self, idp, name, typing, ct=False): super(IDPVocabularyObject, self).__init__(idp) self.name = name self.typing = typing self.ct = ct
[docs] def in_theory(self): """ Doesn't show up in a theory, so returns empty string. """ return ""
def in_vocabulary(self): return self.typedName() def in_structure(self): ct_str = "<ct>" if self.ct == True else "" return self.name + ct_str + ' = {' + self.show_contents() + '}' def typedName(self): return self.name + "(" + ", ".join(map(str, self.typing)) + ")" def show_tuple(self, tup): if isinstance(tup, tuple): return ', '.join(map(str, tup)) # if the tup is already str, we need to encode it to avoid unicode # errors. str() would give an error here. else: return str(tup) def show_contents(self): return "; ".join([self.show_tuple(x) for x in self]) def __len__(self): return len(self.to_set()) def __contains__(self, x): return self.idp.normal_form(x) in self.to_set() def __iter__(self): # if (len(self.typing) > 1): # return iter(self.product_of_types()) # else: return iter(self.to_set()) def product_of_types(self): import itertools types = [getattr(self.idp,x) for x in self.typing] return itertools.product(*types)
[docs]class IDPEnumeratedObject(IDPVocabularyObject): def __init__(self, idp, name, typing, enum, ct): super(IDPEnumeratedObject,self).__init__(idp, name, typing, ct) self._enumeration = self.idp.normal_form_enumeration(enum) def to_set(self): return set(self.enumeration) def changed(self): self.idp.dirty = True @property def enumeration(self): return self._enumeration @enumeration.setter def enumeration(self, enum): self._enumeration = enum self.changed()
[docs]class IDPUnknownObject(IDPEnumeratedObject): def in_structure(self): return "" @property def enumeration(self): self._enumeration = self.idp.fillIn(self.name) return self._enumeration
[docs]class IDPGeneratedObject(IDPVocabularyObject): def __init__(self,*args): super(IDPGeneratedObject,self).__init__(*args[:-1]) self.implementation = args[-1] def product_of_types(self): import itertools types = [getattr(self.idp,x) for x in self.typing] return itertools.product(*types) @property def enumeration(self): return self.product_of_types() def to_set(self): return self.enumeration
# Functions
[docs]class IDPFunction(IDPVocabularyObject, collections.abc.Mapping): def __init__(self, idp, name, types, return_type, partial=False, ct=False): IDPVocabularyObject.__init__(self, idp, name, types) self.return_type = return_type self.partial = partial def show_tuple(self, tup): return super(IDPFunction,self).show_tuple(tup) + "->" + self.idp.for_idp(self[tup]) def typedName(self): return ("partial " if self.partial else '') + super(IDPFunction,self).typedName() + " : " + self.return_type def __iter__(self): sup_it = super(IDPFunction, self).__iter__() for x in sup_it: if self[x] is not None: yield x def __call__(self, *args): return self[args]
[docs]class IDPEnumeratedFunction(IDPFunction, IDPEnumeratedObject, collections.abc.MutableMapping): def __init__(self, idp, name, args, rt, enum, partial=False, ct=False): IDPFunction.__init__(self, idp, name, args, rt, partial) IDPEnumeratedObject.__init__(self, idp, name, args, enum, ct) # check for string def __setitem__(self, key, value): self.enumeration[self.idp.normal_form(key)] = self.idp.normal_form(value) self.changed() def __getitem__(self, key): result = self.enumeration[self.idp.normal_form(key)] if isinstance(getattr(self.idp, self.return_type), IDPIntType): return int(result) return result def __delitem__(self, key): del self.enumeration[self.idp.normal_form(key)] self.changed()
[docs]class IDPUnknownFunction(IDPEnumeratedFunction,IDPUnknownObject): def __init__(self, idp, name, args, rt, partial=False, ct=False): super(IDPUnknownFunction, self).__init__(idp,name,args,rt,{},partial,ct)
[docs]class IDPEmptyConstantFunction(IDPEnumeratedFunction,IDPUnknownObject): def __init__(self, idp, name, args, rt, partial=False): super(IDPEmptyConstantFunction, self).__init__(idp,name,args,rt,{},partial) def typedName(self): return self.name
[docs]class IDPValueConstantFunction(IDPEnumeratedFunction, IDPUnknownObject): def __init__(self, idp, name, args, rt, enumeration, partial=False): self._content = enumeration super().__init__(idp,name,args,rt,{},partial) def in_structure(self): return self.name + " = " + str(self._content)
[docs]class IDPGeneratedFunction(IDPFunction, IDPGeneratedObject): def __init__(self, idp, name, args, rt, impl, partial=False): IDPFunction.__init__(self,idp,name,args,rt, partial) IDPGeneratedObject.__init__(self,idp,name,args,impl) def __getitem__(self, key): args = list(map(self.idp.object_for_name, key)) try: res = self.implementation(args) except AttributeError: if len(key) == 1: res = self.implementation(args[0]) return self.idp.normal_form(res)
# class IDPGeneratedPartialFunction(IDPPartialFunction, IDPGeneratedFunction): # def __getitem__(self, key): # res = super(IDPGeneratedPartialFunction, self).__getitem__(key) # if self.idp.assign_name(None) == res: # return None # else: # return res #### Predicates
[docs]class IDPPredicate(IDPVocabularyObject, collections.abc.Set): def __call__(self, *args): return self.idp.normal_form(args) in self
[docs]class IDPUnknownPredicate(IDPPredicate, IDPUnknownObject): def __init__(self, idp, name, types): IDPPredicate.__init__(self,idp,name,types)
[docs]class IDPEnumeratedPredicate(IDPPredicate, IDPEnumeratedObject, collections.abc.MutableSet):
[docs] def add(self, x): self.enumeration.append(self.idp.normal_form(x)) self.changed()
[docs] def discard(self, x): self.enumeration.discard(x) self.changed()
[docs]class IDPGeneratedPredicate(IDPPredicate, IDPGeneratedObject): pass
[docs]class IDPType(IDPEnumeratedPredicate): def __init__(self, idp, name, enum, ct=False): super(IDPType, self).__init__(idp, name, [], enum, ct) def typedName(self): return self.name def in_vocabulary(self): return "type " + self.name
# def isIntType(self): # x = self.enum[0] # return int(x) == x
[docs]class IDPIntType(IDPType): def in_vocabulary(self): return super(IDPIntType, self).in_vocabulary() + " isa int"
[docs]class IDPIntRangeType(IDPIntType): def in_vocabulary(self): return ("type {} = {{{}}} isa int" .format(super(IDPType, self).in_vocabulary(), self.show_contents())) def show_contents(self): return "".join(self._enumeration) def in_structure(self): return ""
[docs]class IDPFloatType(IDPType): def in_vocabulary(self): return super(IDPFloatType, self).in_vocabulary() + "isa float"
[docs]class IDPFloatRangeType(IDPFloatType): def in_vocabulary(self): return ("type {} = {{{}}} isa float" .format(super(IDPType, self).in_vocabulary(), self.show_contents())) def show_contents(self): return "".join(self._enumeration) def in_structure(self): return ""
[docs]class IDPConstructedType(IDPType): def in_vocabulary(self): return super(IDPConstructedType, self).in_vocabulary() +\ " constructed from {" + self.show_constructed_from() + "}" def show_constructed_from(self): content = ", ".join(self._enumeration) return content # No need for anything in struct def in_structure(self): return ""
[docs]class IDPSpecialType(IDPType): def in_vocabulary(self): return super().in_vocabulary() + " isa " + "".join(self._enumeration) # No need for anything in struct def in_structure(self): return ""
##### Theory objects
[docs]class IDPTheoryObject(IDPObject): def in_structure(self): return "" def in_vocabulary(self): return "" def in_theory(self): raise NotImplementedError("All theory objects should implement the 'in_theory' method")
[docs]class IDPConstraint(IDPTheoryObject): def __init__(self, idp, formula): super(IDPConstraint,self).__init__(idp) self.formula = formula def in_theory(self): if self.formula[-1] != ".": return self.formula + "." else: return self.formula
[docs]class IDPRule(IDPTheoryObject): def __init__(self, idp, head_pred, vars_, body): super(IDPRule,self).__init__(idp) self.head_pred = head_pred self.vars = vars_ self.body = body def in_theory(self): return "!" + " ".join(self.vars) + ": " + self.head_pred + "(" + (", ").join(self.vars) + ") <- " + self.body + "."
[docs]class IDPRuleStr(IDPTheoryObject): def __init__(self, idp, string): super(IDPRuleStr,self).__init__(idp) self.rule = string def in_theory(self): return self.rule
[docs]class IDPDefinition(IDPTheoryObject): def __init__(self, idp, rule_list): super(IDPDefinition, self).__init__(idp) self.rules = [] for rule in rule_list: if isinstance(rule, str): self.rules.append(rule) else: self.rules.append(rule.in_theory()) def in_theory(self): theory_str = "{\n" + "\n".join([x for x in self.rules]) if theory_str[-1] != ".": theory_str += "." return theory_str + "\n}"