]> git.eshelyaron.com Git - sweep.git/commitdiff
ENHANCED: Add optional "reverse" argument flag to sweep-open-query
authorEshel Yaron <me@eshelyaron.com>
Sun, 28 Aug 2022 19:55:45 +0000 (22:55 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sun, 28 Aug 2022 19:55:45 +0000 (22:55 +0300)
Makefile
README.org
sweep-tests.el
sweep.c

index f5758a24be1b9ba5c89eccec3d5138aa5392aeae..6544f4ecb71d012cab6c66ef2ccd8cbe538bfb1b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ CMAKE_OPTIONS += -DSWIPL_INSTALL_IN_LIB=ON
 
 .PHONY: clean all swipl check
 
-all: $(TARGET)
+all: $(TARGET) $(BASENAME).info
 
 $(OBJECT): $(SOURCE) lib/libswipl.$(SOEXT)
        $(CC) $(CFLAGS) -o $@ -c $(SOURCE)
index 96d090cf1952bda5f5ac078ee2b014e24f198450..021160bb9e3ec5f6b5c73cef2de1923ac39fe334 100644 (file)
@@ -95,13 +95,13 @@ The different parts of =sweep= are structured as follows:
 #+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,
@@ -111,7 +111,10 @@ are strings which denote:
 
 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
index 072aaf012799ac4706ca9a0e7fd56cf344135779..84a0610b378eb466ffb4ceffbf380695da6a54f1 100644 (file)
@@ -1,3 +1,11 @@
+(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))
diff --git a/sweep.c b/sweep.c
index 02fd5dd5f5291f8fb44dc5937440fa469878dcad..bbb3f99b715c640f2046f8bb2e61044a63adeafe 100644 (file)
--- a/sweep.c
+++ b/sweep.c
@@ -359,10 +359,14 @@ sweep_open_query(emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data)
   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");
@@ -385,12 +389,12 @@ sweep_open_query(emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data)
 
   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);
 
@@ -484,13 +488,14 @@ REST is passed as the rest of the command line arguments to Prolog.",
   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};