Пример #1
0
def fixture_icmp_checksum_message_first(icmp_message: model.Message) -> pyrflx.MessageValue:
    return pyrflx.MessageValue(
        icmp_message.copy(
            structure=[
                model.Link(
                    l.source,
                    l.target,
                    condition=expr.And(l.condition, expr.ValidChecksum("Checksum")),
                )
                if l.target == model.FINAL
                else l
                for l in icmp_message.structure
            ],
            checksums={
                ID("Checksum"): [
                    expr.ValueRange(
                        expr.First("Message"), expr.Sub(expr.First("Checksum"), expr.Number(1))
                    ),
                    expr.Size("Checksum"),
                    expr.ValueRange(
                        expr.Add(expr.Last("Checksum"), expr.Number(1)), expr.Last("Message")
                    ),
                ]
            },
        )
    )
Пример #2
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),
     )
Пример #3
0
                expr.Number(1),
            ),
        ),
        (
            "A - (B * 2**3 - 1)",
            expr.Sub(
                expr.Variable("A"),
                expr.Sub(
                    expr.Mul(expr.Variable("B"), expr.Pow(expr.Number(2), expr.Number(3))),
                    expr.Number(1),
                ),
            ),
        ),
        (
            "A + B * (-8)",
            expr.Add(expr.Variable("A"), expr.Mul(expr.Variable("B"), expr.Number(-8))),
        ),
        (
            "A + B mod 8 * 2",
            expr.Add(
                expr.Variable("A"),
                expr.Mul(expr.Mod(expr.Variable("B"), expr.Number(8)), expr.Number(2)),
            ),
        ),
    ],
)
def test_expression_mathematical(string: str, expected: expr.Expr) -> None:
    actual = parse_math_expression(string, extended=False)
    assert actual == expected
    assert actual.location
Пример #4
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],
                ),
            )
        ]
    )
Пример #5
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},
    }