def get_spec(self): spec = Specification('sample') spec.add_variable(Variable('set', '[int]bool', 1)) procedure = Procedure('merge_6', 15) procedure.add_parameter(Parameter('set1', '[int]bool')) procedure.add_modifies('set') procedure.add_ensures( '(forall i:int :: set[i] == (old(set)[i] || set1[i]))') procedure.set_implementation('assume false;') spec.set_merge(procedure) gteq = Function('gteq', 5) gteq.add_param(Parameter('set1', '[int]bool')) gteq.add_param(Parameter('set2', '[int]bool')) gteq.set_return('bool') spec.set_gteq(gteq) spec.set_preface( 'var set:[int]bool;\n//@gteq\nfunction gteq(set1:[int]bool, set2:[int]bool) returns(bool)\n{(forall i:int :: set2[i] ==> set1[i])}' ) procedure = Procedure('add', 15) procedure.add_parameter(Parameter('value', 'int')) procedure.add_modifies('set') procedure.add_ensures( '(forall i:int :: (i == value ==> set[i] == true) && (i != value ==> set[i] == old(set)[i]))' ) procedure.set_implementation('set[value] := true;') spec.add_procedure(procedure) return spec
def extract_function(self, spec, position): spec_text = ''.join(spec) semi_colon_index = spec_text.index(';') bracket_index = spec_text.index('{') function_end = min(semi_colon_index, bracket_index) function_text = spec_text[:function_end].strip() fun_name = function_text[9:function_text.index('(')].strip() function = Function(fun_name, position) param_spec = function_text[function_text.index('(') + 1:function_text.index(')')].strip() for each in self.__get_params(param_spec): function.add_param(each) returndt = self.__get_returndt(function_text) function.set_return(returndt) if bracket_index > 1: implementation = spec_text[bracket_index + 1:spec_text.index('}')].strip() function.implementation = implementation return function
def test_check_not_monotonicity(self): spec = Specification('sample') spec.add_variable(Variable('set', '[int]bool', 1)) procedure = Procedure('remove', 15) procedure.add_parameter(Parameter('value', 'int')) procedure.add_modifies('set') procedure.set_implementation('set[value] := false;') spec.add_procedure(procedure) gteq = Function('gteq', 5) gteq.add_param(Parameter('one', '[int]bool')) gteq.add_param(Parameter('two', '[int]bool')) gteq.set_return('bool') spec.set_gteq(gteq) spec.set_preface( 'var set:[int]bool;\n//@gteq\nfunction gteq(set1:[int]bool, set2:[int]bool) returns(bool)\n{(forall i:int :: set2[i] ==> set1[i])}' ) checker = ConvergenceChecker() with pytest.raises(ConvergenceError): checker.check_monotonicity(spec, procedure)
def test_check_lub(self): spec = Specification('sample') spec.add_variable(Variable('set', '[int]bool', 1)) procedure = Procedure('merge_6', 15) procedure.add_parameter(Parameter('set1', '[int]bool')) procedure.add_modifies('set') procedure.add_ensures( '(forall i:int :: set[i] == (old(set)[i] || set1[i]))') procedure.set_implementation('assume false;') spec.set_merge(procedure) gteq = Function('gteq', 5) gteq.add_param(Parameter('set1', '[int]bool')) gteq.add_param(Parameter('set2', '[int]bool')) gteq.set_return('bool') spec.set_gteq(gteq) spec.set_preface( 'var set:[int]bool;\n//@gteq\nfunction gteq(set1:[int]bool, set2:[int]bool) returns(bool)\n{(forall i:int :: set2[i] ==> set1[i])}' ) checker = ConvergenceChecker() assert checker.check_lub(spec) == True
def test_stable_pair(self): spec = Specification('sample') spec.add_variable(Variable('counter', 'int', 1)) procedure = Procedure('inc', 15) procedure.add_parameter(Parameter('value', 'int')) procedure.add_modifies('counter') procedure.add_requires('value > 0') procedure.set_implementation('counter := counter + value;') spec.add_procedure(procedure) merge = Procedure('merge', 15) merge.add_parameter(Parameter('counter1', 'int')) merge.add_modifies('counter') merge.set_implementation('counter := (if counter1 > counter then counter1 else counter);') spec.set_merge(merge) invariant = Function('inv', 10) invariant.add_param(Parameter('counter', 'int')) invariant.set_return('bool') spec.set_invariant(invariant) spec.set_preface('var counter :int;\n//@invariant\nfunction inv(counter:int) returns(bool)\n{\n counter >= 0\n}') checker = SafetyChecker() assert checker.check_stability(spec, procedure) == True
def test_unsafe_proc(self): spec = Specification('sample') spec.add_variable(Variable('counter', 'int', 1)) procedure = Procedure('dec', 15) procedure.add_parameter(Parameter('value', 'int')) procedure.add_modifies('counter') procedure.set_implementation('counter := counter - value;') spec.add_procedure(procedure) merge = Procedure('merge', 15) merge.add_parameter(Parameter('counter1', 'int')) merge.add_modifies('counter') merge.set_implementation('counter := (if counter1 > counter then counter1 else counter);') spec.set_merge(merge) invariant = Function('inv', 10) invariant.add_param(Parameter('counter', 'int')) invariant.set_return('bool') spec.set_invariant(invariant) spec.set_preface('var counter :int;\n//@invariant\nfunction inv(counter:int) returns(bool)\n{\n counter >= 0\n}') checker = SafetyChecker() with pytest.raises(SafetyError): checker.check_safety(spec, procedure)
def test_check_monotonicity(self): spec = Specification('sample') spec.add_variable(Variable('set', '[int]bool', 1)) procedure = Procedure('add', 15) procedure.add_parameter(Parameter('value', 'int')) procedure.add_modifies('set') procedure.add_ensures( '(forall i:int :: (i == value ==> set[i] == true) && (i != value ==> set[i] == old(set)[i]))' ) procedure.set_implementation('set[value] := true;') spec.add_procedure(procedure) gteq = Function('gteq', 5) gteq.add_param(Parameter('set1', '[int]bool')) gteq.add_param(Parameter('set2', '[int]bool')) gteq.set_return('bool') spec.set_gteq(gteq) spec.set_preface( 'var set:[int]bool;\n//@gteq\nfunction gteq(set1:[int]bool, set2:[int]bool) returns(bool)\n{(forall i:int :: set2[i] ==> set1[i])}' ) checker = ConvergenceChecker() assert checker.check_monotonicity(spec, procedure) == True