Exemplo n.º 1
0
    def __init__(self, name: str, first: MathExpr, last: MathExpr,
                 size: MathExpr) -> None:
        first_num = first.simplified()
        if not isinstance(first_num, Number):
            raise ModelError(f'first of "{name}" contains variable')
        last_num = last.simplified()
        if not isinstance(last_num, Number):
            raise ModelError(f'last of "{name}" contains variable')
        if first_num < Number(0):
            raise ModelError(f'first of "{name}" negative')
        if first_num > last_num:
            raise ModelError(f'range of "{name}" negative')
        size_num = size.simplified()
        if not isinstance(size_num, Number):
            raise ModelError(f'size of "{name}" contains variable')
        if log(int(last_num) + 1) / log(2) > int(size_num):
            raise ModelError(f'size for "{name}" too small')
        super().__init__(name)
        self.__first = first
        self.__last = last
        self.__size = size

        constraints: LogExpr = TRUE
        if self.first.simplified() != self.base_first.simplified():
            constraints = GreaterEqual(Value(self.name), self.first)
        if self.last.simplified() != self.base_last.simplified():
            constraints = And(constraints,
                              LessEqual(Value(self.name), self.last))
        self.__constraints = constraints.simplified()
Exemplo n.º 2
0
def test_prefixed_message() -> None:
    assert_equal(
        UnprovenMessage(
            "P.M",
            [
                Link(INITIAL, Field("F1")),
                Link(
                    Field("F1"),
                    Field("F2"),
                    LessEqual(Variable("F1"), Number(100)),
                    first=First("F1"),
                ),
                Link(
                    Field("F1"),
                    Field("F3"),
                    GreaterEqual(Variable("F1"), Number(200)),
                    first=First("F1"),
                ),
                Link(Field("F2"), FINAL),
                Link(Field("F3"), Field("F4"), length=Variable("F3")),
                Link(Field("F4"), FINAL),
            ],
            {
                Field("F1"): deepcopy(MODULAR_INTEGER),
                Field("F2"): deepcopy(MODULAR_INTEGER),
                Field("F3"): deepcopy(RANGE_INTEGER),
                Field("F4"): Opaque(),
            },
        ).prefixed("X_"),
        UnprovenMessage(
            "P.M",
            [
                Link(INITIAL, Field("X_F1")),
                Link(
                    Field("X_F1"),
                    Field("X_F2"),
                    LessEqual(Variable("X_F1"), Number(100)),
                    first=First("X_F1"),
                ),
                Link(
                    Field("X_F1"),
                    Field("X_F3"),
                    GreaterEqual(Variable("X_F1"), Number(200)),
                    first=First("X_F1"),
                ),
                Link(Field("X_F2"), FINAL),
                Link(Field("X_F3"), Field("X_F4"), length=Variable("X_F3")),
                Link(Field("X_F4"), FINAL),
            ],
            {
                Field("X_F1"): deepcopy(MODULAR_INTEGER),
                Field("X_F2"): deepcopy(MODULAR_INTEGER),
                Field("X_F3"): deepcopy(RANGE_INTEGER),
                Field("X_F4"): Opaque(),
            },
        ),
    )
Exemplo n.º 3
0
def test_merge_message_recursive() -> None:
    assert_equal(
        deepcopy(M_DBL_REF).merged(),
        UnprovenMessage(
            "P.Dbl_Ref",
            [
                Link(INITIAL, Field("SR_NR_F1"), length=Number(16)),
                Link(
                    Field("SR_NR_F3"),
                    Field("NR_F1"),
                    Equal(Variable("SR_NR_F3"), Variable("P.ONE")),
                    length=Number(16),
                ),
                Link(Field("SR_NR_F4"), Field("NR_F1"), length=Number(16)),
                Link(Field("NR_F3"), FINAL,
                     Equal(Variable("NR_F3"), Variable("P.ONE"))),
                Link(Field("NR_F4"), FINAL),
                Link(Field("SR_NR_F1"), Field("SR_NR_F2")),
                Link(
                    Field("SR_NR_F2"),
                    Field("SR_NR_F3"),
                    LessEqual(Variable("SR_NR_F2"), Number(100)),
                    first=First("SR_NR_F2"),
                ),
                Link(
                    Field("SR_NR_F2"),
                    Field("SR_NR_F4"),
                    GreaterEqual(Variable("SR_NR_F2"), Number(200)),
                    first=First("SR_NR_F2"),
                ),
                Link(Field("NR_F1"), Field("NR_F2")),
                Link(
                    Field("NR_F2"),
                    Field("NR_F3"),
                    LessEqual(Variable("NR_F2"), Number(100)),
                    first=First("NR_F2"),
                ),
                Link(
                    Field("NR_F2"),
                    Field("NR_F4"),
                    GreaterEqual(Variable("NR_F2"), Number(200)),
                    first=First("NR_F2"),
                ),
            ],
            {
                Field("SR_NR_F1"): Opaque(),
                Field("SR_NR_F2"): deepcopy(MODULAR_INTEGER),
                Field("SR_NR_F3"): deepcopy(ENUMERATION),
                Field("SR_NR_F4"): deepcopy(RANGE_INTEGER),
                Field("NR_F1"): Opaque(),
                Field("NR_F2"): deepcopy(MODULAR_INTEGER),
                Field("NR_F3"): deepcopy(ENUMERATION),
                Field("NR_F4"): deepcopy(RANGE_INTEGER),
            },
        ),
    )
