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

CLP(ℤ): Attribute is sometimes unexpectedly not present #248

Closed
triska opened this issue Dec 1, 2019 · 6 comments
Closed

CLP(ℤ): Attribute is sometimes unexpectedly not present #248

triska opened this issue Dec 1, 2019 · 6 comments

Comments

@triska
Copy link
Contributor

triska commented Dec 1, 2019

With clpz7.pl from https://www.metalevel.at/clpz/scryer/clpz7.pl, I get:

?- X #= Y+Y+Y, X = 3.
false.

Expected result: Success.

The reason for this seems to be that in insert_queue//2 (defined in clpz7.pl), the goal get_atts/2 fails on the third invocation of insert_queue//2 in the example above:

insert_queue(Element, Which) -->
        state(Queue),
        { arg(Which, Queue, Arg),
          get_atts(Arg, queue(Head0,Tail0)),
          (   Head0 == [] ->
              Head = [Element|Tail]
          ;   Head = Head0,
              Tail0 = [Element|Tail]
          ),
          put_atts(Arg, +queue(Head,Tail)) }.

However, the attribute queue/2 is expected to be present on the third invocation. There is nothing that would remove the attribute between the second and third invocation of insert_queue//2 in this example. For reference,Head0 ought to be [], and Tail0 is expected to be a free variable on the third invocation of insert_queue//2.

I will try to find a simpler example that exhibits this issue.

@mthom
Copy link
Owner

mthom commented Dec 2, 2019

I inserted some print statements around the code where the queue attribute is handled, and I saw that it was deleted from the third variable, which is why insert_queue code fails at the third invocation. clear_queue is where it's deleted.

@triska
Copy link
Contributor Author

triska commented Dec 2, 2019

Yes, it is true that clear_queue/1 deletes attributes. However, it also reinstates them, and in this concrete case, after clear_queue/1 has finished, the above get_atts/2 goal succeeds once more (for the second time in total), and only on its third invocation, the above get_atts/2 goal fails. Between the second and the third time, clear_queue/1 is not invoked.

So we have, in total, the following sequence:

  1. the above get_atts/2 succeeds
  2. clear_queue/1 removes attributes and also reinstates some
  3. the above get_atts/2 succeeds
  4. the above get_atts/2 fails unexpectedly.

On a general note, while I try to construct a simpler test case, please focus on #95, since partial strings are the more fundamental feature that will make Scryer Prolog truly unique as soon as it is available, and which will also be automatically tested too when we then discuss other issues.

Meanwhile, I am continuing to post CLP(ℤ) related issues in case you need a short creative pause, and also for later reference.

@mthom
Copy link
Owner

mthom commented Dec 2, 2019

Yes, I think I'll take a break from working on CLP(ℤ), and focus on partial strings.

@mthom
Copy link
Owner

mthom commented Dec 4, 2019

I did a little more digging last night, and found that the queue/2 attribute of the variable had an empty list as the first argument. This caused the predicate responsible for reinstating the predicate to fail. I think it was this:

queue_get_arg_(Queue, Which, Element) :-
        arg(Which, Queue, Arg),
        get_atts(Arg, +queue([Element|Elements],Tail)),
        (   var(Elements) ->
            put_atts(Arg, +queue([],_))
        ;   put_atts(Arg, +queue(Elements,Tail))
        ).

@triska
Copy link
Contributor Author

triska commented Dec 4, 2019

Please note that between (3) and (4) of the steps outlined above, the attribute somehow vanishes (i.e., (4) fails unexpectedly), even though there is nothing between these steps that would remove the attribute.

The value of the concrete arguments of queue/2 is immaterial, since get_atts/2 asks for the most general case (queue(Head0,Tail0), where both Head0 and Tail0 are free variables), and that should always succeed as long as an attribute of this form is present at all.

So, we have that (3) succeeds, and (4) fails even though it is exactly the same goal, which we expect to succeed as long as a queue/2 attribute is present.

mthom added a commit that referenced this issue Dec 5, 2019
@triska
Copy link
Contributor Author

triska commented Dec 5, 2019

This works correctly now, thank you a lot!

@triska triska closed this as completed Dec 5, 2019
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

No branches or pull requests

2 participants