Search code examples
jsonprologswi-prologswi-prolog-for-sharing

Evaluate a string term in prolog


I'm trying to create a prolog program which receives the queries to run as strings (via json) and then print the result (succeed or fails).

:- use_module(library(http/json)).

happy(alice).
happy(albert).

with_albert(alice).

does_alice_dance :- happy(alice),with_albert(alice),
    format('When alice is happy and with albert, she dances ~n').

with_alice(albert).
does_albert_dance :- happy(albert),with_alice(albert),
    format('When albert is happy and with alice, he dances ~n').

fever(martin).
low_appetite(martin).
sick(X):-fever(X),low_appetite(X).

main(json(Request)) :- 
    nl,
    write(Request),
    nl,
    member(facts=Facts, Request),
    format('Facts : ~w ~n',[Facts]),

    atomic_list_concat(Facts, ', ', Atom),
    format('Atom : ~w ~n',[Atom]),

    atom_to_term(Atom,Term,Bindings),
    format('Term  : ~w ~n',Term),
    write(Bindings).

After executing this query :

main(json([facts=['sick(martin)', 'does_alice_dance', 'does_albert_dance']])).

i had :

[facts=[sick(martin), does_alice_dance, does_albert_dance]]
Facts : [sick(martin),does_alice_dance,does_albert_dance] 
Atom : sick(martin), does_alice_dance, does_albert_dance 
Term  : sick(martin),does_alice_dance,does_albert_dance 
[]
true

What i would like to do is to evaluate Term. I tried to make it work using the is/2 and the call predicates but it doesn't seem to work.

using

call(Term)

(i added in the tail of the main), i had this error :

Sandbox restriction!
Could not derive which predicate may be called from
      call(C)
      main(json([facts=['sick(martin)',does_alice_dance,does_albert_dance]]))

using

Result is Term

(Result is a variable i added to store the result), i had this error :

Arithmetic: `does_albert_dance/0' is not a function

Is there ay solution to evaluate strings expressions in prolog please ?


Solution

  • As @David Tonhofer said in the first comment, The issue was that i'm testing my code on an online editor (which restrict some prolog features like the invocation of the call predicate). So after adding the call predicate to the tail of my program :

    main(json(Request)) :- 
        nl,
        write(Request),
        nl,
        member(facts=Facts, Request),
        format('Facts : ~w ~n',[Facts]),
    
        atomic_list_concat(Facts, ', ', Atom),
        format('Atom : ~w ~n',[Atom]),
    
        atom_to_term(Atom,Term,Bindings),
        format('Term  : ~w ~n',Term),
        write(Bindings),
        call(Term).
    

    and testing it on my local machine. It works fine.