Exemplo n.º 4
0
    def constraints(self, name: str, proof: bool = False) -> Expr:
        if proof:
            return And(
                GreaterEqual(Variable(name), self.first), LessEqual(Variable(name), self.last)
            )

        c: Expr = TRUE
        if self.first.simplified() != self.base_first.simplified():
            c = GreaterEqual(Variable(name), self.first)
        if self.last.simplified() != self.base_last.simplified():
            c = And(c, LessEqual(Variable(name), self.last))
        return c.simplified()
Exemplo n.º 5
0
 def __link_expression(self, link: Link) -> Expr:
     name = link.target.name
     return And(
         *[
             Equal(First(name), self.__target_first(link)),
             Equal(Length(name), self.__target_length(link)),
             Equal(Last(name), self.__target_last(link)),
             GreaterEqual(First("Message"), Number(0)),
             GreaterEqual(Last("Message"), Last(name)),
             GreaterEqual(Last("Message"), First("Message")),
             Equal(Length("Message"), Add(Sub(Last("Message"), First("Message")), Number(1))),
             link.condition,
         ]
     )
Exemplo n.º 6
0
 def test_message_field_condition(self) -> None:
     self.assertEqual(ETHERNET_FRAME.field_condition(INITIAL), TRUE)
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("TPID")),
         Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
     )
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("Type_Length")),
         Or(
             NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
             Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
         ),
     )
     self.assertEqual(
         ETHERNET_FRAME.field_condition(Field("Payload")),
         Or(
             And(
                 Or(
                     NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
                     Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
                 ),
                 LessEqual(Variable("Type_Length"), Number(1500)),
             ),
             And(
                 Or(
                     NotEqual(Variable("Type_Length_TPID"), Number(33024, 16)),
                     Equal(Variable("Type_Length_TPID"), Number(33024, 16)),
                 ),
                 GreaterEqual(Variable("Type_Length"), Number(1536)),
             ),
         ),
     )
Exemplo n.º 7
0
 def test_message_incoming(self) -> None:
     self.assertEqual(ETHERNET_FRAME.incoming(INITIAL), [])
     self.assertEqual(
         ETHERNET_FRAME.incoming(Field("Type_Length")),
         [
             Link(
                 Field("Type_Length_TPID"),
                 Field("Type_Length"),
                 NotEqual(Variable("Type_Length_TPID"), Number(0x8100, 16)),
                 first=First("Type_Length_TPID"),
             ),
             Link(Field("TCI"), Field("Type_Length")),
         ],
     )
     self.assertEqual(
         ETHERNET_FRAME.incoming(FINAL),
         [
             Link(
                 Field("Payload"),
                 FINAL,
                 And(
                     GreaterEqual(Div(Length("Payload"), Number(8)), Number(46)),
                     LessEqual(Div(Length("Payload"), Number(8)), Number(1500)),
                 ),
             )
         ],
     )
Exemplo n.º 8
0
def public_context_predicate() -> Expr:
    return And(
        GreaterEqual(Call(const.TYPES_BYTE_INDEX, [Variable("First")]), Variable("Buffer_First")),
        LessEqual(Call(const.TYPES_BYTE_INDEX, [Variable("Last")]), Variable("Buffer_Last")),
        LessEqual(Variable("First"), Variable("Last")),
        LessEqual(Variable("Last"), Div(Last(const.TYPES_BIT_INDEX), Number(2))),
    )
Exemplo n.º 9
0
def test_merge_message_simple_derived() -> None:
    assert_equal(
        deepcopy(M_SMPL_REF_DERI).merged(),
        UnprovenDerivedMessage(
            "P.Smpl_Ref_Deri",
            M_SMPL_REF,
            [
                Link(INITIAL, Field("NR_F1"), length=Number(16)),
                Link(Field("NR_F3"), FINAL,
                     Equal(Variable("NR_F3"), Variable("P.ONE"))),
                Link(Field("NR_F4"), FINAL),
                Link(Field("NR_F1"), Field("NR_F2")),
                Link(
                    Field("NR_F2"),
                    Field("NR_F3"),
                    LessEqual(Variable("NR_F2"), Number(100)),
                    first=First("NR_F2"),
                ),
                Link(
                    Field("NR_F2"),
                    Field("NR_F4"),
                    GreaterEqual(Variable("NR_F2"), Number(200)),
                    first=First("NR_F2"),
                ),
            ],
            {
                Field("NR_F1"): Opaque(),
                Field("NR_F2"): deepcopy(MODULAR_INTEGER),
                Field("NR_F3"): deepcopy(ENUMERATION),
                Field("NR_F4"): deepcopy(RANGE_INTEGER),
            },
        ),
    )
