Пример #1
0
 def field_value(field: model.Field) -> expr.Expr:
     if public:
         return expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])
     return expr.Selected(
         expr.Indexed(
             expr.Variable(ID("Ctx") * "Cursors" if not embedded else "Cursors"),
             expr.Variable(field.affixed_name),
         ),
         "Value",
     )
Пример #2
0
 def valid_predecessors_invariant() -> Expr:
     return AndThen(
         *[
             If(
                 [
                     (
                         Call(
                             "Structural_Valid",
                             [
                                 Indexed(
                                     Variable("Cursors"),
                                     Variable(f.affixed_name),
                                 )
                             ],
                         ),
                         Or(
                             *[
                                 expr.AndThen(
                                     expr.Call(
                                         "Structural_Valid"
                                         if l.source in composite_fields
                                         else "Valid",
                                         [
                                             expr.Indexed(
                                                 expr.Variable("Cursors"),
                                                 expr.Variable(l.source.affixed_name),
                                             )
                                         ],
                                     ),
                                     expr.Equal(
                                         expr.Selected(
                                             expr.Indexed(
                                                 expr.Variable("Cursors"),
                                                 expr.Variable(f.affixed_name),
                                             ),
                                             "Predecessor",
                                         ),
                                         expr.Variable(l.source.affixed_name),
                                     ),
                                     l.condition.substituted(
                                         substitution(message, embedded=True, prefix=prefix)
                                     ),
                                 )
                                 .simplified()
                                 .ada_expr()
                                 for l in message.incoming(f)
                             ]
                         ),
                     )
                 ]
             )
             for f in message.fields
             if f not in message.direct_successors(model.INITIAL)
         ]
     )
Пример #3
0
    def parameter_value(parameter: model.Field, parameter_type: model.Type) -> expr.Expr:
        if isinstance(parameter_type, model.Enumeration):
            if embedded:
                return expr.Call("To_Base_Integer", [expr.Variable(parameter.name)])
            return expr.Call("To_Base_Integer", [expr.Variable("Ctx" * parameter.identifier)])
        if isinstance(parameter_type, model.Scalar):
            if embedded:
                return expr.Variable(parameter.name)
            return expr.Variable("Ctx" * parameter.identifier)

        assert False, f'unexpected type "{type(parameter_type).__name__}"'
Пример #4
0
 def field_size(field: model.Field) -> expr.Expr:
     if public:
         return expr.Call(
             "Field_Size", [expr.Variable("Ctx"), expr.Variable(field.affixed_name)]
         )
     return expr.Add(
         expr.Sub(
             expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "Last"),
             expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "First"),
         ),
         expr.Number(1),
     )
Пример #5
0
def has_aggregate_dependent_condition(message: model.Message, field: model.Field = None) -> bool:
    links = message.outgoing(field) if field else message.structure
    fields = [field] if field else message.fields
    return any(
        r
        for l in links
        for r in l.condition.findall(lambda x: isinstance(x, (expr.Equal, expr.NotEqual)))
        if isinstance(r, (expr.Equal, expr.NotEqual))
        and r.findall(lambda x: isinstance(x, expr.Aggregate))
        and any(
            r.left == expr.Variable(f.identifier) or r.right == expr.Variable(f.identifier)
            for f in fields
        )
    )
Пример #6
0
    def constraints(self,
                    name: str,
                    proof: bool = False,
                    same_package: bool = True) -> ty.Sequence[expr.Expr]:
        if proof:
            return [
                expr.GreaterEqual(expr.Variable(name),
                                  self.first,
                                  location=self.location),
                expr.LessEqual(expr.Variable(name),
                               self.last,
                               location=self.location),
                expr.Equal(expr.Size(name), self.size, location=self.location),
            ]

        raise NotImplementedError
