changeset 698: |
96958d3eb5b0 |
parent: |
35bb0d5ec95e
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; dql.lisp --- Deductive Query Langs 3 ;; Query Engine for Inference-based query langs. 7 ;; Prolog, Datalog, etc. 11 ;; My current understanding is that Prolog and SQL-derived langs share much in 12 ;; common. You can certainly do deductive logic in SQL and you can do 13 ;; relational table-based logic in Prolog. 15 ;; It is interesting to note that they were both discovered around the same 16 ;; time in the 60s-70s, but in very different contexts. Prolog was intended 17 ;; for NLP and SQL (relational-algebra/RA) was the foundation for 18 ;; RDBMS. Prolog never really found the same sort of success had by SQL, but 19 ;; with the AI summer in full bloom and NLP being a hot-topic, perhaps we will 20 ;; see the scales shift. 24 ;; The WAM compiler is a bit too much to understand let alone implement at 25 ;; this stage. The design of this package will be much simpler and optimized 26 ;; for compatibility with Lisp Objects. 28 ;; The design we're going for in this package is what I would consider the 29 ;; Lisper's version of Datalog. We want to implement just enough to be useful 30 ;; as a query language, and then use it to bootstrap a more elegant Prolog 31 ;; compiler, likely in SYN/PROLOG. 35 ;; compiled code + constants -> physical plan -> arena + hash-tables -> engine 53 ;; https://franz.com/support/documentation/11.0/prolog.html 55 ;; https://github.com/wmannis/cl-gambol 57 ;; https://norvig.com/paip/README.html 59 ;; https://en.wikipedia.org/wiki/Negation_as_failure 61 ;; https://github.com/bobschrag/clolog/blob/main/architecture.md 63 ;; https://www.swi-prolog.org/pldoc/man?section=predsummary 65 ;; https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=cc7dcdf130adbd7be4d0ed5d3f4ea890e4477223 72 (declaim (fixnum *lips*)) 74 "Count of logical inferences performed.") 76 (defvar *leash-limit* nil) 78 (defvar *leash-indent-wrap* 20 79 "The output to *LEASH-OUTPUT* indents by one level for each level of a predicate, modulo this value.") 81 (defvar *leash-output* (make-synonym-stream '*trace-output*)) 84 (defvar *interactive* t 85 "true iff interacting with user") 86 (defvar *auto-backtrack* nil 87 "return all solutions if true") 88 (defvar *last-continuation* nil 89 "saved state of the system") 91 "the trail, for backtracking") 96 (defvar *top-level-envs* nil 97 "saves top-level environments") 98 (defvar *top-level-vars* nil 99 "saves top-level variable names") 100 (defvar *rules* (make-hash-table) 101 "hash table for prolog rule heads") 103 "Facts are uncoditional truths. They are expressed simply as rules with no 104 variables in the head and no clauses in the body. During reading of a DQL 105 form, if we find any facts we evaluate them and store them here.") 108 (defconstant +impossible+ 'no "make impossible look nice") 109 (defconstant +solved+ 'yes "make solved look nice") 111 (defconstant +?+ #\?) 113 (defun dql-variable-p (sym) 114 "Valid DQL variables are symbols which start with the character #\? as in '?FOO 117 (eql (char (symbol-name sym) 0) +?+))) 119 (deftype dql-variable () `(satisfies dql-variable-p)) 121 (defun dql-anonymous-p (sym) 122 "Return T if SYM is a DQL anonymous variable represented by the value of +?+." 123 (eq sym (symbolicate +?+))) 125 (deftype dql-anonymous () '(satisfies dql-anonymous-p)) 127 (defgeneric proof-tree (self)) 129 (defgeneric print-proof-tree (self &optional stream)) 132 (define-condition dql-error (error) ()) 134 (deferror simple-dql-error (dql-error simple-error) ()) 136 (defun simple-dql-error (ctrl &rest args) 137 (error 'simpl-dql-error :format-control ctrl :format-arguments args)) 139 (define-condition invalid-dql-anonymous (dql-error) ()) 141 (define-condition invalid-dql-variable (dql-error) ()) 143 ;;; Prolog Predicates 144 (defun dql-predicate-p (sym) 145 "Check if SYM looks like a DQL predicate. It shoulb be suffixed by a #\/ 146 followed by either '* for vararg functors or an integer indicating the arity 147 of the predicate. On success returns the arity or T for varargs." 148 (when-let ((arity (cdr (ssplit #\/ (symbol-name sym))))) 149 (setf (the simple-string arity) (car arity)) 151 (digit-char-p (char arity 0)) 152 (parse-integer arity)) 153 (char= (char arity 0) #\*)))) 155 ;; ports: call, exit, redo, and fail 161 (defmacro <- (head &body body)) 162 (defmacro <-- (head &body body)) 164 (defmacro ?- (&body clauses) 165 "Enter the interactive DQL execution environment, attempting to solve for 169 (defmacro leash (&body (functor arity)) 170 "Prolog equivalent of CL:TRACE." 171 (print functor) (print arity)) 173 (defmacro unleash (&body (functor arity)) 174 "Prolog equivalent of CL:UNTRACE." 175 (print functor) (print arity)) 177 (defun prolog-compile-symbols (&rest functors)) 180 ;; ref: https://en.wikipedia.org/wiki/Cut_(logic_programming) 181 (defconstant +!+ #\!) 183 (define-symbol-macro ! (!)) 189 ;; assert, retract, asserta, and assertz 193 ;; herbrand universe | ground-terms + pred(P) -> herbrand base | map(true) -> herbrand interpretation 198 ;; optimistic vs pessimistic when presented with infinite recursion 201 (defclass dql-query (query) ()) 203 (defclass dql-data-source (data-source) () 204 (:documentation "Data source which can be used withing DQL expressions.")) 207 (defclass dql-parser (query-parser) ())