Related
A function to add one and one:
(defn one-plus-one [] (list + 1 1))
when called returns:
(#object[clojure.core$_PLUS_ 0x47fa7bd5 "clojure.core$_PLUS_#47fa7bd5"] 1 1)
The same function body wrapped in a macro:
(defmacro one-plus-one [] (list + 1 1))
when called returns:
2
Why does Clojure expect macros to return expressions that can be evaluated?
Edit
The answers to the possible duplicate question tells how a macro is different from a function. But does not answer the why. Metaphorically, I know that an object left from an altitude drops vertically to hit the ground. My question is why does it drop vertically?
Let's just start with one thing many people know so well they forget to think about it explicitly when explaining macros, which causes others to be confused when learning to think about macros:
-----------> macros are functions <-------------
They are very often used to take lists of things that look like code, and are very often expected to return lists that can actually be run as code.
The difference between a macro and a function is not what it does (fundamentally), but when it does it. macros run while the code is "loading" and the value they return is run when the program runs.
when you write it as a macro it does two steps:
run the function to produce a list
run that returned list as code to produce a value
when you write it as a function it does one step:
run the function to produce a list
Then it stops.
The return value is diferent because the macro version takes that extra step of running the returned value as code.
code is data ... data is code ... yay lisp!
In Prolog:
I have the following function that counts the occurences of a certain element in a list:
%count(L:list,E:int,N:int) (i,i,o)
count([],_,0).
count([H|T],E,C):-H == E,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).
I tested it and it works well. But here comes the problem, I have another function that has to check if "1" occurs less than 2 times in a list.
check(L):-count(L,1,C),C<2.
Whenever I try to check the list [1,1,1,1] for example, the result I get is "true", which is wrong, and I have no idea why. I tried to make some changes, but the function just won't work.
Improve your testing habits!
When testing Prolog code don't only look at the first answer to some query and conclude "it works".
Non-determinism is central to Prolog.
Quite often, some code appears to be working correctly at first sight (when looking at the first answer) but exhibits problems (mainly wrong answers and/or non-termination) upon backtracking.
Coming back to your original question... If you want / need to preserve logical-purity, consider using the following minimal variation of the code #Ruben presented in his answer:
count([],_,0).
count([E|T],E,C) :-
count(T,E,C1),
C is C1+1.
count([H|T],E,C) :-
dif(H,E),
count(T,E,C).
dif/2 expresses syntactic term inequality in a logical sound way. For info on it look at prolog-dif!
It happens because count([1,1,1,1],1,1) is also true! In your last count it can also be matched when H does equal E. To illustrate this, use ; to make prolog look for more answers to count([1,1,1,1],1,R). You'll see what happens.
count([],_,0).
count([E|T],E,C):-
count(T,E,C1),
C is C1+1.
count([H|T],E,C):-
H \= E,
count(T,E,C).
check(L) :-
count(L,1,C),
C < 2.
?- check([1,1,1,1,1]).
false
?- check([1]).
true
second and third clauses heads match both the same sequence. As a minimal correction, I would commit the test
count([],_,0).
count([H|T],E,C):-H == E,!,count(T,E,C1),C is C1+1.
count([_|T],E,C):-count(T,E,C).
I tried to code a Prolog program that takes 2 value and calculates if the pair is valid or not. If pairs are in different lists, then pairs will be valid and they can make match. If two team in same list(group) then they can't make match which means false.
when i started the program it doesn't show anything. I thought there would be infinite searching or looping. Then tried that simple code
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
match(X):-
member(X,GroupB).
In that code i saw that program always gives me true. I typed; to SWI-Prolog it gave me another true, i typed ; again another true then i realized that the problem should be in that searching part. Thanks for all interests from now. All suggestions are welcome.
edit:
I edited the code like that to try a different style
GroupA([germany,brazil,turkey,korea]).
GroupB([china,usa,chile,italy]).
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
GroupA(L).
GroupB(M).
member(X,L).
member(X,M).
collision(X,Y):-
GroupA(L),
member(X,L),
member(Y,L).
GroupB(L),
member(X,L),
member(Y,L).
match(X,Y) :-
GroupA(L),
memberence(X),
memberence(Y),
\+collision(X,Y).
now i got:
ERROR: Undefined procedure: match/2
ERROR: However, there are definitions for:
ERROR: catch/3
although there is a match(X,Y) procedure why it gives me undefined match/2 error.
GroupA=[germany,brazil,turkey,korea].
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
member(X,GroupA).
member(X,GroupB).
collision(X,Y):-
member(X,GroupA),
member(Y,GroupA).
member(X,GroupB),
member(Y,GroupB).
match(X,Y) :-
memberence(X),
memberence(Y),
\+collision(X,Y).
a)
You have a dot that must be comma in:
collision(X,Y):-
member(X,GroupA),member(Y,GroupA).
member(X,GroupB),member(Y,GroupB).
b)
Better you do not redefine "member", it is standard.
c)
If I change dot by comma in:
collision(X,Y):-
GroupA(L),member(X,L),member(Y,L),
GroupB(L),member(X,L),member(Y,L).
this statement will fail always because there are no list "L" common to GroupA and GroupB.
d)
If we take what seems the original request "takes 2 value and calculates if the pair is valid or not. If pairs are in different lists, then pairs will be valid and they can make match. If two team in same list(group) then they can't make match which means false."
the solution seems obvious:
match(X,Y) :- groupA(A), member(X,A), groupB(B), member(Y,B).
match(Y,X) :- groupA(A), member(X,A), groupB(B), member(Y,B).
You have 2 big problems.
First, you seem to use . and , interchangeably.
Second, you fail to understand Prolog's scoping rules. Anything that isn't asserted into the prolog database is scoped to the immediate statement or the clause of the predicate of which is a part. If you want somebody to know about it, it either has to be a part of the prolog database or passed as an argument. Thus, when you say something like
GroupB = [china,usa,chile,italy].
The variable GroupB Is unified with the list [china,usa,chile,italy]. At which point, the assertion succeeds, and both the newly-bound variable and the list with which it was unified ** go out of scope** and cease to exist. Then, when you attempt to reference it later on:
GroupB=[china,usa,chile,italy].
.
.
.
match(X) :- member(X,GroupB).
The variable GroupB is unbound. Your implementation of member/2,
GroupB=[china,usa,chile,
member(X,[X|_]) .
member(X,[_|T]) :- member(X,T) .
is more than willing to act in a generative manner when given an unbound variable as its 2nd argument, generating lists of variable, successively (and infinitely) longer on backtracking.
I am trying to get a feel for Prolog programming by going through Ulle Endriss' lecture notes. When my solution to an exercise does not behave as expected, I find it difficult to give a good explanation. I think this has to do with my shaky understanding of the way Prolog evaluates expressions.
Exercise 2.6 on page 20 calls for a recursive implementation of a predicate last1 which behaves like the built-in predicate last. My attempt is as follows:
last1([_ | Rest], Last) :- last1(Rest, Last).
last1([Last], Last).
It gives the correct answer, but for lists with more than one element, I have to key in the semicolon to terminate the query. This makes last1 different from the built-in last.
?- last1([1], Last).
Last = 1.
?- last1([1, 2], Last).
Last = 2 ;
false.
If I switch the order in which I declared the rule and fact, then I need to key in the semicolon in both cases.
I think I know why Prolog thinks that last1 may have one more solution (thus the semicolon). I imagine it follows the evaluation sequence
last1([1, 2], Last).
==> last1([2], Last).
==> last1([], Last). OR Last = 2.
==> false OR Last = 2.
That seems to suggest that I should look for a way to avoid matching Rest with []. Regardless, I have no explanation why switching the order of declaration ought to have any effect at all.
Question 1: What is the correct explanation for the behavior of last1?
Question 2: How can I implement a predicate last1 which is indistinguishable from the built-in last?
Question 1:
Prolog systems are not always able to decide whether or not a clause will apply prior to executing it. The precise circumstances are implementation dependent. That is, you cannot rely on that decision in general. Systems do improve here from release to release. Consider as the simplest case:
?- X = 1 ; 1 = 2.
X = 1
; false.
A very clever Prolog could detect that 1 = 2 always fails, and thus simply answer X = 1. instead. On the other hand, such "cleverness" is very costly to implement and time is better spent for optimizing more frequent cases.
So why do Prologs show this at all? The primary reason is to avoid asking meekly for another answer, if Prolog already knows that there is no further answer. So prior to this improvement, you were prompted for another answer for all queries containing variables and got the false or "no" on each and every query with exactly one answer. This used to be so cumbersome that many programmers never asked for the next answer and thus were not alerted about unintended answers.
And the secondary reason is to keep you aware of the limitations of the implementation: If Prolog asks for another answer on this general query, this means that it still uses some space which might accumulate and eat up all your computing resources.
In your example with last1/2 you encounter such a case. And you already did something very smart, BTW: You tried to minimize the query to see the first occurrence of the unexpected behavior.
In your example query last1([1,2],X) the Prolog system does not look at the entire list [1,2] but only looks at the principal functor. So for the Prolog system the query looks the same as last1([_|_],X) when it decides which clauses to apply. This goal now fits to both clauses, and this is the reason why Prolog will remember the second clause as an alternative to try out.
But, think of it: This choice is now possible for all elements but the last! Which means that you pay some memory for each element! You can actually observe this by using a very long list. This I get on my tiny 32-bit laptop — you might need to add another zero or two on a larger system:
?- length(L,10000000), last1(L,E).
resource_error(_). % ERROR: Out of local stack
On the other hand, the predefined last/2 works smoothly:
?- length(L,10000000), last(L,E).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I|...].
In fact, it uses constant space!
There are now two ways out of this:
Try to optimize your definition. Yes, you can do this, but you need to be very smart! The definition by #back_dragon for example is incorrect. It often happens that beginners try to optimize a program when in fact they are destroying its semantics.
Ask yourself if you are actually defining the same predicate as last/2. In fact, you're not.
Question 2:
Consider:
?- last(Xs, X).
Xs = [X]
; Xs = [_A,X]
; Xs = [_A,_B,X]
; Xs = [_A,_B,_C,X]
; Xs = [_A,_B,_C,_D,X]
; ... .
and
?- last1(Xs, X).
loops.
So your definition differs in this case with SWI's definition. Exchange the order of the clauses.
?- length(L,10000000), last2(L,E).
L = [_A,_B,_C,_D,_E,_F,_G,_H,_I|...]
; false.
Again, this false! But this time, the big list works. And this time, the minimal query is:
?- last2([1],E).
E = 1
; false.
And the situation is quite similar: Again, Prolog will look at the query in the same way as last2([_|_],E) and will conclude that both clauses apply. At least, we now have constant overhead instead of linear overhead.
There are several ways to overcome this overhead in a clean fashion - but they all very much depend on the innards of an implementation.
SWI-Prolog attempts to avoid prompting for more solutions when it can determine that there are none. I think that the interpreter inspect the memory looking for some choice point left, and if it can't find any, simply state the termination. Otherwise it waits to let user choice the move.
I would attempt to make last1 deterministic in this way:
last1([_,H|Rest], Last) :- !, last1([H|Rest], Last).
last1([Last], Last).
but I don't think it's indistinguishable from last. Lurking at the source code of the library (it's simple as ?- edit(last).)
%% last(?List, ?Last)
%
% Succeeds when Last is the last element of List. This
% predicate is =semidet= if List is a list and =multi= if List is
% a partial list.
%
% #compat There is no de-facto standard for the argument order of
% last/2. Be careful when porting code or use
% append(_, [Last], List) as a portable alternative.
last([X|Xs], Last) :-
last_(Xs, X, Last).
last_([], Last, Last).
last_([X|Xs], _, Last) :-
last_(Xs, X, Last).
we can appreciate a well thought implementation.
this code would work:
last1([Last], Last).
last1([_ | Rest], Last) :- last1(Rest, Last), !.
it is because prolog things there might be more combinations but, with this symbol: !, prolog won't go back after reaching this point
For my diploma thesis I chose to implement the task of the ICFP 2004 contest.
The task--as I translated it to myself--is to write a compiler which translates a high-level ant-language into a low-level ant-assembly. In my case this means using a DSL written in Clojure (a Lisp dialect) as the high-level ant-language to produce ant-assembly.
UPDATE:
The ant-assembly has several restrictions: there are no assembly-instructions for calling functions (that is, I can't write CALL function1, param1), nor returning from functions, nor pushing return addresses onto a stack. Also, there is no stack at all (for passing parameters), nor any heap, or any kind of memory. The only thing I have is a GOTO/JUMP instruction.
Actually, the ant-assembly is for to describe the transitions of a state machine (=the ants' "brain"). For "function calls" (=state transitions) all I have is a JUMP/GOTO.
While not having anything like a stack, heap or a proper CALL instruction, I still would like to be able to call functions in the ant-assembly (by JUMPing to certain labels).
At several places I read that transforming my Clojure DSL function calls into continuation-passing style (CPS) I can avoid using the stack[1], and I can translate my ant-assembly function calls into plain JUMPs (or GOTOs). Which is exactly what I need, because in the ant-assembly I have no stack at all, only a GOTO instruction.
My problem is that after an ant-assembly function has finished, I have no way to tell the interpreter (which interprets the ant-assembly instructions) where to continue. Maybe an example helps:
The high-level Clojure DSL:
(defn search-for-food [cont]
(sense-food-here? ; a conditional w/ 2 branches
(pickup-food ; true branch, food was found
(go-home ; ***
(drop-food
(search-for-food cont))))
(move ; false branch, continue searching
(search-for-food cont))))
(defn run-away-from-enemy [cont]
(sense-enemy-here? ; a conditional w/ 2 branches
(go-home ; ***
(call-help-from-others cont))
(search-for-food cont)))
(defn go-home [cont]
(turn-backwards
; don't bother that this "while" is not in CPS now
(while (not (sense-home-here?))
(move)))
(cont))
The ant-assembly I'd like to produce from the go-home function is:
FUNCTION-GO-HOME:
turn left nextline
turn left nextline
turn left nextline ; now we turned backwards
SENSE-HOME:
sense here home WE-ARE-AT-HOME CONTINUE-MOVING
CONTINUE-MOVING:
move SENSE-HOME
WE-ARE-AT-HOME:
JUMP ???
FUNCTION-DROP-FOOD:
...
FUNCTION-CALL-HELP-FROM-OTHERS:
...
The syntax for the ant-asm instructions above:
turn direction which-line-to-jump
sense direction what jump-if-true jump-if-false
move which-line-to-jump
My problem is that I fail to find out what to write to the last line in the assembly (JUMP ???). Because--as you can see in the example--go-home can be invoked with two different continuations:
(go-home
(drop-food))
and
(go-home
(call-help-from-others))
After go-home has finished I'd like to call either drop-food or call-help-from-others. In assembly: after I arrived at home (=the WE-ARE-AT-HOME label) I'd like to jump either to the label FUNCTION-DROP-FOOD or to the FUNCTION-CALL-HELP-FROM-OTHERS.
How could I do that without a stack, without PUSHing the address of the next instruction (=FUNCTION-DROP-FOOD / FUNCTION-CALL-HELP-FROM-OTHERS) to the stack? My problem is that I don't understand how continuation-passing style (=no stack, only a GOTO/JUMP) could help me solving this problem.
(I can try to explain this again if the things above are incomprehensible.)
And huge thanks in advance for your help!
--
[1] "interpreting it requires no control stack or other unbounded temporary storage". Steele: Rabbit: a compiler for Scheme.
Yes, you've provided the precise motivation for continuation-passing style.
It looks like you've partially translated your code into continuation-passing-style, but not completely.
I would advise you to take a look at PLAI, but I can show you a bit of how your function would be transformed, assuming I can guess at clojure syntax, and mix in scheme's lambda.
(defn search-for-food [cont]
(sense-food-here? ; a conditional w/ 2 branches
(search-for-food
(lambda (r)
(drop-food r
(lambda (s)
(go-home s cont)))))
(search-for-food
(lambda (r)
(move r cont)))))
I'm a bit confused by the fact that you're searching for food whether or not you sense food here, and I find myself suspicious that either this is weird half-translated code, or just doesn't mean exactly what you think it means.
Hope this helps!
And really: go take a look at PLAI. The CPS transform is covered in good detail there, though there's a bunch of stuff for you to read first.
Your ant assembly language is not even Turing-complete. You said it has no memory, so how are you supposed to allocate the environments for your function calls? You can at most get it to accept regular languages and simulate finite automata: anything more complex requires memory. To be Turing-complete you'll need what amounts to a garbage-collected heap. To do everything you need to do to evaluate CPS terms you'll also need an indirect GOTO primitive. Function calls in CPS are basically (possibly indirect) GOTOs that provide parameter passing, and the parameters you pass require memory.
Clearly, your two basic options are to inline everything, with no "external" procedures (for extra credit look up the original meaning of "internal" and "external" here), or somehow "remember" where you need to go on "return" from a procedure "call" (where the return point does not necessarily need to fall in the physical locations immediately following the "calling" point). Basically, the return point identifier can be a code address, an index into a branch table, or even a character symbol -- it just needs to identify the return target relative to the called procedure.
The most obvious here would be to track, in your compiler, all of the return targets for a given call target, then, at the end of the called procedure, build a branch table (or branch ladder) to select from one of the several possible return targets. (In most cases there are only a handful of possible return targets, though for commonly used procedures there could be hundreds or thousands.) Then, at the call point, the caller needs to load a parameter with the index of its return point relative to the called procedure.
Obviously, if the callee in turn calls another procedure, the first return point identifier must be preserved somehow.
Continuation passing is, after all, just a more generalized form of a return address.
You might be interested in Andrew Appel's book Compiling with Continuations.