Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does prolog have a spread/splat/*args operator?

In many procedural languages (such as python), I can "unpack" a list and use it as arguments for a function. For example...

def print_sum(a, b, c):
  sum = a + b + c
  print("The sum is %d" % sum)

print_sum(*[5, 2, 1])

This code will print: "The sum is 8"

Here is the documentation for this language feature.

Does prolog have a similar feature?

Is there a way to replicate this argument-unpacking behaviour in Prolog?

For example, I'd like to unpack a list variable before passing it into call.

Could I write a predicate like this?

assert_true(Predicate, with_args([Input])) :-
  call(Predicate, Input).

% Where `Input` is somehow unpacked before being passed into `call`.

...That I could then query with

?- assert_true(reverse, with_args([ [1, 2, 3], [3, 2, 1] ])).
% Should be true, currently fails.

?- assert_true(succ, with_args([ 2, 3 ]).
% Should be true, currently fails.

?- assert_true(succ, with_args([ 2, 4 ]).
% Should be false, currently fails.

Notes

  • You may think that this is an XY Problem. It could be, but don't get discouraged. It'd be ideal to receive an answer for just my question title.

  • You may tell me that I'm approaching the problem poorly. I know your intentions are good, but this kind of advice won't help to answer the question. Please refer to the above point.

  • Perhaps I'm approaching Prolog in too much of a procedural mindset. If this is the case, then what mindset would help me to solve the problem?

  • I'm using SWI-Prolog.

like image 888
byxor Avatar asked Dec 24 '22 22:12

byxor


1 Answers

The built-in (=..)/2 (univ) serves this purpose. E.g.

?- G =.. [g, 1, 2, 3].
   G = g(1,2,3).

?- g(1,2,3) =.. Xs.
   Xs = [g,1,2,3].

However, note that many uses of (=..)/2 where the number of arguments is fixed can be replaced by call/2...call/8.

like image 115
false Avatar answered Jan 18 '23 10:01

false