コード例 #1
0
ファイル: cpp.py プロジェクト: imclab/pomagma
def write_ensurers(code, functions):

    code(
        '''
        $bar
        // compound ensurers
        ''',
        bar=bar,
    ).newline()

    functions = [(name, signature.get_nargs(arity))
                 for arity, funs in functions.iteritems()
                 if signature.get_nargs(arity) > 0
                 for name in funs]

    def Ob(x):
        return 'Ob %s' % x

    for name1, argc1 in functions:
        for name2, argc2 in functions:
            if name1 > name2:
                continue

            vars1 = ['key1'] if argc1 == 1 else ['lhs1', 'rhs1']
            vars2 = ['key2'] if argc2 == 1 else ['lhs2', 'rhs2']
            code(
                '''
                inline void ensure_${name1}_${name2} (
                    $typed_args1,
                    $typed_args2)
                {
                    if (Ob val1 = $NAME1.find($args1)) {
                        $NAME2.insert($args2, val1);
                    } else {
                        if (Ob val2 = $NAME2.find($args2)) {
                            $NAME1.insert($args1, val2);
                        }
                    }
                }
                ''',
                name1=name1.lower(),
                name2=name2.lower(),
                NAME1=name1,
                NAME2=name2,
                args1=', '.join(vars1),
                args2=', '.join(vars2),
                typed_args1=', '.join(map(Ob, vars1)),
                typed_args2=', '.join(map(Ob, vars2)),
            ).newline()
コード例 #2
0
ファイル: expressions.py プロジェクト: imclab/pomagma
 def __init__(self, name, *args):
     assert isinstance(name, str)
     assert re.match('[a-zA-Z][a-zA-Z_]*$', name),\
         'invalid name: {0}'.format(name)
     args = list(args)
     arity = signature.get_arity(name)
     assert len(args) == signature.get_nargs(arity)
     for arg in args:
         assert isinstance(arg, Expression), arg
     self._name = name
     self._args = args
     self._arity = arity
     self._polish = ' '.join([name] + [arg._polish for arg in args])
     self._hash = hash(self._polish)
     if arity == 'Variable':
         self._var = self
         self._vars = set([self])
     elif arity == 'NullaryFunction':
         self._var = Expression(name + '_')
         self._vars = set()
     elif arity in [
             'InjectiveFunction',
             'BinaryFunction',
             'SymmetricFunction',
     ]:
         var = re.sub('[ _]+', '_', self.polish).rstrip('_')
         self._var = Expression(var)
         self._vars = union(arg.vars for arg in args)
     else:
         self._var = None
         self._vars = union(arg.vars for arg in args)
コード例 #3
0
ファイル: expressions.py プロジェクト: fritzo/pomagma
 def __init__(self, name, *args):
     assert isinstance(name, str), type(name)
     assert re_name.match(name), name
     arity = signature.get_arity(name)
     assert len(args) == signature.get_nargs(arity), (args, arity)
     for arg in args:
         assert isinstance(arg, Expression), arg
     self._name = intern(name)
     self._args = args
     self._arity = arity
     self._polish = intern(' '.join([name] + [arg._polish for arg in args]))
     self._hash = hash(self._polish)
     self._sort = (len(self._polish), self._polish)
     # all other fields are lazily initialized
     self._var = None
     self._vars = None
     self._consts = None
     self._terms = None
