Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quint verify reports an unsound counterexample #963

Closed
konnov opened this issue Jun 19, 2023 · 16 comments · Fixed by #984
Closed

quint verify reports an unsound counterexample #963

konnov opened this issue Jun 19, 2023 · 16 comments · Fixed by #984
Assignees
Labels
bug Something isn't working

Comments

@konnov
Copy link
Contributor

konnov commented Jun 19, 2023

When I run quint verify on river.qnt as follows:

quint verify --max-steps=50 --invariant=noSolution river.qnt

I rightfully reports a counterexample, but the contents of the counterexample is definitely is not what I expected:

$ quint verify --max-steps=50 --invariant=noSolution river.qnt
An example execution:

[State 0]
{
  boat: Set(),
  destination: Set(),
  origin: Set("cabbage", "farmer", "goat", "wolf")
}

[State 1]
{
  boat: Set("cabbage", "farmer", "goat", "wolf"),
  destination: Set(),
  origin: Set("cabbage", "wolf")
}

[State 2]
{
  boat: Set(),
  destination: Set("farmer", "goat"),
  origin: Set("cabbage", "wolf")
}
...

The boat should carry at most one item, in addition to the farmer. We should find which part of the pipeline contains a bug.

@konnov konnov added the bug Something isn't working label Jun 19, 2023
@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

We should run it against the older version of Apalache, before the arena refactoring. The TLA+ file can be extracted when running the server as:

$APALACHE_HOME/bin/apalache-mc server --write-intermediate=true

@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

@thpani, @Kukovec, ideas?

@thpani
Copy link
Contributor

thpani commented Jun 19, 2023

have you checked if the translation is correct?

@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

It seems to be like how I expected it.

@Kukovec
Copy link
Contributor

Kukovec commented Jun 19, 2023

Could it be that because of

boat' = boat.union(toEmbark),
origin' = origin.exclude(toEmbark),

and the fact that toEmbark is nondet, it is getting independently computed 2x?

@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

-------------------------- MODULE 12_OutAnalysisPass --------------------------

EXTENDS Integers, Sequences, FiniteSets, TLC, Apalache

VARIABLE
  (*
    @type: Set(Str);
  *)
  origin

VARIABLE
  (*
    @type: Set(Str);
  *)
  boat

VARIABLE
  (*
    @type: Set(Str);
  *)
  destination

(*
  @type: (() => Bool);
*)
Init_si_0000 ==
  origin' := { "wolf", "goat", "cabbage", "farmer" }
    /\ boat' := {}
    /\ destination' := {}

(*
  @type: (() => Bool);
*)
Next_si_0000 ==
  "farmer" \in boat
    /\ boat' := {}
    /\ destination' := (destination \union boat)
    /\ origin' := origin

(*
  @type: (() => Bool);
*)
Next_si_0001 ==
  "farmer" \in boat
    /\ boat' := {}
    /\ origin' := (origin \union boat)
    /\ destination' := destination

