feature -- Comparison (verified) is_equal_ (other: like Current): BOOLEAN -- Is the abstract state of Current equal to that of `other'? note explicit: contracts require closed_with_subjects: is_closed_with_subjects other_closed_with_subjects: other.is_closed_with_subjects do Result := True ensure definition: Result = is_model_equal (other) end frozen equal_ (x, y: ANY): BOOLEAN note explicit: contracts require x_void_or_closed: attached x implies x.closed y_void_or_closed: attached y implies y.closed x_subjects_closed: attached x implies across x.subjects as s all s.closed end y_subjects_closed: attached y implies across y.subjects as s all s.closed end do if x = Void then Result := y = Void elseif x.generating_type = y.generating_type then Result := x.is_equal_ (y) end ensure Result = model_equals (x, y) end feature -- Output (verified) out_: V_STRING -- New string containing terse printable representation -- of current object note status: impure, skip do create Result.make_from_string (out) ensure modify ([]) out_fresh: Result.is_fresh out_wrapped: Result.is_wrapped end feature -- Verification: contract clauses frozen modify (a_objects: TUPLE): BOOLEAN -- Does this routine modify `a_objects'? do Result := True ensure instance_free: class end frozen modify_field (a_fields: ANY; a_objects: TUPLE): BOOLEAN -- Does this routine modify attributes `a_fields' of objects in `a_objects'? do Result := True ensure instance_free: class end frozen modify_model (a_models: ANY; a_objects: TUPLE): BOOLEAN -- Does this routine modify model queries `a_models' of objects in `a_objects'? do Result := True ensure instance_free: class end frozen modify_agent (a_agent: ANY; a_args: TUPLE): BOOLEAN -- Does this routine modify whatever agent `a_agent' with arguments `a_args' modifies? do Result := True ensure instance_free: class end frozen reads (a_objects: TUPLE): BOOLEAN -- Does this function read `a_objects'? do Result := True ensure instance_free: class end frozen reads_field (a_fields: ANY; a_objects: TUPLE): BOOLEAN -- Does this function read attributes `a_fields' of objects in `a_objects'? do Result := True ensure instance_free: class end frozen reads_model (a_models: ANY; a_object: TUPLE): BOOLEAN -- Does this function read model queries `a_models' of objects in `a_objects'? do Result := True ensure instance_free: class end frozen decreases (a_variants: TUPLE): BOOLEAN -- Does this routine / loop descrease `a_variants'? do Result := True ensure instance_free: class end frozen inv: BOOLEAN -- Invariant of `Current'. do Result := True end frozen inv_without (a_clauses: TUPLE): BOOLEAN -- Invariant of `Current' without `a_clauses'. do Result := True end frozen inv_only (a_clauses: TUPLE): BOOLEAN -- Invariant of `Current' restricted to `a_clauses'. do Result := True end frozen is_fresh: BOOLEAN -- Was Current unallocated in the pre-state? do Result := True end feature -- Verification: ownership operations frozen wrap -- Wrap object `a'. do end frozen wrap_all (a: MML_SET [ANY]) -- Wrap all objects in `a' simultaneously. do end frozen unwrap -- Unwrap object `a'. do end frozen unwrap_no_inv -- Unwrap object `a' and do not assume its invariant. do end frozen unwrap_all (a: MML_SET [ANY]) -- Unwrap all objects in `a' simultaneously. do end feature -- Verification: ownership queries frozen is_wrapped: BOOLEAN -- Is `Current' wrapped? do Result := True end frozen is_free: BOOLEAN -- Is `Current' free? do Result := True end frozen is_open: BOOLEAN -- Is `Current open? do Result := True end frozen is_field_writable (a_field: STRING): BOOLEAN -- Is field `a_field' of `Current' writable? do Result := True end frozen is_fully_writable: BOOLEAN -- Are all fields of `Current' writable? do Result := True end frozen is_field_readable (a_field: STRING): BOOLEAN -- Is field `a_field' of `Current' readable? do Result := True end frozen is_fully_readable: BOOLEAN -- Are all fields of `Current' readable? do Result := True end frozen transitive_owns: MML_SET [ANY] -- Reflexive transitive closure of `owns'. note status: ghost do check is_executable: False then end end frozen ownership_domain: MML_SET [ANY] -- Ownership domain of `Current' -- (coincides with `transitive_owns' when `closed' and contains only `Current' otherwise). note status: ghost do check is_executable: False then end end frozen universe: MML_SET [ANY] -- Set of all objects. note status: ghost do check is_executable: False then end end feature -- Verification: ownership fields frozen closed: BOOLEAN -- Is this object in a consistent state. note status: ghost do ensure instance_free: class end frozen owner: ANY assign set_owner -- Owner of this object. note status: ghost do check is_executable: False then end end frozen set_owner (a: ANY) -- Set owner of this object to `a'. do end owns: MML_SET [ANY] assign set_owns -- Owns set of this object. note status: ghost guard: True do check is_executable: False then end end frozen set_owns (a: MML_SET [ANY]) -- Set owns set of this object. do end subjects: MML_SET [ANY] assign set_subjects -- Subjects set of this object. note status: ghost guard: True do check is_executable: False then end end frozen set_subjects (a: MML_SET [ANY]) -- Set subjects set of this object. do end observers: MML_SET [ANY] assign set_observers -- Observers set of this object. note status: ghost guard: in_observers do check is_executable: False then end end frozen set_observers (a: MML_SET [ANY]) -- Set observers set of this object. note status: ghost do ensure observers = a end in_observers (new_observers: like observers; o: ANY): BOOLEAN -- Is `o' in `new_observers'? (Guard for `observers') note status: functional, ghost do Result := attached {like observers.any_item} o as x and then new_observers [x] end is_closed_with_subjects: BOOLEAN -- Are `Current' and its `subjects' closed? note status: functional, ghost, inv_unfriendly do Result := closed and across subjects as s all s.closed end end feature -- Verification: auxiliary is_model_equal (other: like Current): BOOLEAN -- Is the abstract state of `Current' equal to that of `other'? note status: ghost explicit: contracts require other /= Void -- generating_type = other.generating_type reads (Current, other) do Result := True ensure reflexive: other = Current implies Result symmetric: Result = other.is_model_equal (Current) end lemma_transitive (x: like Current; ys: MML_SET [like Current]) -- Property that follows from transitivity of `is_model_equal'. -- ToDo: reformulate once we have call_forall. note status: lemma require equal_x: is_model_equal (x) ys_exist: ys.non_void do ensure x_in_ys_iff_current_in_ys: across ys as y some is_model_equal (y) end = across ys as y some x.is_model_equal (y) end end frozen model_equals (x, y: ANY): BOOLEAN note status: ghost, functional require reads (x, y) do Result := (x = Void and y = Void) or ((x /= Void and x.generating_type = y.generating_type) and then x.is_model_equal (y)) ensure reflexive: x = y implies Result symmetric: Result = model_equals (y, x) end frozen old_: like Current -- Old expression outside of postconditions. do check is_executable: False then end end frozen use_definition (a_function_call: ANY) -- Bring definition of the opaque function in `a_function_call' into scope. do end