예제 #1
0
 def test_expr_variables(self) -> None:
     self.assertEqual(
         Or(
             Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
         ).variables(),
         [Variable("Y"), Variable("X")],
     )
     self.assertEqual(
         Or(
             Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
         ).variables(),
         [Variable("Y"), Variable("X")],
     )
     self.assertEqual(
         Or(
             Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
         ).variables(),
         [Variable("Y"), Variable("X")],
     )
     self.assertEqual(
         Or(
             Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(1)))
         ).variables(),
         [Variable("Y"), Variable("X")],
     )
예제 #2
0
 def test_bin_expr_converted(self) -> None:
     self.assertEqual(
         Less(Variable("X"), Number(1)).converted(
             lambda x: Name(x.name) if isinstance(x, Variable) else x
         ),
         Less(Name("X"), Number(1)),
     )
     self.assertEqual(
         Sub(Variable("X"), Number(1)).converted(
             lambda x: Name("Y") if x == Sub(Variable("X"), Number(1)) else x
         ),
         Name("Y"),
     )
예제 #3
0
 def test_expr_variables_duplicates(self) -> None:
     self.assertEqual(
         And(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Or(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Add(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(
         Mul(Variable("X"), Variable("Y"), Variable("X")).variables(),
         [Variable("X"), Variable("Y")],
     )
     self.assertEqual(Sub(Variable("X"), Variable("X")).variables(), [Variable("X")])
     self.assertEqual(Div(Variable("X"), Variable("X")).variables(), [Variable("X")])
     self.assertEqual(
         Or(
             Greater(Variable("X"), Number(42)), And(TRUE, Less(Variable("X"), Number(1)))
         ).variables(),
         [Variable("X")],
     )
예제 #4
0
def test_exclusive_conflict() -> None:
    f1 = Field(ID("F1", Location((8, 4))))
    structure = [
        Link(INITIAL, f1),
        Link(f1,
             FINAL,
             condition=Greater(Variable("F1"), Number(50), Location((10, 5)))),
        Link(f1,
             Field("F2"),
             condition=Less(Variable("F1"), Number(80), Location((11, 7)))),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): RANGE_INTEGER,
        Field("F2"): RANGE_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'<stdin>:8:4: model: error: conflicting conditions for field "F1"\n'
        r"<stdin>:10:5: model: info: condition 0 [(]F1 -> Final[)]: F1 > 50\n"
        r"<stdin>:11:7: model: info: condition 1 [(]F1 -> F2[)]: F1 < 80"
        r"$",
    )
예제 #5
0
    def create_present_function() -> UnitPart:
        specification = FunctionSpecification(
            "Present", "Boolean",
            [Parameter(["Ctx"], "Context"),
             Parameter(["Fld"], "Field")])

        return UnitPart(
            [SubprogramDeclaration(specification)],
            [
                ExpressionFunctionDeclaration(
                    specification,
                    AndThen(
                        Call("Structural_Valid", [
                            Indexed(Variable("Ctx.Cursors"), Variable("Fld"))
                        ]),
                        Less(
                            Selected(
                                Indexed(Variable("Ctx.Cursors"),
                                        Variable("Fld")), "First"),
                            Add(
                                Selected(
                                    Indexed(Variable("Ctx.Cursors"),
                                            Variable("Fld")), "Last"),
                                Number(1),
                            ),
                        ),
                    ),
                )
            ],
        )
예제 #6
0
def enumeration_functions(enum: Enumeration) -> List[Subprogram]:
    common_precondition = And(
        Less(Value('Offset'), Number(8)),
        Equal(
            Length('Buffer'),
            Add(
                Div(Add(Size(enum.base_name), Value('Offset'), Number(-1)),
                    Number(8)), Number(1))))

    control_expression = LogCall(
        f'Convert_To_{enum.base_name} (Buffer, Offset)')

    validation_expression: Expr
    if enum.always_valid:
        validation_expression = Value('True')
    else:
        validation_cases: List[Tuple[Expr, Expr]] = []
        validation_cases.extend(
            (value, Value('True')) for value in enum.literals.values())
        validation_cases.append((Value('others'), Value('False')))

        validation_expression = CaseExpression(control_expression,
                                               validation_cases)
    validation_function = ExpressionFunction(
        f'Valid_{enum.name}', 'Boolean', [('Buffer', 'Types.Bytes'),
                                          ('Offset', 'Natural')],
        validation_expression, [Precondition(common_precondition)])

    function_name = f'Convert_To_{enum.name}'
    parameters = [('Buffer', 'Types.Bytes'), ('Offset', 'Natural')]
    precondition = Precondition(
        And(common_precondition,
            LogCall(f'Valid_{enum.name} (Buffer, Offset)')))
    conversion_cases: List[Tuple[Expr, Expr]] = []
    conversion_function: Subprogram

    if enum.always_valid:
        conversion_cases.extend((value, Aggregate(Value('True'), Value(key)))
                                for key, value in enum.literals.items())
        conversion_cases.append(
            (Value('others'), Aggregate(Value('False'), Value('Raw'))))

        conversion_function = Function(
            function_name, enum.name, parameters,
            [Declaration('Raw', enum.base_name, control_expression)],
            [ReturnStatement(CaseExpression(Value('Raw'), conversion_cases))],
            [precondition])
    else:
        conversion_cases.extend(
            (value, Value(key)) for key, value in enum.literals.items())
        conversion_cases.append(
            (Value('others'), LogCall(f'Unreachable_{enum.name}')))

        conversion_function = ExpressionFunction(
            function_name, enum.name, parameters,
            CaseExpression(control_expression, conversion_cases),
            [precondition])

    return [validation_function, conversion_function]
예제 #7
0
    def create_valid_function() -> UnitPart:
        specification = FunctionSpecification(
            "Valid", "Boolean",
            [Parameter(["Ctx"], "Context"),
             Parameter(["Fld"], "Field")])

        return UnitPart(
            [
                SubprogramDeclaration(
                    specification,
                    [
                        Postcondition(
                            If([(
                                Result("Valid"),
                                And(
                                    Call(
                                        "Structural_Valid",
                                        [Variable("Ctx"),
                                         Variable("Fld")],
                                    ),
                                    Call("Present",
                                         [Variable("Ctx"),
                                          Variable("Fld")]),
                                ),
                            )])),
                    ],
                )
            ],
            [
                ExpressionFunctionDeclaration(
                    specification,
                    AndThen(
                        Equal(
                            Selected(
                                Indexed(Variable("Ctx.Cursors"),
                                        Variable("Fld")), "State"),
                            Variable("S_Valid"),
                        ),
                        Less(
                            Selected(
                                Indexed(Variable("Ctx.Cursors"),
                                        Variable("Fld")), "First"),
                            Add(
                                Selected(
                                    Indexed(Variable("Ctx.Cursors"),
                                            Variable("Fld")), "Last"),
                                Number(1),
                            ),
                        ),
                    ),
                )
            ],
        )
예제 #8
0
def test_bin_expr_substituted() -> None:
    assert_equal(
        Less(Variable("X"), Number(1)).substituted(
            lambda x: Variable(f"P_{x}") if isinstance(x, Variable) else x
        ),
        Less(Variable("P_X"), Number(1)),
    )
    assert_equal(
        Sub(Variable("X"), Number(1)).substituted(
            lambda x: Variable("Y") if x == Sub(Variable("X"), Number(1)) else x
        ),
        Variable("Y"),
    )
    assert_equal(
        NotEqual(Variable("X"), Number(1)).substituted(
            lambda x: Variable(f"P_{x}")
            if isinstance(x, Variable)
            else (Equal(x.left, x.right) if isinstance(x, NotEqual) else x)
        ),
        Equal(Variable("P_X"), Number(1)),
    )
예제 #9
0
def parse_relation(string: str, location: int, tokens: list) -> Relation:
    if tokens[1] == '<':
        return Less(tokens[0], tokens[2])
    if tokens[1] == '<=':
        return LessEqual(tokens[0], tokens[2])
    if tokens[1] == '=':
        return Equal(tokens[0], tokens[2])
    if tokens[1] == '>=':
        return GreaterEqual(tokens[0], tokens[2])
    if tokens[1] == '>':
        return Greater(tokens[0], tokens[2])
    if tokens[1] == '/=':
        return NotEqual(tokens[0], tokens[2])
    raise ParseFatalException(string, location, 'unexpected relation operator')
예제 #10
0
def parse_relation(string: str, location: int,
                   tokens: ParseResults) -> Relation:
    if tokens[1] == "<":
        return Less(tokens[0], tokens[2])
    if tokens[1] == "<=":
        return LessEqual(tokens[0], tokens[2])
    if tokens[1] == "=":
        return Equal(tokens[0], tokens[2])
    if tokens[1] == ">=":
        return GreaterEqual(tokens[0], tokens[2])
    if tokens[1] == ">":
        return Greater(tokens[0], tokens[2])
    if tokens[1] == "/=":
        return NotEqual(tokens[0], tokens[2])
    raise ParseFatalException(string, location, "unexpected relation operator")
예제 #11
0
def test_expr_contains() -> None:
    assert Variable("X") in Or(
        Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
    )
    assert Variable("Z") not in Or(
        Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
    )
    assert Less(Variable("X"), Number(42)) in Or(
        Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42)))
    )
    assert Less(Variable("Z"), Number(42)) not in Or(
        Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(1)))
    )
