.PHONY: clean all swipl check
-all: $(TARGET)
+all: $(TARGET) $(BASENAME).info
$(OBJECT): $(SOURCE) lib/libswipl.$(SOEXT)
$(CC) $(CFLAGS) -o $@ -c $(SOURCE)
#+FINDEX: sweep-open-query
=sweep= provides the Elisp function =sweep-open-query= for invoking Prolog
predicates. The invoked predicate must be of arity two and will be
-called in mode =p(+In, -Out)=, i.e. the predicate should treat the first
-argument as input and expect a variable for the second argument which
-should be unified with the some output. This restriction is placed in
-order to facilitate a natural calling convention between Elisp, a
-functional language, and Prolog, a logical one.
+called in mode =p(+In, -Out)= i.e. the predicate should treat the
+first argument as input and expect a variable for the second argument
+which should be unified with the some output. This restriction is
+placed in order to facilitate a natural calling convention between
+Elisp, a functional language, and Prolog, a logical one.
-The =sweep-open-query= function takes four arguments, the first three
+The =sweep-open-query= function takes five arguments, the first three
are strings which denote:
- The name of the Prolog context module from which to execute the
query,
The fourth argument to =sweep-open-query= is converted into a Prolog
term and used as the first argument of the predicate (see [[Conversion
-of Elisp objects to Prolog terms]]).
+of Elisp objects to Prolog terms]]). The fifth argument is an
+optional "reverse" flag, when this flag is set to non-nil, the order
+of the arguments is reversed such the predicate is called in mode
+=p(-Out, +In)= rather than =p(+In, -Out)=.
#+FINDEX: sweep-next-solution
The function =sweep-next-solution= can be used to examine the results of
+(ert-deftest lists:member/2 ()
+ "Tests calling the Prolog predicate permutation/2 from Elisp."
+ (should (equal (sweep-open-query "user" "lists" "member" (list 1 2 3) t) t))
+ (should (equal (sweep-next-solution) (cons t 1)))
+ (should (equal (sweep-next-solution) (cons t 2)))
+ (should (equal (sweep-next-solution) (cons '! 3)))
+ (should (equal (sweep-cut-query) t)))
+
(ert-deftest lists:permutation/2 ()
"Tests calling the Prolog predicate permutation/2 from Elisp."
(should (equal (sweep-open-query "user" "lists" "permutation" (list 1 2 3)) t))
char * f = NULL;
term_t a = PL_new_term_refs(2);
emacs_value r = enil(env);
+ emacs_value s = NULL;
(void)data;
- (void)nargs;
-
+ if (nargs == 4) {
+ s = enil(env);
+ } else {
+ s = args[4];
+ }
if (PL_current_query() != 0) {
ethrow(env, "Prolog is already executing a query");
p = PL_predicate(f, 2, m);
- if (value_to_term(env, args[3], a+0) < 0) {
+ if (value_to_term(env, args[3], a+(env->is_not_nil(env, s) ? 1 : 0)) < 0) {
goto cleanup;
}
PL_open_query(n, PL_Q_NODEBUG | PL_Q_EXT_STATUS | PL_Q_CATCH_EXCEPTION, p, a);
- o = a+1;
+ o = a+(env->is_not_nil(env, s) ? 0 : 1);
r = et(env);
emacs_value symbol_open_query = env->intern (env, "sweep-open-query");
emacs_value func_open_query =
env->make_function(env,
- 4, 4,
+ 4, 5,
sweep_open_query,
"Query Prolog.\n\
ARG1 is a string denoting the context module for the query.\n\
ARG2 and ARG3 are strings designating the module and predicate name of the Prolog predicate to invoke, which must be of arity 2.\n\
ARG4 is any object that can be converted to a Prolog term, and will be passed as the first argument of the invoked predicate.\n\
The second argument of the predicate is left unbound and is assumed to treated by the invoked predicate as an output variable.\n\
+If ARG5 is non-nil, reverse the order of the predicate arguments such that the first argument is the output variable and the second argument is the input term derived from ARG4.
Further instantiations of the output variable can be examined via `sweep-next-solution'.",
NULL);
emacs_value args_open_query[] = {symbol_open_query, func_open_query};