]> Repositorios git - scryer-prolog.git/commitdiff
ADDED: First version of call_nth/2.
authorMarkus Triska <[email protected]>
Sun, 23 Aug 2020 20:13:11 +0000 (22:13 +0200)
committerMarkus Triska <[email protected]>
Mon, 24 Aug 2020 17:29:08 +0000 (19:29 +0200)
A thread-safe implementation is possible for example with
'$nb_setarg'/3 (see #390).

README.md
src/lib/iso_ext.pl

index dab6a379d02a59f280da0ed648d9418b3f85ba2a..1ce4b8295e7dfb2d09ee75dce973be454632ec25 100644 (file)
--- a/README.md
+++ b/README.md
@@ -450,7 +450,7 @@ The modules that ship with Scryer&nbsp;Prolog are also called
   Predicates for reasoning about environment&nbsp;variables.
 * [`iso_ext`](src/lib/iso_ext.pl)
   Conforming extensions to and candidates for inclusion in the Prolog
-  ISO&nbsp;standard, such as `setup_call_cleanup/3` and
+  ISO&nbsp;standard, such as `setup_call_cleanup/3`, `call_nth/2` and
   `call_with_inference_limit/3`.
 * [`crypto`](src/lib/crypto.pl)
   Cryptographically secure random numbers and hashes, HMAC-based key
index e206fd0b5baba2b48c527607f5e5372a80cd6528..e5ba94c16bfb86a526224eee0aa88e072380e988 100644 (file)
@@ -7,7 +7,9 @@
                     call_with_inference_limit/3, forall/2,
                     partial_string/1, partial_string/3,
                     partial_string_tail/2, setup_call_cleanup/3,
-                    variant/2]).
+                    call_nth/2, variant/2]).
+
+:- use_module(library(error), [can_be/2,domain_error/3]).
 
 forall(Generate, Test) :-
     \+ (Generate, \+ Test).
@@ -161,3 +163,35 @@ partial_string_tail(String, Tail) :-
        '$partial_string_tail'(String, Tail)
     ;  throw(error(type_error(partial_string, String), partial_string_tail/2))
     ).
+
+:- dynamic(i_call_nth_nesting/2).
+:- dynamic(i_call_nth_counter/1).
+
+call_nth(Goal, N) :-
+    can_be(integer, N),
+    (   integer(N), N =< 0,
+        domain_error(positive_integer, N, call_nth/2)
+    ;   true
+    ),
+    setup_call_cleanup(call_nth_nesting(ID),
+                       (   Goal,
+                           retract(i_call_nth_nesting(ID,N0)),
+                           N1 is N0 + 1,
+                           asserta(i_call_nth_nesting(ID,N1)),
+                           (   integer(N) ->
+                               N = N1,
+                               !
+                           ;   N = N1
+                           )
+                       ),
+                       (   retract(i_call_nth_nesting(ID,_)),
+                           retract(i_call_nth_counter(ID))
+                       )).
+
+call_nth_nesting(ID) :-
+    (   i_call_nth_counter(ID0) ->
+        ID is ID0 + 1
+    ;   ID = 0
+    ),
+    asserta(i_call_nth_nesting(ID, 0)),
+    asserta(i_call_nth_counter(ID)).