Beispiel #1
0
    def product(self, node):
        args = node.args
        if len(args) == 2:
            n = ast2str(args[0])
            n = n.replace(",", ";")
            n = n.replace(" ", "")
            n = n.replace("_sage_const_", "")
            N = int(n)
            right = self.visit(args[1])

            e_coeff = Coeff(right.batch, var('e'))
            b_coeff = Coeff(right.batch, var('b'))
            p_coeff = Coeff(right.batch, var('p'))

            total = N * right.total
            batch = (N * e_coeff) * formula('e') + \
                    (N * p_coeff) * formula('p')

            if N != 0:
                if b_coeff != 0:
                    s = right.type_[5:] + '_mul'
                    total += (N - 1) * formula(s)
                    batch += formula('b')

            R = Reduced(right.type_, node, total=total, batch=batch)
            return R
        else:
            semantic_error(node,\
              "invalid arguments for product:" + ast2str(node))
Beispiel #2
0
    def operation_Pow(self, X, Y, node, **kwargs):
        #        self.Print("operation_Pow:", X.type_,",", Y.type_)
        #        self.Print("operation_Pow:", kwargs['X_value'],",", kwargs['Y_value'])
        X_value = kwargs['X_value']
        Y_value = kwargs['Y_value']

        if (type(Y_value) == int):
            if (Y_value == 1) or (Y_value == 0):
                if (X.type_ == 'TYPE_INTEGER') or \
                   (X.type_ == 'TYPE_GROUP')   or \
                   (X.type_ == 'TYPE_GROUP0')  or \
                   (X.type_ == 'TYPE_GROUP1')  or \
                   (X.type_ == 'TYPE_GROUP2')  or \
                   (X.type_ == 'TYPE_TARGET'):
                    return X
            if (Y_value < 0):
                mY = Reduced('TYPE_INTEGER', node.right, total=0, batch=0)
                one = Reduced('TYPE_INTEGER', node.right, total=0, batch=0)
                Pow_kwargs = {}
                Pow_kwargs['X_value'] = X_value
                Pow_kwargs['Y_value'] = -Y_value
                Div_kwargs = {}
                Div_kwargs['X_value'] = 1
                Div_kwargs['Y_value'] = 'unknown'
                return self.operation_Div(one,\
                  self.operation_Pow(X,mY,node,**Pow_kwargs),\
                  node, **Div_kwargs)

        if (X.type_ == 'TYPE_TARGET') or \
           (X.type_ == 'TYPE_GROUP')  or \
           (X.type_ == 'TYPE_GROUP0') or \
           (X.type_ == 'TYPE_GROUP1') or \
           (X.type_ == 'TYPE_GROUP2'):
            X.batch = Batch(X)
            Y.batch = Batch(Y)
            X_b_coeff = Coeff(X.batch, var('b'))
            X_e_coeff = Coeff(X.batch, var('e'))
            X_p_coeff = Coeff(X.batch, var('p'))
            Y_b_coeff = Coeff(Y.batch, var('b'))
            Y_e_coeff = Coeff(Y.batch, var('e'))
            Y_p_coeff = Coeff(Y.batch, var('p'))
            s = X.type_[5:] + '_mul'
            total = X_e_coeff * formula(s)
            batch = (X_e_coeff + X_b_coeff) * formula('e') + \
                    (X_p_coeff            ) * formula('p')
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y)+total, batch=batch, **kwargs)
        elif X.type_ == 'TYPE_INTEGER':
            s = X.type_[5:] + '_pow'
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y)+formula(s), batch=0, **kwargs)
        else:
            warning(node, 'cannot infer type of ' + ast2str(X.node))
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y), batch=0, **kwargs)
Beispiel #3
0
def transfer_batch(X):
    X.batch = Batch(X)
    e_coeff = Coeff(X.batch, var('e'))
    b_coeff = Coeff(X.batch, var('b'))
    p_coeff = Coeff(X.batch, var('p'))
    if e_coeff != 0:
        s = X.type_[5:] + '_batch(' + str(e_coeff) + ';' \
                                    + str(b_coeff) + ')'
        X.total = formula(s) + X.total
    if p_coeff != 0:
        s = 'pairing_batch(' + str(p_coeff) + ')'
        X.total = formula(s) + X.total
        X.total -= (p_coeff - 1) * formula('TARGET_mul')
    X.batch = 0
Beispiel #4
0
 def visit_For(self, node):
     body = self.visit(node.body)
     transfer_batch(body)
     total = body.total
     if node.orelse:
         orelse = self.visit(node.orelse)
         transfer_batch(orelse)
         orelse = orelse.total
     else:
         orelse = 0
     t = ast2str(node.target)
     t = t.replace(",", ";")
     t = t.replace(" ", "")
     t = t.replace("_sage_const_", "")
     u = ast2str(node.iter)
     u = u.replace(",", ";")
     u = u.replace(" ", "")
     u = u.replace("_sage_const_", "")
     s = 'for_statement("'
     s += t
     s += '";"'
     s += u
     s += '";'
     s += str(total).replace(' ', '')
     s += ';'
     s += str(orelse).replace(' ', '')
     s += ")"
     total = formula(s)
     return Reduced('TYPE_FOR', node, total=total, batch=0)
Beispiel #5
0
 def visit_If(self, node):
     body = self.visit(node.body)
     transfer_batch(body)
     total = body.total
     # elifs.
     if (node.orelse and len(node.orelse) == 1 and \
            isinstance(node.orelse[0], ast.If)):
         orelse = self.visit(node.orelse[0])
         transfer_batch(orelse)
         orelse = orelse.total
     # final else
     elif node.orelse:
         orelse = self.visit(node.orelse)
         transfer_batch(orelse)
         orelse = orelse.total
     else:
         orelse = 0
     t = ast2str(node.test)
     t = t.replace(",", ";")
     t = t.replace(" ", "")
     s = 'if_statement("'
     s += t
     s += '";'
     s += str(total)
     s += ';'
     s += str(orelse)
     s += ")"
     total = formula(s)
     return Reduced('TYPE_IF', node, total=total, batch=0)
Beispiel #6
0
def transfer_bitexp(X, n):
    X.batch = Batch(X)
    e_coeff = Coeff(X.batch, var('e'))
    b_coeff = Coeff(X.batch, var('b'))
    p_coeff = Coeff(X.batch, var('p'))
    if e_coeff != 0:
        s = X.type_[5:] +                   \
            '_bitexp(' + str(n)       + ';' \
                       + str(e_coeff) + ';' \
                       + str(b_coeff) + ')'
        X.total = formula(s) + X.total
    if p_coeff != 0:
        s = "pairing_batch(" + str(p_coeff) + ")"
        X.total = formula(s) + X.total
        X.total -= (p_coeff - 1) * formula("TARGET_mul")
    X.batch = 0
Beispiel #7
0
    def operation_Name(self, node):
        total = 0
        batch = 0
        if hasattr(node, 'InferredType'):
            type_ = node.InferredType
        else:
            type_ = 'TYPE_UNKNOWN16'

        if (type_ == 'TYPE_GROUP')  or \
           (type_ == 'TYPE_GROUP0') or \
           (type_ == 'TYPE_GROUP1') or \
           (type_ == 'TYPE_GROUP2') or \
           (type_ == 'TYPE_TARGET'):
            batch = formula('b')

        if hasattr(node, 'InferredValue'):
            value = node.InferredValue
            return Reduced(type_,
                           node,
                           value=value,
                           total=total,
                           batch=batch,
                           id=node.id)
        else:
            return Reduced(type_, node, total=total, batch=batch, id=node.id)
Beispiel #8
0
    def visit_Call(self, node):
        func = node.func
        args = node.args
        ret = self.visit(func)
        total = 0
        batch = 0
        type_ = InferredType(node)

        if not hasattr(ret, 'id'):
            if type(args) in [list, tuple]:
                for i in range(len(args)):
                    child = self.visit(args[i])
                    transfer_batch(child)
                    total = child.total + total
        else:
            symbol = ret.node.id

            if (symbol == 'bitexp'): return self.bitexp(node)
            if (symbol == 'inline'): return self.inline(node)
            if (symbol == 'product'): return self.product(node)

            if type(args) in [list, tuple]:
                for i in range(len(args)):
                    child = self.visit(args[i])
                    transfer_batch(child)
                    total = child.total + total
                    # <-- process_Assign

            if (symbol == 'e'):
                return Reduced('TYPE_TARGET', node, total=total, \
                         batch=formula('b') + formula('p'))
            else:
                if (symbol != 'Integer')  and \
                   (symbol != 'Group')    and \
                   (symbol != 'Group0')   and \
                   (symbol != 'Group1')   and \
                   (symbol != 'Group2')   and \
                   (symbol != 'Target'):
                    total = formula('call_' + symbol) + total
                if (type_ == 'TYPE_GROUP')  or \
                   (type_ == 'TYPE_GROUP0') or \
                   (type_ == 'TYPE_GROUP1') or \
                   (type_ == 'TYPE_GROUP2') or \
                   (type_ == 'TYPE_TARGET'):
                    batch = formula('b')

        return Reduced(type_, node, total=total, batch=batch)