Exemplo n.º 10
0
    def __prove_coverage(self) -> None:
        """
        Prove that the fields of a message cover all message bits, i.e. there are no holes in the
        message definition.

        Idea: Let f be the bits covered by the message. By definition
            (1) f >= Message'First and f <= Message'Last
        holds. For every field add a conjunction of the form
            (2) Not(f >= Field'First and f <= Field'Last),
        effectively pruning the range that this field covers from the bit range of the message. For
        the overall expression, prove that it is false for all f, i.e. no bits are left.
        """
        for path in [p[:-1] for p in self.__paths[FINAL] if p]:
            # Calculate (1)
            message_range = And(
                GreaterEqual(Variable("f"), First("Message")),
                LessEqual(Variable("f"), Last("Message")),
            )
            # Calculate (2) for all fields
            fields = And(
                *[
                    Not(
                        And(
                            GreaterEqual(Variable("f"), self.__target_first(l)),
                            LessEqual(Variable("f"), self.__target_last(l)),
                        )
                    )
                    for l in path
                ]
            )
            # Define that the end of the last field of a path is the end of the message
            last_field = Equal(self.__target_last(path[-1]), Last("Message"))
            # Constraints for links and types
            path_expressions = self.__with_constraints(
                And(*[self.__link_expression(l) for l in path])
            )

            # Coverage expression must be False, i.e. no bits left
            coverage = Not(And(*[fields, last_field, path_expressions, message_range]))
            result = coverage.forall()
            if result != ProofResult.sat:
                path_message = " -> ".join([l.target.name for l in path])
                message = str(coverage).replace("\n\t", "")
                raise ModelError(
                    f"path {path_message} does not cover whole message"
                    f' in "{self.full_name}" ({result}: {message})'
                )
Exemplo n.º 11
0
    def __prove_field_positions(self) -> None:
        for f in self.__fields:
            for p, l in [(p, p[-1]) for p in self.__paths[f] if p]:
                path_expressions = And(*[self.__link_expression(l) for l in p])
                length = self.__target_length(l)
                positive = If(
                    [
                        (
                            And(
                                self.__type_constraints(And(path_expressions, length)),
                                path_expressions,
                            ),
                            GreaterEqual(length, Number(0)),
                        )
                    ],
                    TRUE,
                )
                result = positive.forall()
                if result != ProofResult.sat:
                    path_message = " -> ".join([l.target.name for l in p])
                    message = str(positive.simplified()).replace("\n\t", "")
                    raise ModelError(
                        f'negative length for field "{f.name}" on path {path_message}'
                        f' in "{self.full_name}" ({result}: {message})'
                    )

                first = self.__target_first(l)
                start = If(
                    [
                        (
                            And(
                                self.__type_constraints(And(path_expressions, first)),
                                path_expressions,
                            ),
                            GreaterEqual(first, First("Message")),
                        )
                    ],
                    TRUE,
                )
                result = start.forall()
                if result != ProofResult.sat:
                    path_message = " -> ".join([l.target.name for l in p])
                    message = str(start.simplified()).replace("\n\t", "")
                    raise ModelError(
                        f'start of field "{f.name}" on path {path_message} before'
                        f' message start in "{self.full_name} ({result}: {message})'
                    )
Exemplo n.º 12
0
 def bounded_composite_setter_preconditions(message: Message,
                                            field: Field) -> Sequence[Expr]:
     return [
         Call(
             "Field_Condition",
             [
                 Variable("Ctx"),
                 NamedAggregate(("Fld", Variable(field.affixed_name)))
             ] + ([Variable("Length")]
                  if common.length_dependent_condition(message) else []),
         ),
         GreaterEqual(
             Call("Available_Space",
                  [Variable("Ctx"),
                   Variable(field.affixed_name)]),
             Variable("Length"),
         ),
         LessEqual(
             Add(
                 Call("Field_First",
                      [Variable("Ctx"),
                       Variable(field.affixed_name)]),
                 Variable("Length"),
             ),
             Div(Last(const.TYPES_BIT_INDEX), Number(2)),
         ),
         Or(*[
             And(
                 *[
                     Call("Valid",
                          [Variable("Ctx"),
                           Variable(field.affixed_name)])
                     for field in message.fields
                     if Variable(field.name) in l.condition.variables()
                 ],
                 l.condition.substituted(
                     mapping={
                         Variable(field.name): Call(f"Get_{field.name}",
                                                    [Variable("Ctx")])
                         for field in message.fields
                         if Variable(field.name) in l.condition.variables()
                     }),
             ) for l in message.incoming(field)
             if Last("Message") in l.length
         ]),
         Equal(
             Mod(
                 Call("Field_First",
                      [Variable("Ctx"),
                       Variable(field.affixed_name)]),
                 Size(const.TYPES_BYTE),
             ),
             Number(1),
         ),
         Equal(
             Mod(Variable("Length"), Size(const.TYPES_BYTE)),
             Number(0),
         ),
     ]
Exemplo n.º 13
0
def buffer_constraints(last: MathExpr) -> LogExpr:
    last = last.simplified()
    index_constraint = LessEqual(First('Buffer'),
                                 Div(Last('Types.Index_Type'), Number(2)))
    if last != Last('Buffer'):
        length_constraint = GreaterEqual(
            Length('Buffer'), Add(last, -First('Buffer'), Number(1)))
        return And(length_constraint, index_constraint)
    return index_constraint
