0

This is the question

enter image description here

find value A.


inverse([],[]).

inverse([H|T],D) :-
  inverse(T,Z),
  append(Z,[H],D).

append([],X,X).

append([X|L],M,[X|N]) :-
  append(L,M,N).

This is the answer:

enter image description here

Plese help me to understand this!

Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • Do you understand how unification works? – Guy Coder Dec 17 '18 at 15:29
  • Sorry, I will be careful next time. – Mai Hoàng Nam Dec 17 '18 at 15:53
  • I don't know how to translate an image to code. – Mai Hoàng Nam Dec 17 '18 at 15:55
  • 1
    Just my first time doing an exersice about prolog and I didn't know where to start. – Mai Hoàng Nam Dec 17 '18 at 15:56
  • `I don't know how to translate an image to code`. Don't worry about that. You are new to Prolog and new to StackOverflow and as I noted in my answer the source code you have is not standard. – Guy Coder Dec 17 '18 at 15:57
  • Please check ["Which site?"](https://meta.stackexchange.com/questions/129598/which-computer-science-programming-stack-exchange-do-i-post-in) for general issues. Stack Overflow is not a tutorial or help site. – Prune Dec 17 '18 at 21:57
  • @Prune The question is not really off topic for a Prolog question here. What makes this one harder than most is that as the OP notes, the professor is old and it clearly shows in the example code. I have only seen Prolog done like this in the 70s and 80s or in books that straddle math and logic. The formatting of the trace is also one that I don't use. – Guy Coder Dec 17 '18 at 22:36
  • I don't know how to translate an image to code. Ok OK I know that's I shouldn't ask questions for my self in StackOverflow, I won't do it anymore. Guy Coder you help me so much but I think we shouldn't end this topic here for the community. – Mai Hoàng Nam Dec 18 '18 at 02:08
  • 'Stack Overflow is not a tutorial or help site' I'm really sorry about that. – Mai Hoàng Nam Dec 18 '18 at 02:08
  • to translate an image to code you could just type by hand the code which you see in the image. If you see some non-ASCII symbols there, you can invent something else to use instead of that symbol, and explain this in the comments. :) – Will Ness Dec 18 '18 at 06:35
  • 1
    @WillNess FYI. When I need to insert special characters into a document and the editor doesn't support a rich character search option, I use [Shapecatcher](http://shapecatcher.com/). With it you draw the character and then it gives you back the character, a name and even the Unicode code for it. Once you use it a few times you never fear using special charters again, only bad editors. The nice part is once you find the character you want often it is just a cut and paste to get it into your document. – Guy Coder Dec 18 '18 at 21:52

1 Answers1

1

The images of the Prolog code you posted show some unusual or very old Prolog, in particular for list the use of [H:T] is now done as [H|T], notice the change from : to |, and <= is more common as :-.

To understand the Prolog code it is easier to start from the bottom up. I will not cover unification or backward chaining in this as going to that level of detail would require a chapters worth here.

The first predicate to understand is append/3. Normally you never see the code for append given as it is a built-in predicate, but here it is given.

Append/3 has three parameters which are all list. The first two are appended together to form the third.

?- append_01([],[],R).
R = [].

?- append_01([a],[],R).
R = [a].

?- append_01([],[a],R).
R = [a].

?- append_01([a],[b],R).
R = [a, b].

but Prolog predicates can have other modes of operation which can bind values to what would be considered input parameters in other programming languages, e.g.

?- append(X,[b],[a,b]).
X = [a] ;
false.

?- append_01([a],Y,[a,b]).
Y = [b].

?- append(X,Y,[a,b]).
X = []    , Y = [a, b] ;
X = [a]   , Y = [b]    ;
X = [a, b], Y = []     ;
false.

or can just be used to verify the arguments

?- append([a],[b],[a,b]).
true.

?- append([a],[c],[a,b]).
false.

Next is the predicate inverse/2 which is more commonly known in Prolog as reverse/2, and again the source code is given here.

This simply takes one list and reverses it, e.g.

?- inverse([],X).
X = [].

?- inverse([a],X).
X = [a].

?- inverse([a,b],X).
X = [b, a].

however this version of the source code does not do well in other modes, e.g.

?- inverse(X,[]).
X = [] ;

Action (h for help) ? abort
% Execution Aborted

but that doesn't matter to answer the question.


The next part of what you posted is a trace of the execution of the query

?- inverse([[1,2,3],[5,4]],A).

In order to use the trace on your code, since there is a built-in predicate for append/3 I had to rename the predicate. Here is the code I used.

inverse([],[]).

inverse([H|T],D) :-
  inverse(T,Z),
  append_01(Z,[H],D).

append_01([],X,X).

append_01([X|L],M,[X|N]) :-
  append_01(L,M,N).

Using SWI-Prolog

set up the trace

?- visible(+all),leash(-all). 

start the trace

trace.

execute the query

[trace] ?- inverse([[1,2,3],[5,4]],A).

returns

   Call: (8) inverse([[1, 2, 3], [5, 4]], _7548)
   Unify: (8) inverse([[1, 2, 3], [5, 4]], _7548)
   Call: (9) inverse([[5, 4]], _7794)
   Unify: (9) inverse([[5, 4]], _7794)
   Call: (10) inverse([], _7794)
   Unify: (10) inverse([], [])
   Exit: (10) inverse([], [])
   Call: (10) append_01([], [[5, 4]], _7802)
   Unify: (10) append_01([], [[5, 4]], [[5, 4]])
   Exit: (10) append_01([], [[5, 4]], [[5, 4]])
   Exit: (9) inverse([[5, 4]], [[5, 4]])
   Call: (9) append_01([[5, 4]], [[1, 2, 3]], _7548)
   Unify: (9) append_01([[5, 4]], [[1, 2, 3]], [[5, 4]|_7792])
   Call: (10) append_01([], [[1, 2, 3]], _7792)
   Unify: (10) append_01([], [[1, 2, 3]], [[1, 2, 3]])
   Exit: (10) append_01([], [[1, 2, 3]], [[1, 2, 3]])
   Exit: (9) append_01([[5, 4]], [[1, 2, 3]], [[5, 4], [1, 2, 3]])
   Exit: (8) inverse([[1, 2, 3], [5, 4]], [[5, 4], [1, 2, 3]])
A = [[5, 4], [1, 2, 3]].

I will not explain the details of a trace as other SO Q&A do that.


The trace you posted also has more detail than generated by using the trace, e.g. the bindings (θ).

To see the bindings use gtrace/0

?- gtrace.
% The graphical front-end will be used for subsequent tracing
true.

then execute the query

[trace]?- inverse([[1,2,3],[5,4]],A).

and press space bar to single step. You will have to experiment with it to learn how it works; AFAIK there is no posted documentation on how to use it.

enter image description here


From OP comment:

There are some replacements from letters to numbers and theta symbol that make me hard to understand.

While the bindings (θ) are more specific to logic languages, the numbers are also seen in stack based functional languages, see De Bruijn index. Also instead of writing the bindings using vertical line separator (---) , I prefer to use (↦) as seen here.

The lines 1 -4 are just the source code stated again.

Normally with a trace the goal is to covey a tree structure of the executions (calls) but with these lines unless you know how Prolog works it is really hard to see that there is a tree structure.

The lines with the over-bars are meant to help understand what is going on, but if you just follow the flow of the executions (calls) then you may find as I do that they just cause confusion and can be ignored.

At you noted in the comments the Res(_,_) are referring to previous lines in the trace. So Res(5,2) on line 6 can be read as Line 6 is the result of a call from line 5 and which then calls line 2.

The unifications or bindings (θ) are show as as sets. I am not exactly sure what the super and sub script numbers represent but they are clearly linked to De Bruijn indexes. You will have to ask your teacher to explain the super and sub scripts.

After trying several times to explain this with just text, I finally resorted to using Microsoft Visio to do it as graphical tree which was much easier, faster and more accurate.

Even though it was not needed, I added the line trace output from SWI-Prolog into the image and then placed only the call lines in the corresponding places in the tree so that if you want to correlate the two you can. I did it for myself as a check to make sure it was correct.

I would not be surprised if there are a few typo mistakes as I had to redo parts of it many times to make it easy to comprehend. Hopefully I achieved that goal.

enter image description here

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • My teacher asked to me to present my exercise like the second image I posted. And there're some steps that I don't understand. – Mai Hoàng Nam Dec 17 '18 at 16:21
  • @MaiHoàngNam Normally I would have you ask another question, as at StackOverflow you ask a question and get an answer. These are not suppose to turn into discussions. I will help you understand one or two specific things, but if you ask to many I will require you to start a new post (question). – Guy Coder Dec 17 '18 at 16:24
  • @MaiHoàngNam Which specific step do you not understand? – Guy Coder Dec 17 '18 at 16:25
  • There are some replacements from letters to numbers and theta symbol that make me hard to understand what my teacher meant. – Mai Hoàng Nam Dec 17 '18 at 16:25
  • 1
    He's an old teacher and he teaches us to do homework with the old method. – Mai Hoàng Nam Dec 17 '18 at 16:26
  • I can understand what you explained for me but I can't send it like a homework to my teacher. =)) – Mai Hoàng Nam Dec 17 '18 at 16:28
  • `There are some replacements from letters to numbers and theta symbol that make me hard to understand` I will add to may answer. It will take a few minutes. – Guy Coder Dec 17 '18 at 16:28
  • Yeah, I think u are a Prolog professor xD and you are so friendly with a new member. – Mai Hoàng Nam Dec 17 '18 at 16:31
  • 1
    My teacher call ------inverse is negative of inverse, RES(5, 2) is represented for connecting step 5 and 2. – Mai Hoàng Nam Dec 17 '18 at 17:00
  • I'm talking about the inverse with the line on the head that you captured. – Mai Hoàng Nam Dec 17 '18 at 17:04
  • I think your answer is enough for me. I just want to know the basic of Prolog for the exam and thank you for helping me to understand that. – Mai Hoàng Nam Dec 17 '18 at 17:59
  • 1
    My teacher told us to understand what a computer does with Prolog not how the program running. – Mai Hoàng Nam Dec 17 '18 at 18:01
  • @MaiHoàngNam I am done with my answer. I hope I never have to look at a trace done in this format again. – Guy Coder Dec 18 '18 at 21:28
  • 1
    I understood how Prolog works, but my math teacher forced us to solve it with mathematical terminology. Fortunately, I was able to solve it with the resolution of the "negative proposition" (my teacher called it that). My teacher wanted students to understand how the machine works with Prolog, but in the form of negative proof (down to top), it is slightly opposite of what you explained to me. XD – Mai Hoàng Nam Dec 26 '18 at 03:16