Visual Prolog
Implementation of programming language PrologVisual Prolog is an IDE created by Prolog Development Center (PDC). Originally it was known as PDC Prolog, later its marketing was done by Borland Software Corporation under the name Turbo Prolog, and now it’s back to PDC.
Visual Prolog is available in two editions — Commercial (proprietary, supports more features) and Personal (free for non-commercial purposes).
Examples:
Hello, World!:
Example for versions Visual Prolog 7.2Visual Prolog provides automatic project creation, so you have to create a new project, choose “Console” as UI Strategy, navigate to file main.pro
and replace its contents with the given code. The code differs from the standard one only in terms stdio::write
(to write the message to the console) and programControl::sleep
(to pause program execution).
implement main
open core
constants
className = "main".
classVersion = "".
clauses
classInfo(className, classVersion).
clauses
run():-
console::init(),
stdio::write("Hello, World!"),
programControl::sleep(1000),
succeed().
end implement main
goal
mainExe::run(main::run).
Factorial:
Example for versions Visual Prolog 7.2Create a new project with UI Strategy “Console” and replace contents of files main.cl
and main.pro
with given code.
In main.cl
the only added line factorial : (integer N, integer F) procedure (i,o).
specifies that factorial
is a predicate of arity 2, with known first and unknown second argument. Keyword procedure
describes the behavior of predicate, indicating that is will always succeed with only one solution, so no backtracking is required.
In main.pro
the actual description of newly specified predicate takes place. There are two possible matches for each call of factorial
— with zero or arbitrary first argument. Visual Prolog searches the clauses for matching call in the order of their appearance in the code, so if first argument is zero, it starts with first clause factorial(0,F)
. The first rule in this clause is !
, a so-called cut, which prevents backtracking to second clause factorial(N,F)
and thus ensures that there is only one solution to the call. After this the return variable F
is set to 0! = 1 and the result of the clause is printed. The second clause factorial(N,F)
recursively calculates F1
as factorial of N-1
, assigns N*F1
to return variable F
and prints the result. Finally, stdio::nl
prints a new line.
When the main program runs, factorial
is called exactly once, for N=12. With each call of recursion N is decremented until it reaches 0. After this factorials are returned and printed in increasing order of N. This program can process only factorials up to 12!, since trying to calculate 13! causes an integer overflow.
% main.cl
class main
open core
predicates
classInfo : core::classInfo.
factorial : (integer N, integer F) procedure (i,o).
predicates
run : core::runnable.
end class main
% main.pro
implement main
open core
constants
className = "main".
classVersion = "".
clauses
classInfo(className, classVersion).
factorial(0,F) :-
!,
F = 1,
stdio::write("0! = 1"),
stdio::nl.
factorial(N,F) :-
factorial(N-1,F1),
F = N*F1,
stdio::write(N, "! = ", F),
stdio::nl.
clauses
run():-
console::init(),
factorial(12,F),
programControl::sleep(1000),
succeed().
end implement main
goal
mainExe::run(main::run).
Fibonacci numbers:
Example for versions Visual Prolog 7.2Create a new project with UI Strategy “Console” and replace contents of files main.cl
and main.pro
with given code.
Here we define two new predicates — fibonacci(N,F)
to calculate Nth Fibonacci number and loop(N)
to output it. We don’t use memoization to store already calculated numbers, so this implementation is rather inefficient. Note the way the predicates are defined — each predicate is written as one clause using conjunction ,
and disjunction ;
of elementary predicates (instead of breaking them in several clauses which use only disjunction).
% main.cl
class main
open core
predicates
classInfo : core::classInfo.
fibonacci : (integer N, integer F) procedure (i,o).
loop : (integer N) procedure (i).
predicates
run : core::runnable.
end class main
% main.pro
implement main
open core
constants
className = "main".
classVersion = "".
clauses
classInfo(className, classVersion).
fibonacci(N,F) :-
N < 3, !, F = 1;
fibonacci(N-1,F1), fibonacci(N-2,F2), F = F1 + F2.
loop(N) :-
( N = 1, !, fibonacci(1,F);
loop(N-1), fibonacci(N,F) ),
stdio::write(F, ", ").
clauses
run():-
console::init(),
loop(16),
stdio::write("..."),
programControl::sleep(1000),
succeed().
end implement main
goal
mainExe::run(main::run).
Quadratic equation:
Example for versions Visual Prolog 7.2Create a new project with UI Strategy “Console” and replace contents of files main.cl
and main.pro
with given code.
In main.cl
the only added line q : () procedure().
specifies that q
is a predicate which doesn’t accept parameters. Keyword procedure
describes the behavior of predicate, indicating that is will always succeed with only one solution, so no backtracking is required.
In main.pro the actual description of newly specified predicate takes place. q
takes no arguments, since it reads everything it needs from stdio
. Conditional evaluation (construct if-then-else
) works much like in other languages, with the difference of !
sign before then
clause. This is a cut, meaning that once the condition is satisfied, no backtracking is needed.
The tricky part about this example is that we can’t calculate discriminant before checking its sign like in other examples. Default data type for D
in assignment D = B*B-4*A*C
is uReal
, which is unsigned and can’t hold negative values. Thus, we have to check the sign of discriminant first and then assign its absolute value to a variable D
.
% main.cl
class main
open core
predicates
classInfo : core::classInfo.
q : () procedure().
predicates
run : core::runnable.
end class main
% main.pro
implement main
open core
constants
className = "main".
classVersion = "".
clauses
classInfo(className, classVersion).
q() :-
stdio::write("A = "),
A = stdio::read(),
if (A = 0), ! then
stdio::write("Not a quadratic equation."), stdio::nl
else
stdio::write("B = "),
B = stdio::read(),
stdio::write("C = "),
C = stdio::read(),
if (B*B = 4*A*C), ! then
stdio::writef("x = %f", -B/2.0/A)
elseif (B*B > 4*A*C), ! then
D = B*B-4*A*C,
stdio::writef("x1 = %f\n", (-B+math::sqrt(D))/2.0/A),
stdio::writef("x2 = %f", (-B-math::sqrt(D))/2.0/A)
else
D = -B*B+4*A*C,
stdio::writef("x1 = (%f, %f)\n", -B/2.0/A, math::sqrt(D)/2.0/A),
stdio::writef("x2 = (%f, %f)", -B/2.0/A, -math::sqrt(D)/2.0/A)
end if
end if.
clauses
run():-
console::init(),
q(),
succeed().
end implement main
goal
mainExe::run(main::run).
Comments
]]>blog comments powered by Disqus
]]>