Exemplo n.º 1
0
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
Exemplo n.º 2
0
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]
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
 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