Source code for lazy

import numpy as np
import json

#from stategraph.cells import *
from dicts import *
from cell import *

[docs]class LazyCell(Cell): """ This is a proxy for accessing (partially enumerated) sets of candidate cells. LazyCells are constrained to be within the value of their prototype Question: How to handle dynamic properties? Answer: When we ``update_intension()``, the members that are saved will be filtered against the criteria of the prototype. """ def __init__(self, prototype): """ - Memoize should be 'True' when the update_intension function accesses a remote API or the number of elements being generated is very small. """ # we need this dict notation in the __init__ b/c the __setattr__ is # overloaded self.__dict__['prototype'] = prototype self.__dict__['members'] = {} # define constraints if not isinstance(prototype, DictCell): raise Exception("Error: prototype must be a DictCell") self.__dict__['include'] = {} # additional members (hash -> members) self.__dict__['exclude'] = set() # hash ids to exclude # broker object parameters self.__dict__['_size_full_intension'] = np.inf self.__dict__['_size_known_intension'] = 0 self.__dict__['_update_members'] = True
[docs] def size(self): """ Size of LazyCell: the size of the intension plus accounting for excluded and included additions. The exclusions are assumed to be part of the set. The inclusions are assumed to **NOT** be part of the intension. :returns: int -- size of LazyCell """ return self._size_full_intension \ - len(self.exclude)\ + len(self.include)
[docs] def update(self): """ Updates intension and then adds or includes extension """ # updates intension self.update_intension() self._size_known_intension = len(self.members) self._update_members = False
[docs] def update_intension(self): """ Subclass specific method for generating self.members The methods responsibilities are: - Defining self.members: mapping hash(m) -> m - Defining self._size_full_intension """ raise NotImplemented("Each LazyCell must have an update_intension" + " method. Missing in %s" % self.__class__.__name__)
[docs] def is_entailed_by(self, other): """ Means merging other with self does not produce any new information. :returns: boolean """ if not set(self.include.keys()).issubset(set(other.include.keys())): return False if not self.exclude.isuperset(other.exclude): return False if not self.prototype.is_entailed_by(other.prototype): return False return True
[docs] def is_equal(self, other): """ The objects must be the same - Same members (if enumerated) - Or same structure (if not enumerated) If the merge does not produce any new information (or contradiction) then these are equal. :returns: boolean """ print type(self.prototype), type(other.prototype) if not self.prototype.is_equal(other.prototype): print "Different prototypes" return False if self.exclude != other.exclude: print "Different excludes" return False if self.include != other.include: print "Different includes" return False return True
[docs] def get_instances(self): """ Returns the members of the LazyDict in sorted order, as an iterator :returns: iter """ if self._update_members: self.update() return iter(sorted(self.members.iteritems()))
[docs] def is_contradiction(self, other): """ Is contradiction means that a merge of the new information with the LazyCell will result in 0 members and is over constrained. :returns: boolean """ raise NotImplemented
[docs] def merge(self, other): """ Other is some description of a parameter that is responsible for generating the instances :returns: boolean """ raise NotImplemented
def __getattr__(self, key): """ Get via . operator """ if not hasattr(self, 'prototype'): # to make pickle work raise AttributeError("No property attribute 'prototype'") if key in self.prototype: return self.prototype[key] elif hasattr(self, key): return object.__getattr__(self, key) else: raise AttributeError("No attribute '%s'" % (key,)) def __setattr__(self, key, val): """ Set via . operator """ if key in self.prototype: self.prototype[key] = val self._update_members = True # TODO: we could be more efficient about this and only # _update_members if values are actually changed else: object.__setattr__(self, key, val) def __iter__(self): for x,y in self.prototype: yield x,y def __contains__(self, key): return key in self.prototype def __repr__(self): """ String representation """ s = "LazyCell: %i\n" % (id(self)) s += "\t prototype:\n" s += str(self.prototype) return s def __hash__(self): """ Extend Cell's hash method to include excludes/includes""" hash_val = hash(self.prototype) hash_val += reduce(lambda x, y: hash(x) ^ hash(y), self.exclude, 0) hash_val += reduce(lambda x, y: hash(x) ^ hash(y), self.include, 0) return hash_val __eq__ = is_equal