Introduction to ECLiPSe Prolog
ECLiPSe can be downloaded free of charge from the project site: http://eclipseclp.org.
1 Starting ECLiPSe
Here is an example of the start of the session:
$eclipsep
ECLiPSe Constraint Logic Programming System [kernel] ...
Version 6.0 #162 (i386_linux), Mon Sep 20 06:09 2010 [eclipse 1]:
2 Compiling a file
ECLiPSe files have the extension ecl or pl.
A tp1.ecl file is loaded into the environment by
[eclipse 1]: [tp1].
Be careful not to start the file name with an uppercase letter because Prolog would then interpret it as the name of a variable.
3 Running a goal
To execute a goal, simply enter a query followed by a period. A first response is produced. You can then either press the key ";" to get the answer or the Enter key to stop searching for answer(s).
Example :
[eclipse 2]: dessert(D).
D = pear_sorbet
Yes (0.00s cpu, solution 1, maybe more) ? ;
D = strawberries_chantilly
Yes (0.00s cpu, solution 2, maybe more)?
[eclipse 3]:
4 History
The query h. displays the history of the current ECLiPSe session. Example :
[Eclipse 4]: h.
1 [tp1].
2 desserts(D).
3 desserts (melon_en_surprise).
To replay a goal from the history, simply type the number of this goal in the history followed by a period:
[Eclipse 4]: 3. dessert(melon_en_surprise).
Yes (0.00s cpu)
Another even more convenient way to manage the history is to start ECLiPSe from the start under the control of rlwrap (read-line wrapper), then use the arrow keys:
$ rlwrap eclipsep
ECLiPSe Constraint Logic Programming System [kernel] ...
[eclipse 1]:
5 Quitting ECLiPSe
To quit ECLiPSe, you can use the halt predicate or the shortcut Ctrl + D .
Tracing support
Remarks
- What you have to type is in bold underlined
- Remember that iterators are transformed into recursions and that it is the transformed code that is traced
- It is recommended to specify a loop_name when you use an iterator in order to know which iterator is being traced
Start the tracing mode (for the next executions)
[eclipse]: trace.
Debugger switched on - creep mode
Tune the display so that you can see information about the domains (crucial!)
[eclipse]: true.
(1) 1 CALL true %> ?
... gives the list of possible tracing commands (see below)
%> o
current output mode is "QPm", toggle char: D
new output mode is "DQPm".
%> creep
(1) 1 EXIT true %> creep
Yes (0.00s cpu)
Quit the tracing mode (for the next executions)
[eclipse 21]: notrace.
Debugger switched off
Trace information (cf Chapter 14 “Debugging” of Eclipse User manual )
Trace line
(1) 1 CALL solve(X, Y, Z, [a,b,c]) %>
(invoc. nb) depth port goal prompt
Ports
- CALL a procedure is called for the first time concerning a particular invocation,
- NEXT the next possibly matching clause of a procedure is tried because unification failed or a sub-goal failed,
- ELSE the next branch of a disjunction is tried because some goal in the previous branch failed
- EXIT a procedure succeeds,
- FAIL a procedure fails, there is no (other) solution,
- REDO a procedure that already gave a solution is called again for an alternative,
- DELAY a procedure delays,
- RESUME a procedure is woken (the flow enters the procedure box as for a call) because of a unification of a suspending variable,
- LEAVE a procedure is left before having failed or exited because of a call to exit_block/1,
The main tracing commands (Full list accessible by typing “?”, see above)
- h, ? : help
- N : tracer off permanently
- <cr> : creep [once]
- i: jump to invocation number N
- l: leap to spypoint [N times]
- n: nodebug (continue with tracer off)
- q: jump to the most recent failure's culprit
- s: skip subgoal
- z: zap to port
- g: goto ancestor goal (caller)
How to trace breadth-first
- execute one goal
- <creep> to “enter” one level
- <skip> until the exit, fail or leave of a suspicious goal
- remember the invocation number
- <nodebug>
- re-execute same goal
- <i> to jump to the suspicious goal
- iterate
Example
[eclipse 16]: resoudre(X, Y, Z, [AffZ, AffZselonX, AffX, Aff1Y, Aff2Y]).
(1) 1 CALL resoudre(X, Y, Z, [AffZ, AffZselonX, AffX, ...]) %> creep
(2) 2 CALL var(X, Y, Z, AffZ, AffZselonX, AffX, Aff1Y, Aff2Y) %> skip
(2) 2 EXIT var(X{[femme, homme]}, ...) %> skip
(5) 2 CALL poser_pb(X{[femme, homme]}, Y{[femme, homme]}, ...) %> skip
(5) 2 EXIT poser_pb(X{[femme, homme]}, Y{[femme, homme]}, ...) %> nodebug? [y] % accept the default value proposed by the tracer (Here [y] for yes) by simply typing "CR"
[eclipse 17]: resoudre(X, Y, Z, [AffZ, AffZselonX, AffX, Aff1Y, Aff2Y]).
(1) 1 CALL resoudre(X, Y, Z, [AffZ, AffZselonX, AffX, ...]) %> i jump to invoc: [1]? 5
(5) 2 CALL poser_pb(X{[femme, homme]}, Y{[femme, homme]}, Z{[femme, homme]}, AffZ{[0, 1]}, AffZselonX{[0, 1]}, AffX{[0, 1]}, Aff1Y{[0, 1]}, Aff2Y{[0, 1]}) %>
...
How to trace back errors
- <zap> to leave
- to go where the error occurs
- <G> or <g> to inspect goal stack
- <+> to put a spy point or remember the suspicious ancestor goal invocation number
- reexecute
- <l> to leap to the spy point or <i> to jump to the invocation number
Example
[eclipse 2]: t_tab12. % a predicate of yours
instantiation fault in subscript(_197, [1], _200) in module eclipse
Abort
[eclipse 3]: trace.
Debugger switched on - creep mode
[eclipse 4]: t_tab12.
(1) 1 CALL t_tab12 %> zap to port: [~ call] leave % here you do not want the default value, you want the "leave" port
instantiation fault in subscript(_544, [1], _547) in module eclipse
(8) 4 LEAVE subscript(..., ..., ..., ...) %> G print all ancestors? [y]
- +(0) 0 .... trace_body(..., ...)
- (1) 1 .... t_tab12
- (2) 2 .... display_tab2(...)
- (6) 3 .... do__7(..., ...) %> abort? [y]
Abort
[eclipse 4]: t_tab12.
(1) 1 CALL t_tab12 %> i jump to invoc: [1]? 6 % the goal that you want to debug
...