def _expand_expression(expression: expr.Expr) -> List[expr.Expr]: """Create disjunction by expanding the expression and return it as a list.""" if isinstance(expression, expr.Or): return expression.terms if not isinstance(expression, expr.And): return [expression] atoms = [] disjunctions = [] for e in expression.terms: if isinstance(e, expr.Or): disjunctions.append(e.terms) else: atoms.append(e) disjunctions.append([expr.And(*atoms)]) result: List[expr.Expr] = [] for value in (expr.And(*dict.fromkeys(p)).simplified() for p in product(*disjunctions)): for seen in result: if expr.Not(expr.Equal( value, seen)).check().result == expr.ProofResult.UNSAT: break else: result.append(value) return result
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") ), ] }, ) )
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
("42 <= X", expr.LessEqual(expr.Number(42), expr.Variable("X"))), ("X > 42", expr.Greater(expr.Variable("X"), expr.Number(42))), ("X >= 42", expr.GreaterEqual(expr.Variable("X"), expr.Number(42))), ("((X = 42))", expr.Equal(expr.Variable("X"), expr.Number(42))), ], ) def test_expression_relation(string: str, expected: expr.Expr) -> None: actual = parse_bool_expression(string, extended=False) assert actual == expected assert actual.location @pytest.mark.parametrize( "string,expected", [ ("X and Y", expr.And(expr.Variable("X"), expr.Variable("Y"))), ("X or Y", expr.Or(expr.Variable("X"), expr.Variable("Y"))), ("((X or Y))", expr.Or(expr.Variable("X"), expr.Variable("Y"))), ], ) def test_expression_boolean(string: str, expected: expr.Expr) -> None: actual = parse_bool_expression(string, extended=False) assert actual == expected assert actual.location @pytest.mark.parametrize( "string,expected", [ ("X + Y", expr.Add(expr.Variable("X"), expr.Variable("Y"))), ("X + Y (Z)", expr.Add(expr.Variable("X"), expr.Call("Y", [expr.Variable("Z")]))),
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), ), ], ), ( expr.And( expr.Or( expr.Equal(expr.Variable("A"), expr.TRUE), expr.Equal(expr.Variable("B"), expr.TRUE), ), expr.Equal(expr.Variable("C"), expr.TRUE), ),