1

If I have three atoms X, Y and Z where

X = 1
Y = 2
Z = +

How do I put them together so that X Z Y = 3?

Edit: Using ThanosQR's univ solution, I have modified my code as follows:

% Parse list
parse_list([stop|_], _) :- !.   % stop predicate if element is "stop"
parse_list([X, Y|Z]) :- % go through the list line by line
    number(X, Number_1),
    number(Z, Number_2),
    operation(Y, Operation),
    Line =.. [Operation, Number_1, Number_2], 
    Result is Line,
    write(Result).

number(one, 1). 
operation(plus, +). % etc... etc... 

I get false... Not sure why..

Facundo Casco
  • 10,065
  • 8
  • 42
  • 63
chutsu
  • 13,612
  • 19
  • 65
  • 86
  • Please state your Prolog system (probably SWI) and the actual failing query. – false Nov 29 '11 at 22:39
  • You get false since the head of the second clause is incorrect. It surely should be `parse_list([X,Y,Z|Rest]) :-`. Also, the second clause has no recursion after the last write: `parse_list([Rest]).` That seems to be missing. Finally, the head of the first clause has two arguments, the head of the second has one. This is inconsistent! – twinterer Nov 30 '11 at 12:35
  • Thanks, I'll try your suggestions. Thats a typo in the head of the first clause, it should be one argument. – chutsu Nov 30 '11 at 13:08

2 Answers2

3

First, a general remark: If you mix impure predicates like write/1 into otherwise pure code, you end up with a very hard to debug program. So first try to identify the relation you are after. Maybe it is something like tokens_meaning(Tokens,Meaning) where Tokens it the list of tokens, as above, and Meaning is some expression to evaluate.

For identifying one problem, it suffices to look at the following fragment:

...
parse_list([X, Y|Z]) :- % go through the list line by line
    number(X, Number_1),
    number(Z, Number_2),
    ...

number(one, 1).

So what you expect here is that you have a term of the following form:

[one, Y|one]

That is, the Z should be the rest of the list. So either [] or something longer like [_] but not one.

But in your case you expect a name like one. That certainly does not make sense. Probably you meant:

parse_list([X, Y, Z| Whatever]) :-
false
  • 10,264
  • 13
  • 101
  • 209
  • The reason I'm doing: parse_list([X, Y|Z]) is because I'm assuming the list will always have three elements [X, Y, Z]. And can you elaborate more on the pure code and unpure, am not too sure I understand what you mean by that. – chutsu Nov 30 '11 at 10:47
  • 1
    @chutsu: It is still difficult for me to figure out what you actually want. `parse_list([X, Y, Z]) :- ...` might be what you want. But there are still too many things open. Otherwise, please [refer to this thread](http://stackoverflow.com/q/8305811/772868) for how a program with I/O and pure Prolog intertwined might become a cleaner program. – false Dec 01 '11 at 13:32
  • Yes, indeed. Turns out I failed to define one of the numbers in number/2 that is what caused the fail. Sorry for the headache I have caused you. And thanks very much for helping me on this matter. – chutsu Dec 01 '11 at 18:20
1

try the univ operator:

R =.. [Z,X,Y], A is R.
Thanos Tintinidis
  • 5,828
  • 1
  • 20
  • 31