Пример #7
0
    def constraints(self,
                    name: str,
                    proof: bool = False,
                    same_package: bool = True) -> ty.Sequence[expr.Expr]:
        if proof:
            prefixed_literals = {
                self.package * l: v
                for l, v in self.literals.items()
            }
            if self.package == const.BUILTINS_PACKAGE:
                literals = self.literals
            elif same_package:
                literals = {**self.literals, **prefixed_literals}
            else:
                literals = prefixed_literals
            result: ty.List[expr.Expr] = [
                expr.Or(
                    *[
                        expr.Equal(expr.Variable(name), expr.Literal(l),
                                   self.location) for l in literals
                    ],
                    location=self.location,
                )
            ]
            result.extend([
                expr.Equal(expr.Literal(l), v, self.location)
                for l, v in literals.items()
            ])
            result.append(expr.Equal(expr.Size(name), self.size,
                                     self.location))
            return result

        raise NotImplementedError
Пример #8
0
 def valid_message_condition(self,
                             message: Message,
                             structural: bool = False) -> Expr:
     return (expr.Or(*[
         expr.AndThen(
             expr.Call(
                 "Structural_Valid" if structural and isinstance(
                     message.field_types[l.source], Composite) else "Valid",
                 [
                     expr.Variable("Ctx"),
                     expr.Variable(l.source.affixed_name, immutable=True),
                 ],
             ),
             l.condition,
         ) for l in message.incoming(FINAL) if l.target == FINAL
     ]).substituted(common.substitution(
         message, self.prefix)).simplified().ada_expr())
Пример #9
0
def test_named_aggregate_rflx_expr() -> None:
    assert ada.NamedAggregate(
        ("X", ada.Number(1)),
        (ada.ValueRange(ada.Number(2), ada.Number(3)), ada.Variable("Y")),
    ).rflx_expr() == expr.NamedAggregate(
        ("X", expr.Number(1)),
        (expr.ValueRange(expr.Number(2), expr.Number(3)), expr.Variable("Y")),
    )
Пример #10
0
 def condition(pair: FieldPair) -> expr.Expr:
     if isinstance(pair.source_type, Integer):
         first = pair.source_type.first.value
         last = pair.source_type.last.value
         if last - first > 0:
             return expr.Equal(
                 expr.Variable(pair.source.name),
                 expr.Number(draw(st.integers(min_value=first, max_value=last))),
             )
     elif isinstance(pair.source_type, Enumeration) and len(pair.source_type.literals) > 1:
         return expr.Equal(
             expr.Variable(pair.source.name),
             expr.Variable(
                 list(pair.source_type.literals.keys())[
                     draw(st.integers(min_value=0, max_value=len(pair.source_type.literals) - 1))
                 ]
             ),
         )
     return expr.TRUE
Пример #11
0
def test_substitution_relation_aggregate(
    relation: Callable[[expr.Expr, expr.Expr], expr.Relation], left: expr.Expr, right: expr.Expr
) -> None:
    equal_call = expr.Call(
        "Equal",
        [
            expr.Variable("Ctx"),
            expr.Variable("F_Value"),
            expr.Aggregate(
                expr.Val(expr.Variable("Types.Byte"), expr.Number(1)),
                expr.Val(expr.Variable("Types.Byte"), expr.Number(2)),
            ),
        ],
    )

    assert_equal(
        relation(left, right).substituted(common.substitution(TLV_MESSAGE)),
        equal_call if relation == expr.Equal else expr.Not(equal_call),
    )
Пример #12
0
 def size(pair: FieldPair) -> expr.Expr:
     max_size = 2**29 - 1
     if isinstance(pair.target_type, (Opaque, Sequence)):
         if isinstance(pair.source_type, Integer):
             if pair.source_type.last.value <= max_size:
                 return expr.Mul(expr.Variable(pair.source.name), expr.Number(8))
         return expr.Number(
             draw(st.integers(min_value=1, max_value=max_size).map(lambda x: x * 8))
         )
     return expr.UNDEFINED
