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

SI-7020 Determinism for pattern matcher warnings #2826

Merged
merged 1 commit into from
Aug 13, 2013

Conversation

retronym
Copy link
Member

Use LinkedHashSet for the DPLL algorithm for determistic
counter example generation.

Before, the test compiled with:

[info] v2.10.2 => /Users/jason/usr/scala-v2.10.2-0-g60d462e
test/files/neg/t7020.scala:3: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:10: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:17: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:24: warning: match may not be exhaustive.
It would fail on the following input: List(_, _)
  List(5) match {
      ^

Review by @adriaanm, /cc @gbasler

@ghost ghost assigned adriaanm Aug 13, 2013
@retronym
Copy link
Member Author

A few more runs before the patch:

icket/7020-2.10.x ~/code/scala2 scalac-hash v2.10.2 test/files/neg/t7020.scala
[info] v2.10.2 => /Users/jason/usr/scala-v2.10.2-0-g60d462e
test/files/neg/t7020.scala:3: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:10: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:17: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7)), _), List((x: Int forSome x not in (1, 2, 4, 5, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:24: warning: match may not be exhaustive.
It would fail on the following input: List(_, _)
  List(5) match {
      ^
four warnings found
ticket/7020-2.10.x ~/code/scala2 scalac-hash v2.10.2 test/files/neg/t7020.scala
[info] v2.10.2 => /Users/jason/usr/scala-v2.10.2-0-g60d462e
test/files/neg/t7020.scala:3: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List((x: Int forSome x not in (1, 2, 5, 6)), _), List((x: Int forSome x not in (2, 4, 5, 6)), _), List((x: Int forSome x not in (2, 5, 6)), _), List((x: Int forSome x not in (2, 5, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:10: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:17: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2)), _), List((x: Int forSome x not in (2, 4)), _), List((x: Int forSome x not in (2, 5)), _), List((x: Int forSome x not in (2, 6)), _), List((x: Int forSome x not in (2, 7)), _), List((x: Int forSome x not in 2), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
test/files/neg/t7020.scala:24: warning: match may not be exhaustive.
It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5)), _), List((x: Int forSome x not in (1, 2, 4, 5, 6)), _), List((x: Int forSome x not in (1, 2, 4, 5, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
  List(5) match {
      ^
four warnings found

// appearing only in either positive/negative positions
val pures = (pos ++ neg) -- impures
val pures: mutable.LinkedHashSet[Sym] = (pos ++ neg) -- impures

if (pures nonEmpty) {
val pureSym = pures.head
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LinkedHashSet affects mainly what literal is choosen here (aka branching literal). I'm wondering if there's a good heuristic on what literal to choose. Also Sat4J might have a different heuristic...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to push the checkfile update. At least for this case, picking the first in the set gives the shortest error messages, but I don't know why that is or if it holds in general.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more explanation:
If the pattern match is not exhaustive, the DPLL procedure provides a counter example. There could be more than one and it just reports the first one it finds, so depending on what direction in the search it took, the counter example will look different. And the choice of the literal determines exactly that.

I'm not sure now, if it searches for all models or just for one in this case.
Another possibility would be to always search for all models, and then sort them according to some preference.

Use LinkedHashSet for the DPLL algorithm for determistic
counter example generation.

Before, the test compiled with:

    [info] v2.10.2 => /Users/jason/usr/scala-v2.10.2-0-g60d462e
    test/files/neg/t7020.scala:3: warning: match may not be exhaustive.
    It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
      List(5) match {
          ^
    test/files/neg/t7020.scala:10: warning: match may not be exhaustive.
    It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 5, 6, 7))), List(_, _)
      List(5) match {
          ^
    test/files/neg/t7020.scala:17: warning: match may not be exhaustive.
    It would fail on the following inputs: List((x: Int forSome x not in (1, 2, 4, 6, 7)), _), List(1, _), List(2, _), List(4, _), List(5, _), List(6, _), List(7, _), List(??, _)
      List(5) match {
          ^
    test/files/neg/t7020.scala:24: warning: match may not be exhaustive.
    It would fail on the following input: List(_, _)
      List(5) match {
          ^
@JamesIry
Copy link
Contributor

With RC1 approaching we need to decide whether this is in 2.10.3 or deferred to 2.10.4

@adriaanm do you want to review?

@adriaanm
Copy link
Contributor

Happy to review. If this resolves the issue in the Tseitin PR, I think they both should go in.

@adriaanm
Copy link
Contributor

LGTM -- it's a good point that we'll need to fix this again when switching to sat4j in 2.11, though.

adriaanm added a commit that referenced this pull request Aug 13, 2013
SI-7020 Determinism for pattern matcher warnings
@adriaanm adriaanm merged commit ebb0339 into scala:2.10.x Aug 13, 2013
@retronym
Copy link
Member Author

I should mention that there are quite a few more non-linked maps and sets in the pattern matcher. I just changed the ones that triggered this non-determinism. I suppose we don't depend on iteration order for the others, or we haven't found tests that show that yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants