Esempio n. 1
0
    def _binary_operation(self, stmt: Call, operator: BinaryOperation.Operator,
                          state: State):
        """Semantics of a call to a binary operation.

        :param stmt: call to binary operation to be executed
        :param operator: binary operator
        :param state: state before executing the call statements
        :return: state modified by the call statement
        """
        assert len(stmt.arguments
                   ) == 2  # binary operations have exactly two arguments
        argument1 = self.semantics(stmt.arguments[0], state).result
        argument2 = self.semantics(stmt.arguments[1], state).result
        result = set()
        if isinstance(operator, BinaryArithmeticOperation.Operator):
            for left, right in itertools.product(argument1, argument2):
                operation = BinaryArithmeticOperation(stmt.typ, left, operator,
                                                      right)
                result.add(operation)
        elif isinstance(operator, BinaryComparisonOperation.Operator):
            for left, right in itertools.product(argument1, argument2):
                operation = BinaryComparisonOperation(stmt.typ, left, operator,
                                                      right)
                result.add(operation)
        elif isinstance(operator, BinaryBooleanOperation.Operator):
            for left, right in itertools.product(argument1, argument2):
                operation = BinaryBooleanOperation(stmt.typ, left, operator,
                                                   right)
                result.add(operation)
        else:
            error = f"Semantics for binary operator {operator} is not yet implemented!"
            raise NotImplementedError(error)
        state.result = result
        return state
Esempio n. 2
0
    def _binary_operation(self, stmt: Call, operator: BinaryOperation.Operator,
                          state, interpreter):
        """Semantics of a call to a binary operation.

        :param stmt: call to binary operation to be executed
        :param operator: binary operator
        :param state: state before executing the call statements
        :return: state modified by the call statement
        """
        arguments = list()
        updated = state
        for i in range(len(stmt.arguments)):
            updated = self.semantics(stmt.arguments[i], updated, interpreter)
            arguments.append(updated.result)
        assert len(
            arguments) >= 2  # binary operations have at least two arguments
        result = set()
        if isinstance(operator, BinaryArithmeticOperation.Operator):
            for product in itertools.product(*arguments):
                operation = product[0]
                for i in range(1, len(arguments)):
                    right = product[i]
                    operation = BinaryArithmeticOperation(
                        stmt.typ, operation, operator, right)
                result.add(operation)
        elif isinstance(operator, BinarySequenceOperation.Operator):
            for product in itertools.product(*arguments):
                operation = product[0]
                for i in range(1, len(arguments)):
                    right = product[i]
                    operation = BinarySequenceOperation(
                        stmt.typ, operation, operator, right)
                result.add(operation)
        elif isinstance(operator, BinaryComparisonOperation.Operator):
            for product in itertools.product(*arguments):
                operation = product[0]
                for i in range(1, len(arguments)):
                    right = product[i]
                    operation = BinaryComparisonOperation(stmt.typ,
                                                          operation,
                                                          operator,
                                                          right,
                                                          forloop=stmt.forloop)
                result.add(operation)
        elif isinstance(operator, BinaryBooleanOperation.Operator):
            for product in itertools.product(*arguments):
                operation = product[0]
                for i in range(1, len(arguments)):
                    right = product[i]
                    operation = BinaryBooleanOperation(stmt.typ, operation,
                                                       operator, right)
                result.add(operation)
        else:
            error = f"Semantics for binary operator {operator} is not yet implemented!"
            raise NotImplementedError(error)
        state.result = result
        return state
Esempio n. 3
0
 def _assume(self,
             condition: Expression,
             bwd: bool = False) -> 'StringSetState':
     if isinstance(condition, UnaryBooleanOperation):
         if condition.operator == UnaryBooleanOperation.Operator.Neg:
             expression = condition.expression
             if isinstance(expression, BinaryComparisonOperation):
                 typ = expression.typ
                 left = expression.left
                 operator = expression.operator.reverse_operator()
                 right = expression.right
                 new_expression = BinaryComparisonOperation(
                     typ, left, operator, right)
                 return self._assume(new_expression, bwd=bwd)
             elif isinstance(expression, UnaryBooleanOperation):
                 if expression.operator == UnaryBooleanOperation.Operator.Neg:
                     return self._assume(expression.expression, bwd=bwd)
             elif isinstance(expression, BinaryBooleanOperation):
                 left = expression.left
                 op = UnaryBooleanOperation.Operator.Neg
                 left = UnaryBooleanOperation(left.typ, op, left)
                 operator = expression.operator.reverse_operator()
                 right = expression.right
                 op = UnaryBooleanOperation.Operator.Neg
                 right = UnaryBooleanOperation(right.typ, op, right)
                 typ = expression.typ
                 new_expression = BinaryBooleanOperation(
                     typ, left, operator, right)
                 return self._assume(new_expression, bwd=bwd)
     elif isinstance(condition, BinaryBooleanOperation):
         if condition.operator == BinaryBooleanOperation.Operator.And:
             right = deepcopy(self)._assume(condition.right, bwd=bwd)
             return self._assume(condition.left, bwd=bwd).meet(right)
         if condition.operator == BinaryBooleanOperation.Operator.Or:
             right = deepcopy(self)._assume(condition.right, bwd=bwd)
             return self._assume(condition.left, bwd=bwd).join(right)
     elif isinstance(condition, BinaryComparisonOperation):
         if condition.operator == BinaryComparisonOperation.Operator.Eq:
             left = condition.left
             right = condition.right
             left_eval = self._evaluation.visit(condition.left, self,
                                                dict())
             right_eval = self._evaluation.visit(condition.right, self,
                                                 dict())
             self._refinement.visit(left, left_eval, right_eval[right],
                                    self)
             self._refinement.visit(right, right_eval, left_eval[left],
                                    self)
     return self
Esempio n. 4
0
 def visit_BinaryBooleanOperation(self,
                                  expr: BinaryBooleanOperation):
     left = self.visit(expr.left)
     right = self.visit(expr.right)
     return BinaryBooleanOperation(expr.typ, left, expr.operator,
                                   right)