Пример #13
0
    def field_value(field: model.Field, field_type: model.Type) -> expr.Expr:
        if isinstance(field_type, model.Enumeration):
            if public:
                return expr.Call(
                    "To_Base_Integer", [expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])]
                )
            return expr.Selected(
                expr.Indexed(cursors, expr.Variable(field.affixed_name)),
                "Value",
            )
        if isinstance(field_type, model.Scalar):
            if public:
                return expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])
            return expr.Selected(
                expr.Indexed(cursors, expr.Variable(field.affixed_name)),
                "Value",
            )
        if isinstance(field_type, model.Composite):
            return expr.Variable(field.name)

        assert False, f'unexpected type "{type(field_type).__name__}"'
Пример #14
0
                                 skip_model_verification=True).package(
                                     "Parameterized").new_message("Message"))
    validation_result = validator._validate_message(  # pylint: disable = protected-access
        Path(TEST_DIR /
             "parameterized/message/valid/parameterized_message.raw"),
        valid_original_message=True,
        message_value=message,
    )
    assert validation_result.validation_success


@pytest.mark.parametrize(
    "expression,expected",
    [
        (
            expr.Or(expr.Equal(expr.Variable("A"), expr.TRUE),
                    expr.Equal(expr.Variable("B"), expr.TRUE)),
            [
                expr.Equal(expr.Variable("A"), expr.TRUE),
                expr.Equal(expr.Variable("B"), expr.TRUE),
            ],
        ),
        (
            expr.And(expr.Equal(expr.Variable("A"), expr.TRUE),
                     expr.Equal(expr.Variable("B"), expr.TRUE)),
            [
                expr.And(
                    expr.Equal(expr.Variable("A"), expr.TRUE),
                    expr.Equal(expr.Variable("B"), expr.TRUE),
                ),
            ],
Пример #15
0
def message_structure_invariant(
    message: model.Message, prefix: str, link: model.Link = None, embedded: bool = False
) -> Expr:
    def prefixed(name: str) -> expr.Expr:
        return expr.Selected(expr.Variable("Ctx"), name) if not embedded else expr.Variable(name)

    if not link:
        return message_structure_invariant(
            message, prefix, message.outgoing(model.INITIAL)[0], embedded
        )

    source = link.source
    target = link.target

    if target == model.FINAL:
        return TRUE

    field_type = message.types[target]
    condition = link.condition.substituted(substitution(message, prefix, embedded)).simplified()
    size = (
        field_type.size
        if isinstance(field_type, model.Scalar)
        else link.size.substituted(
            substitution(message, prefix, embedded, target_type=const.TYPES_BIT_LENGTH)
        ).simplified()
    )
    first = (
        prefixed("First")
        if source == model.INITIAL
        else link.first.substituted(
            substitution(message, prefix, embedded, target_type=const.TYPES_BIT_INDEX)
        )
        .substituted(
            mapping={
                expr.UNDEFINED: expr.Add(
                    expr.Selected(
                        expr.Indexed(prefixed("Cursors"), expr.Variable(source.affixed_name)),
                        "Last",
                    ),
                    expr.Number(1),
                )
            }
        )
        .simplified()
    )
    invariant = [
        message_structure_invariant(message, prefix, l, embedded) for l in message.outgoing(target)
    ]

    return If(
        [
            (
                AndThen(
                    Call(
                        "Structural_Valid",
                        [Indexed(prefixed("Cursors").ada_expr(), Variable(target.affixed_name))],
                    ),
                    *([condition.ada_expr()] if condition != expr.TRUE else []),
                ),
                AndThen(
                    Equal(
                        Add(
                            Sub(
                                Selected(
                                    Indexed(
                                        prefixed("Cursors").ada_expr(),
                                        Variable(target.affixed_name),
                                    ),
                                    "Last",
                                ),
                                Selected(
                                    Indexed(
                                        prefixed("Cursors").ada_expr(),
                                        Variable(target.affixed_name),
                                    ),
                                    "First",
                                ),
                            ),
                            Number(1),
                        ),
                        size.ada_expr(),
                    ),
                    Equal(
                        Selected(
                            Indexed(
                                prefixed("Cursors").ada_expr(),
                                Variable(target.affixed_name),
                            ),
                            "Predecessor",
                        ),
                        Variable(source.affixed_name),
                    ),
                    Equal(
                        Selected(
                            Indexed(
                                prefixed("Cursors").ada_expr(),
                                Variable(target.affixed_name),
                            ),
                            "First",
                        ),
                        first.ada_expr(),
                    ),
                    *[i for i in invariant if i != TRUE],
                ),
            )
        ]
    )
Пример #16
0
def test_conversion_rflx_expr() -> None:
    assert ada.Conversion("X",
                          ada.Variable("Y")).rflx_expr() == expr.Conversion(
                              "X", expr.Variable("Y"))
Пример #17
0
def test_not_rflx_expr() -> None:
    assert ada.Not(ada.Variable("X")).rflx_expr() == expr.Not(
        expr.Variable("X"))
Пример #18
0
def test_math_expr_ada_expr(
        expression: Callable[[ada.Expr, ada.Expr], ada.Expr]) -> None:
    result = expression(ada.Variable("X"), ada.Variable("Y")).rflx_expr()
    expected = getattr(expr, expression.__name__)(expr.Variable("X"),
                                                  expr.Variable("Y"))
    assert result == expected
Пример #19
0
def test_qualified_expr_rflx_expr() -> None:
    assert ada.QualifiedExpr(
        "X", ada.Variable("Y")).rflx_expr() == expr.QualifiedExpr(
            "X", expr.Variable("Y"))
Пример #20
0
def substitution_facts(
    message: model.Message,
    prefix: str,
    embedded: bool = False,
    public: bool = False,
    target_type: Optional[ID] = const.TYPES_BASE_INT,
) -> Mapping[expr.Name, expr.Expr]:
    def prefixed(name: str) -> expr.Expr:
        return expr.Variable(ID("Ctx") * name) if not embedded else expr.Variable(name)

    first = prefixed("First")
    last = expr.Call("Written_Last", [expr.Variable("Ctx")]) if public else prefixed("Written_Last")
    cursors = prefixed("Cursors")

    def field_first(field: model.Field) -> expr.Expr:
        if public:
            return expr.Call(
                "Field_First", [expr.Variable("Ctx"), expr.Variable(field.affixed_name)]
            )
        return expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "First")

    def field_last(field: model.Field) -> expr.Expr:
        if public:
            return expr.Call(
                "Field_Last", [expr.Variable("Ctx"), expr.Variable(field.affixed_name)]
            )
        return expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "Last")

    def field_size(field: model.Field) -> expr.Expr:
        if public:
            return expr.Call(
                "Field_Size", [expr.Variable("Ctx"), expr.Variable(field.affixed_name)]
            )
        return expr.Add(
            expr.Sub(
                expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "Last"),
                expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "First"),
            ),
            expr.Number(1),
        )

    def parameter_value(parameter: model.Field, parameter_type: model.Type) -> expr.Expr:
        if isinstance(parameter_type, model.Enumeration):
            if embedded:
                return expr.Call("To_Base_Integer", [expr.Variable(parameter.name)])
            return expr.Call("To_Base_Integer", [expr.Variable("Ctx" * parameter.identifier)])
        if isinstance(parameter_type, model.Scalar):
            if embedded:
                return expr.Variable(parameter.name)
            return expr.Variable("Ctx" * parameter.identifier)

        assert False, f'unexpected type "{type(parameter_type).__name__}"'

    def field_value(field: model.Field, field_type: model.Type) -> expr.Expr:
        if isinstance(field_type, model.Enumeration):
            if public:
                return expr.Call(
                    "To_Base_Integer", [expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])]
                )
            return expr.Selected(
                expr.Indexed(cursors, expr.Variable(field.affixed_name)),
                "Value",
            )
        if isinstance(field_type, model.Scalar):
            if public:
                return expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])
            return expr.Selected(
                expr.Indexed(cursors, expr.Variable(field.affixed_name)),
                "Value",
            )
        if isinstance(field_type, model.Composite):
            return expr.Variable(field.name)

        assert False, f'unexpected type "{type(field_type).__name__}"'

    def type_conversion(expression: expr.Expr) -> expr.Expr:
        return expr.Call(target_type, [expression]) if target_type else expression

    return {
        **{expr.First("Message"): type_conversion(first)},
        **{expr.Last("Message"): type_conversion(last)},
        **{expr.Size("Message"): type_conversion(expr.Add(last, -first, expr.Number(1)))},
        **{expr.First(f.name): type_conversion(field_first(f)) for f in message.fields},
        **{expr.Last(f.name): type_conversion(field_last(f)) for f in message.fields},
        **{expr.Size(f.name): type_conversion(field_size(f)) for f in message.fields},
        **{
            expr.Variable(p.identifier): type_conversion(parameter_value(p, t))
            for p, t in message.parameter_types.items()
        },
        **{
            expr.Variable(f.name): type_conversion(field_value(f, t))
            for f, t in message.field_types.items()
        },
        **{
            expr.Literal(l): type_conversion(expr.Call("To_Base_Integer", [expr.Variable(l)]))
            for t in message.types.values()
            if isinstance(t, model.Enumeration) and t != model.BOOLEAN
            for l in t.literals.keys()
        },
        **{
            expr.Literal(t.package * l): type_conversion(
                expr.Call("To_Base_Integer", [expr.Variable(prefix * t.package * l)])
            )
            for t in message.types.values()
            if isinstance(t, model.Enumeration) and t != model.BOOLEAN
            for l in t.literals.keys()
        },
        # https://github.com/Componolit/RecordFlux/issues/276
        **{expr.ValidChecksum(f): expr.TRUE for f in message.checksums},
    }
