def test(t1: Place) -> Place: IOExists1(Place)(lambda t_end: ( Requires(token(t1, 2) and test_io(t1, t_end)), Ensures(token(t_end) and t_end == Result()), )) Open(test_io(t1)) t2 = NoOp(t1) t3, t4 = Split(t2) res, t5 = SetVar(t4, 1) t6 = Join(t3, t5) t_end = NoOp(t6) Assert(res == 1) return t_end
def hello(t1: Place) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 2) and write_string_io(t1, "Hello World!", t2) ), Ensures( token(t2) and t2 == Result() ) ) ) t2 = write_string(t1, "Hello World!") return t2
def Split(t_pre: Place) -> Tuple[Place, Place]: """Perform ``split_io``.""" IOExists2(Place, Place)( lambda t_post1, t_post2: ( Requires( token(t_pre, 1) and split_io(t_pre, t_post1, t_post2) and MustTerminate(1) ), Ensures( token(t_post1) and t_post1 == Result()[0] and token(t_post2) and t_post2 == Result()[1] ), ) )
def write_only_positive(t1: Place) -> Place: IOExists3(Place, Place, int)(lambda t2, t3, value: ( Requires( token(t1, 2) and read_int_io(t1, value, t2) and write_int_io( t2, value, t3)), Ensures((token(t3) and t3 == Result()) if value > 0 else (token( t2) and write_int_io(t2, value, t3) and t2 == Result())), )) t2, number = read_int(t1) if number > 0: t3 = write_int(t2, number) else: t3 = t2 return t3
def write_int(self, b: bool, t1: Place) -> Place: IOExists1(Place)( lambda t2: ( Requires( #:: ExpectedOutput(not.wellformed:insufficient.permission)|ExpectedOutput(carbon)(not.wellformed:insufficient.permission) token(t1, 2) and ((Acc(self.int_field1, 1 / 2) and write_int_io( t1, self.int_field1, t2)) if b else (Acc(self.int_field2, 1 / 2) and write_int_io( t1, self.int_field2, t2)))), Ensures((Acc(self.int_field1, 1 / 2) if b else Acc( self.int_field2, 1 / 2)) and token(t2) and t2 == Result()), )) t2 = write_int(t1, self.int_field1) return t2
def client2(t1: Place, value: int) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 3) and write_int_io(t1, value, t2) ), Ensures( token(t2) and t2 == Result() ), ) ) writer = WriterSub(value) t2 = writer.write_int(t1) return t2
def main(t1: Place) -> Place: IOExists4(Place, Place, bool, bool)( lambda t2, t3, success1, success2: ( Requires( token(t1, 2) and write_char_io(t1, stdout, 'h', success1, t2) and write_char_io(t2, stdout, 'i', success2, t3) and MustTerminate(2) ), Ensures( token(t3) and t3 == Result() ) )) success, t2 = putchar('h', t1) success, t3 = putchar('i', t2) return t3
def write_int1(self, t1: Place, value: int) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 2) and Acc(self.int_field, 1 / 4) and # Ask less permission. write_int_io(t1, self.int_field, t2)), Ensures( # Getter is heap dependent, therefore need access to # self.int_field. Acc(self.int_field, 1 / 4) and # Ask less permission. token(t2) and t2 == Result()), )) t2 = write_int(t1, self.int_field) return t2
def write_non_negative(t1: Place) -> Place: IOExists3(Place, Place, int)(lambda t2, t3, value: ( Requires( token(t1, 2) and read_int_io(t1, value, t2) and (write_int_io(t2, value, t3) if value >= 0 else write_int_io(t2, -value, t3))), Ensures(token(t3) and t3 == Result()), )) t2, number = read_int(t1) if number >= 0: t3 = write_int(t2, number) else: t3 = write_int(t2, -number) return t3
def main(t1: Place) -> Place: IOExists1(Place)(lambda t2: ( Requires(token(t1) and main_io(t1, t2)), Ensures(token(t2) and t2 == Result()), )) t2 = GetGhostOutput(main_io(t1), 't_post') # type: Place Open(main_io(t1)) success = True t_loop = t1 while success: Invariant( token(t_loop, 1) and tee_io(t_loop, t2) if success else token(t_loop) and no_op_io(t_loop, t2)) Open(tee_io(t_loop)) c, success, t_loop = getchar(t_loop) if success: t_loop = tee_out(t_loop, c) return NoOp(t_loop)
def print_sequence1(t1: Place, n: int) -> Place: """Prints n(n-1)...1.""" IOExists1(Place)(lambda t2: ( Requires(n > 0 and token(t1, n + 1) and print_sequence_io(t1, n, t2) and MustTerminate(n + 1)), Ensures(token(t2) and t2 == Result()), )) Open(print_sequence_io(t1, n)) t3 = print_int(t1, n) if n > 1: t2 = print_sequence1(t3, n - 1) else: t2 = t3 return t2
def read_write_int3(t1: Place) -> Place: IOExists6(Place, Place, Place, Place, int, int)(lambda t2, t3, t4, t5, value1, value2: ( Requires( token(t1, 2) and read_int_io(t1, value1, t2) and read_int_io(t2, value2, t3) and write_int_io( t3, value1, t4) and write_int_io(t4, value2, t5)), Ensures(token(t5) and t5 == Result()), )) t2, number1 = read_int(t1) t3, number2 = read_int(t2) #:: ExpectedOutput(call.precondition:insufficient.permission) t4 = write_int(t3, number2) #:: ExpectedOutput(carbon)(call.precondition:insufficient.permission) t5 = write_int(t4, number1) return t5
def hello2(t1: Place) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 2) and write_string_io(t1, "Hello World!", t2) ), Ensures( token(t2) and t2 == Result() ) ) ) #:: ExpectedOutput(call.precondition:insufficient.permission) t2 = write_string(t1, "Hello World") return t2
def write_int(self, t1: Place) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 2) and Acc(self.int_field, 1/2) and write_int_io(t1, self.int_field, t2) ), Ensures( Acc(self.int_field, 1/2) and token(t2) and t2 == Result() ), ) ) t2 = write_int(t1, self.int_field) return t2
def Eval(t_pre: Place, func: Callable[[T], V], arg: T) -> Tuple[V, Place]: IOExists2(Place, object)( lambda t_post, result: ( Requires( token(t_pre, 1) and eval_io(t_pre, func, arg, result, t_post) and MustTerminate(1) ), Ensures( token(t_post) and t_post is Result()[1] and result is Result()[0] # and resul result == func(arg) # This is part of the contract but guaranteed via additional inhales after # any call to Eval, and cannot be part of the contract written here # because the fact that func can have an arbitrary precondition would make # the contract of Eval not well-formed. ), ) )
def pop_read_ahead(self, t1: Place) -> Tuple[Place, Optional[str]]: IOExists3(str, bool, Place)( lambda new_char, success, t2: ( Requires( Acc(self.c) and token(t1, 2) and read_char_io(t1, stdin, new_char, success, t2) ), Ensures( Acc(self.c) and self.c is new_char and Old(self.c) is Result()[1] and token(t2) and t2 == Result()[0] ) ) ) c_copy = self.c self.c, success, t2 = getchar(t1) return (t2, c_copy)
def run(t1: Place) -> None: Requires(token(t1, 2) and listener_io(t1)) Ensures(False) Open(listener_io(t1)) server_socket, t_loop = create_server_socket(t1) while True: Invariant( token(t_loop, 1) and listener_loop_io(t_loop, server_socket) and server_socket != None) Open(listener_loop_io(t_loop, server_socket)) client_socket, t3 = accept(t_loop, server_socket) t4, t_loop = Split(t3) handle_client(client_socket, t4)
def mkdir(t1: Place, path: str) -> Place: IOExists2(Place, OSErrorWrapper)( lambda t2, ex: ( Requires( path is not None and token(t1, 1) and mkdir_io(t1, path, ex, t2) and MustTerminate(1) ), Ensures( token(t2) and t2 == Result() and ex is None ), Exsures(OSErrorWrapper, ex is RaisedException() and Acc(ex.place) and ex.place == t2 and token(t2) and Acc(ex.exception) and isinstance(ex.exception, Exception) ), ) )
def is_dir(t1: Place, path: str) -> Tuple[bool, Place]: IOExists3(Place, OSErrorWrapper, bool)( lambda t2, ex, success: ( Requires( path is not None and token(t1, 1) and is_dir_io(t1, path, ex, success, t2) and MustTerminate(1) ), Ensures( token(t2) and t2 == Result()[1] and ex is None and success == Result()[0] ), Exsures(OSErrorWrapper, ex is RaisedException() and Acc(ex.place) and ex.place == t2 and token(t2) and Acc(ex.exception) and isinstance(ex.exception, Exception) ), ) )
def read_int_twice1(t1: Place) -> Tuple[Place, int, int]: IOExists3(Place, int, int)( lambda t2, value1, value2: ( Requires( token(t1, 2) and read_int_twice_io(t1, value1, value2, t2) ), Ensures( token(t2) and t2 == Result()[0] and value1 == Result()[1] and value2 == Result()[2] ), ) ) Open(read_int_twice_io(t1)) t2, number1 = read_int(t1) t3, number2 = read_int(t2) return t3, number1, number2
def print_sequence2(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 t2 = GetGhostOutput(print_sequence_io(t, n), 't_post') # type: Place while n > 1: Invariant( token(t, 1) and print_sequence_io(t, n, t2) and MustTerminate(n)) Open(print_sequence_io(t, n)) t = print_int(t, n) n -= 1 Open(print_sequence_io(t, n)) t = print_int(t, 1) return t
def main(t1: Place) -> None: Requires(token(t1, 2) and infinite_counter_io(t1, 0)) Ensures(False) count = 0 t_cur = t1 while True: Invariant( token(t_cur, 1) and infinite_counter_io(t_cur, count) and count >= 0) unary_count = 0 Open(infinite_counter_io(t_cur, count)) t1_unary = t_cur t_unary_end = GetGhostOutput(print_unary_io(t1_unary, count), 't_end') # type: Place while (unary_count != count): Invariant( token(t1_unary, 1) and print_unary_io(t1_unary, count - unary_count, t_unary_end) and unary_count <= count) Open(print_unary_io(t1_unary, count - unary_count)) success, t1_unary = putchar('1', t1_unary) unary_count += 1 Open(print_unary_io(t1_unary, 0)) t2 = NoOp(t1_unary) success, t_cur = putchar('\n', t2) count = count + 1
def write_four_ints_3(t1: Place) -> Place: IOExists2(Place, Place)( lambda t2, t3: ( Requires( token(t1, 2) and write_two_ints_io(t1, t2) and write_two_ints_io(t2, t3) ), Ensures( #:: ExpectedOutput(postcondition.violated:insufficient.permission) token(t3) and t3 == Result() ), ) ) Open(write_two_ints_io(t1)) t2 = write_int(t1, 4) t3 = write_int(t2, 8) return t3
def read_int_twice2(t1: Place) -> Tuple[Place, int, int]: IOExists3(Place, int, int)( lambda t2, value1, value2: ( Requires( token(t1, 2) and read_int_twice_io(t1, value1, value2, t2) ), Ensures( #:: ExpectedOutput(postcondition.violated:assertion.false) token(t2) and t2 == Result()[0] and value1 == Result()[1] and value2 == Result()[2] ), ) ) Open(read_int_twice_io(t1)) t2, number1 = read_int(t1) t3, number2 = read_int(t2) return t3, number2, number1
def main(t1: Place) -> Place: IOExists8( str, Place, str, bool, Place, Place, bool, bool)(lambda read_ahead, t_read_ahead, read_last, valid, t_brackets_end, t_end, success1, success2: ( Requires( token(t1) and read_char_io(t1, stdin, read_ahead, success1, t_read_ahead) and brackets_io(t_read_ahead, read_ahead, read_last, valid, t_brackets_end) and len(read_last) == 0 and write_char_io(t_brackets_end, stdout, ('1' if valid else '0'), success2, t_end)), Ensures(token(t_end) and t_end == Result()), )) m = Matcher() m.c, success, t2 = getchar(t1) t3, match = m.brackets(t2) if match: success, t4 = putchar('1', t3) else: success, t4 = putchar('0', t3) return t4
def SetVar(t_pre: Place, value: int) -> Tuple[int, Place]: """Perform ``set_var_io``. .. note:: Mypy does not allow generics as function arguments. Therefore, we have to use a concrete type for ``value``. """ IOExists2(Place, int)( lambda t_post, result: ( Requires( token(t_pre, 1) and set_var_io(t_pre, value, result, t_post) and MustTerminate(1) ), Ensures( token(t_post) and t_post == Result()[1] and result == Result()[0] and value == result ), ) )
def ensure_dir_exists(t1: Place, path: str) -> Tuple[bool, Place]: IOExists2(Place, bool)( lambda t2, success: ( Requires( path is not None and token(t1, 2) and ensure_dir_exists_io(t1, path, success, t2) and MustTerminate(2) ), Ensures( token(t2) and t2 == Result()[1] and Result()[0] == success ), ) ) Open(ensure_dir_exists_io(t1, path)) try: t3 = mkdir(t1, path) t2 = NoOp(t3) return True, t2 except OSErrorWrapper as ex1: try: res, t2 = is_dir(ex1.place, path) return res, t2 except OSErrorWrapper as ex2: return False, ex2.place
def stdlib_putchar(lib: StandardLibrary, c: str, t1: Place, t_postponed: Place) -> Tuple[Place, Place]: IOExists2(Place, Place)(lambda t1_new, t2: ( Requires( token(t1, 2) and stdlib(lib, t1, t_postponed) and stdlib_putchar_io(t_postponed, c, t2) and MustTerminate(2)), Ensures(t1_new == Result()[0] and t2 == Result()[1] and stdlib( lib, t1_new, t2) and token(t1_new, 2)), )) Unfold(stdlib(lib, t1, t_postponed)) Open(stdlib_putchar_io(t_postponed, c)) if lib.buffer_size == 1: t2 = syscall_putchar(t1, lib.buffer) t3 = syscall_putchar(t2, c) lib.buffer_size = 0 Fold(stdlib(lib, t3, t3)) return t3, t3 else: lib.buffer = c lib.buffer_size = 1 t4 = GetGhostOutput(stdlib_putchar_io(t_postponed, c), 't_post') # type: Place Fold(stdlib(lib, t1, t4)) return t1, t4
def getchar(t1: Place) -> Tuple[str, bool, Place]: IOExists3(str, bool, Place)(lambda c, success, t2: ( Requires(token(t1, 1) and read_char_io(t1, stdin, c, success, t2)), Ensures(c is Result()[0] and success == Result()[1] and t2 == Result()[ 2] and token(t2) and (len(c) == 1 if success else len(c) == 0)), ))
def putc(c: str, fp: int, t1: Place) -> Tuple[bool, Place]: IOExists2(Place, bool)(lambda t2, success: (Requires( token(t1, 1) and write_char_io(t1, fp, c, success, t2 ) and MustTerminate(1) ), Ensures(token(t2) and success == Result()[0] and t2 == Result()[1])))