usethesource / rascal

The implementation of the Rascal meta-programming language (including interpreter, type checker, parser generator, compiler and JVM based run-time system)
http://www.rascal-mpl.org
Other
408 stars 77 forks source link

Incorrect result in nested list matching with backtracking #1453

Open PaulKlint opened 4 years ago

PaulKlint commented 4 years ago

Describe the bug

Bug in nested list matching with backtracking

To Reproduce

value main()
    = [1, [*int _, int N, *int _], N] := [1, [10,20], 20];

Expected behavior true but result is false

Desktop (please complete the following information):

The Rascal MetaProgramming Language 0.19.3.202009261610 (unstable)

jurgenvinju commented 4 years ago

Note to self; have to try an surround with an if or for to see if that makes a difference. Could be that the "expression without conditional context" fails to trigger the backtracking behavior

dvitel commented 2 years ago

Have same issue

rascal>if ([p1, p2] := [[0,0],[7,0]]) println("matched  <p1> and <p2>"); else println("not matched");
not matched

Same bug I observed in matching in function declaration for lists restructuring:

...
value reduceList([[p2, [p3, [[l, r], s4]]], s1]) = reduceList([[p2, [add(p3, l), [0, add(r, s4)]]], s1]);
value reduceList([[p2, [p3, [p4, [l, r]]]], s1]) = reduceList([[p2, [p3, [add(p4, l), 0]]], add(r, s1)]);
...

In my case replacing lists with tuples works.

jurgenvinju commented 2 years ago

hmmm.. this is really annoying. Thanks for reporting! Have you tried with adding types to the variables? Sometimes that helps.

rascal>if ([list[int] p1, list[int] p2] := [[0,0],[7,0]]) println("matched  <p1> and <p2>"); else println("not matched");
matched  [0,0] and [7,0]
ok
jurgenvinju commented 2 years ago

Mmmm... in my version this also works:

rascal>if ([p1, p2] := [[0,0],[7,0]]) println("matched  <p1> and <p2>"); else println("not matched");
matched  [0,0] and [7,0]
ok

@dvitel there is an (annoying) feature of Rascal that when matching a previously bound variable it checks for equality rather than binding it again. We are planning to remove this feature, and add an explicit matching combinator for equality checking. Anyway, this could also be the cause of your match failing. Could you check your example in a fresh terminal?

dvitel commented 2 years ago

It works, my mistake. I forgot this Rascal behavior, p1 and/or p2 were just bound before I applied pattern. It makes sense why pattern did not match.

jurgenvinju commented 2 years ago

No problem; I've made that mistakes many many times myself. That's why we think we have to fix the language design on that point :-)