Exemplo n.º 14
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')
Exemplo n.º 15
0
def create_ethernet_pdu() -> PDU:
    uint48 = ModularInteger('UINT48', Pow(Number(2), Number(48)))
    uint16 = RangeInteger('UINT16',
                          Number(0),
                          Sub(Pow(Number(2), Number(16)), Number(1)),
                          Number(16))
    payload_array = Array('Payload_Array')

    initial = InitialNode()
    destination = Node('Destination', uint48)
    source = Node('Source', uint48)
    tpid = Node('TPID', uint16)
    tci = Node('TCI', uint16)
    ether_type = Node('EtherType', uint16)
    payload = Node('Payload', payload_array)

    initial.edges = [Edge(destination)]
    destination.edges = [Edge(source)]
    source.edges = [Edge(tpid)]
    tpid.edges = [Edge(tci,
                       Equal(Value('TPID'), Number(0x8100))),
                  Edge(ether_type,
                       NotEqual(Value('TPID'), Number(0x8100)),
                       first=First('TPID'))]
    tci.edges = [Edge(ether_type)]
    ether_type.edges = [Edge(payload,
                             LessEqual(Value('EtherType'), Number(1500)),
                             Mul(LengthValue('EtherType'), Number(8))),
                        Edge(payload,
                             GreaterEqual(Value('EtherType'), Number(1536)),
                             Sub(Last('Message'), Last('EtherType')))]
    payload.edges = [Edge(FINAL,
                          And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                              LessEqual(Div(Length('Payload'), Number(8)), Number(1500))))]

    return PDU('Ethernet.Frame', initial)
Exemplo n.º 16
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")
Exemplo n.º 17
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")
Exemplo n.º 18
0
 def bounded_composite_setter_preconditions(
     self, message: Message, field: Field
 ) -> Sequence[Expr]:
     return [
         Call(
             "Field_Condition",
             [Name("Ctx"), NamedAggregate(("Fld", Name(field.affixed_name)))]
             + ([Name("Length")] if length_dependent_condition(message) else []),
         ),
         GreaterEqual(
             Call("Available_Space", [Name("Ctx"), Name(field.affixed_name)]), Name("Length"),
         ),
         LessEqual(
             Add(Call("Field_First", [Name("Ctx"), Name(field.affixed_name)]), Name("Length"),),
             Div(Last(self.types.bit_index), Number(2)),
         ),
         Or(
             *[
                 And(
                     *[
                         Call("Valid", [Name("Ctx"), Name(field.affixed_name)])
                         for field in message.fields
                         if Variable(field.name) in l.condition.variables()
                     ],
                     l.condition.simplified(
                         {
                             Variable(field.name): Call(f"Get_{field.name}", [Name("Ctx")])
                             for field in message.fields
                             if Variable(field.name) in l.condition.variables()
                         }
                     ),
                 )
                 for l in message.incoming(field)
                 if Last("Message") in l.length
             ]
         ),
     ]
Exemplo n.º 19
0
    def test_pdu_fields_ethernet(self) -> None:
        expected = OrderedDict([
            ('Destination',
             Field('Destination',
                   ModularInteger('UINT48', Pow(Number(2), Number(48))),
                   TRUE,
                   {
                       '0':
                       Variant(
                           [],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47)
                           })
                   })),
            ('Source',
             Field('Source',
                   ModularInteger('UINT48', Pow(Number(2), Number(48))),
                   TRUE,
                   {
                       '00':
                       Variant(
                           [
                               ('Destination', '0')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95)
                           })
                   })),
            ('TPID',
             Field('TPID',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   Or(NotEqual(Value('TPID'), Number(0x8100)),
                      Equal(Value('TPID'), Number(0x8100))),
                   {
                       '000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111)
                           })
                   })),
            ('TCI',
             Field('TCI',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   TRUE,
                   {
                       '0000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000')
                           ],
                           Equal(Value('TPID'), Number(0x8100)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127)
                           })
                   })),
            ('EtherType',
             Field('EtherType',
                   RangeInteger('UINT16',
                                Number(0),
                                Sub(Pow(Number(2), Number(16)), Number(1)),
                                Number(16)),
                   Or(GreaterEqual(Value('EtherType'), Number(1536)),
                      LessEqual(Value('EtherType'), Number(1500))),
                   {
                       '00000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000')
                           ],
                           TRUE,
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143)
                           }),
                       '0001':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000')
                           ],
                           NotEqual(Value('TPID'), Number(0x8100)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111)
                           })
                   })),
            ('Payload',
             Field('Payload',
                   Array('Payload_Array'),
                   And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                       LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                   {
                       '000000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000')
                           ],
                           LessEqual(Value('EtherType'), Number(1500)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(144),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(143))
                           }),
                       '000001':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000')
                           ],
                           GreaterEqual(Value('EtherType'), Number(1536)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Add(Last('Message'), Number(-143)),
                               First('Payload'): Number(144),
                               Last('Payload'): Last('Message')
                           }),
                       '00010':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001')
                           ],
                           LessEqual(Value('EtherType'), Number(1500)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(112),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(111))
                           }),
                       '00011':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001')
                           ],
                           GreaterEqual(Value('EtherType'), Number(1536)),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Add(Last('Message'), Number(-111)),
                               First('Payload'): Number(112),
                               Last('Payload'): Last('Message')
                           })
                   })),
            ('FINAL',
             Field('FINAL',
                   Null(),
                   TRUE,
                   {
                       '0000000':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000'),
                               ('Payload', '000000')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(144),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(143))
                           }),
                       '0000010':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('TCI', '0000'),
                               ('EtherType', '00000'),
                               ('Payload', '000001')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('TCI'): Number(16),
                               First('TCI'): Number(112),
                               Last('TCI'): Number(127),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(128),
                               Last('EtherType'): Number(143),
                               Length('Payload'): Add(Last('Message'), Number(-143)),
                               First('Payload'): Number(144),
                               Last('Payload'): Last('Message')
                           }),
                       '000100':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001'),
                               ('Payload', '00010')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Mul(LengthValue('EtherType'), Number(8)),
                               First('Payload'): Number(112),
                               Last('Payload'): Add(Mul(LengthValue('EtherType'), Number(8)),
                                                    Number(111))
                           }),
                       '000110':
                       Variant(
                           [
                               ('Destination', '0'),
                               ('Source', '00'),
                               ('TPID', '000'),
                               ('EtherType', '0001'),
                               ('Payload', '00011')
                           ],
                           And(GreaterEqual(Div(Length('Payload'), Number(8)), Number(46)),
                               LessEqual(Div(Length('Payload'), Number(8)), Number(1500))),
                           {
                               Length('Destination'): Number(48),
                               First('Destination'): Number(0),
                               Last('Destination'): Number(47),
                               Length('Source'): Number(48),
                               First('Source'): Number(48),
                               Last('Source'): Number(95),
                               Length('TPID'): Number(16),
                               First('TPID'): Number(96),
                               Last('TPID'): Number(111),
                               Length('EtherType'): Number(16),
                               First('EtherType'): Number(96),
                               Last('EtherType'): Number(111),
                               Length('Payload'): Add(Last('Message'), Number(-111)),
                               First('Payload'): Number(112),
                               Last('Payload'): Last('Message')
                           })
                   }))
        ])

        self.assertEqual(ETHERNET_PDU.fields(), expected)
