obj GenericDB = GenericRecord*; obj GenericRecord = key:GenericKey; obj GenericKey; op AddRecord(gdb:GenericDB, gr:GenericRecord)->(gdb':GenericDB) pre: FindRecord(gdb, gr.key) = empty; post: FindRecord(gdb', gr.key) = gr; end; op DelRecord(gdb:GenericDB, key:Key)->(gdb':GenericDB) pre: FindRecord(gdb, key) != empty; post: FindRecord(gdb, n) = empty; end; op UpdateRecord(gdb:GenericDB, gr:GenericRecord)->(gdb':GenericDB) pre: FindRecord(gdb, gr.key) != empty; post: FindRecord(gdb', gr.key) = gr; end; op FindRecord(gdb:GenericDB, key:Key)->(gr':GenericRecord) pre: exists (gr:GenericRecord) (gr in gbd) and (gr.key = key); post: (gr' in gdb) and (gr'.key = key); end; (* * Formal meaning of failed precond: * op returns empty (which is the empty of the return type) *)