R

*Rule
A global variable holding the current Pilog rule symbol. It is cleared at the beginning of a new REPL. See also be and clause.
: (be likes (John Mary))
-> likes
: *Rule
-> likes
*Run
This global variable can hold a list of prg expressions which are used during key, sync, wait and listen. The first element of each expression must either be a positive number (thus denoting a file descriptor to wait for) or a negative number (denoting a timeout value in milliseconds (in that case another number must follow to hold the remaining time)). A poll(2) system call is performed with these values, and the corresponding prg body is executed when input data are available or when a timeout occurred (with @ set to the file descriptor or timeout value). See also task.
: (de *Run (-2000 0 (println '2sec)))     # Install 2-sec-timer
-> *Run
: 2sec                                    # Prints "2sec" every 2 seconds
2sec
2sec
                                          # (Ctrl-D) Exit
$
+Ref
Prefix class for maintaining non-unique indexes to +relations, a subclass of +index. Accepts an optional argument for a +Hook attribute. See also Database.
(rel tel (+Fold +Ref +String))  # Phone number with folded, non-unique index
+Ref2
Prefix class for maintaining a secondary ("backing") index to +relations. Can only be used as a prefix class to +Key or +Ref. It maintains an index in the current (sub)class, in addition to that in one of the superclasses (must be a +Ref), to allow (sub)class-specific queries. See also Database.
(class +Ord +Entity)             # Order class
(rel nr (+Need +Ref +Number))    # Order number
...
(class +EuOrd +Ord)              # EU-specific order subclass
(rel nr (+Ref2 +Key +Number))    # Order number with backing index
+relation
Abstract base class of all database relations. Relation objects are usually defined with rel. The class hierarchy includes the classes +Any, +Bag, +Bool, +Number, +Date, +Time, +Symbol, +String, +Link, +Joint and +Blob, and the prefix classes +Hook, +Hook2, +index, +Key, +Ref, +Ref2, +Idx, +IdxFold, +Sn, +Fold, +Aux, +UB, +Dep, +List, +Need, +Mis, +Alt and +Swap. See also Database and +Entity.

Messages to relation objects include

mis> (Val Obj)       # Return error if mismatching type or value
has> (Val X)         # Check if the value is present
put> (Obj Old New)   # Put new value
rel> (Obj Old New)   # Maintain relational structures
lose> (Obj Val)      # Delete relational structures
keep> (Obj Val)      # Restore deleted relational structures
zap> (Obj Val)       # Clean up relational structures
(rand ['cnt1 'cnt2] | ['T]) -> cnt | flg
Returns a pseudo random number in the range of the positive short numbers cnt1 and cnt2 (or -2147483648 .. +2147483647 if no arguments are given). If the argument is T, a boolean value flg is returned. Note that if a range is given, the results are "more random" because the higher bits of the internal generator are used. See also seed.
: (rand 3 9)
-> 3
: (rand 3 9)
-> 7
(range 'num1 'num2 ['num3]) -> lst
Produces a list of numbers in the range num1 through num2. When num3 is non-NIL, it is used to increment num1 (if it is smaller than num2) or to decrement num1 (if it is greater than num2). See also need.
: (range 1 6)
-> (1 2 3 4 5 6)
: (range 6 1)
-> (6 5 4 3 2 1)
: (range -3 3)
-> (-3 -2 -1 0 1 2 3)
: (range 3 -3 2)
-> (3 1 -1 -3)
range/3
Pilog predicate that succeeds if the first argument is in the range of the result of applying the get algorithm to the following arguments. Typically used as filter predicate in select/3 database queries. See also Comparing, isa/2, same/3, bool/3, head/3, fold/3, part/3 and tolr/3.
: (?
   @Nr (1 . 5)  # Numbers between 1 and 5
   @Nm "part"
   (select (@Item)
      ((nr +Item @Nr) (nm +Item @Nm))
      (range @Nr @Item nr)
      (part @Nm @Item nm) ) )
 @Nr=(1 . 5) @Nm="part" @Item={B1}
 @Nr=(1 . 5) @Nm="part" @Item={B2}
-> NIL
(rank 'any 'lst ['flg]) -> lst
Searches a ranking list. lst should be sorted. Returns the element from lst with a maximal CAR less or equal to any (if flg is NIL), or with a minimal CAR greater or equal to any (if flg is non-NIL), or NIL if no match is found. See also assoc and Comparing.
: (rank 0 '((1 . a) (100 . b) (1000 . c)))
-> NIL
: (rank 50 '((1 . a) (100 . b) (1000 . c)))
-> (1 . a)
: (rank 100 '((1 . a) (100 . b) (1000 . c)))
-> (100 . b)
: (rank 300 '((1 . a) (100 . b) (1000 . c)))
-> (100 . b)
: (rank 9999 '((1 . a) (100 . b) (1000 . c)))
-> (1000 . c)
: (rank 50 '((1000 . a) (100 . b) (1 . c)) T)
-> (100 . b)
(rassoc 'any 'lst) -> lst
Reverse assoc. Returns the first element from lst with its CDR equal to any, or NIL if no match is found. See also rasoq and asoq.
: (rassoc 7 '((999 1 2 3) ("b" . 7) ("ok" "Hello")))
-> ("b" . 7)
: (rassoc (1 2 3) '((999 1 2 3) ("b" . 7) ("ok" "Hello")))
-> (999 1 2 3)
: (rassoc 'u '((999 1 2 3) ("b" . 7) ("ok" "Hello")))
-> NIL
(rasoq 'any 'lst) -> lst
Reverse asoq. Returns the first element from lst with any as its CDR, or NIL if no match is found. == is used for comparison (pointer equality). See also assoc and rassoc.
: (rasoq 'b '((1 . a) (2 . b) (3 . c))) )
-> (2 . b)
: (rasoq "b" '((1 . a) (2 . b) (3 . c))) )
-> NIL
(raw ['flg]) -> flg
Console mode control function. When called without arguments, it returns the current console mode (NIL for "cooked mode"). Otherwise, the console is set to the new state. See also key.
$ pil +
: (raw)
-> NIL
: (raw T)
-> T
...  # Raw mode, no echo!
(rc 'sym 'any1 ['any2 ['any3 'any4..]]) -> any
Fetches a value from a resource file sym, or stores one or more key-value pairs (any1 . any2) in that file, using the key any1 (and optionally any3 etc. for multiple stores). All values are stored in a list in the file, using assoc. During the whole operation, the file is exclusively locked with ctl.
: (info "a.rc")               # File exists?
-> NIL                        # No
: (rc "a.rc" 'a 1)            # Store 1 for 'a'
-> 1
: (rc "a.rc" 'b (2 3 4))      # Store (2 3 4) for 'b'
-> (2 3 4)
: (rc "a.rc" 'c 'b)           # Store 'b' for 'c'
-> b
: (info "a.rc")               # Check file
-> (28 733124 . 61673)
: (in "a.rc" (echo))          # Display it
((c . b) (b 2 3 4) (a . 1))
-> T
: (rc "a.rc" 'c)              # Fetch value for 'c'
-> b
: (rc "a.rc" @)               # Fetch value for 'b'
-> (2 3 4)
(rd ['sym]) -> any
(rd 'cnt) -> num | NIL
Binary read: Reads one item from the current input channel in encoded binary format. When called with a cnt argument (second form), that number of raw bytes (in big endian format if cnt is positive, otherwise little endian) is read as a single number. Upon end of file, if the sym argument is given, it is returned, otherwise NIL. See also pr, tell, hear and wr.
: (out "x" (pr 'abc "EOF" 123 "def"))
-> "def"
: (in "x" (rd))
-> abc
: (in "x"
   (make
      (use X
         (until (== "EOF" (setq X (rd "EOF")))  # '==' detects end of file
            (link X) ) ) ) )
-> (abc "EOF" 123 "def")  # as opposed to reading a symbol "EOF"

: (in "/dev/urandom" (rd 20))
-> 396737673456823753584720194864200246115286686486
(read ['sym1 ['sym2]]) -> any
Reads one item from the current input channel. NIL is returned upon end of file. When called without arguments, an arbitrary Lisp expression is read. Otherwise, a token (a number, an internal symbol, a transient symbol (for punctuation), or a list of symbols (for a string)) is read. In that case, sym1 specifies which set of characters to accept for continuous symbol names (in addition to the standard alphanumerical characters), and sym2 an optional comment character. See also any, str, line, skip and eof.
: (list (read) (read) (read))    # Read three things from console
123                              # a number
abcd                             # a symbol
(def                             # and a list
ghi
jkl
)
-> (123 abcd (def ghi jkl))
: (make (while (read "_" "#") (link @)))
abc = def_ghi("xyz"+-123) # Comment
NIL
-> (abc "=" def_ghi "(" ("x" "y" "z") "+" "-" 123 ")")
(recur fun) -> any
(recurse ..) -> any
Implements anonymous recursion, by defining the function recurse on the fly. During the execution of fun, the symbol recurse is bound to the function definition fun. See also let and lambda.
: (de fibonacci (N)
   (when (lt0 N)
      (quit "Bad fibonacci" N) )
   (recur (N)
      (if (>= 2 N)
         1
         (+
            (recurse (dec N))
            (recurse (- N 2)) ) ) ) )
-> fibonacci
: (fibonacci 22)
-> 17711
: (fibonacci -7)
-7 -- Bad fibonacci
(redef sym . fun) -> sym
Redefines sym in terms of itself. The current definition is saved in a new symbol, which is substituted for each occurrence of sym in fun, and which is also returned. See also de, undef, daemon and patch.
: (de hello () (prinl "Hello world!"))
-> hello
: (pp 'hello)
(de hello NIL
   (prinl "Hello world!") )
-> hello

: (redef hello (A B)
   (println 'Before A)
   (prog1 (hello) (println 'After B)) )
-> "hello"
: (pp 'hello)
(de hello (A B)
   (println 'Before A)
   (prog1 ("hello") (println 'After B)) )
-> hello
: (hello 1 2)
Before 1
Hello world!
After 2
-> "Hello world!"

: (redef * @
   (msg (rest))
   (pass *) )
-> "*"
: (* 1 2 3)
(1 2 3)
-> 6

: (redef + @
   (pass (ifn (num? (next)) pack +) (arg)) )
-> "+"
: (+ 1 2 3)
-> 6
: (+ "a" 'b '(c d e))
-> "abcde"

(rel sym lst [any ..]) -> any
Defines a relation for sym in the current class *Class, using lst as the list of classes for that relation, and possibly additional arguments any for its initialization. See also Database, class, extend, dm and var.
(class +Person +Entity)
(rel nm  (+List +Ref +String))            # Names
(rel tel (+Ref +String))                  # Telephone
(rel adr (+Joint) prs (+Address))         # Address

(class +Address +Entity)
(rel cit (+Need +Hook +Link) (+City))     # City
(rel str (+List +Ref +String) cit)        # Street
(rel prs (+List +Joint) adr (+Person))    # Inhabitants

(class +City +Entity)
(rel nm  (+List +Ref +String))            # Zip / Names
(release 'sym) -> NIL
Releases the mutex represented by the file 'sym'. This is the reverse operation of acquire.
: (release "sema1")
-> NIL
(remark 'any)
Global variable holding a (possibly empty) function, which will be called when a value is printed in the REPL. It can be used to provide further information about that value.
: (date)
-> 739542  # 2024-12-16
: (scl 3)
-> 3  # 0.003
: 12.3
-> 12300  # 12.300
: (date)
-> 739542  # 2024-12-16 739.542
remote/2
Pilog predicate for remote database queries. It takes a list and an arbitrary number of clauses. The list should contain a Pilog variable for the result in the CAR, and a list of resources in the CDR. The clauses will be evaluated on remote machines according to these resources. Each resource must be a cons pair of two functions, an "out" function in the CAR, and an "in" function in the CDR. See also *Ext, revolve/2, select/3 and db/3.
(setq *Ext           # Set up external offsets
   (mapcar
      '((@Host @Ext)
         (cons @Ext
            (curry (@Host @Ext (Sock)) (Obj)
               (when (or Sock (setq Sock (connect @Host 4040)))
                  (ext @Ext
                     (out Sock (pr (cons 'qsym Obj)))
                     (prog1
                        (in Sock (rd))
                        (unless @
                           (close Sock)
                           (off Sock) ) ) ) ) ) ) )
      '("localhost")
      '(20) ) )

(de rsrc ()  # Simple resource handler, ignoring errors or EOFs
   (extract
      '((@Ext Host)
         (let? @Sock (connect Host 4040)
            (cons
               (curry (@Ext @Sock) (X)  # out
                  (ext @Ext (out @Sock (pr X))) )
               (curry (@Ext @Sock) ()  # in
                  (ext @Ext (in @Sock (rd))) ) ) ) )
      '(20)
      '("localhost") ) )

: (?
   @Nr (1 . 3)
   @Sup 2
   @Rsrc (rsrc)
   (remote (@Item . @Rsrc)
      (db nr +Item @Nr @Item)
      (val @Sup @Item sup nr) )
   (show @Item) )
{AF2} (+Item)
   pr 1250
   inv 100
   sup {AG2}
   nm "Spare Part"
   nr 2
 @Nr=(1 . 3) @Sup=2 @Rsrc=((((X) (ext 20 (out 3 (pr X)))) NIL (ext 20 (in 3 (rd))))) @Item={AF2}
-> NIL
(remove 'cnt 'lst) -> lst
Removes the element at position cnt from lst. This is a non-destructive operation. See also insert, place, append, delete and replace.
: (remove 3 '(a b c d e))
-> (a b d e)
: (remove 1 '(a b c d e))
-> (b c d e)
: (remove 9 '(a b c d e))
-> (a b c d e)
(repeat) -> lst
Makes the current Pilog definition "tail recursive", by closing the previously defined rules in the definition's T property to a circular list. See also repeat/0 and be.
(be a (1))     # Define three facts
(be a (2))
(be a (3))
(repeat)       # Unlimited supply

: (? (a @N))
 @N=1
 @N=2
 @N=3
 @N=1
 @N=2
 @N=3.         # Stop
-> NIL
repeat/0
Pilog predicate that always succeeds, also on backtracking. See also repeat and true/0.
: (be integer (@I)   # Generate unlimited supply of integers
   (^ @C (box 0))    # Init to zero
   (repeat)          # Repeat from here
   (^ @I (inc @C)) )
-> integer

: (? (integer @X))
 @X=1
 @X=2
 @X=3
 @X=4.               # Stop
-> NIL
(replace 'lst 'any1 'any2 ..) -> lst
Replaces in lst all occurrences of any1 with any2. For optional additional argument pairs, this process is repeated. This is a non-destructive operation. See also append, delete, insert, remove and place.
: (replace '(a b b a) 'a 'A)
-> (A b b A)
: (replace '(a b b a) 'b 'B)
-> (a B B a)
: (replace '(a b b a) 'a 'B 'b 'A)
-> (B A A B)
(request 'typ 'sym ['hook] 'val ..) -> obj
Returns a database object. If a matching object cannot be found (using db), a new object of the given type is created (using new). See also obj.
: (request '(+Item) 'nr 2)
-> {B2}
(request! 'typ 'sym ['hook] 'val ..) -> obj
Transaction wrapper function for request. See also new!, set!, put! and inc!.
(rest) -> lst
Can only be used inside functions with a variable number of arguments (with @). Returns the list of all remaining arguments from the internal list. See also args, next, arg and pass.
: (de foo @ (println (rest)))
-> foo
: (foo 1 2 3)
(1 2 3)
-> (1 2 3)
(retract) -> lst
Removes a Pilog fact or rule. See also be, clause, asserta and assertz.
: (be a (1))
-> a
: (be a (2))
-> a
: (be a (3))
-> a

: (retract '(a (2)))
-> (((1)) ((3)))

:  (? (a @N))
 @N=1
 @N=3
-> NIL
retract/1
Pilog predicate that removes a fact or rule. See also retract, asserta/1 and assertz/1.
: (be a (1))
-> a
: (be a (2))
-> a
: (be a (3))
-> a

: (? (retract (a 2)))
-> T
: (rules 'a)
1 (be a (1))
2 (be a (3))
-> a
(rev 'cnt1 'cnt2) -> cnt
Reverses the lowest cnt1 bits of cnt2. See also >> and hash.
: (bin (rev 4 (bin "0101")))
-> "1010"
: (rev 32 1)
-> 2147483648
: (hex @)
-> "80000000"
: (rev 32 (hex "E0000000"))
-> 7
(reverse 'lst) -> lst
Returns a reversed copy of lst. See also flip.
: (reverse (1 2 3 4))
-> (4 3 2 1)
(rewind) -> flg
Sets the file position indicator for the current output stream to the beginning of the file, and truncates the file length to zero. Returns T when successful. See also flush.
: (out "a" (prinl "Hello world"))
-> "Hello world"
: (in "a" (echo))
Hello world
-> T
: (info "a")
-> (12 733216 . 53888)
: (out "a" (rewind))
-> T
: (info "a")
-> (0 733216 . 53922)
revolve/2
Pilog predicate for quasi-parallel evaluation of clauses. It takes a list and an arbitrary number of clauses. The list should contain a Pilog variable for the result in the CAR, another Pilog variable for passing the values in the CADR, and a list of values in the CDDR. The clauses will be evaluated in a round-robin fashion. See also remote/2.
: (solve
   (quote
      @Rsrc '((1 2 3 4) (5 6 7 8) (a b c))
      (revolve (@Res @Lst . @Rsrc)
         (lst @Res @Lst) ) )
   @Res )
-> (1 5 a 2 6 b 3 7 c 4 8)
(rid 'var 'any) -> any
Destructively removes all occurrences of any from the (possibly circular) value of var, and returns the new value. See also fifo, queue, cut and del.
$: (off E)
-> NIL
: (fifo 'E 1 2 3 2 4 2)
-> 2
: E
-> (2 1 2 3 2 4 .)
$: (rid 'E 2)
-> (4 1 3 .)
$: (rid 'E 4)
-> (3 1 .)
(rollback) -> flg
Cancels a transaction, by discarding all modifications of external symbols. See also commit.
: (pool "db")
-> T
# .. Modify external objects ..
: (rollback)            # Rollback
-> T
(root 'tree) -> (num . sym)
Returns the root of a database index tree, with the number of entries in num, and the base node in sym. See also tree.
: (root (tree 'nr '+Item))
-> (6 . {H1})
(rot 'lst ['cnt]) -> lst
Rotate: The contents of the cells of lst are (destructively) shifted right, and the value from the last cell is stored in the first cell. Without the optional cnt argument, the whole list is rotated, otherwise only the first cnt elements. See also flip .
: (rot (1 2 3 4))             # Rotate all four elements
-> (4 1 2 3)
: (rot (1 2 3 4 5 6) 3)       # Rotate only the first three elements
-> (3 1 2 4 5 6)
(round 'num1 ['num2]) -> sym
Formats a number num1 with num2 decimal places, according to the current scale *Scl. num2 defaults to 3. See also Numbers and format.
: (scl 4)               # Set scale to 4
-> 4  # 0.0004
: (round 123456)        # Format with three decimal places
-> "12.346"
: (round 123456 2)      # Format with two decimal places
-> "12.35"
: (format 123456 *Scl)  # Format with full precision
-> "12.3456"
(rules 'sym ..) -> sym
Prints all rules defined for the sym arguments. See also Pilog and be.
: (rules 'member 'append)
1 (be member (@X (@X . @)))
2 (be member (@X (@ . @Y)) (member @X @Y))
1 (be append (NIL @X @X))
2 (be append ((@A . @X) @Y (@A . @Z)) (append @X @Y @Z))
-> append
(run 'any ['cnt]) -> any
If any is an atom, run behaves like eval. Otherwise any is a list, which is evaluated in sequence. The last result is returned. If an offset cnt is given, the value of @ in the cnt'th call environment is used during that evaluation. cnt should be greater than zero. See also up.
: (run '((println (+ 1 2 3)) (println 'OK)))
6
OK
-> OK

: (de f Prg
   (let A 12
      (println (cons 'Prg Prg) (cons 'A A))
      (run Prg 1) ) )
-> f
: (let (Prg 77  A 99)
   (f
      (println (cons 'Prg Prg) (cons 'A A)) ) )
(Prg (println (cons 'Prg Prg) (cons 'A A))) (A . 12)
(Prg . 77) (A . 99)
-> (A . 99)