cl-ds / data /repos /cl-prolog2 /src /util.lisp
j14i's picture
3375 CL macro transformation examples from 85 libraries
43203b4 verified
Raw
History Blame Contribute Delete
3.18 kB
(in-package :cl-prolog2.impl)
(named-readtables:in-readtable :fare-quasiquote)
(defun sort-clauses (rules)
"Destructively sort the rules by dictionary ordering.
Useful for avoiding noncontiguous-clauses errors (rules for the same clauses are not written adjacently).
Facts (rules without conditions) are given precedence to the standard rules.
Sorting is stable.
However, since it alters the ordering of the rules and Prolog checks the rules from top-to-bottom,
it may corrupt the program especially when cut operator (!) is involved."
(stable-sort rules
(lambda (a b)
(ematch* (a b)
((`(:- (,name1 ,@args1) ,@_) `(:- (,name2 ,@args2) ,@_))
(cond
((string< name1 name2) t)
((string= name1 name2)
(< (length args1) (length args2)))
((string> name1 name2) nil)))
((`(:- (,name1 ,@args1) ,@_) `(,name2 ,@args2))
(cond
((string< name1 name2) t)
((string= name1 name2)
(< (length args1) (length args2)))
((string> name1 name2) nil)))
((`(,name1 ,@args1) `(:- (,name2 ,@args2) ,@_))
(cond
((string< name1 name2) t)
((string= name1 name2)
(<= (length args1) (length args2)))
((string> name1 name2) nil)))
((`(,name1 ,@args1) `(,name2 ,@args2))
(cond
((string< name1 name2) t)
((string= name1 name2)
(< (length args1) (length args2)))
((string> name1 name2) nil)))))))
(defun print-sexp (&key swi)
"
This function returns a cl-prolog2 program for a prolog rule print-sexp/1,
which prints a prolog term in a SEXP form.
print-sexp prints atoms/numbers as atoms/numbers, a term as a list, and a list as a list.
To be used with SWI, SWI should be non-nil due to the implementation-specific matter.
(It uses compound_name_arguments/2 instead of =../2 for printing a term.)
usage:
(run-prolog `((:- main
(print-sexp (parent-of luke anakin))
halt)
(:- (initialization main))
,@(print-sexp :swi t))
:swi :output :string)
;; -> \"(parent-of luke anakin)\", NIL, 0
"
`((:- (print-sexp (list))
(write "()")
!)
(:- (print-sexp ?term)
(atomic ?term)
(write ?term)
!)
(:- (print-sexp (list* ?car ?cdr))
(write "(")
(print-sexp ?car)
(print-sexp-list-aux ?cdr)
(write ")")
!)
(:- (print-sexp ?term)
,@(if swi
`((compound_name_arguments ?term ?head ?args)
(print-sexp (list* ?head ?args)))
`((=.. ?term ?l)
(print-sexp ?l))))
(print-sexp-list-aux (list))
(:- (print-sexp-list-aux (list* ?car ?cdr))
(atomic ?car) !
(write " ")
(print-sexp ?car)
(print-sexp-list-aux ?cdr))
(:- (print-sexp-list-aux (list* ?car ?cdr))
(write " \\n")
(print-sexp ?car)
(print-sexp-list-aux ?cdr))))