alessandro-montanari / tuprolog

Automatically exported from code.google.com/p/tuprolog
0 stars 0 forks source link

Sub-solve fails when all distinct vars named X_eNNN #19

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Original report from 2011, updated in 2013.

When the engine is called to solve a goal where variables are X_eNNN 
(typically: results from previous inference), the cloning of these variables 
fails and create similar vars, and link all originals to the same.
Serious impact - nothing works any longer when this issue hits.
See attached fail for partial description. Ask if more needed.

Update 2013:
Hello,
Here attached is a TestCase to reproduce at least part of the problem. I'm 
working to recreate the complete case I had a while ago. Note: I'm using and 
old version of tuProlog 2.4.1beta, maybe this is now fixed.
Run this TestCase and see the standard output logs. To summarize, I invoke a 
structure mapper predicate (transform/2) with 2 free vars A and B. After 
transformation, the structure holds free vars named X_eNNN (2 distinct numbers, 
I assume still 2 distinct vars). Then I call a Java-implemented predicate and I 
further call the engine's solver to do some more inference. At this "inner" 
level, things start to go wrong, my X_eNNN vars refer to the same variable X...
s(A, B), transform(S, T), java_prim(T).
Inner goal: fact(s(X_e34,X_e35))
Inner solution: [X / 1, X / 1]
Inner solution: [X / 1, X / 2] !!!!!!
Inner solution: [X / 2, X / 1] !!!!!!
Inner solution: [X / 2, X / 2]

Original issue reported on code.google.com by enrico.d...@gmail.com on 6 Dec 2013 at 1:25

Attachments:

GoogleCodeExporter commented 9 years ago
Hello Roberta,

Thank you for your so prompt feedback!
That's correct.  I've checked it once more using the debugger (see session 
below) and could even notice that a goal looking like :
    fact(s(X_e0,X_e0))
has actually the 2 variables being different memory locations, different 
timestamps, therefore different vars.

I've set a breakpoint in method:
    alice.tuprolog.Engine.prepareGoal()
at line:
    this.goalVars = goalVars.values();

Executed the TestCase, the breakpoint will be hit two times.
On the second time, you yill notice that 
        startGoal = fact(s(X_e0,X_e0))
(which _looks_ dubious)

This is caused by:
        goalVars = {X_e34=X_e0, X_e35=X_e0}

This is in line with the text file comments originally submitted with the issue.

But apparently it's only a display problem, not a real source of errors.
In my case, in my java predicate, I was traversing the Struct and had issue 
identifying variables by their names.
I think that's the reason for reporting the "bug".

You may close it now.

Best regards,
Laurent

-----Original Message-----
From: Roberta Calegari [mailto:roberta.calegari@unibo.it] 
Sent: 2013-07-31 17:58
To: Laurent TETTONI; Enrico Denti
Subject: Re: RE : Your bug report #57 of December 2011..

Hi Laurent,
first of all, thank you very much for all your indications.

We were able to reproduce the strange behaviour, and explored the issue in 
depth.

It turned out that the problem is not a real bug, but an "apparent" one in the 
sense that the answer is not wrong per se, but the representation of the answer 
provided by tuProlog is misleading.
I attach your example commented with all details, together with a possible 
workaround. Just let me know if something is not clear enough.

More generally speaking, we are considering a redesign/reengineering of some 2p 
internals, and one of the major poins will certainly be the handling of 
variable (re)naming: currently, tuProlog names a new variable, internally, 
after the name of the variable of the clause it is using, and this is why you 
got so many "X" -- which however do not refer to the same variable. In the 
redesign, we mean to change this behaviour, having variables named after their 
name in the original user goal. In you example, this approach would lead to 
variables names like A_e42, B_e43, much clearer than X_e234 and X_e545.

Again, thanks a lot for your help and your time!
Roberta (& Enrico)
------------

/* To avoid the problem the query must be split in two queries, so that the 
inner solution is retrived
     * only when the tuProlog Finite State Machine has reached its final state, where it actually links
     * variables to their "real" names: accessing those variables before tuProlog can do so returns the
     * variables internal (=misleading) names.
     * In the refactored example below, the first query computes T, then another query solves
     * java_prim(T) -- but only after the term T has been correctly linked and represented.

    queryPhrase ="transform(s(A, B), T).";
    Parser p = new Parser(queryPhrase);
    Term queryTerm = p.nextTerm(true);
    SolveInfo solveInfo = prologEngine.solve(queryTerm);
    reportSolutions(prologEngine, "Outer solution: ", solveInfo);
    try{
         System.out.println(solveInfo.getTerm("T"));
         Struct s = new Struct("java_prim", solveInfo.getTerm("T"));
         SolveInfo solveInfo2 = prologEngine.solve(s);
         reportSolutions(prologEngine, "Outer solution 2: ", solveInfo2);
    }
    catch (Exception e){}

     /* This new code gives the following output:
     * Outer solution: [A, B, T / s(A,B)]
          Inner goal: fact(s(A_e0,B_e0))
          Inner solution: [A / 1, B / 1]
          Inner solution: [A / 1, B / 2]
          Inner solution: [A / 2, B / 1]
          Inner solution: [A / 2, B / 2]
          Outer solution 2: [A, B]
     *
     * The problem is the internal variable representation in tuProlog: as you guessed, both variables
     * inside are named X_nnn, but they are not the same variable:
unfortunately, when printing them out,
     * tuProlog cuts the "_nnn" part away, as this is normally handled internally and should not be of
     * interest to the user. In your example, when T is still being computed (T=s(X_e42,X_e43)), the
     * inner query returns
     *   Inner solution: [X / 1, X / 1]
     *   Inner solution: [X / 1, X / 2]
     *   Inner solution: [X / 2, X / 1]
     *   Inner solution: [X / 2, X / 2]
     * because in the 2p internal representation these "X" refer to two different variables,namely
     * X_e42 (that is, =A) and X_e43 (that is, B). The fact that they are not the same variable turns
     * out clear when the engine completes the first query, unifying the first X with A and the second
     * X with B.
     *
     * Summing up, in the current tuProlog architecture it is not possible to call an inner query and
     * inspect its variables before the outer query has completed, otherwise "strange" representations
     * of result appear, that are correct from the tuProlog viewpoint but "absurd" to the user's eyes.

Original comment by roberta....@gmail.com on 29 May 2014 at 10:27