Quadratic equation in Prolog

Example for versions Visual Prolog 7.2

Create 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).