Piotr Zakrzewski
Piotr Zakrzewski

Reputation: 3891

Evaluate term in Prolog and write it

Hi I am learning prolog (using swi-prolog 7 on Mac) but I cannot find enough docs/tutorials to explain how to print out a result of a term evaluation. I tried code below but it always prints out ERROR: prolog/test.pl:2: user:main: false for any arguments.

#!/usr/bin/env swipl
:- initialization(main, main).

fun1(A, B):- A < B.
fun2([A1 | A2]):- A3 is fun1(A1, A2), write(A3).

main(args) :- fun2(args).

How can I write result of fun1 to stdout in SWI-Prolog?

Upvotes: 2

Views: 1175

Answers (1)

Guy Coder
Guy Coder

Reputation: 24976

Perhaps this?

fun1(A,B,Value) :-
    (
        A < B
    ->
        Value = true
    ;
        Value = false
    ).

fun2(A1,A2) :-
    fun1(A1, A2, Value ),
    format('Result: ~w~n',[Value]).

Example run:

?- fun2(1,2).
Result: true
true.

In Prolog you have to think of the result of each line as being true or false and then possibly binding a value to a variable or something more complex as state.

The code in the question was returning that the predicate was true or false but not binding a value to a variable or altering state. By adding Value as an additional parameter and then binding a value in the predicate, the value in Value was able to be used for display.


EDIT

Question from OP in comment

I have never seen -> is it documented somewhere? Sorry if it is a noobie question.

No it is not a noobie question, and actually it was wise of you to just ask instead of festering on it.

See: Control Predicates

In particular ->/2 or (:Condition -> :Action) is often used with ;/2 and together they work like an if then else, e.g.

if then else syntax:

NB This is not Prolog syntax but a syntax common in many imperative programming languages.

if (<condition>) then
  <when true>
else
  <when false>

-> ; syntax:

This is Prolog syntax.

(
   <condition>
->
   <when true>
;
   <when false>
)

EDIT

Question from OP in comment

When I run this code without the init block and main, so just in interactive mode, then it works. When I try to make a script out of it I get the same error ERROR: prolog/test.pl:2: user:main: false

First

main(args) :- fun2(args).

args is a value but needs to be a variable and in Prolog variables by default start with a capital letter.

main(Args) :- fun2(Args).

Next, Args as received in main/1 is a list, but fun2/2 expects two separate parameters. So by deconstructing Args into a list of two items with Args = [A1,A2] the items in the list can be used as individual items to be passed as parameters to fun2/2.

main(Args) :-
    Args = [A1,A2],
    fun2(A1,A2).

Example run from top level.

?- main([1,2]).
Result: true
true.

I leave it as an exercise to check if this works as needed from the command line.

Upvotes: 5

Related Questions