コード例 #1
0
ファイル: auto_salience.py プロジェクト: ubarkai/rulu
def _topological_sort(dependencies):
    seen = set()
    order = []
    explored = set()

    for v in dependencies.keys():  # process all vertices
        if v in explored:
            continue
        fringe = [v]  # nodes yet to look at
        while fringe:
            w = fringe[-1]  # depth first search
            if w in explored:  # already looked down this branch
                fringe.pop()
                continue
            seen.add(w)  # mark as seen
            # Check successors for cycles and for new nodes
            new_nodes = []
            for n in dependencies[w]:
                if n not in explored:
                    if n in seen:  #CYCLE !!
                        raise RuleEngineError(
                            "Dependencies graph contains a cycle, cannot set salience automatically."
                        )
                    new_nodes.append(n)
            if new_nodes:  # Add new_nodes to fringe
                fringe.extend(new_nodes)
            else:  # No new nodes so w is fully explored
                explored.add(w)
                order.append(w)
                fringe.pop()  # done considering this node
    return list(reversed(order))
コード例 #2
0
ファイル: operators.py プロジェクト: ubarkai/rulu
 def get_type(self):
     lhs_type, rhs_type = [arg.get_type() for arg in self.args]
     if lhs_type in (Integer, Number) and rhs_type in (Integer, Number):
         return Integer if lhs_type is Integer and rhs_type is Integer else Number
     else:
         raise RuleEngineError('Illegal operator "{}" on {} and {}'.format(
             self.op.__name__, self.lhs.get_type(), self.rhs.get_type()))
コード例 #3
0
ファイル: operators.py プロジェクト: ubarkai/rulu
 def __init__(self, expr):
     expr = normalize_expr(expr)
     super(Condition, self).__init__(all_fields=expr.all_fields)
     if expr.get_type() is not Boolean:
         raise RuleEngineError(
             'Condition must be of boolean type. Got "{}", which is {}'.
             format(expr, expr.get_type()))
     self.expr = expr
コード例 #4
0
ファイル: rule.py プロジェクト: ubarkai/rulu
 def set_target_fields(self, **fields):
     if self.target is not None:
         raise RuleEngineError('Target already set')
     self.target_fields = {
         key: FieldExpr(_type=TYPE_MAP.get(_type, _type))
         for key, _type in fields.iteritems()
     }
     self.target = make_slotted_type(Fact, self.name, **self.target_fields)
コード例 #5
0
 def __init__(self, *args):
     self.args = map(normalize_expr, args)
     types = {arg.get_type() for arg in self.args[1:3]}
     if len(types) != 1:
         raise RuleEngineError("Different return types: {}".format(types))
     self.return_type = types.pop()
     all_fields = reduce(set.union, (arg.all_fields for arg in self.args),
                         set())
     super(ConditionalExpr, self).__init__(all_fields=all_fields)
コード例 #6
0
ファイル: expr.py プロジェクト: ubarkai/rulu
def normalize_expr(expr):
    if isinstance(expr, BaseExpr):
        return expr
    elif isinstance(expr, ConvertibleToExpr):
        return expr._to_expr()
    else:
        try:
            return PrimitiveExpr(expr)
        except TypeError:
            raise RuleEngineError('Expected primitive or expression, found {}'.format(expr))
コード例 #7
0
ファイル: slots.py プロジェクト: ubarkai/rulu
 def __init__(self, **kwargs):
     if self._clips_type is None:
         raise RuleEngineError('Class {} is not bound to a rule engine and cannot be instantiated'.format(type(self)))
     existing_clips_obj = kwargs.get('_clips_obj')
     if existing_clips_obj is None:
         self._clips_obj = self._create_clips_obj()
         self._clips_obj.AssignSlotDefaults()
         for key, value in kwargs.iteritems():
             field = self._fields.get(key)
             if field is None:
                 raise RuleEngineError('Field {} does not exist in {}'.format(key, self._name))
             if not field.get_type()._isinstance(value):
                 raise RuleEngineError('In {}: expected {} should be of type {}, got {}.'.
                                       format(self._name, key, field.get_type(), value))
             if isinstance(value, HasSlots):
                 value = value._clips_obj
             self._clips_obj.Slots[key] = field._type._to_clips_value(value)
     else:
         self._clips_obj = self._copy_clips_obj(existing_clips_obj)
     self._data = tuple(self._fields[key]._type._from_clips_value(self._clips_obj.Slots[key]) 
                        for key in self._ordered_fields)