예제 #12
0
def parse_relation(string: str, location: int,
                   tokens: ParseResults) -> Relation:
    def locn() -> Location:
        return Location(tokens[0].location.start, tokens[0].location.source,
                        tokens[2].location.end)

    if tokens[1] == "<":
        return Less(tokens[0], tokens[2], locn())
    if tokens[1] == "<=":
        return LessEqual(tokens[0], tokens[2], locn())
    if tokens[1] == "=":
        return Equal(tokens[0], tokens[2], locn())
    if tokens[1] == ">=":
        return GreaterEqual(tokens[0], tokens[2], locn())
    if tokens[1] == ">":
        return Greater(tokens[0], tokens[2], locn())
    if tokens[1] == "/=":
        return NotEqual(tokens[0], tokens[2], locn())
    raise ParseFatalException(string, location, "unexpected relation operator")
예제 #13
0
def test_invalid_type_condition_modular_lower() -> None:
    structure = [
        Link(INITIAL, Field("F1")),
        Link(Field("F1"),
             Field("F2"),
             condition=Less(Variable("F1"), Number(0))),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): MODULAR_INTEGER,
        Field("F2"): MODULAR_INTEGER,
    }
    assert_message_model_error(
        structure,
        types,
        r"^"
        r'model: error: contradicting condition in "P.M"\n'
        r'model: info: on path: "F1"\n'
        r'model: info: unsatisfied "F1 >= 0"\n'
        r'model: info: unsatisfied "F1 < 0"',
    )