Beispiel #9
0
 def operation_Add(self, X, Y, node, **kwargs):
     #        self.Print("operation_Add:", X.value,",", Y.value)
     if (X.type_ != 'TYPE_INTEGER') or \
        (Y.type_ != 'TYPE_INTEGER'):
         return Reduced(X.type_, node, total=0)
     transfer_batch(X)
     transfer_batch(Y)
     s = X.type_[5:] + '_add'
     total = formula(s) + Total(X) + Total(Y)
     return Reduced(X.type_, node, total=total, batch=0, **kwargs)
Beispiel #10
0
 def operation_Sub(self, X, Y, node, **kwargs):
     #        self.Print("operation_Sub:", X.type_,",", Y.type_)
     if (X.type_ != 'TYPE_INTEGER') or \
        (Y.type_ != 'TYPE_INTEGER'):
         return Reduced(X.type_, node, total=0)
     transfer_batch(X)
     transfer_batch(Y)
     s = X.type_[5:] + '_sub'
     total = formula(s) + Total(X) + Total(Y)
     #        print("operation_Sub:", total)
     return Reduced(X.type_, node, total=total, batch=0, **kwargs)
Beispiel #11
0
    def operation_Div(self, X, Y, node, **kwargs):
        #        self.Print("operation_Div:", X.type_,",", Y.type_)
        X_value = kwargs['X_value']
        Y_value = kwargs['Y_value']

        # X/1

        if (Y.type_ == 'TYPE_INTEGER') and (Y_value == 1):
            if (X.type_ == 'TYPE_INTEGER') or \
               (X.type_ == 'TYPE_GROUP')   or \
               (X.type_ == 'TYPE_GROUP0')  or \
               (X.type_ == 'TYPE_GROUP1')  or \
               (X.type_ == 'TYPE_GROUP2')  or \
               (X.type_ == 'TYPE_TARGET'):
                return X

        # 1/Y

        if (X.type_ == 'TYPE_INTEGER') and (X_value == 1):
            if (Y.type_ == 'TYPE_GROUP')   or \
               (Y.type_ == 'TYPE_GROUP0')  or \
               (Y.type_ == 'TYPE_GROUP1')  or \
               (Y.type_ == 'TYPE_GROUP2'):
                return Y
            if (Y.type_ == 'TYPE_TARGET'):
                X.type_ = 'TYPE_TARGET'
                X.batch = formula('b')
            # if (X.type_ == 'TYPE_INTEGER'):

        # if not (((X.type_ == 'TYPE_INTEGER') or  \
        #          (X.type_ == 'TYPE_GROUP')   or  \
        #          (X.type_ == 'TYPE_GROUP0')  or  \
        #          (X.type_ == 'TYPE_GROUP1')  or  \
        #          (X.type_ == 'TYPE_GROUP2')  or  \
        #          (X.type_ == 'TYPE_TARGET')) and \
        #         (X.type_ == Y.type_)):
        #     OPERATION_ERROR2()

        if (X.type_ == 'TYPE_TARGET') or \
           (X.type_ == 'TYPE_GROUP') or \
           (X.type_ == 'TYPE_GROUP0') or \
           (X.type_ == 'TYPE_GROUP1') or \
           (X.type_ == 'TYPE_GROUP2'):
            X.batch = Batch(X)
            Y.batch = Batch(Y)
            X_b_coeff = Coeff(X.batch, var('b'))
            X_e_coeff = Coeff(X.batch, var('e'))
            X_p_coeff = Coeff(X.batch, var('p'))
            Y_b_coeff = Coeff(Y.batch, var('b'))
            Y_e_coeff = Coeff(Y.batch, var('e'))
            Y_p_coeff = Coeff(Y.batch, var('p'))
            total = 0
            batch = (X_e_coeff + Y_e_coeff) * formula('e') + \
                    (X_p_coeff + Y_p_coeff) * formula('p')
            if (X_b_coeff != 0) and (Y_b_coeff != 0):
                s = X.type_[5:] + '_div'
                total = formula(s)
            if (X_b_coeff != 0) or (Y_b_coeff != 0):
                batch += formula('b')
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y)+total, batch=batch, **kwargs)
        elif X.type_ == 'TYPE_INTEGER':
            s = X.type_[5:] + '_div'
            total = formula(s)
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y)+formula(s), batch=0, **kwargs)
        else:
            warning(node, 'cannot infer type of ' + ast2str(X.node))
            return Reduced(X.type_, node, \
                     total=Total(X)+Total(Y), batch=0, **kwargs)