def ensure_dir_exists_io( t_pre: Place, path: str, result: bool = Result(), t_post: Place = Result()) -> bool: """Ensure that directory exists IO. Should force the implementation to handle exceptions because the methods that throw exceptions should not be able to set the ``result``. """ Terminates(True) TerminationMeasure(2) return IOExists4(OSErrorWrapper, OSErrorWrapper, Place, bool)( lambda ex1, ex2, t2, is_dir_res: ( mkdir_io(t_pre, path, ex1, t2) and ( ( no_op_io(t2, t_post) and result == True ) if ex1 is None else ( is_dir_io(t2, path, ex2, is_dir_res, t_post) and Implies(ex2 is None, result == is_dir_res) and Implies(ex2 is not None, result == False) ) ) ) )
def print_sequence3(t1: Place, n: int) -> Place: """Prints n(n-1)...1.""" IOExists1(Place)(lambda t2: ( Requires(n > 0 and token(t1, 2) and print_sequence_io(t1, n, t2) and MustTerminate(2)), Ensures(token(t2) and t2 == Result()), )) t = t1 Open(print_sequence_io(t, n)) t2 = GetGhostOutput(print_sequence_io(t, n), 't_post') # type: Place while n > 1: IOExists1(Place)(lambda t_next: ( Invariant( token(t, 1) and Implies( n > 1, print_int_io(t, n, t_next) and print_sequence_io( t_next, n - 1, t2)) and Implies( not n > 1, print_int_io(t, n, t2))), Invariant(MustTerminate(n)), )) t = print_int(t, n) n -= 1 Open(print_sequence_io(t, n)) t = print_int(t, n) return t
def over_in_minus_one_conditional(l: ObjectLock, b: bool) -> None: Requires(Implies(b, MustRelease(l, 1))) #:: Label(over_in_minus_one_conditional__MustRelease__False) Requires(Implies(not b, MustRelease(l, -1))) # Negative measure is equivalent to False. Assert(Implies(not b, False)) #:: ExpectedOutput(assert.failed:assertion.false) Assert(False)
def over_in_minus_one_conditional(b: bool) -> None: Requires(Implies(b, MustTerminate(1))) #:: Label(over_in_minus_one_conditional__MustTerminate__False) Requires(Implies(not b, MustTerminate(-1))) # Negative measure is equivalent to False. Assert(Implies(not b, False)) #:: ExpectedOutput(assert.failed:assertion.false) Assert(False)
def valid(self) -> bool: return (Acc(self.left) and Acc(self.right) and Acc(self.height, 1 / 10) and self.height >= 0 and Implies( self.left is not None, self.left.valid() and Acc(self.left.height, 1 / 10) and self.left.height == self.height - 1) and Implies( self.right is not None, self.right.valid() and Acc(self.right.height, 1 / 10) and self.right.height == self.height - 1))
def hidden_obligation_ok() -> None: Requires(MustTerminate(2)) i = 0 n = 10 while i < n: Invariant(Implies(i > n, MustTerminate(n+i))) Invariant(Implies(False, MustTerminate(1))) Invariant(Implies(i <= n, MustTerminate(n-i+1))) i = i + 1
def test_condition_io9(t_pre: Place, t_post: Place = Result()) -> bool: Terminates(True) TerminationMeasure(2) return IOExists3(Place, Place, bool)( lambda t1, t2, value: (random_bool_io(t_pre, value, t1) and Implies( value, conditionally_terminating_io(t1, value, t2)) and no_op_io( t1, t2) and no_op_io(t2, t_post)))
def nested4(self) -> None: Requires(Acc(self.x) and self.x is not None) Requires(WaitLevel() < Level(self.x)) x = 1 self.x.acquire() while x < 5: Invariant(Acc(self.x)) Invariant(Implies(x < 5, MustRelease(self.x, 10 - x))) x += 1 y = 1 while y < 5: Invariant(Acc(self.x)) Invariant(Implies(y < 5 or x < 5, MustRelease(self.x, 10 - y))) y += 1 if y == 5 and x == 5: self.x.release()
def test_condition_io4(t_pre: Place, value: bool, t_post: Place = Result()) -> bool: Terminates(value) TerminationMeasure(2) #:: ExpectedOutput(termination_check.failed:child_termination.not_implied) return (Implies(value, non_terminating_io(t_pre, t_post)) and no_op_io(t_pre, t_post))
def test_generation_2() -> None: b = True while b: Invariant(Implies(not b, MustTerminate(1))) b = False while True: pass
def test_gap_io7(t_pre: Place, value: bool, t_post: Place = Result()) -> bool: Terminates(value) TerminationMeasure(2) return IOExists2( Place, Place)(lambda t1, t2: (no_op_io(t_pre, t1) and Implies(not value, gap_io(t1, t2)) and no_op_io(t1, t2) and no_op_io(t2, t_post)))
def test_io( t_pre: Place, b: bool, ) -> bool: Terminates(True) return IOExists1(int)( #:: ExpectedOutput(invalid.program:invalid.io_operation.body.use_of_undefined_existential) lambda value: Implies(b, value == 2))
def no_obligation_2(l: Lock[object]) -> None: Requires(l is not None) i = 5 while i > 0: Invariant(Implies(False, MustRelease(l))) #:: ExpectedOutput(call.precondition:insufficient.permission) l.release() i -= 1
def hidden_obligation() -> None: Requires(MustTerminate(2)) i = 0 n = 10 #:: ExpectedOutput(leak_check.failed:loop_context.has_unsatisfied_obligations) while i < n: Invariant(Implies(i > n, MustTerminate(n-i))) i = i + 1
def MustRelease_body_2(lock: Lock[object]) -> None: Requires(MustRelease(lock, 1)) i = 0 #:: ExpectedOutput(carbon)(leak_check.failed:loop_body.leaks_obligations) while i < 5: #:: ExpectedOutput(invariant.not.preserved:insufficient.permission) Invariant(Implies(i < 5, MustRelease(lock, 1))) i += 1
def MustInvoke_body_2(t1: Place) -> None: Requires(token(t1, 1)) i = 0 #:: ExpectedOutput(carbon)(leak_check.failed:loop_body.leaks_obligations) while i < 5: #:: ExpectedOutput(invariant.not.preserved:insufficient.permission) Invariant(Implies(i < 5, token(t1, 1))) i += 1
def test_gap_io9(t_pre: Place, t_post: Place = Result()) -> bool: Terminates(True) TerminationMeasure(2) return IOExists3(Place, Place, bool)( lambda t1, t2, value: ( random_bool_io(t_pre, value, t1) and #:: ExpectedOutput(termination_check.failed:gap.enabled) Implies(value, gap_io(t1, t2)) and no_op_io(t1, t2) and no_op_io( t2, t_post)))
def test_condition_io7(t_pre: Place, t_post: Place = Result()) -> bool: Terminates(True) TerminationMeasure(2) return IOExists3(Place, Place, bool)( lambda t1, t2, value: ( random_bool_io(t_pre, value, t1) and #:: ExpectedOutput(termination_check.failed:child_termination.not_implied) Implies(not value, non_terminating_io(t1, t2)) and no_op_io( t1, t2) and no_op_io(t2, t_post)))
def m2_transfer_rel(self) -> None: Requires(Acc(self.x) and MustRelease(self.x, 2)) x = 1 while x < 5: Invariant(Acc(self.x)) Invariant(Implies(x < 5, MustRelease(self.x, 10 - x))) x += 1 if x >= 5: self.x.release()
def m9(self) -> None: Requires(Acc(self.b) and self.b > 17) Requires(Acc(self.a) and MustRelease(self.a, self.b)) while self.b > 2: Invariant(Acc(self.a) and Acc(self.b)) Invariant(Implies(self.b > 4, MustRelease(self.a, self.b))) if self.b > 4: self.b -= 1 if self.b == 4: self.a.release()
def ensure_dir_exists_io2( t_pre: Place, path: str, exception: OSErrorWrapper = Result(), t_post: Place = Result() ) -> bool: """Ensure that directory exists IO. This IO allows the implementation to propagate exceptions. However, it strictly specifies which exceptions can be propagated (in this case only ``ex1``). """ Terminates(True) TerminationMeasure(2) return IOExists4(OSErrorWrapper, OSErrorWrapper, Place, bool)( lambda ex1, ex2, t2, is_dir_res: (mkdir_io(t_pre, path, ex1, t2) and ( (no_op_io(t2, t_post) and exception is None) if ex1 is None else (is_dir_io(t2, path, ex2, is_dir_res, t_post) and ((Implies(is_dir_res, exception is None) and Implies( not is_dir_res, exception is ex1)) if ex2 is None else (exception == ex1))))))
def nested1_after_inner(self) -> None: Requires(Acc(self.x) and MustRelease(self.x, 2)) x = 1 y = 1 while x < 5: Invariant(Acc(self.x)) Invariant(Implies(x < 5, MustRelease(self.x, 10 - x))) x += 1 #:: ExpectedOutput(leak_check.failed:loop_context.has_unsatisfied_obligations) while y < 5: y += 1 if x == 5: self.x.release()
def nested2_after_inner(self) -> None: Requires(Acc(self.x) and MustRelease(self.x, 2)) x = 1 y = 1 while x < 5: Invariant(Acc(self.x)) Invariant(Implies(x < 5, MustRelease(self.x, 10 - x))) x += 1 while y < 5: Invariant(MustTerminate(20 - y)) y += 1 if x == 5: self.x.release()
def __init__(self, locked_object: T, above: Optional[BaseLock] = None, below: Optional[BaseLock] = None) -> None: """ Create a lock whose level is below that of ``below`` and above that of ``above``, which protects ``locked_object``. Creating the lock "shares" the object (i.e., exhales the invariant). Create subclasses of this class and override ``invariant`` to create a lock with an invariant. ``Level(above)`` defaults to ``WaitLevel()``. """ Requires(MustTerminate(1)) Requires( Implies(above is None and below is not None, WaitLevel() < Level(below))) Requires( Implies(above is not None and below is not None, Level(above) < Level(below))) Requires(self.invariant()) Ensures(Implies(above is None, WaitLevel() < Level(self))) Ensures(Implies(above is not None, Level(above) < Level(self))) Ensures(Implies(below is not None, Level(self) < Level(below)))
def read_all(t1: Place, socket: Socket, timeout: int) -> Tuple[Optional[str], Place]: IOExists2(str, Place)( lambda data, t2: ( Requires( token(t1, 1) and read_all_io(t1, socket, timeout, data, t2) and Implies(timeout > 0, MustTerminate(1)) ), Ensures( token(t2) and Result()[1] == t2 and Result()[0] is data ), ) )
def over_in_many(b: bool) -> None: Requires(MustTerminate(1)) Requires(MustTerminate(2)) Requires(MustTerminate(3)) Requires(MustTerminate(4)) Requires(Implies(b, MustTerminate(4))) Requires(Implies(b, MustTerminate(5))) Requires(Implies(b, MustTerminate(6))) Requires(Implies(not b, MustTerminate(1))) Requires(Implies(not b, MustTerminate(2))) Requires(Implies(not b, MustTerminate(3)))
def test2() -> None: while True: Invariant(Implies(False, MustTerminate(1))) pass
def test1() -> None: Requires(Implies(False, MustTerminate(1)))
def no_obligation_1(l: Lock[object]) -> None: Requires(Implies(False, MustRelease(l))) Requires(l is not None) #:: ExpectedOutput(call.precondition:insufficient.permission) l.release()
def test_exhale_2() -> None: i = 0 while i < 5: Invariant(Implies(i > 0, MustTerminate(5 - i))) Invariant(Implies(i > 0, MustTerminate(6 - i))) i += 1