Exemplo n.º 20
0
def sufficient_space_for_field_condition(field_name: Name) -> Expr:
    return GreaterEqual(
        Call("Available_Space", [Variable("Ctx"), field_name]),
        Call("Field_Length", [Variable("Ctx"), field_name]),
    )
Exemplo n.º 21
0
 def test_less_neg(self) -> None:
     self.assertEqual(-Less(Variable("X"), Number(1)), GreaterEqual(Variable("X"), Number(1)))
Exemplo n.º 22
0
def context_predicate(message: Message, composite_fields: Sequence[Field], prefix: str) -> Expr:
    def valid_predecessors_invariant() -> Expr:
        return AndThen(
            *[
                If(
                    [
                        (
                            Call(
                                "Structural_Valid",
                                [Indexed(Variable("Cursors"), Variable(f.affixed_name))],
                            ),
                            Or(
                                *[
                                    AndThen(
                                        Call(
                                            "Structural_Valid"
                                            if l.source in composite_fields
                                            else "Valid",
                                            [
                                                Indexed(
                                                    Variable("Cursors"),
                                                    Variable(l.source.affixed_name),
                                                )
                                            ],
                                        ),
                                        Equal(
                                            Selected(
                                                Indexed(
                                                    Variable("Cursors"), Variable(f.affixed_name),
                                                ),
                                                "Predecessor",
                                            ),
                                            Variable(l.source.affixed_name),
                                        ),
                                        l.condition.substituted(
                                            substitution(message, embedded=True)
                                        ),
                                    ).simplified()
                                    for l in message.incoming(f)
                                ]
                            ),
                        )
                    ]
                )
                for f in message.fields
                if f not in message.direct_successors(INITIAL)
            ]
        )

    def invalid_successors_invariant() -> Expr:
        return AndThen(
            *[
                If(
                    [
                        (
                            AndThen(
                                *[
                                    Call(
                                        "Invalid",
                                        [Indexed(Variable("Cursors"), Variable(p.affixed_name))],
                                    )
                                    for p in message.direct_predecessors(f)
                                ]
                            ),
                            Call(
                                "Invalid", [Indexed(Variable("Cursors"), Variable(f.affixed_name))],
                            ),
                        )
                    ]
                )
                for f in message.fields
                if f not in message.direct_successors(INITIAL)
            ]
        )

    return AndThen(
        If(
            [
                (
                    NotEqual(Variable("Buffer"), Variable("null")),
                    And(
                        Equal(First("Buffer"), Variable("Buffer_First")),
                        Equal(Last("Buffer"), Variable("Buffer_Last")),
                    ),
                )
            ]
        ),
        public_context_predicate(),
        ForAllIn(
            "F",
            ValueRange(First("Field"), Last("Field")),
            If(
                [
                    (
                        Call("Structural_Valid", [Indexed(Variable("Cursors"), Variable("F"))]),
                        And(
                            GreaterEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "First"),
                                Variable("First"),
                            ),
                            LessEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "Last"),
                                Variable("Last"),
                            ),
                            LessEqual(
                                Selected(Indexed(Variable("Cursors"), Variable("F")), "First"),
                                Add(
                                    Selected(Indexed(Variable("Cursors"), Variable("F")), "Last"),
                                    Number(1),
                                ),
                            ),
                            Equal(
                                Selected(
                                    Selected(Indexed(Variable("Cursors"), Variable("F")), "Value"),
                                    "Fld",
                                ),
                                Variable("F"),
                            ),
                        ),
                    )
                ]
            ),
        ),
        valid_predecessors_invariant(),
        invalid_successors_invariant(),
        message_structure_invariant(message, prefix, embedded=True),
    )
