Fix the race checker for a lazy singleton

Review the AI's codeEasy10 min

Your task

An assistant wrote a lazy singleton in Java with double-checked locking. It reads instance without a lock, and only locks and checks again when it is null. It left out volatile, so a reader on the unlocked path can get the object before its fields are written. The team is writing a checker that decides, for one order of events, whether a reader can see a half-built object.

An assistant wrote reader_can_see_broken_object(events, instance_is_volatile). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • events: the events in the order they happen, as strings. Four labels matter:
    • "W:ctor_data": the constructor writes the data field.
    • "W:publish": the writer stores the object in instance.
    • "R:read_ref": a reader reads instance without the lock.
    • "R:read_data": that reader uses the object's data. Ignore any other string.
  • instance_is_volatile: true when instance is declared volatile.
  • Return true when the reader can see a half-built object, and false otherwise.

Rules the tests check:

  • For each label, only its first occurrence counts.
  • Return false when "W:publish", "R:read_ref" or "R:read_data" never appears.
  • Return false when the first "R:read_ref" comes before the first "W:publish". That reader sees null and takes the locked path.
  • Return false when the first "R:read_data" comes before the first "R:read_ref".
  • Otherwise the publish is safe only when instance_is_volatile is true and "W:ctor_data" comes before "W:publish". Return true when the publish is not safe, including when "W:ctor_data" never appears.

Examples

reader_can_see_broken_object(events: list[str], instance_is_volatile: bool) -> bool
Example 1
Inputreader_can_see_broken_object(["W:ctor_data", "W:publish", "R:read_ref", "R:read_data"], False)
OutputTrue
Example 2
Inputreader_can_see_broken_object(["W:ctor_data", "W:publish", "R:read_ref", "R:read_data"], True)
OutputFalse