def get_events(seq): events = set() if seq.optional: logger('skipped optional rule {}', seq) return events free_vars = seq.vars for sequent in normalize(seq): for antecedent in sequent.antecedents: if antecedent.name == 'EQUAL': lhs, rhs = antecedent.args assert lhs.is_var() and rhs.is_var(), antecedent # HACK ignore equation antecedents else: events.add(antecedent) # HACK to deal with Equation args succedent = iter(sequent.succedents).next() for arg in succedent.args: if not arg.is_var(): events.add(arg) antecedent_vars = union(a.vars for a in sequent.antecedents) for var in succedent.vars & free_vars - antecedent_vars: compound_count = sum(1 for arg in succedent.args if arg.args) in_count = sum(1 for arg in succedent.args if var in arg.vars) # if the var is in a compound in both succedent.args, # then succedent.args are sufficient events. if in_count < 2 or compound_count < 2: events.add(var) return events
def compile_given(seq, atom): context = frozenset([atom]) bound = frozenset(get_bound(atom)) normals = sorted(normalize_given(seq, atom, bound)) assert normals, 'failed to compile {0} given {1}'.format(seq, atom) logger('derived {} rules from {} | {}', len(normals), atom, seq) return [optimize_given(n, context, bound) for n in normals]
def derive_facts(rule): facts = set() if len(rule.antecedents) == 0 and len(rule.succedents) == 1: expr = iter(rule.succedents).next() for derived in iter_closures(expr): lhs, rhs = derived.args if lhs != rhs: assert derived.is_rel() facts.add(derived) facts = sorted(list(facts), key=lambda expr: len(expr.polish)) logger('derived {0} facts from {1}'.format(len(facts), expr)) return facts
def compile_full(seq): results = [] if seq.optional: logger('skipped optional rule {}', seq) return results for derived_seq in normalize(seq): context = frozenset() bound = frozenset() results.append(optimize_given(derived_seq, context, bound)) assert results, 'failed to compile {0}'.format(seq) logger('derived {} rules from {}', len(results), seq) return results
def compile_given(seq, atom): context = set([atom]) bound = atom.vars if atom.is_fun(): bound.add(atom.var) results = [] for normal in normalize_given(seq, atom, bound): # print 'DEBUG normal =', normal ranked = rank_compiled(normal, context, bound) results.append(min(ranked)) assert results, 'failed to compile {0} given {1}'.format(seq, atom) logger('derived {0} rules from {1} | {2}'.format(len(results), atom, seq)) return results
def compile_full(seq): results = [] if seq.optional: logger('skipped optional rule {0}'.format(seq)) return results for part in normalize(seq): context = set() bound = set() ranked = rank_compiled(part, context, bound) results.append(min(ranked)) assert results, 'failed to compile {0}'.format(seq) logger('derived {0} rules from {1}'.format(len(results), seq)) return results
def merge_programs(program1, program2): assert program1 != program2, 'duplicate' if sizeof_program(program1) > sizeof_program(program2): program1, program2 = program2, program1 program = [] for i in xrange(min(len(program1), len(program2))): if program1[i] != program2[i]: break program.append(program1[i]) logger('saved {} operations by merging', i) program1 = program1[i:] program2 = program2[i:] assert program1 and program2 jump, padding = get_jump(sizeof_program(program1)) program.append(('SEQUENCE', str(jump))) program += list(program1) program += [('PADDING',)] * padding program += list(program2) return tuple(program)
def process_tasks(self): logger('processing {} merge tasks', len(self._tasks)) while self._tasks: _, id1, id2 = heapq.heappop(self._tasks) if id1 in self._programs and id2 in self._programs: yield id1, id2