예제 #14
0
def test_exclusive_with_length_valid() -> None:
    structure = [
        Link(INITIAL, Field("F1"), length=Number(32)),
        Link(
            Field("F1"),
            FINAL,
            condition=And(Equal(Length("F1"), Number(32)),
                          Less(Variable("F1"), Number(50))),
        ),
        Link(
            Field("F1"),
            Field("F2"),
            condition=And(Equal(Length("F1"), Number(32)),
                          Greater(Variable("F1"), Number(80))),
        ),
        Link(Field("F2"), FINAL),
    ]
    types = {
        Field("F1"): Opaque(),
        Field("F2"): MODULAR_INTEGER,
    }
    Message("P.M", structure, types)
예제 #15
0
 def test_expr_contains(self) -> None:
     self.assertTrue(
         Variable("X")
         in Or(Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42))))
     )
     self.assertFalse(
         Variable("Z")
         in Or(Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42))))
     )
     self.assertTrue(
         Less(Variable("X"), Number(42))
         in Or(Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(42))))
     )
     self.assertFalse(
         Less(Variable("Z"), Number(42))
         in Or(Greater(Variable("Y"), Number(42)), And(TRUE, Less(Variable("X"), Number(1))))
     )
예제 #16
0
def test_dot_graph_with_double_edge(tmp_path: Path) -> None:
    f_type = ModularInteger("P::T", Pow(Number(2), Number(32)))
    m = Message(
        "P::M",
        structure=[
            Link(INITIAL, Field("X")),
            Link(Field("X"), FINAL, Greater(Variable("X"), Number(100))),
            Link(Field("X"), FINAL, Less(Variable("X"), Number(50))),
        ],
        types={Field("X"): f_type},
    )
    expected = """
        digraph "P::M" {
            graph [bgcolor="#00000000", pad="0.1", ranksep="0.1 equally", splines=true,
                   truecolor=true];
            edge [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", penwidth="2.5"];
            node [color="#6f6f6f", fillcolor="#009641", fontcolor="#ffffff", fontname=Arimo,
                  shape=box, style="rounded,filled", width="1.5"];
            Initial [fillcolor="#ffffff", label="", shape=circle, width="0.5"];
            X;
            intermediate_0 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0,
                            label="(⊤, 32, ⋆)", penwidth=0, style="", width=0];
            Initial -> intermediate_0 [arrowhead=none];
            intermediate_0 -> X [minlen=1];
            intermediate_1 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0,
                            label="(X < 50, 0, ⋆)", penwidth=0, style="", width=0];
            X -> intermediate_1 [arrowhead=none];
            intermediate_1 -> Final [minlen=1];
            intermediate_2 [color="#6f6f6f", fontcolor="#6f6f6f", fontname="Fira Code", height=0,
                            label="(X > 100, 0, ⋆)", penwidth=0, style="", width=0];
            X -> intermediate_2 [arrowhead=none];
            intermediate_2 -> Final [minlen=1];
            Final [fillcolor="#6f6f6f", label="", shape=circle, width="0.5"];
        }
        """

    assert_graph(create_message_graph(m), expected, tmp_path)