Exemplo n.º 23
0
    def context_predicate(self, message: Message, composite_fields: Sequence[Field]) -> Expr:
        def valid_predecessors_invariant() -> Expr:
            return AndThen(
                *[
                    If(
                        [
                            (
                                Call(
                                    "Structural_Valid", [Indexed("Cursors", Name(f.affixed_name))]
                                ),
                                Or(
                                    *[
                                        AndThen(
                                            Call(
                                                "Structural_Valid"
                                                if l.source in composite_fields
                                                else "Valid",
                                                [Indexed("Cursors", Name(l.source.affixed_name))],
                                            ),
                                            Equal(
                                                Selected(
                                                    Indexed("Cursors", Name(f.affixed_name)),
                                                    "Predecessor",
                                                ),
                                                Name(l.source.affixed_name),
                                            ),
                                            l.condition,
                                        ).simplified(self.substitution(message, False))
                                        for l in message.incoming(f)
                                    ]
                                ),
                            )
                        ]
                    )
                    for f in message.fields
                    if f not in message.direct_successors(INITIAL)
                ]
            )

        def invalid_successors_invariant() -> Expr:
            return AndThen(
                *[
                    If(
                        [
                            (
                                AndThen(
                                    *[
                                        Call("Invalid", [Indexed("Cursors", Name(p.affixed_name))])
                                        for p in message.direct_predecessors(f)
                                    ]
                                ),
                                Call("Invalid", [Indexed("Cursors", Name(f.affixed_name))]),
                            )
                        ]
                    )
                    for f in message.fields
                    if f not in message.direct_successors(INITIAL)
                ]
            )

        return AndThen(
            If(
                [
                    (
                        NotEqual(Name(Name("Buffer")), NULL),
                        And(
                            Equal(First(Name("Buffer")), Name(Name("Buffer_First"))),
                            Equal(Last(Name("Buffer")), Name(Name("Buffer_Last"))),
                        ),
                    )
                ]
            ),
            GreaterEqual(
                Call(self.types.byte_index, [Name(Name("First"))]), Name(Name("Buffer_First"))
            ),
            LessEqual(Call(self.types.byte_index, [Name(Name("Last"))]), Name(Name("Buffer_Last"))),
            LessEqual(Name(Name("First")), Name(Name("Last"))),
            LessEqual(Name(Name("Last")), Div(Last(self.types.bit_index), Number(2))),
            ForAllIn(
                "F",
                ValueRange(First("Field"), Last("Field")),
                If(
                    [
                        (
                            Call("Structural_Valid", [Indexed(Name("Cursors"), Name("F"))]),
                            And(
                                GreaterEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "First"),
                                    Name(Name("First")),
                                ),
                                LessEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "Last"),
                                    Name(Name("Last")),
                                ),
                                LessEqual(
                                    Selected(Indexed(Name("Cursors"), Name("F")), "First"),
                                    Add(
                                        Selected(Indexed(Name("Cursors"), Name("F")), "Last"),
                                        Number(1),
                                    ),
                                ),
                                Equal(
                                    Selected(
                                        Selected(Indexed(Name("Cursors"), Name("F")), "Value"),
                                        "Fld",
                                    ),
                                    Name("F"),
                                ),
                            ),
                        )
                    ]
                ),
            ),
            valid_predecessors_invariant(),
            invalid_successors_invariant(),
            self.message_structure_invariant(message, prefix=False),
        )