コード例 #4
0
ファイル: cpp.py プロジェクト: imclab/pomagma
def write_event_tasks(code, sequents):

    code(
        '''
        $bar
        // event tasks
        ''',
        bar=bar,
    ).newline()

    event_tasks = {}
    for sequent in sequents:
        for event in compiler.get_events(sequent):
            name = '<variable>' if event.is_var() else event.name
            tasks = event_tasks.setdefault(name, [])
            strategies = compiler.compile_given(sequent, event)
            strategies.sort(key=lambda (cost, _): cost)
            costs = [cost for cost, _ in strategies]
            cost = log_sum_exp(*costs)
            tasks.append((event, cost, strategies))

    def get_group(name):
        special = {
            'LESS': 'PositiveOrder',
            'NLESS': 'NegativeOrder',
            '<variable>': 'Exists',
        }
        return special.get(name, signature.get_arity(name))

    group_tasks = {}
    for name, tasks in event_tasks.iteritems():
        groupname = get_group(name)
        group_tasks.setdefault(groupname, {})[name] = tasks

    # TODO sort groups
    # event_tasks = event_tasks.items()
    # event_tasks.sort(key=lambda (name, tasks): (len(tasks), len(name), name))

    group_tasks = list(group_tasks.iteritems())
    group_tasks.sort()

    for groupname, group in group_tasks:
        group = list(group.iteritems())
        group.sort()

        body = Code()

        for eventname, tasks in group:
            subbody = Code()
            nargs = signature.get_nargs(signature.get_arity(group[0][0]))
            args = [[], ['arg'], ['lhs', 'rhs']][nargs]
            for arg in args:
                subbody('const Ob $arg = task.$arg;', arg=arg)
            if signature.is_fun(eventname):
                subbody(
                    '''
                    const Ob val = $eventname.find($args);
                    ''',
                    eventname=eventname,
                    args=', '.join(args))

            for event, _, strategies in tasks:
                subsubbody = Code()
                diagonal = (nargs == 2 and event.args[0] == event.args[1])
                if diagonal:
                    subsubbody(
                        '''
                        const Ob $local __attribute__((unused)) = $arg;
                        ''',
                        local=event.args[0],
                        arg=args[0],
                    )
                else:
                    for local, arg in zip(event.args, args):
                        subsubbody(
                            '''
                            const Ob $local __attribute__((unused)) = $arg;
                            ''',
                            local=local,
                            arg=arg,
                        )
                if event.is_fun():
                    subsubbody('const Ob $arg = val;', arg=event.var.name)
                elif event.is_var():
                    subsubbody('const Ob $arg = task.ob;', arg=event.name)
                subcost = 0
                for cost, strategy in strategies:
                    subsubbody.newline()
                    strategy.cpp(subsubbody)
                    subcost += cost
                if diagonal:
                    subbody(
                        '''
                        if (lhs == rhs) { // cost = $cost
                            $subsubbody
                        }
                        ''',
                        cost=cost,
                        subsubbody=wrapindent(subsubbody),
                    )
                else:
                    subbody(
                        '''
                        { // cost = $cost
                            $subsubbody
                        }
                        ''',
                        cost=cost,
                        subsubbody=wrapindent(subsubbody),
                    )

            if eventname in ['LESS', 'NLESS', '<variable>']:
                body(str(subbody)).newline()
            else:
                body(
                    '''
                if (task.fun == & $eventname) {
                    $subbody
                }
                ''',
                    eventname=eventname,
                    subbody=wrapindent(subbody),
                ).newline()

        code(
            '''
            void execute (const ${groupname}Task & task)
            {
                $body
            }
            ''',
            groupname=groupname,
            body=wrapindent(body),
        ).newline()

    nontrivial_arities = [groupname for groupname, _ in group_tasks]
    for arity in signature.FUNCTION_ARITIES:
        if arity not in nontrivial_arities:
            code(
                '''
                void execute (const ${arity}Task &) {}
                ''',
                arity=arity,
            ).newline()
コード例 #5
0
ファイル: cpp.py プロジェクト: imclab/pomagma
def write_merge_task(code, functions):
    body = Code()
    body(
        '''
        const Ob dep = task.dep;
        const Ob rep = carrier.find(dep);
        POMAGMA_ASSERT(dep > rep, "ill-formed merge: " << dep << ", " << rep);
        bool invalid = NLESS.find(dep, rep) or NLESS.find(rep, dep);
        POMAGMA_ASSERT(not invalid, "invalid merge: " << dep << ", " << rep);

        std::vector<std::thread> threads;
        threads.push_back(std::thread(
            &BinaryRelation::unsafe_merge,
            &LESS,
            dep));
        threads.push_back(std::thread(
            &BinaryRelation::unsafe_merge,
            &NLESS,
            dep));
        ''',
    )

    functions = [
        (name, arity, signature.get_nargs(arity))
        for arity, funs in functions.iteritems()
        for name in funs
    ]
    functions.sort(key=lambda (name, arity, argc): -argc)

    for name, arity, argc in functions:
        if argc <= 1:
            body('$name.unsafe_merge(dep);', name=name)
        else:
            body(
                '''
                threads.push_back(std::thread(
                    &$arity::unsafe_merge,
                    &$name,
                    dep));
                ''',
                name=name,
                arity=arity,
            )
    body.newline()

    body(
        '''
        for (auto & thread : threads) { thread.join(); }
        carrier.unsafe_remove(dep);
        '''
    )

    code(
        '''
        void execute (const MergeTask & task)
        {
            $body
        }
        ''',
        body=wrapindent(body),
    ).newline()
コード例 #6
0
def parse_tokens_to_expr(tokens):
    head = tokens.pop()
    arity = get_arity(head)
    nargs = get_nargs(arity)
    args = [parse_tokens_to_expr(tokens) for _ in xrange(nargs)]
    return Expression.make(head, *args)
コード例 #7
0
ファイル: synthesize.py プロジェクト: fritzo/pomagma
def make_template(name):
    assert isinstance(name, str), name
    holes = [HOLE] * get_nargs(get_arity(name))
    return Expression.make(name, *holes)