-1

in such a program using library(real):

:- use_module( library(real) ).
:- use_module( library(lists) ).
:- use_module( library(apply_macros) ).
:- use_module( library(readutil) ).

my_sum(L, S):-
    i <- L,
    <- i,
    S <- sum(i).

is there a way to modify the program to be able to run it backwards? Currently, this works:

?- my_sum([1,2,3],X).
X = 6.

But this results in an exception:

?- my_sum(L,2).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [13] _6776=..[_6782|_6784]
ERROR:   [12] real:r_call(_6814,[rvar(i),...|_6832]) at /home/raoul/lib/swipl/pack/real/prolog/real.pl:1101
ERROR:    [8] my_sum(_6862++[...|_6870],2) at /home/raoul/Bureau/prolog_relational_stats/relational_R.pl:16
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
Raoul
  • 1,872
  • 3
  • 26
  • 48

1 Answers1

3

From p. 4 of the manual:

The <-/1 predicate sends an R expression, represented as a ground Prolog term, to R, without getting any results back to Prolog. The <-/2 operator facilitates bi-directional communication. If the left-hand side is a free variable, the library assumes that we are passing data from R to Prolog. If the left-hand side is bound, Real assumes that we are passing data or function calls to R.

So your code fails if L is uninstantiated.

You can handle the cases like this:

my_sum(L,S) :-
  ( ground(L), var(S) ->
    i <- L, <- i, S <- sum(i)
  ; var(L), ground(S) ->
    % your code here
  ; % error?
    ).

Then my_sum/2 can be used in either direction.

Tomas By
  • 1,396
  • 1
  • 11
  • 23
  • Thank you. I had understood what the problem was, but not well enough to solve it. I am still a beginner in Prolog. – Raoul Dec 06 '17 at 21:23