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 quickSort(arr: List[int]) -> List[int]: Requires(Acc(list_pred(arr), 2/3)) Requires(MustTerminate(2 + len(arr))) Ensures(Acc(list_pred(arr), 2/3)) Ensures(Implies(len(arr) > 1, list_pred(Result()))) Ensures(Implies(len(arr) <= 1, Result() is arr)) less = [] # type: List[int] pivotList = [] # type: List[int] more = [] # type: List[int] if len(arr) <= 1: return arr else: pivot = arr[0] for i in arr: Invariant(list_pred(less) and list_pred(pivotList) and list_pred(more)) Invariant(len(Previous(i)) == len(less) + len(more) + len(pivotList)) Invariant(Implies(len(Previous(i)) > 0, len(pivotList) > 0)) Invariant(Acc(list_pred(arr), 1/2) and len(arr) > 0 and arr[0] == pivot) Invariant(MustTerminate(len(arr) - len(Previous(i)))) if i < pivot: less.append(i) elif i > pivot: more.append(i) else: pivotList.append(i) less = quickSort(less) more = quickSort(more) return less + pivotList + more
def release(self) -> None: """Release the lock.""" Requires(MustTerminate(1)) Requires(MustRelease(self, 1)) Requires(self.invariant()) Requires(Low(self)) Requires(LowEvent())
def syscall_putchar(t1: Place, c: str) -> Place: IOExists1(Place)(lambda t2: ( Requires( token(t1, 1) and syscall_putchar_io(t1, c, t2) and MustTerminate(1) ), Ensures(token(t2) and t2 == Result()), ))
def End(t_pre: Place) -> Place: """Perform ``end_io``.""" Requires( token(t_pre, 1) and end_io(t_pre) and MustTerminate(1) )
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 open(t1: Place, file_name: str) -> Tuple[File, Place]: IOExists2(Place, File)(lambda t2, fp: ( Requires( token(t1, 1) and open_io(t1, file_name, fp, t2) and MustTerminate( 1)), Ensures(token(t2) and t2 == Result()[1] and fp is Result()[0]), ))
def dns_query_topo(self, qname: str) -> List[Tuple[HostAddrBase, int]]: Requires(Acc(self.State(), 1 / 10)) Requires(qname in SERVICE_TYPES) Requires(MustTerminate(2)) Ensures(Acc(self.State(), 1 / 10)) """ Query dns for an answer. If the answer is empty, or an error occurs then return the relevant topology entries instead. :param str qname: Service to query for. """ assert qname in SERVICE_TYPES Unfold(Acc(self.State(), 1 / 10)) Unfold(Acc(self.topology.State(), 1 / 10)) service_map = { BEACON_SERVICE: self.topology.beacon_servers, CERTIFICATE_SERVICE: self.topology.certificate_servers, PATH_SERVICE: self.topology.path_servers, SIBRA_SERVICE: self.topology.sibra_servers, } # type: Dict[str, List[RouterElement]] # Generate fallback from local topology results = [(srv.addr, srv.port) for srv in service_map[qname]] # FIXME(kormat): replace with new discovery service when that's ready. # results = self._dns.query(qname, fallback, self._quiet_startup()) Fold(Acc(self.topology.State(), 1 / 10)) Fold(Acc(self.State(), 1 / 10)) if not results: # No results from local toplogy either raise SCIONServiceLookupError("No %s servers found" % qname) return results
def _scmp_validate_error(self, pkt: SCIONExtPacket, e: SCMPError) -> None: Requires(MustTerminate(1)) # if pkt.cmn_hdr.next_hdr == L4Proto.SCMP and pkt.ext_hdrs[0].error: # # Never respond to an SCMP error with an SCMP error. # logging.info( # "Dropping SCMP error packet due to validation error. %s", e) # return # if isinstance(e, (SCMPBadIOFOffset, SCMPBadHOFOffset)): # # Can't handle normally, as the packet isn't reversible. # reply = self._scmp_bad_path_metadata(pkt, e) # else: # logging.warning("Error: %s", type(e)) # reply = pkt.reversed_copy() # args = () # type: Tuple[object, ...] # if isinstance(e, SCMPUnspecified): # args = (str(e),) # elif isinstance(e, (SCMPOversizePkt, SCMPBadPktLen)): # args = (e.args[1],) # the relevant MTU. # elif isinstance(e, (SCMPTooManyHopByHop, SCMPBadExtOrder, # SCMPBadHopByHop)): # args = e.args # if isinstance(e, SCMPBadExtOrder): # # Delete the problematic extension. # del reply.ext_hdrs[args[0]] # reply.convert_to_scmp_error(self.addr, e.CLASS, e.TYPE, pkt, *args) # if pkt.addrs.src.isd_as == self.addr.isd_as: # # No path needed for a local reply. # reply.path = SCIONPath() # next_hop, port = self.get_first_hop(reply) # reply.update() # self.send(reply, next_hop, port) pass
def handle_client(client_socket: Socket, t1: Place) -> None: Requires(client_socket is not None) Requires(token(t1, 2) and handle_client_io(t1, client_socket)) Requires(MustTerminate(2)) Open(handle_client_io(t1, client_socket)) data, t4 = read_all(t1, client_socket, timeout=1) Open(output_io(t4, client_socket, data)) if data is not None: t5, t6 = Split(t4) t7 = print_int(t6, get_address(client_socket)) t8 = send(t5, client_socket, data) t9 = Join(t8, t7) else: t9 = NoOp(t4) t10 = close(t9, client_socket) End(t10)
def acquire(self) -> None: """Acquire the lock.""" Requires(MustTerminate(1)) Requires(WaitLevel() < Level(self)) Requires(Low(self)) Requires(LowEvent()) Ensures(self.invariant()) Ensures(MustRelease(self))
def decr_pred(c: Cell, n: int) -> int: Requires(Acc(c.val)) Requires(MustTerminate(2)) Ensures(cell_pred(c, Old(c.val) - n)) c.val = c.val - n res = c.val Fold(cell_pred(c, c.val)) return res
def notify(t1: Place) -> None: Requires(token(t1, 2) and notify_io(t1) and MustTerminate(2)) Open(notify_io(t1)) t2 = send(t1) t3 = End(t2)
def __init__(self, value: int) -> None: Requires(MustTerminate(1)) Ensures(Acc(self.int_field1)) # type: ignore Ensures(self.int_field1 == value) # type: ignore Ensures(Acc(self.int_field2)) # type: ignore Ensures(self.int_field2 == value) # type: ignore self.int_field1 = value self.int_field2 = value
def main(self, t1: Place) -> Place: IOExists1(Place)(lambda t2: ( Requires(token(t1, 2) and example_io(t1, t2) and MustTerminate(2)), Ensures(token(t2) and t2 == Result()), )) Open(example_io(t1)) success, t2 = putchar('h', t1) success, t3 = putchar('i', t2) return t3
def printTwice(l: Lock[Cell], x: int) -> None: Requires(LowEvent()) Requires(Low(l) and Low(x)) Requires(MustTerminate(4)) Requires(WaitLevel() < Level(l)) l.acquire() sif_print(x) sif_print(x) l.release()
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 stdlib_flush_stdout(lib: StandardLibrary, t1: Place, t_postponed: Place) -> None: Requires( token(t1, 3) and stdlib(lib, t1, t_postponed) and MustTerminate(2)) Ensures(token(t_postponed, 3) and stdlib(lib, t_postponed, t_postponed)) Unfold(stdlib(lib, t1, t_postponed)) if lib.buffer_size == 1: syscall_putchar(t1, lib.buffer) lib.buffer_size = 0 Fold(stdlib(lib, t_postponed, t_postponed))
def main(t1: Place, lib: StandardLibrary) -> Place: IOExists2(Place, Place)(lambda t2, t3: ( Requires( token(t1) and stdlib(lib, t1, t1) and stdlib_putchar_io( t1, 'h', t2) and stdlib_putchar_io(t2, 'i', t3) and MustTerminate(4)), Ensures(token(t3, 10) and stdlib(lib, t3, t3) and t3 == Result()), )) t2, t_postponed = stdlib_putchar(lib, 'h', t1, t1) t3, t_postponed = stdlib_putchar(lib, 'i', t2, t_postponed) stdlib_flush_stdout(lib, t3, t_postponed) return t_postponed
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 main(t1: Place) -> Place: IOExists1(Place)(lambda t2: ( Requires( token(t1, 2) and output_anything(t1, t2) and MustTerminate(2)), Ensures(token(t2)), )) i = get_any_char() Open(output_anything(t1)) t2 = SetVar(t1, i) success, t3 = putchar(i, t2) return t3
def ensure_dir_exists2(t1: Place, path: str) -> Place: IOExists2(Place, OSErrorWrapper)( lambda t2, ex: ( Requires( path is not None and token(t1, 2) and ensure_dir_exists_io2(t1, path, ex, t2) and MustTerminate(2) ), Ensures( token(t2) and t2 == Result() and ex is None ), Exsures(OSErrorWrapper, #:: UnexpectedOutput(postcondition.violated:assertion.false,55) | UnexpectedOutput(carbon)(postcondition.violated:assertion.false,168) ex is RaisedException() and Acc(ex.place) and ex.place == t2 and token(t2) and Acc(ex.exception) and isinstance(ex.exception, Exception) ), ) ) Open(ensure_dir_exists_io2(t1, path)) res = True try: t3 = mkdir(t1, path) t2 = NoOp(t3) return t2 except OSErrorWrapper as ex1: try: res, t2 = is_dir(ex1.place, path) except OSErrorWrapper as ex2: raise ex1 else: if not res: raise ex1 else: return t2
def print_int(t1: Place, value: int) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 1) and print_io(t1, value, t2) and MustTerminate(1) ), Ensures( token(t2) and t2 == Result() ) ) )
def close(t1: Place, socket: Socket) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 1) and close_io(t1, socket, t2) and socket != None and MustTerminate(1) ), Ensures( token(t2) and t2 == Result() ), ) )
def main(t1: Place) -> Place: IOExists1(Place)(lambda t2: ( Requires( token(t1, 2) and matching_brackets(t1, t2) and MustTerminate(2)), Ensures(token(t2)), )) Open(matching_brackets(t1)) Open(matching_brackets_helper(t1)) success, t2 = putchar('(', t1) Open(matching_brackets(t2)) t3 = NoOp(t2) success, t4 = putchar(')', t3) Open(matching_brackets(t4)) t5 = NoOp(t4) return t5
def NoOp(t_pre: Place) -> Place: """Perform ``no_op_io``.""" IOExists1(Place)( lambda t_post: ( Requires( token(t_pre, 1) and no_op_io(t_pre, t_post) and MustTerminate(1) ), Ensures( token(t_post) and t_post == Result() ), ) )
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 create_server_socket(t1: Place) -> Tuple[Socket, Place]: IOExists2(Socket, Place)( lambda socket, t2: ( Requires( token(t1, 1) and create_server_socket_io(t1, socket, t2) and MustTerminate(1) ), Ensures( token(t2) and Result()[1] == t2 and socket != None and Result()[0] is socket ), ) )
def send(t1: Place, socket: Socket, data: str) -> Place: IOExists1(Place)( lambda t2: ( Requires( token(t1, 1) and send_io(t1, socket, data, t2) and data is not None and socket != None and MustTerminate(1) ), Ensures( token(t2) and t2 == Result() ), ) )
def Join(t_pre1: Place, t_pre2: Place) -> Place: """Perform ``join_io``.""" IOExists1(Place)( lambda t_post: ( Requires( token(t_pre1, 1) and token(t_pre2, 1) and join_io(t_pre1, t_pre2, t_post) and MustTerminate(1) ), Ensures( token(t_post) and t_post == Result() ), ) )