Exemplo n.º 24
0
         Field("Type_Length"),
         NotEqual(Variable("Type_Length_TPID"), Number(0x8100, 16)),
         first=First("Type_Length_TPID"),
     ),
     Link(Field("TPID"), Field("TCI")),
     Link(Field("TCI"), Field("Type_Length")),
     Link(
         Field("Type_Length"),
         Field("Payload"),
         LessEqual(Variable("Type_Length"), Number(1500)),
         Mul(Variable("Type_Length"), Number(8)),
     ),
     Link(
         Field("Type_Length"),
         Field("Payload"),
         GreaterEqual(Variable("Type_Length"), Number(1536)),
     ),
     Link(
         Field("Payload"),
         FINAL,
         And(
             GreaterEqual(Div(Size("Payload"), Number(8)), Number(46)),
             LessEqual(Div(Size("Payload"), Number(8)), Number(1500)),
         ),
     ),
 ],
 {
     Field("Destination"): ETHERNET_ADDRESS,
     Field("Source"): ETHERNET_ADDRESS,
     Field("Type_Length_TPID"): ETHERNET_TYPE_LENGTH,
     Field("TPID"): ETHERNET_TPID,
Exemplo n.º 25
0
 def test_greater_equal_neg(self) -> None:
     self.assertEqual(-GreaterEqual(Variable("X"), Number(1)), Less(Variable("X"), Number(1)))
Exemplo n.º 26
0
def create_ethernet_frame() -> Message:
    address_type = ModularInteger("Ethernet.Address",
                                  Pow(Number(2), Number(48)))
    type_length_type = RangeInteger("Ethernet.Type_Length", Number(46),
                                    Sub(Pow(Number(2), Number(16)), Number(1)),
                                    Number(16))
    tpid_type = RangeInteger("Ethernet.TPID", Number(0x8100, 16),
                             Number(0x8100, 16), Number(16))
    tci_type = ModularInteger("Ethernet.TCI", Pow(Number(2), Number(16)))

    structure = [
        Link(INITIAL, Field("Destination")),
        Link(Field("Destination"), Field("Source")),
        Link(Field("Source"), Field("Type_Length_TPID")),
        Link(
            Field("Type_Length_TPID"),
            Field("TPID"),
            Equal(Variable("Type_Length_TPID"), Number(0x8100, 16)),
            first=First("Type_Length_TPID"),
        ),
        Link(
            Field("Type_Length_TPID"),
            Field("Type_Length"),
            NotEqual(Variable("Type_Length_TPID"), Number(0x8100, 16)),
            first=First("Type_Length_TPID"),
        ),
        Link(Field("TPID"), Field("TCI")),
        Link(Field("TCI"), Field("Type_Length")),
        Link(
            Field("Type_Length"),
            Field("Payload"),
            LessEqual(Variable("Type_Length"), Number(1500)),
            Mul(Variable("Type_Length"), Number(8)),
        ),
        Link(
            Field("Type_Length"),
            Field("Payload"),
            GreaterEqual(Variable("Type_Length"), Number(1536)),
            Sub(Last("Message"), Last("Type_Length")),
        ),
        Link(
            Field("Payload"),
            FINAL,
            And(
                GreaterEqual(Div(Length("Payload"), Number(8)), Number(46)),
                LessEqual(Div(Length("Payload"), Number(8)), Number(1500)),
            ),
        ),
    ]

    types = {
        Field("Destination"): address_type,
        Field("Source"): address_type,
        Field("Type_Length_TPID"): type_length_type,
        Field("TPID"): tpid_type,
        Field("TCI"): tci_type,
        Field("Type_Length"): type_length_type,
        Field("Payload"): Payload(),
    }

    return Message("Ethernet.Frame", structure, types)
Exemplo n.º 27
0
 def create_internal_functions(
     self, message: Message, scalar_fields: Mapping[Field, Scalar]
 ) -> UnitPart:
     return UnitPart(
         [],
         [
             SubprogramBody(
                 ProcedureSpecification(
                     "Set_Field_Value",
                     [
                         InOutParameter(["Ctx"], "Context"),
                         Parameter(["Val"], "Field_Dependent_Value"),
                         OutParameter(["Fst", "Lst"], self.types.bit_index),
                     ],
                 ),
                 [
                     *self.common.field_bit_location_declarations(Selected("Val", "Fld")),
                     *self.common.field_byte_location_declarations(),
                 ],
                 [
                     Assignment("Fst", Name("First")),
                     Assignment("Lst", Name("Last")),
                     CaseStatement(
                         Selected("Val", "Fld"),
                         [
                             (
                                 Name(f.affixed_name),
                                 [
                                     CallStatement(
                                         "Insert",
                                         [
                                             Selected("Val", f"{f.name}_Value"),
                                             Slice(
                                                 Selected(Selected("Ctx", "Buffer"), "all"),
                                                 Name("Buffer_First"),
                                                 Name("Buffer_Last"),
                                             ),
                                             Name("Offset"),
                                         ],
                                     )
                                     if f in scalar_fields
                                     else NullStatement()
                                 ],
                             )
                             for f in message.all_fields
                         ],
                     ),
                 ],
                 [
                     Precondition(
                         AndThen(
                             Not(Constrained("Ctx")),
                             Call("Has_Buffer", [Name("Ctx")]),
                             In(Selected("Val", "Fld"), Range("Field")),
                             Call("Valid_Next", [Name("Ctx"), Selected("Val", "Fld")]),
                             self.common.sufficient_space_for_field_condition(
                                 Selected("Val", "Fld")
                             ),
                             ForAllIn(
                                 "F",
                                 Range("Field"),
                                 If(
                                     [
                                         (
                                             Call(
                                                 "Structural_Valid",
                                                 [
                                                     Indexed(
                                                         Selected("Ctx", "Cursors"), Name("F"),
                                                     )
                                                 ],
                                             ),
                                             LessEqual(
                                                 Selected(
                                                     Indexed(
                                                         Selected("Ctx", "Cursors"), Name("F"),
                                                     ),
                                                     "Last",
                                                 ),
                                                 Call(
                                                     "Field_Last",
                                                     [Name("Ctx"), Selected("Val", "Fld")],
                                                 ),
                                             ),
                                         )
                                     ]
                                 ),
                             ),
                         )
                     ),
                     Postcondition(
                         And(
                             Call("Has_Buffer", [Name("Ctx")]),
                             Equal(
                                 Name("Fst"),
                                 Call("Field_First", [Name("Ctx"), Selected("Val", "Fld")]),
                             ),
                             Equal(
                                 Name("Lst"),
                                 Call("Field_Last", [Name("Ctx"), Selected("Val", "Fld")]),
                             ),
                             GreaterEqual(Name("Fst"), Selected("Ctx", "First")),
                             LessEqual(Name("Fst"), Add(Name("Lst"), Number(1))),
                             LessEqual(
                                 Call(self.types.byte_index, [Name("Lst")]),
                                 Selected("Ctx", "Buffer_Last"),
                             ),
                             ForAllIn(
                                 "F",
                                 Range("Field"),
                                 If(
                                     [
                                         (
                                             Call(
                                                 "Structural_Valid",
                                                 [
                                                     Indexed(
                                                         Selected("Ctx", "Cursors"), Name("F"),
                                                     )
                                                 ],
                                             ),
                                             LessEqual(
                                                 Selected(
                                                     Indexed(
                                                         Selected("Ctx", "Cursors"), Name("F"),
                                                     ),
                                                     "Last",
                                                 ),
                                                 Name("Lst"),
                                             ),
                                         )
                                     ]
                                 ),
                             ),
                             *[
                                 Equal(e, Old(e))
                                 for e in [
                                     Selected("Ctx", "Buffer_First"),
                                     Selected("Ctx", "Buffer_Last"),
                                     Selected("Ctx", "First"),
                                     Selected("Ctx", "Cursors"),
                                 ]
                             ],
                         )
                     ),
                 ],
             )
         ],
     )
Exemplo n.º 28
0
def test_greater_equal() -> None:
    assert GreaterEqual(Number(100), Number(1)).z3expr() == (z3.IntVal(100) >= z3.IntVal(1))
Exemplo n.º 29
0
def array_functions(array: Array, package: str) -> List[Subprogram]:
    common_precondition = LogCall(f'Is_Contained (Buffer)')

    return [
        Function('Valid_First', 'Boolean', [('Buffer', 'Types.Bytes')], [], [
            ReturnStatement(
                LogCall('Valid_Next (Buffer, Offset_Type (Buffer\'First))'))
        ], [Precondition(common_precondition)]),
        Procedure('Get_First', [
            ('Buffer', 'Types.Bytes'), ('Offset', 'out Offset_Type'),
            ('First', 'out Types.Index_Type'), ('Last', 'out Types.Index_Type')
        ], [], [
            Assignment('Offset', Value('Offset_Type (Buffer\'First)')),
            CallStatement('Get_Next', ['Buffer', 'Offset', 'First', 'Last'])
        ], [
            Precondition(
                And(common_precondition, LogCall('Valid_First (Buffer)'))),
            Postcondition(
                And(
                    And(GreaterEqual(Value('First'), First('Buffer')),
                        LessEqual(Value('Last'), Last('Buffer'))),
                    LogCall(f'{package}.{array.element_type}.Is_Contained '
                            '(Buffer (First .. Last))')))
        ]),
        Function('Valid_Next', 'Boolean', [
            ('Buffer', 'Types.Bytes'), ('Offset', 'Offset_Type')
        ], [], [
            PragmaStatement('Assume', [
                (f'{package}.{array.element_type}.Is_Contained '
                 '(Buffer (Types.Index_Type (Offset) .. Buffer\'Last))')
            ]),
            ReturnStatement(
                LogCall(
                    f'{package}.{array.element_type}.Is_Valid '
                    '(Buffer (Types.Index_Type (Offset) .. Buffer\'Last))'))
        ], [Precondition(common_precondition)]),
        Procedure(
            'Get_Next', [('Buffer', 'Types.Bytes'),
                         ('Offset', 'in out Offset_Type'),
                         ('First', 'out Types.Index_Type'),
                         ('Last', 'out Types.Index_Type')], [],
            [
                Assignment('First', Value('Types.Index_Type (Offset)')),
                Assignment(
                    'Last',
                    Add(
                        Value('First'),
                        Cast(
                            'Types.Length_Type',
                            MathCall(f'{package}.{array.element_type}.'
                                     'Message_Length (Buffer (First '
                                     '.. Buffer\'Last))')), Number(-1))),
                Assignment('Offset', Value('Offset_Type (Last + 1)')),
                PragmaStatement(
                    'Assume', [(f'{package}.{array.element_type}.Is_Contained '
                                '(Buffer (First .. Last))')])
            ], [
                Precondition(
                    And(common_precondition,
                        LogCall('Valid_Next (Buffer, Offset)'))),
                Postcondition(
                    And(
                        And(GreaterEqual(Value('First'), First('Buffer')),
                            LessEqual(Value('Last'), Last('Buffer'))),
                        LogCall(f'{package}.{array.element_type}.Is_Contained '
                                '(Buffer (First .. Last))')))
            ])
    ]
Exemplo n.º 30
0
 def test_greater_equal_simplified(self) -> None:
     self.assertEqual(
         GreaterEqual(Value('X'), Add(Number(21), Number(21))).simplified(),
         GreaterEqual(Value('X'), Number(42)))