def test_genAST_subst_def2(self): string=''' MACHINE Test VARIABLES z, b, x INVARIANT x:NAT & z:NAT & b:BOOL INITIALISATION x:=2 ; Assign(x+1, z) ; Assign(TRUE, b) DEFINITIONS Assign(Expr, VarName) == VarName := Expr; END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) #Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch)# init VARIABLES and eval INVARIANT invariant = root.children[2] assert isinstance(invariant, AInvariantMachineClause) assert interpret(invariant, env) assert env.get_value("z")==3 assert env.get_value("b")==True assert env.get_value("x")==2
def test_genAST_sub_any(self): string = ''' MACHINE Test VARIABLES xx INVARIANT xx:NAT INITIALISATION BEGIN xx:=1; ANY r1, r2 WHERE r1 : NAT & r2 : NAT & r1*r1 + r2*r2 = 25 THEN xx := r1 + r2 END END END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._min_int = -1 env._max_int = 5 mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env) assert env.get_value("xx")==5 or env.get_value("xx")==7 # 3+4 or 5+0
def test_genAST_sub_let(self): string = ''' MACHINE Test VARIABLES SumR, DifferenceR, Var1, Var2 INVARIANT SumR:NAT & DifferenceR:NAT & Var1:NAT & Var2:NAT INITIALISATION BEGIN Var1:=2; Var2:=3; LET r1, r2 BE r1 = (Var1 + Var2) / 2 & r2 = (Var1 - Var2) / 2 IN SumR := r1 + r2 || DifferenceR := r1 - r2 END END END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._min_int = -1 env._max_int = 5 mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env) assert env.get_value("SumR")==1 assert env.get_value("DifferenceR")==3 assert env.get_value("Var1")==2 assert env.get_value("Var2")==3
def test_genAST_sub_case3(self): # Build AST string = ''' MACHINE Test VARIABLES xx INVARIANT xx:NAT INITIALISATION BEGIN xx:=1; CASE 1+1 OF EITHER 4,5,6 THEN xx:=2 OR 7,8,9 THEN xx:=3 ELSE xx:=4 END END END END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env) assert env.get_value("xx")==4
def test_genAST_sub_var(self): # Build AST string = ''' MACHINE Test VARIABLES xx INVARIANT xx:NAT INITIALISATION BEGIN xx:=1; VAR varLoc1, varLoc2 IN varLoc1 := xx + 1 ; varLoc2 := 2 * varLoc1 ; xx := varLoc2 END END END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._min_int = -1 env._max_int = 5 mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env) assert env.get_value("xx")==4
def test_library_length(self): string = ''' MACHINE LibraryStrings CONSTANTS length PROPERTIES /* compute the length of a string */ length: STRING --> INTEGER & length = %x.(x:STRING|STRING_LENGTH(x)) DEFINITIONS STRING_LENGTH(x) == length(x); EXTERNAL_FUNCTION_STRING_LENGTH == STRING --> INTEGER; ASSERTIONS length("abc") = 3; length("") = 0; length("hello") = 5 END ''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) assert isinstance(get_type_by_name(env, "length"), PowerSetType) assert isinstance(get_type_by_name(env, "length").data, CartType) assert isinstance(get_type_by_name(env, "length").data.left.data, StringType) assert isinstance(get_type_by_name(env, "length").data.right.data, IntegerType) arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[4], AAssertionsMachineClause) interpret(root.children[4], env)
def test_genAST_para_def(self): # Build AST string =''' MACHINE Test VARIABLES z INVARIANT z:MyType INITIALISATION z:= Expr(2) DEFINITIONS Expr(X) == 1+X; MyType == NAT; END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT invariant = root.children[2] assert isinstance(invariant, AInvariantMachineClause) assert interpret(invariant, env) assert env.get_value("z")==3
def test_simple_model_checking2(self): path = "examples/rpython_performance/SigmaLoop.mch" if os.name=='nt': path="examples/rpython_performance\SigmaLoop" ast_string = file_to_AST_str(path) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._max_int = 2**31 mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend solution_file_read = False bstates = set_up_constants(root, env, mch, solution_file_read) assert len(bstates)==0 # no setup possible bstates = exec_initialisation(root, env, mch, solution_file_read) assert len(bstates)==1 # only one possibility (sum:=45) assert len(env.state_space.seen_states)==0 assert isinstance(bstates[0], BState) env.state_space.set_current_state(bstates[0]) assert len(env.state_space.seen_states)==1 invatiant = root.children[2] assert isinstance(invatiant, AInvariantMachineClause) assert interpret(invatiant, env) assert len(env.state_space.stack)==2 next_states = calc_next_states(env, mch) assert len(next_states)==1 assert len(env.state_space.stack)==2 # init and empty setup assert env.get_value('sum')==55 env.state_space.set_current_state(next_states[0].bstate) assert env.get_value('sum')==55
def test_examples_no_query_op(self): string = ''' MACHINE Query VARIABLES xx INVARIANT xx:NAT INITIALISATION xx:=1 OPERATIONS no_query = xx:=2 END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env)
def test_CartesianProductOverride(self): string = ''' MACHINE CartesianProductOverride SETS S;T CONSTANTS a,b,c PROPERTIES /* Rule Hypotheses */ a : S <-> T & dom(a) = b & c <: T & /* Rule Conclusion */ not( a <+ b * c = b * c ) END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # eval CONSTANTS and PROPERTIES assert isinstance(root.children[3], APropertiesMachineClause) assert interpret(root.children[3], env)
def test_set_up_constants_nondeterministic2(self): string = ''' MACHINE Param2 PROPERTIES num:NAT & num <4 CONSTANTS num VARIABLES xx INVARIANT xx:NAT INITIALISATION xx:=num END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._min_int = -16 env._max_int = 16 mch = parse_ast(root, env) type_check_bmch(root, env, mch) bstates = set_up_constants(root, env, mch) assert len(bstates)==4 for bstate in bstates: env.state_space.add_state(bstate) num = bstate.get_value("num", mch) assert num in [0,1,2,3] env.state_space.undo()
def test_examples_knights_knaves(self): string =''' MACHINE KnightsKnaves /* Puzzle from Smullyan: Knights: always tell the truth Knaves: always lie 1: A says: “B is a knave or C is a knave” 2: B says “A is a knight” What are A & B & C? */ CONSTANTS A,B,C PROPERTIES A:BOOL & B:BOOL & C:BOOL /* TRUE if they are a Knight */ & (A=TRUE <=> (B=FALSE or C=FALSE)) & (B=TRUE <=> A=TRUE) END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # search for CONSTANTS which make PROPERTIES True assert env.get_value("A") == True assert env.get_value("B") == True assert env.get_value("C") == False
def test_examples_simple_testset(self): string = ''' MACHINE TestSet SETS ID={aa, bb, cc} CONSTANTS iv PROPERTIES iv:ID VARIABLES xx INVARIANT xx:ID INITIALISATION xx:=iv END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[5], AInvariantMachineClause) assert interpret(root.children[5], env)
def test_examples_simple_bakery1(self): string =''' MACHINE Bakery1 ABSTRACT_VARIABLES p1, p2, y1, y2 INVARIANT p1:0..2 & p2:0..2 & y1:NATURAL & y2:NATURAL & (p1=2 => p2<2) & (p2=2 => p1<2) INITIALISATION p1,p2,y1,y2 := 0,0,0,0 END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env)
def test_types_complex_union_empty_set(self): string = '''MACHINE Test SETS U = {g, h, i}; R={j,k,l} CONSTANTS gg PROPERTIES gg : U +-> (R >+> R) & gg = { g |-> {j |-> l}, h |-> {k |-> k}, i |-> {}} END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) assert isinstance(get_type_by_name(env, "gg"), PowerSetType) assert isinstance(get_type_by_name(env, "gg").data, CartType) assert isinstance(get_type_by_name(env, "gg").data.left, PowerSetType) assert isinstance(get_type_by_name(env, "gg").data.right, PowerSetType) assert isinstance(get_type_by_name(env, "gg").data.left.data, SetType) assert get_type_by_name(env, "gg").data.left.data.name =="U" image_type = get_type_by_name(env, "gg").data.right.data.data assert isinstance(image_type, CartType) assert isinstance(image_type.left.data, SetType) assert isinstance(image_type.right.data, SetType) assert image_type.left.data.name=="R" assert image_type.right.data.name=="R"
def test_genAST_sub_let2(self): string = ''' MACHINE Test VARIABLES X, Y INVARIANT X:NAT & Y:NAT INITIALISATION BEGIN X:=10; LET r1, X BE X = 6 & r1 = X / 2 IN Y := r1 END END END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() env._min_int = -1 env._max_int = 5 mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[2], AInvariantMachineClause) assert interpret(root.children[2], env) assert env.get_value("X")==10 assert env.get_value("Y")==3
def test_simple_model_checking0(self): path = "examples/rpython_performance/Lift2.mch" if os.name=='nt': path="examples\rpython_performance\Lift2" ast_string = file_to_AST_str(path) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend env._max_int = 2**31 solution_file_read = False bstates = set_up_constants(root, env, mch, solution_file_read) assert len(bstates)==0 # no setup possible bstates = exec_initialisation(root, env, mch, solution_file_read) assert len(bstates)==1 # only one possibility (floor:=4) assert len(env.state_space.seen_states)==0 assert isinstance(bstates[0], BState) env.state_space.set_current_state(bstates[0]) assert len(env.state_space.seen_states)==1 invatiant = root.children[2] assert isinstance(invatiant, AInvariantMachineClause) assert interpret(invatiant, env) assert len(env.state_space.stack)==2 next_states = calc_next_states(env, mch) assert len(next_states)==2 assert len(env.state_space.stack)==2 # init and empty setup assert env.get_value('floor')==4 env.state_space.undo() assert len(env.state_space.stack)==1 # setup assert len(env.state_space.seen_states)==1 for n_state in next_states: bstate = n_state.bstate assert isinstance(bstate, BState) if not env.state_space.is_seen_state(bstate): env.state_space.set_current_state(bstate) assert len(env.state_space.stack)==3 # dec, inc, setup assert len(env.state_space.seen_states)==3 assert env.get_value('floor')==3 or env.get_value('floor')==5 # TODO: Bstate needs refactoring. # - Remove init state # - dont map None to values if parsing unit is no machine # - check empty on stack length 0 # model checking loop while not env.state_space.empty(): assert interpret(invatiant, env) next_states = calc_next_states(env, mch) env.state_space.undo() for n_state in next_states: bstate = n_state.bstate if not env.state_space.is_seen_state(bstate): env.state_space.set_current_state(bstate) assert len(env.state_space.seen_states)==100
def test_types_two_para_def(self): # Build AST string=''' MACHINE Test VARIABLES z INVARIANT z:MyDef(NAT,{0}) INITIALISATION z:= MyDef(5,1) DEFINITIONS MyDef(X,Y) == X-Y; END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Type env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) parse_ast(root, env) lst = [] type_with_known_types(root, env, lst, ["z"]) assert isinstance(get_type_by_name(env, "z"), IntegerType)
def test_abrial_book_page83_fail(self): # added some 42 in the assertions clause string = """ MACHINE BBook_Page83 /* Translation of example from page 83 of Abrial's B-Book */ CONSTANTS p,w,q,f,g,s,t,h,k PROPERTIES p = {3|->5, 3|->9, 6|->3, 9|->2} & w = {1, 2, 3} & p[w] = {5,9} & q = {2|->7, 3|->4, 5|->1, 9|->5} & q <+ p = {3|->5, 3|->9, 6|->3, 9|->2, 2|->7, 5|->1} & f = {8|->10, 7|->11, 2|->11, 6|->12} & g = {1|->20, 7|->20, 2|->21, 1|->22} & f >< g = {(7|->(11|->20)), (2|->(11|->21))} & s = {1,4} & t = {2,3} & prj1(s,t) = {((1|->2)|->1),((1|->3)|->1),((4|->2)|->4),((4|->3)|->4)} & prj2(s,t) = {((1|->2)|->2),((1|->3)|->3),((4|->2)|->2),((4|->3)|->3)} & h = {1|->11, 4|->12} & k = {2|->21, 7|->22} & (h||k) = { (1,2) |-> (11,21), (1,7) |-> (11,22), (4,2) |-> (12,21), (4,7) |-> (12,22) } ASSERTIONS p[w] = {5,42}; q <+ p = {(3|->5),(3|->9),(6|->3),(9|->2),(2|->7),(5|->42)}; f >< g = {(7|->(11|->20)), (2|->(11|->42))}; prj1(s,t) = {((1|->2)|->1),((1|->3)|->1),((4|->2)|->4),((4|->3)|->42)}; prj2(s,t) = {((1|->2)|->2),((1|->3)|->3),((4|->2)|->2),((4|->3)|->42)}; (h||k) = { (1,2) |-> (11,21), (1,7) |-> (11,22), (4,2) |-> (12,21), (4,7) |-> (12,42) } END""" # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # eval CONSTANTS and PROPERTIES # eval ASSERTIONS (again) assert isinstance(root.children[3], AAssertionsMachineClause) assert not interpret(root.children[3].children[0], env) assert not interpret(root.children[3].children[1], env) assert not interpret(root.children[3].children[2], env) assert not interpret(root.children[3].children[3], env) assert not interpret(root.children[3].children[4], env) assert not interpret(root.children[3].children[5], env)
def test_types_wrong_parameter_type2(self): string = ''' MACHINE Test(a,b) CONSTRAINTS a:b END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) py.test.raises(BTypeException, "type_check_bmch(root, env, mch)")
def test_only_invariant(self): string = ''' MACHINE Only INVARIANT 4=4 END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) arbitrary_init_machine(root, env, mch)
def test_types_complex_function_image8(self): string = ''' MACHINE Test VARIABLES f,x,y,z INVARIANT f(x,y,z)=42 & x=1 & y = (1,1) & z=1 INITIALISATION f:={((1,(1,1)),1,42),((1,(1,1)),1,42)} ; x:=1; z:=1 ; y:=(1,1) END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch)
def test_types_complex_function_image7(self): string = ''' MACHINE Test VARIABLES f,g INVARIANT g(f(1 |-> 1) |-> 1) /= 42 & f<: NAT * NAT *NAT INITIALISATION f:={(1,1,1),(1,1,1)} ; g:={(1,1,1)} END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch)
def test_types_complex_function_image2(self): string = ''' MACHINE Test VARIABLES yy, xx INVARIANT yy<:%aa,bb.((aa,bb):xx | prj1(INTEGER, INTEGER)(aa,bb)) & xx<:INTEGER * NATURAL1 INITIALISATION xx:={(1,2),(2,2)} ; yy:={((1,2),1),((2,2),2)} END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch)
def test_library_append(self): string = ''' MACHINE m DEFINITIONS EXTERNAL_FUNCTION_STRING_APPEND == STRING*STRING --> STRING; STRING_APPEND(x,y) == append(x,y); STRING_LENGTH(x) == length(x); EXTERNAL_FUNCTION_STRING_LENGTH == STRING --> INTEGER; ABSTRACT_CONSTANTS append, length PROPERTIES append = %(x,y).(x: STRING & y: STRING | STRING_APPEND(x,y)) & length: STRING --> INTEGER & length = %x.(x:STRING|STRING_LENGTH(x)) ASSERTIONS append("abc","abc") = "abcabc"; append("","abc") = "abc"; append("abc","") = "abc"; /*{x|x:{"abc","abcabc","hello"} & #(prefx).(append(prefx,"c")=x)} = {"abcabc","abc"};*/ {x|x/="" & #y.(append(x,y)="abc" & y/="")} = {"a","ab"}; /* compute true prefixes */ {x|x/="" & #y.(append(y,x)="abc" & y/="")} = {"c","bc"}; /* compute true postfixes */ {y|y/="" & #(x,z).(append(x,append(y,z))="abc" & length(x)+length(z)>0)} = /* compute true substrings */ {"a","ab","b","bc","c"}; {y|y/="" & #(x,z).(append(append(x,y),z)="abc" & length(x)+length(z)>0)} = /* compute true substrings */ {"a","ab","b","bc","c"} END''' # TODO: prolog-style args # {x|x:{"abc","abcabc","hello"} & #(prefx).(append(prefx,"c")=x)} = {"abcabc","abc"}; # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) assert isinstance(get_type_by_name(env, "append"), PowerSetType) assert isinstance(get_type_by_name(env, "append").data, CartType) assert isinstance(get_type_by_name(env, "append").data.left.data, CartType) assert isinstance(get_type_by_name(env, "append").data.left.data.left.data, StringType) assert isinstance(get_type_by_name(env, "append").data.left.data.right.data, StringType) assert isinstance(get_type_by_name(env, "append").data.right.data, StringType) arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[4], AAssertionsMachineClause) interpret(root.children[4], env)
def test_types_impossible_resolve(self): string = ''' MACHINE Test SETS S ={a,b,c} CONSTANTS xx,yy,zz PROPERTIES xx-yy=zz*{a,b,c} END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) py.test.raises(ResolveFailedException, "type_check_bmch(root, env, mch)")
def test_genAST_subst_def3(self): string=''' MACHINE Test3 SEES UsingDefinitions END''' string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) #Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch)
def test_types_simple_dirprod3(self): string = ''' MACHINE Test SETS C; D; X ={a,b,c} CONSTANTS r1, r2, r3, A, B PROPERTIES r1:A<->C & r2:B<->D & r3=r1 >< r2 & A<:X & B<:X END''' # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch)
def test_library_codes(self): string = ''' MACHINE LibraryStrings CONSTANTS codes, append PROPERTIES append = %(x,y).(x: STRING & y: STRING | STRING_APPEND(x,y)) & /* obtain the characters of a string as a B sequence of Ascii codes; it is reversible */ codes: STRING --> (INTEGER <-> INTEGER) & codes = %(s).(s:STRING|STRING_CODES(s)) DEFINITIONS STRING_CODES(x) == codes(x); EXTERNAL_FUNCTION_STRING_CODES == (STRING --> (INTEGER<->INTEGER)); EXTERNAL_FUNCTION_STRING_APPEND == STRING*STRING --> STRING; STRING_APPEND(x,y) == append(x,y) ASSERTIONS codes("") = <>; /* codes(" ") = [32]; the Java parser currently swallows whitespace within strings */ codes("abc") = [97,98,99]; {x| codes(x) = codes("abc") ^ codes("abc")} = {"abcabc"}; !(x,y).(x:{"abc","hello",""} & y:{"abc","hello",""} => codes(append(x,y)) = codes(x)^codes(y)) END ''' # FIXME: composition typechecking bug # {x| codes(x) = (codes("abc") ; succ) } = {"bcd"}; # TODO: prolog style args # {x| codes(x) = %i.(i:1..26|96+i)} = {"abcdefghijklmnopqrstuvwxyz"} # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() dh = DefinitionHandler(env, str_ast_to_python_ast) dh.repl_defs(root) mch = parse_ast(root, env) type_check_bmch(root, env, mch) assert isinstance(get_type_by_name(env, "codes"), PowerSetType) assert isinstance(get_type_by_name(env, "codes").data, CartType) assert isinstance(get_type_by_name(env, "codes").data.left.data, StringType) assert isinstance(get_type_by_name(env, "codes").data.right.data.data, CartType) assert isinstance(get_type_by_name(env, "codes").data.right.data.data.left.data, IntegerType) assert isinstance(get_type_by_name(env, "codes").data.right.data.data.right.data, IntegerType) arbitrary_init_machine(root, env, mch) # init VARIABLES and eval INVARIANT assert isinstance(root.children[4], AAssertionsMachineClause) interpret(root.children[4], env)
def test_abrial_book_page82_fail(self): # changes example: change 3|->5 to 1->5 in p (PROPERTIES-clause) string = """ MACHINE BBook_Page80 /* Translation of example from page 82 of Abrial's B-Book */ CONSTANTS p,q,u,s,t PROPERTIES p = {1|->5, 3|->9, 6|->3, 9|->2} & q = {2|->7, 3|->4, 5|->1, 9|->5} & u = {1,2,3} & s = {4,7,3} & t = {4,8,1} ASSERTIONS p~ = {5|->3, 9|->3, 3|->6, 2|->9}; dom(p) = {3,6,9}; ran(p) = {5,9,3,2}; (p;q) = {3|->1, 3|->5, 6|->4, 9|->7}; id(u) = {1|->1, 2|->2, 3|->3}; s <|p = {3|->5, 3|->9}; p |> t = {}; s <<| p = {6|->3, 9|->2}; p |>> t = {3|->5, 3|->9, 6|->3, 9|->2} END """ # Build AST string_to_file(string, file_name) ast_string = file_to_AST_str(file_name) root = str_ast_to_python_ast(ast_string) # Test env = Environment() mch = parse_ast(root, env) type_check_bmch(root, env, mch) # also checks all included, seen, used and extend arbitrary_init_machine(root, env, mch) # eval CONSTANTS and PROPERTIES # eval ASSERTIONS (again) assert isinstance(root.children[3], AAssertionsMachineClause) assert not interpret(root.children[3].children[0], env) assert not interpret(root.children[3].children[1], env) assert interpret(root.children[3].children[2], env) assert not interpret(root.children[3].children[3], env) assert interpret(root.children[3].children[4], env) assert not interpret(root.children[3].children[5], env) assert interpret(root.children[3].children[6], env) assert not interpret(root.children[3].children[7], env) assert not interpret(root.children[3].children[8], env)