コード例 #8
0
ファイル: rule.py プロジェクト: ubarkai/rulu
 def _init_target(self, engine):
     target_name = self.get_target_name()
     if target_name is None:
         raise RuleEngineError(
             'Cannot build rule, target name not set or multiple targets have the same name'
         )
     if self.name is None:
         self.name = target_name
     if self.target._name is None:
         self.target._name = target_name
     if target_name not in engine.clips_types:
         self.target._build(engine)
コード例 #9
0
 def load(self, filename):
     """
     Load facts and class instances from a text file in CLIPS format
     (as written by the save() method)
     """
     try:
         self.logger.debug('Loading facts from {}'.format(filename))
         self.environment.LoadFacts(filename)
         instance_filename = _get_instance_filename(filename)
         if os.path.exists(instance_filename):
             self.environment.LoadInstances(instance_filename)
     except IOError:
         raise RuleEngineError(
             'Error while loading {}.\n Error log:\n{}'.format(
                 filename, clips.ErrorStream.Read()))
コード例 #10
0
ファイル: xls_export.py プロジェクト: ubarkai/rulu
def export_facts_to_xls(facts_filename, out_filename, max_rows_in_sheet=10000):
    workbook = xlwt.Workbook()
    writers = {}
    _logger.info('Exporting facts to {}.'.format(out_filename))
    for template_name, fact in read_fact_file(facts_filename):
        writer = writers.get(template_name)
        if writer is None:
            writer = ExportSheetWriter(workbook,
                                       template_name,
                                       max_rows_in_sheet=max_rows_in_sheet)
            writers[template_name] = writer
        writer.write_fact(fact)
    if not writers:
        raise RuleEngineError('No facts found, cannot export to Excel')
    workbook.save(out_filename)
コード例 #11
0
ファイル: actions.py プロジェクト: ubarkai/rulu
    def prepare_rule(self, rule):
        if self.rule is not None:
            raise RuleEngineError(
                '"Assert" instance may only be used in a single rule.')
        self.rule = rule

        # Deduce fields for rule target
        if rule.target_fields is None:
            implied_fields = {
                key: value.get_type()
                for key, value in self.data.iteritems()
            }
            rule.set_target_fields(**implied_fields)
        # Fields of input facts cannot be used directly in the Assert() clause.
        # They must be bound to variables.
        for key, value in self.data.iteritems():
            for field in value.all_fields:
                rule.add_variable(field)
コード例 #12
0
ファイル: expr.py プロジェクト: ubarkai/rulu
 def get_type(self):
     raise RuleEngineError('Cannot infer type for {}'.format(self))
コード例 #13
0
ファイル: aggregations.py プロジェクト: ubarkai/rulu
 def process_one(self, **kwargs):
     if self.finalized:
         raise RuleEngineError('Aggregation failed')
     key = tuple(key(**kwargs) for key in keys)
     value = kwargs.values()[0] if len(kwargs) == 1 else Bunch(kwargs)
     self.data[key].append(value)
コード例 #14
0
ファイル: slots.py プロジェクト: ubarkai/rulu
 def _build(cls, engine):
     if not cls._fields:
         raise RuleEngineError('{} has no fields'.format(cls._name))
     logger.getChild('slots').debug('Building: %s, slots: %s', cls._name, cls._slots)
     cls._environment = engine.environment
     engine.register_clips_type(cls)
コード例 #15
0
ファイル: rule.py プロジェクト: ubarkai/rulu
 def set_name(self, name):
     if self.name not in (None, name):
         raise RuleEngineError(
             'Tried to set target name to "{}", but it is already "{}"'.
             format(name, self.name))
     self.name = name
コード例 #16
0
ファイル: rule.py プロジェクト: ubarkai/rulu
 def set_target(self, target=None):
     if self.target_fields is not None:
         raise RuleEngineError(
             'Cannot set both target template and target fields')
     self.target = target
     self.target_fields = target._fields