(*
  @type: (() => Bool);
*)
Next_si_0002 ==
  "farmer" \in origin
    /\ Skolem((\E s$1 \in SUBSET origin:
      (Cardinality(s$1) <= 2 /\ "farmer" \in s$1)
        /\ (((~(\A t_2$1 \in { "goat", "cabbage" }:
                t_2$1 \in origin /\ ~(t_2$1 \in s$1))
              \/ ("farmer" \in origin /\ ~("farmer" \in s$1)))
            /\ (~(\A t_5$1 \in { "goat", "wolf" }:
                t_5$1 \in origin /\ ~(t_5$1 \in s$1))
              \/ ("farmer" \in origin /\ ~("farmer" \in s$1))))
          /\ boat' := (boat \union s$1)
          /\ origin' := { t_7$1 \in origin: ~(t_7$1 \in s$1) }
          /\ destination' := destination)))

(*
  @type: (() => Bool);
*)
Next_si_0003 ==
  "farmer" \in destination
    /\ Skolem((\E s$2 \in SUBSET destination:
      (Cardinality(s$2) <= 2 /\ "farmer" \in s$2)
        /\ (((~(\A t_9$1 \in { "goat", "cabbage" }:
                t_9$1 \in destination /\ ~(t_9$1 \in s$2))
              \/ ("farmer" \in destination /\ ~("farmer" \in s$2)))
            /\ (~(\A t_c$1 \in { "goat", "wolf" }:
                t_c$1 \in destination /\ ~(t_c$1 \in s$2))
              \/ ("farmer" \in destination /\ ~("farmer" \in s$2))))
          /\ boat' := (boat \union s$2)
          /\ destination' := { t_e$1 \in destination: ~(t_e$1 \in s$2) }
          /\ origin' := origin)))

(*
  @type: Bool;
*)
VCInv_si_0 == ~(origin = {}) \/ ~(boat = {})

(*
  @type: Bool;
*)
VCNotInv_si_0 == origin = {} /\ boat = {}

================================================================================

@thpani
Copy link
Contributor

thpani commented Jun 19, 2023

TLA+ looks good, I would also guess arenas:
boat in state #1 is wrong, but it somehow seems to have been right going into state #2.

Screenshot 2023-06-19 at 14 29 45

@Kukovec
Copy link
Contributor

Kukovec commented Jun 19, 2023

Does running the TLA produce the same witness purely in Apalache?

@thpani
Copy link
Contributor

thpani commented Jun 19, 2023

Trace above is from the translated TLA+:

--------------------------- MODULE River ---------------------------

EXTENDS Integers, Sequences, FiniteSets, TLC, Apalache

VARIABLE
  (*
    @type: Set(Str);
  *)
  origin

VARIABLE
  (*
    @type: Set(Str);
  *)
  boat

VARIABLE
  (*
    @type: Set(Str);
  *)
  destination

(*
  @type: ((Set(Str)) => Bool);
*)
isSafe(location) ==
  ({ "goat", "cabbage" } \subseteq location => "farmer" \in location)
    /\ ({ "goat", "wolf" } \subseteq location => "farmer" \in location)

(*
  @type: (() => Bool);
*)
init ==
  origin' := { "wolf", "goat", "cabbage", "farmer" }
    /\ boat' := {}
    /\ destination' := {}

(*
  @type: (() => Bool);
*)
embarkOrigin ==
  "farmer" \in origin
    /\ (\E toEmbark \in {
      s \in SUBSET origin:
        Cardinality(s) <= 2 /\ "farmer" \in s
    }:
      isSafe((origin \ toEmbark))
        /\ boat' := (boat \union toEmbark)
        /\ origin' := (origin \ toEmbark)
        /\ destination' := destination)

(*
  @type: (() => Bool);
*)
disembarkDestination ==
  "farmer" \in boat
    /\ boat' := {}
    /\ destination' := (destination \union boat)
    /\ origin' := origin

(*
  @type: (() => Bool);
*)
embarkDestination ==
  "farmer" \in destination
    /\ (\E toEmbark \in {
      s \in SUBSET destination:
        Cardinality(s) <= 2 /\ "farmer" \in s
    }:
      isSafe((destination \ toEmbark))
        /\ boat' := (boat \union toEmbark)
        /\ destination' := (destination \ toEmbark)
        /\ origin' := origin)

(*
  @type: (() => Bool);
*)
disembarkOrigin ==
  "farmer" \in boat
    /\ boat' := {}
    /\ origin' := (origin \union boat)
    /\ destination' := destination

(*
  @type: (() => Bool);
*)
safety == isSafe(origin) /\ isSafe(boat) /\ isSafe(destination)

(*
  @type: (() => Bool);
*)
noSolution == origin /= {} \/ boat /= {}

(*
  @type: (() => Bool);
*)
consistency ==
  origin \intersect destination = {}
    /\ origin \intersect boat = {}
    /\ boat \intersect destination = {}

(*
  @type: (() => Bool);
*)
step ==
  embarkOrigin
    \/ disembarkDestination
    \/ embarkDestination
    \/ disembarkOrigin

================================================================================

@Kukovec Kukovec self-assigned this Jun 19, 2023
@Kukovec
Copy link
Contributor

Kukovec commented Jun 19, 2023

interestingly, when I pass --inv=noSolution Apalache finds a conterexample which violates consistency, but with
--inv=consistency it finds no conterexample for the same length...

@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

Yeah, I tried the same. So it is probably model reconstruction.

@konnov
Copy link
Contributor Author

konnov commented Jun 19, 2023

Can you try noSolution /\ consistency?

@Kukovec
Copy link
Contributor

Kukovec commented Jun 19, 2023

I did that too, same CE as just noSolution

@konnov
Copy link
Contributor Author

konnov commented Jun 20, 2023

Just an update, it is not a bug in the transpiler but a bug in the recent refactoring.

@konnov
Copy link
Contributor Author

konnov commented Jun 26, 2023

Since this has been fixed on the Apalache side, shall we check that this has been fixed in Quint and close the issue?

@thpani
Copy link
Contributor

thpani commented Jun 27, 2023

Since this has been fixed on the Apalache side, shall we check that this has been fixed in Quint and close the issue?

Since this is transpilation-related, lemme take this over.

Yes, we're good on quint verify - I will open a PR to bring the river example back.

@thpani thpani assigned thpani and unassigned Kukovec Jun 27, 2023
thpani added a commit that referenced this issue Jun 27, 2023
The issue we encountered before (#963) should've been fixed in Apalache:
apalache-mc/apalache#2606
thpani added a commit that referenced this issue Jun 27, 2023
The issue we encountered before (#963) should've been fixed in Apalache:
apalache-mc/apalache#2606
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants