3

Background

A list of integer coefficients can be used to represent a polynomial (in X). For example, 1 + 3x + 3x^2 + 2x^3 is represented by [1,3,3,2].

Let P be one of these lists.

I need to write axioms that take these coefficients and do different things with them.

Example: axioms for a relation eval(P,A,R) where R is the result of evaluating the polynomial represented by P at X = A (expect P and A to be fully instantiated). For example, eval([3,1,2],3,R) produces R=24. (This is because 3(3)^0 + 1(3)^1 + 2(3)^2 = 3 + 3 + 18 = 24).

This Prolog tutorial discusses searching a list recursively: "It sees if something is the first item in the list. If it is, we succeed. If it is not, then we throw away the first item in the list and look at the rest".

on(Item,[Item|Rest]).  

on(Item,[DisregardHead|Tail]):-

      on(Item,Tail).

Question

How does this code throw away the first item in the list?

The question then becomes, once I've found it, how do I use it to calculate as described above?

jessicaraygun
  • 315
  • 1
  • 4
  • 15
  • Isn't it obvious how `DisregardHead` is thrown away? It is on the left side of `:-` but not on the right. – Janus Troelsen Feb 24 '13 at 00:48
  • 1
    @JanusTroelsen: Nobody was born with intrinsic knowledge of Prolog operations, nor even Prolog itself. What might be obvious to you might not be obvious to someone who is new to a programming language, or programming in general. – Dave Jarvis Feb 24 '13 at 00:53
  • @DaveJarvis: It was no snark, it was a genuine question. The question was not about the `:-` operator. – Janus Troelsen Feb 24 '13 at 00:55
  • I thought that :- meant "if" or "implies". Is that not the case? – jessicaraygun Feb 24 '13 at 00:57
  • 1
    @Jessicat close, but the opposite: `A :- B` means `if B then A`. In the second predicate, `if the item is on the tail of the list, then the item is on the list`. – mgibsonbr Feb 24 '13 at 01:01
  • @mgibsonbr I have found this [resource](http://cs.union.edu/~striegnk/learn-prolog-now/html/node5.html#subsec.l1.kb3) that seems to say the opposite: given playsAirGuitar(vincent):- listensToMusic(vincent), happy(vincent). ``Vincent plays air guitar if he listens to music and he is happy''. Is that just another way of looking at it? – jessicaraygun Feb 25 '13 at 17:35
  • @Jessicat Actually we're both saying the same thing. `A if B and C` is equivalent in natural language to `if B and C then A`. In both cases, `A` is the **consequent** and `B and C` is the **antecedent**. – mgibsonbr Feb 25 '13 at 19:31

2 Answers2

3

How does this code throw away the first item in the list?

By calling on recursivelly on the list's tail, you're ignoring the first element. And since you won't use it, you should call it _ instead of DisregardHead (some compilers will warn you of "singleton variable").

once I've found it, how do I use it to calculate as described above?

Well, on is supposed to return multiple results - one for each match - while your goal is to have a single result that takes the whole list into account. So you shouldn't disregard the first element, but incorporate it in the results. Example:

my_pred([],0).
my_pred([Item|Tail],Result) :-
    my_pred(Tail,IntermResult),
    combine(Item,IntermResult,Result). % Ex.: Result is Item + IntermResult

I haven't given a complete code since it appears you're still learning, but can do if that's what you want. This is also a very simple example, and not optimized (i.e. no tail recursion).

Additional hint: if you express your polinomial this way, it should become clear how a recursive calculation could be done:

1 + x * (3 + x * (3 + x * (2 + x * 0)))
mgibsonbr
  • 21,755
  • 7
  • 70
  • 112
  • Do I need to instantiate combine somewhere? Is that what you meant by incomplete code? – jessicaraygun Feb 24 '13 at 01:35
  • I used `combine` to represent an arbitrary operation (or operations). In principle you could implement it that way, but you can also replace it i.e. by the statement in the comments and it will be fine (in this case, `my_pred` will calculate the sum of the list). Of course, to do what you want you'd need to use a different statement, as well as an additional parameter (the `x` in the polynomial). – mgibsonbr Feb 24 '13 at 02:29
2

I made a 90 sec video to show how you can use SWI-Prolog's guitracer to intuitively understand simple Prolog programs. On Ubuntu/Debian just do sudo apt-get install swi-prolog and you can try out the debugger yourself using the commands in the video (which are swipl, [filename] (load file), guitracer., trace. and then the query).

Using SWI-Prolog's guitracer

Right click the image and choose "View Image" (Firefox) if the text is unreadable.

Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
  • 1
    @JanusTroelsen this is really useful info, but... it's not an answer to this question (in fact, it's only related to the question in the sense that you used the OP code as example). However, if you posted it somewhere more relevant (as you may know, you can [ask and answer your own question](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/), as long as it's on topic in this site and it's not a duplicate) I'd gladly upvote it (both the answer AND the question). (*Edit:* check [this question](http://stackoverflow.com/q/11355151/520779) for instance) – mgibsonbr Feb 24 '13 at 02:44