Пример #21
0

def test_derivation_spec() -> None:
    generator = generate(DERIVATION_MODEL)
    assert_specification(generator)


def test_derivation_body() -> None:
    generator = generate(DERIVATION_MODEL)
    assert_body(generator)


@pytest.mark.parametrize(
    "left,right",
    [
        (expr.Variable("Value"), expr.Aggregate(expr.Number(1), expr.Number(2))),
        (expr.Aggregate(expr.Number(1), expr.Number(2)), expr.Variable("Value")),
    ],
)
@pytest.mark.parametrize("relation", [expr.Equal, expr.NotEqual])
def test_substitution_relation_aggregate(
    relation: Callable[[expr.Expr, expr.Expr], expr.Relation], left: expr.Expr, right: expr.Expr
) -> None:
    equal_call = expr.Call(
        "Equal",
        [
            expr.Variable("Ctx"),
            expr.Variable("F_Value"),
            expr.Aggregate(
                expr.Val(expr.Variable("Types.Byte"), expr.Number(1)),
                expr.Val(expr.Variable("Types.Byte"), expr.Number(2)),
Пример #22
0
    def func(expression: expr.Expr) -> expr.Expr:  # pylint: disable = too-many-branches
        def byte_aggregate(aggregate: expr.Aggregate) -> expr.Aggregate:
            return expr.Aggregate(*[expr.Val(const.TYPES_BYTE, e) for e in aggregate.elements])

        if isinstance(expression, expr.Name) and expression in facts:
            return facts[expression]

        if isinstance(expression, expr.String):
            return expr.Aggregate(*expression.elements)

        if isinstance(expression, (expr.Equal, expr.NotEqual)):
            field = None
            aggregate = None
            if isinstance(expression.left, expr.Variable) and isinstance(
                expression.right, expr.Aggregate
            ):
                field = model.Field(expression.left.name)
                aggregate = byte_aggregate(expression.right)
            elif isinstance(expression.left, expr.Aggregate) and isinstance(
                expression.right, expr.Variable
            ):
                field = model.Field(expression.right.name)
                aggregate = byte_aggregate(expression.left)
            if field and field in message.fields and len(field.identifier.parts) == 1 and aggregate:
                if embedded:
                    return expression.__class__(
                        expr.Indexed(
                            expr.Variable(ID("Buffer") * "all"),
                            expr.ValueRange(
                                expr.Call(
                                    const.TYPES_TO_INDEX,
                                    [
                                        expr.Selected(
                                            expr.Indexed(
                                                expr.Variable("Cursors"),
                                                expr.Variable(field.affixed_name),
                                            ),
                                            "First",
                                        )
                                    ],
                                ),
                                expr.Call(
                                    const.TYPES_TO_INDEX,
                                    [
                                        expr.Selected(
                                            expr.Indexed(
                                                expr.Variable("Cursors"),
                                                expr.Variable(field.affixed_name),
                                            ),
                                            "Last",
                                        )
                                    ],
                                ),
                            ),
                        ),
                        aggregate,
                    )
                equal_call = expr.Call(
                    "Equal",
                    [expr.Variable("Ctx"), expr.Variable(field.affixed_name), aggregate],
                )
                return equal_call if isinstance(expression, expr.Equal) else expr.Not(equal_call)

            boolean_literal = None
            other = None
            if (
                isinstance(expression.left, expr.Literal)
                and expression.left.identifier in model.BOOLEAN.literals
            ):
                boolean_literal = expression.left
                other = expression.right
            if (
                isinstance(expression.right, expr.Literal)
                and expression.right.identifier in model.BOOLEAN.literals
            ):
                boolean_literal = expression.right
                other = expression.left
            if boolean_literal and other:
                return expression.__class__(
                    other, type_conversion(expr.Call("To_Base_Integer", [boolean_literal]))
                )

        def field_value(field: model.Field) -> expr.Expr:
            if public:
                return expr.Call(f"Get_{field.name}", [expr.Variable("Ctx")])
            return expr.Selected(
                expr.Indexed(
                    expr.Variable(ID("Ctx") * "Cursors" if not embedded else "Cursors"),
                    expr.Variable(field.affixed_name),
                ),
                "Value",
            )

        if isinstance(expression, expr.Relation):
            if (
                isinstance(expression.left, expr.Variable)
                and model.Field(expression.left.name) in message.fields
                and isinstance(expression.right, expr.Number)
            ):
                return expression.__class__(
                    field_value(model.Field(expression.left.name)), expression.right
                )
            if (
                isinstance(expression.right, expr.Variable)
                and model.Field(expression.right.name) in message.fields
                and isinstance(expression.left, expr.Number)
            ):
                return expression.__class__(
                    expression.left, field_value(model.Field(expression.right.name))
                )

        return expression
Пример #23
0
 def prefixed(name: str) -> expr.Expr:
     return expr.Variable(ID("Ctx") * name) if not embedded else expr.Variable(name)
Пример #24
0
def test_quantified_expression_rflx_expr(
        expression: Callable[[str, ada.Expr, ada.Expr], ada.Expr]) -> None:
    result = expression("X", ada.Variable("Y"), ada.Variable("Z")).rflx_expr()
    expected = getattr(expr, expression.__name__)("X", expr.Variable("Y"),
                                                  expr.Variable("Z"))
    assert result == expected
Пример #25
0
        ("16#6664#", expr.Number(26212)),
        ("16#66_64#", expr.Number(26212)),
        ("-1000", expr.Number(-1000)),
        ("-1_000", expr.Number(-1000)),
        ("-16#6664#", expr.Number(-26212)),
        ("-16#66_64#", expr.Number(-26212)),
    ],
)
def test_expression_numeric_literal(string: str, expected: expr.Expr) -> None:
    actual = parse_math_expression(string, extended=False)
    assert actual == expected
    assert actual.location


@pytest.mark.parametrize(
    "string,expected", [("X", expr.Variable("X")), ("X::Y", expr.Variable("X::Y"))]
)
def test_variable(string: str, expected: decl.Declaration) -> None:
    actual = parse_expression(string, lang.GrammarRule.variable_rule)
    assert actual == expected
    assert actual.location


@pytest.mark.parametrize(
    "string,expected",
    [
        ("X'First", expr.First(expr.Variable("X"))),
        ("X'Last", expr.Last(expr.Variable("X"))),
        ("X'Size", expr.Size(expr.Variable("X"))),
        ("X'Head", expr.Head(expr.Variable("X"))),
        ("X'Opaque", expr.Opaque(expr.Variable("X"))),
Пример #26
0
 def field_last(field: model.Field) -> expr.Expr:
     if public:
         return expr.Call(
             "Field_Last", [expr.Variable("Ctx"), expr.Variable(field.affixed_name)]
         )
     return expr.Selected(expr.Indexed(cursors, expr.Variable(field.affixed_name)), "Last")
Пример #27
0
def variables(draw: Draw, elements: st.SearchStrategy[str]) -> expr.Variable:
    return expr.Variable(draw(elements))
Пример #28
0
 def prefixed(name: str) -> expr.Expr:
     return expr.Selected(expr.Variable("Ctx"), name) if not embedded else expr.Variable(name)
Пример #29
0
def test_consistency_specification_parsing_generation(tmp_path: Path) -> None:
    tag = Enumeration(
        "Test::Tag",
        [("Msg_Data", expr.Number(1)), ("Msg_Error", expr.Number(3))],
        expr.Number(8),
        always_valid=False,
    )
    length = ModularInteger("Test::Length",
                            expr.Pow(expr.Number(2), expr.Number(16)))
    message = Message(
        "Test::Message",
        [
            Link(INITIAL, Field("Tag")),
            Link(
                Field("Tag"),
                Field("Length"),
                expr.Equal(expr.Variable("Tag"), expr.Variable("Msg_Data")),
            ),
            Link(Field("Tag"), FINAL,
                 expr.Equal(expr.Variable("Tag"), expr.Variable("Msg_Error"))),
            Link(
                Field("Length"),
                Field("Value"),
                size=expr.Mul(expr.Variable("Length"), expr.Number(8)),
            ),
            Link(Field("Value"), FINAL),
        ],
        {
            Field("Tag"): tag,
            Field("Length"): length,
            Field("Value"): OPAQUE
        },
        skip_proof=True,
    )
    session = Session(
        "Test::Session",
        "A",
        "C",
        [
            State(
                "A",
                declarations=[],
                actions=[stmt.Read("X", expr.Variable("M"))],
                transitions=[
                    Transition("B"),
                ],
            ),
            State(
                "B",
                declarations=[
                    decl.VariableDeclaration("Z", BOOLEAN.identifier,
                                             expr.Variable("Y")),
                ],
                actions=[],
                transitions=[
                    Transition(
                        "C",
                        condition=expr.And(
                            expr.Equal(expr.Variable("Z"), expr.TRUE),
                            expr.Equal(expr.Call("G", [expr.Variable("F")]),
                                       expr.TRUE),
                        ),
                        description="rfc1149.txt+45:4-47:8",
                    ),
                    Transition("A"),
                ],
                description="rfc1149.txt+51:4-52:9",
            ),
            State("C"),
        ],
        [
            decl.VariableDeclaration("M", "Test::Message"),
            decl.VariableDeclaration("Y", BOOLEAN.identifier, expr.FALSE),
        ],
        [
            decl.ChannelDeclaration("X", readable=True, writable=True),
            decl.TypeDeclaration(Private("Test::T")),
            decl.FunctionDeclaration("F", [], "Test::T"),
            decl.FunctionDeclaration("G", [decl.Argument("P", "Test::T")],
                                     BOOLEAN.identifier),
        ],
        [BOOLEAN, OPAQUE, tag, length, message],
    )
    model = Model(types=[BOOLEAN, OPAQUE, tag, length, message],
                  sessions=[session])
    model.write_specification_files(tmp_path)
    p = parser.Parser()
    p.parse(tmp_path / "test.rflx")
    parsed_model = p.create_model()
    assert parsed_model.types == model.types
    assert parsed_model.sessions == model.sessions
    assert parsed_model == model
Пример #30
0
def test_value_range_rflx_expr() -> None:
    assert ada.ValueRange(ada.Variable("X"),
                          ada.Variable("Y")).rflx_expr() == expr.ValueRange(
                              expr.Variable("X"), expr.Variable("Y"))