The reason of error
several classes interfaces and/or namespaces have the same name "main" is that 'empty' projects already contain a class
main and you have created a second class having the same name. Class names must be unique however (in each namespace).
I think there are two issues about the example
Tail Recursion:
1st) It is written in an earlier version of Visual Prolog. In the current Visual Prolog 9 the intended place, where to insert your code, is different. When we create a new console style project in current VIP, main.cl will be:
Code: Select all
% Copyright
class main
open core
predicates
run : core::runnable.
end class main
and main.pro is
Code: Select all
% Copyright
implement main
open core
clauses
run() :-
CP = commandLineParser::new(),
CP:acceptEmpty := true,
CP:addOption_help("-help"),
% define command line options here
if ErrorMessage = isSome(CP:parse()) then
stdio::write(ErrorMessage)
else
% place your own code here
end if.
end implement main
goal
console::runUtf8(main::run).
Provided you do not need/want the
commandLineParser stuff, you can clean them up a little, so that they become:
Code: Select all
class main
predicates
run : core::runnable.
end class main
and
Code: Select all
implement main
clauses
run() :-
% place your own code here
end implement main
goal
console::runUtf8(main::run).
Now (and always) leave the goal as it is. Just replace the
% place your own code here by your main code. That is in case of the old wiki-example the lines from the goal. Ommit but the line
console::init(),. This line was good only in an earlier VIP version. Thereafter main.pro looks:
Code: Select all
implement main
clauses
run() :-
main::length_of([1, 2, 3], L, 0), /* start with Counter = 0 */
stdio::write(" L = ", L).
end implement main
goal
console::runUtf8(main::run).
Complete setting up the example by inserting the declaration und clauses of predicate
length_of/2->. Done that, main.cl and main.pro are:
Code: Select all
class main
predicates
length_of : (A* List, integer Counter) -> integer Result.
predicates
run : core::runnable.
end class main
Code: Select all
implement main
clauses
length_of([], Counter) = Counter.
length_of([_ | T], Counter) = Result :-
NewCounter = Counter + 1,
Result = length_of(T, NewCounter).
clauses
run() :-
main::length_of([1, 2, 3], L, 0), /* start with Counter = 0 */
stdio::write(" L = ", L).
end implement main
goal
console::runUtf8(main::run).
When you now compile resp. build the project, then
2nd) issue pops up:
Undeclared identifier 'main::length_of/3', the identifier is known as 'length_of/2->' in the class 'main'. The compiler complains because the call
main::length_of([1, 2, 3], L, 0) does not fit to the declaration of predicate
length_of/2->.
Having corrected the wrong call and furthermore removing a superflous qualification
main:: the implementation eventually becomes:
Code: Select all
implement main
clauses
length_of([], Counter) = Counter.
length_of([_ | T], Counter) = Result :-
NewCounter = Counter + 1,
Result = length_of(T, NewCounter).
clauses
run() :-
L = length_of([1, 2, 3], 0), /* start with Counter = 0 */
stdio::write(" L = ", L).
end implement main
goal
console::runUtf8(main::run).
Now the example works fine.
It can however be coded a bit shorter:
Code: Select all
implement main
clauses
length_of([], Counter) = Counter.
length_of([_ | T], Counter) = length_of(T, Counter + 1).
clauses
run() :-
L = length_of([1, 2, 3], 0), /* start with Counter = 0 */
stdio::write(" L = ", L).
end implement main
goal
console::runUtf8(main::run).