예제 #17
0
 def test_relation_variables(self) -> None:
     self.assertEqual(Less(Variable("X"), Name("Y")).variables(), [Variable("X")])
     self.assertEqual(
         Less(Variable("X"), Variable("Y")).variables(), [Variable("X"), Variable("Y")]
     )
예제 #18
0
 def test_less_than(self) -> None:
     self.assertEqual(
         Less(Number(1), Number(100)).z3expr(),
         z3.IntVal(1) < z3.IntVal(100))
예제 #19
0
def test_less_neg() -> None:
    assert -Less(Variable("X"), Number(1)) == GreaterEqual(Variable("X"), Number(1))
예제 #20
0
 def test_greater_equal_neg(self) -> None:
     self.assertEqual(-GreaterEqual(Variable("X"), Number(1)), Less(Variable("X"), Number(1)))
예제 #21
0
 def test_less_simplified(self) -> None:
     self.assertEqual(
         Less(Variable("X"), Add(Number(21), Number(21))).simplified(),
         Less(Variable("X"), Number(42)),
     )
예제 #22
0
 def test_less_neg(self) -> None:
     self.assertEqual(-Less(Variable("X"), Number(1)), GreaterEqual(Variable("X"), Number(1)))
예제 #23
0
 def test_relation_contains(self) -> None:
     self.assertTrue(Variable("X") in Less(Variable("X"), Number(42)))
예제 #24
0
파일: model.py 프로젝트: senier/RecordFlux
 def constraints(self, name: str, proof: bool = False) -> Expr:
     if proof:
         return And(
             Less(Variable(name), self.__modulus), GreaterEqual(Variable(name), Number(0))
         )
     return TRUE
예제 #25
0
def test_less_simplified() -> None:
    assert Less(Number(0), Number(1)).simplified() == TRUE
    assert Less(Number(1), Number(1)).simplified() == FALSE
    assert Less(Number(2), Number(1)).simplified() == FALSE
예제 #26
0
def test_greater_equal_neg() -> None:
    assert -GreaterEqual(Variable("X"), Number(1)) == Less(Variable("X"), Number(1))
예제 #27
0
 def test_less_simplified(self) -> None:
     self.assertEqual(
         Less(Value('X'), Add(Number(21), Number(21))).simplified(),
         Less(Value('X'), Number(42)))
예제 #28
0
 def test_and_contains(self) -> None:
     self.assertTrue(Variable("X") in And(TRUE, Less(Variable("X"), Number(42))))
     self.assertFalse(Variable("Y") in And(TRUE, Less(Variable("X"), Number(42))))
예제 #29
0
def test_less_than() -> None:
    assert Less(Number(1), Number(100)).z3expr() == (z3.IntVal(1) < z3.IntVal(100))
예제 #30
0
 def test_or_contains(self) -> None:
     self.assertTrue(Variable("X") in Or(Less(Variable("X"), Number(42)), TRUE))
     self.assertFalse(Variable("Y") in Or(Less(Variable("X"), Number(42)), TRUE))