;;; -*- Mode: LISP; Syntax: Common-Lisp -*- ;;; File: qga.lsp ;;; this code can be used to generate the sets of clauses for ;;; quasigroup examples used in H. Zhang and M.E. Stickel, ;;; "Implementing the Davis-Putnam Method", submitted to the ;;; SAT 2000 special issue of Journal of Automated Reasoning ;;; ;;; to write a set of quasigroup example files in DIMACS format: ;;; (compile-file "qga.lsp") ;;; (load "qga") ;;; ;;; written by Mark E. Stickel (stickel@ai.sri.com) (defmacro COLLECT (item place) ;; like (setf place (nconc place (list item))) ;; except last cell of list is remembered in place-last ;; so that operation is O(1) ;; collect can be used instead of (push item place) + (nreverse place) loop idiom ;; user must declare place-last variable or slot (let* ((args (if (atom place) nil (mapcar #'(lambda (arg) (list (gensym) arg)) (rest place)))) (place (if (atom place) place (cons (first place) (mapcar #'first args)))) (place-last (if (atom place) (intern (concatenate 'string (symbol-name place) "-LAST")) (cons (intern (concatenate 'string (symbol-name (first place)) "-LAST")) (rest place)))) (v (gensym)) (l (gensym))) `(let* ((,v (cons ,item nil)) ,@args (,l ,place)) (cond ((null ,l) (setf ,place (setf ,place-last ,v))) (t (rplacd ,place-last (setf ,place-last ,v)) ,l))))) (defstruct DP-CLAUSE-SET (atoms nil) (number-of-atoms 0) ;; in atom-hash-table, may not all appear in clauses (number-of-clauses 0) (number-of-literals 0) (p-clauses nil) ;; clauses that initially contained only positive literals (n-clauses nil) ;; clauses that initially contained only negative literals (m1-clauses nil) ;; clauses that initially were mixed Horn clauses (m2-clauses nil) ;; clauses that initially were mixed non-Horn clauses (atom-hash-table (make-hash-table :test #'equal)) (atoms-last nil) (p-clauses-last nil) (n-clauses-last nil) (m1-clauses-last nil) (m2-clauses-last nil) (number-to-atom-hash-table (make-hash-table))) (defstruct DP-CLAUSE (number-of-unresolved-positive-literals 0 :type fixnum) (number-of-unresolved-negative-literals 0 :type fixnum) (positive-literals nil) (negative-literals nil) (next nil)) (defstruct DP-ATOM name number (value nil) (contained-positively-clauses nil) (contained-negatively-clauses nil) (next nil) (number-of-occurrences 0)) (defvar *DEFAULT-DIMACS-CNF-FORMAT* :p) (defvar *DEFAULT-PRINT-WARNINGS* nil) (defun DP-INSERT (clause clause-set &optional (print-warnings *default-print-warnings*)) (cl:assert (not (null clause)) () "Cannot insert the empty clause.") (cl:assert (not (member 0 clause)) () "Clause ~S contains 0, which cannot be used as a literal." clause) (if clause-set (assert-dp-clause-set-p clause-set) (setq clause-set (make-dp-clause-set))) (unless (eq print-warnings :safe) (let ((v (clause-contains-repeated-atom clause))) (cond ((eq v :tautology) (when print-warnings (warn "Complementary literals in clause ~A." clause)) (return-from dp-insert clause-set)) (v (when print-warnings (warn "Duplicate literals in clause ~A." clause)) (setq clause (delete-duplicates clause :test #'equal)))))) (let ((cl (make-dp-clause)) (nlits 0) (p 0) (n 0) (positive-literals nil) (negative-literals nil) positive-literals-last negative-literals-last) (dolist (lit clause) (let* ((pos (positive-literal-p lit)) (atom0 (if pos lit (complementary-literal lit))) (atom (if (dp-atom-p atom0) atom0 (atom-named atom0 clause-set :if-does-not-exist :create)))) (incf (dp-atom-number-of-occurrences atom)) (incf nlits) (cond (pos (unless (eq :false (dp-atom-value atom)) (incf p)) (collect atom positive-literals) (push cl (dp-atom-contained-positively-clauses atom))) (t (unless (eq :true (dp-atom-value atom)) (incf n)) (collect atom negative-literals) (push cl (dp-atom-contained-negatively-clauses atom)))))) (incf (dp-clause-set-number-of-clauses clause-set)) (incf (dp-clause-set-number-of-literals clause-set) nlits) (when positive-literals (setf (dp-clause-number-of-unresolved-positive-literals cl) p) (setf (dp-clause-positive-literals cl) positive-literals)) (when negative-literals (setf (dp-clause-number-of-unresolved-negative-literals cl) n) (setf (dp-clause-negative-literals cl) negative-literals)) (cond ((null negative-literals) (if (dp-clause-set-p-clauses clause-set) (let ((temp (dp-clause-set-p-clauses-last clause-set))) (setf (dp-clause-next temp) (setf (dp-clause-set-p-clauses-last clause-set) cl))) (setf (dp-clause-set-p-clauses clause-set) (setf (dp-clause-set-p-clauses-last clause-set) cl)))) ((null positive-literals) (if (dp-clause-set-n-clauses clause-set) (let ((temp (dp-clause-set-n-clauses-last clause-set))) (setf (dp-clause-next temp) (setf (dp-clause-set-n-clauses-last clause-set) cl))) (setf (dp-clause-set-n-clauses clause-set) (setf (dp-clause-set-n-clauses-last clause-set) cl)))) ((null (rest positive-literals)) (if (dp-clause-set-m1-clauses clause-set) (let ((temp (dp-clause-set-m1-clauses-last clause-set))) (setf (dp-clause-next temp) (setf (dp-clause-set-m1-clauses-last clause-set) cl))) (setf (dp-clause-set-m1-clauses clause-set) (setf (dp-clause-set-m1-clauses-last clause-set) cl)))) (t (if (dp-clause-set-m2-clauses clause-set) (let ((temp (dp-clause-set-m2-clauses-last clause-set))) (setf (dp-clause-next temp) (setf (dp-clause-set-m2-clauses-last clause-set) cl))) (setf (dp-clause-set-m2-clauses clause-set) (setf (dp-clause-set-m2-clauses-last clause-set) cl)))))) clause-set) (defvar *DP-READ-STRING*) (defvar *DP-READ-INDEX*) (defun DP-READ (s dimacs-cnf-format print-warnings) ;; reads a single clause if dimacs-cnf-format = nil ;; reads a single literal if dimacs-cnf-format = t (loop (cond (dimacs-cnf-format (multiple-value-bind (x i) (read-from-string *dp-read-string* nil :eof :start *dp-read-index*) (cond ((eq :eof x) (if (eq :eof (setq *dp-read-string* (read-line s nil :eof))) (return :eof) (setq *dp-read-index* 0))) ((integerp x) (setq *dp-read-index* i) (return x)) ((eql 0 *dp-read-index*) ;ignore DIMACS problem/comment line (when print-warnings (warn "Skipping line ~A" *dp-read-string*)) (if (eq :eof (setq *dp-read-string* (read-line s nil :eof))) (return :eof) (setq *dp-read-index* 0))) (t (when print-warnings (warn "Skipping noninteger ~A" x)) (setq *dp-read-index* i))))) (t (let ((x (read s nil :eof))) (cond ((or (eq :eof x) (consp x)) (return x)) ;no syntax checking (print-warnings (warn "Skipping nonclause ~A" x)))))))) (defmacro CLAUSE-CONTAINS-TRUE-POSITIVE-LITERAL (clause) (let ((atom (gensym))) `(dolist (,atom (dp-clause-positive-literals ,clause) nil) (when (eq :true (dp-atom-value ,atom)) (return t))))) (defmacro CLAUSE-CONTAINS-TRUE-NEGATIVE-LITERAL (clause) (let ((atom (gensym))) `(dolist (,atom (dp-clause-negative-literals ,clause)) (when (eq :false (dp-atom-value ,atom)) (return t))))) (defun DP-COUNT (clause-set &optional print-p) ;; (dp-count clause-set) returns and optionally prints the ;; clause and literal count of clauses stored in clause-set (let ((nclauses 0) (nliterals 0) (natoms 0) (assigned nil)) (when clause-set (dolist (atom (dp-clause-set-atoms clause-set)) (when (or (dp-atom-contained-positively-clauses atom) ;atom appears in clause-set (dp-atom-contained-negatively-clauses atom)) (if (dp-atom-value atom) (setq assigned t) (incf natoms)))) (cond ((not assigned) (setq nclauses (dp-clause-set-number-of-clauses clause-set)) (setq nliterals (dp-clause-set-number-of-literals clause-set))) (t (do ((clause (dp-clause-set-p-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-positive-literal clause) (incf nclauses) (incf nliterals (dp-clause-number-of-unresolved-positive-literals clause)))) (do ((clause (dp-clause-set-n-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-negative-literal clause) (incf nclauses) (incf nliterals (dp-clause-number-of-unresolved-negative-literals clause)))) (do ((clause (dp-clause-set-m1-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (incf nclauses) (incf nliterals (dp-clause-number-of-unresolved-positive-literals clause)) (incf nliterals (dp-clause-number-of-unresolved-negative-literals clause)))) (do ((clause (dp-clause-set-m2-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (incf nclauses) (incf nliterals (dp-clause-number-of-unresolved-positive-literals clause)) (incf nliterals (dp-clause-number-of-unresolved-negative-literals clause))))))) (when print-p (format t "~&Clause set contains ~D clauses with ~D literals formed from ~D atoms~A." nclauses nliterals natoms (if (stringp print-p) print-p ""))) (values nclauses nliterals natoms))) (defun DP-CLAUSES (map-fun clause-set &optional decode-fun) ;; either return or apply map-fun to all clauses in clause-set (when clause-set (cond (map-fun (do ((clause (dp-clause-set-p-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-positive-literal clause) (funcall map-fun (decode-dp-clause clause decode-fun)))) (do ((clause (dp-clause-set-n-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-negative-literal clause) (funcall map-fun (decode-dp-clause clause decode-fun)))) (do ((clause (dp-clause-set-m1-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (funcall map-fun (decode-dp-clause clause decode-fun)))) (do ((clause (dp-clause-set-m2-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (funcall map-fun (decode-dp-clause clause decode-fun))))) (t (let ((result nil) result-last) (do ((clause (dp-clause-set-p-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-positive-literal clause) (collect (decode-dp-clause clause decode-fun) result))) (do ((clause (dp-clause-set-n-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (clause-contains-true-negative-literal clause) (collect (decode-dp-clause clause decode-fun) result))) (do ((clause (dp-clause-set-m1-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (collect (decode-dp-clause clause decode-fun) result))) (do ((clause (dp-clause-set-m2-clauses clause-set) (dp-clause-next clause))) ((null clause)) (unless (or (clause-contains-true-positive-literal clause) (clause-contains-true-negative-literal clause)) (collect (decode-dp-clause clause decode-fun) result))) result))))) (defun DP-OUTPUT-CLAUSES-TO-FILE (filename clause-set &key (dimacs-cnf-format *default-dimacs-cnf-format*)) ;; write clauses in clause-set to a file (with-open-file (s filename :direction :output :if-exists :new-version) (cond (dimacs-cnf-format (when (eq :p dimacs-cnf-format) (format s "p cnf ~D ~D~%" (dp-clause-set-number-of-atoms clause-set) (dp-count clause-set))) (dp-clauses #'(lambda (clause) (dolist (lit clause) (princ lit s) (princ " " s)) (princ 0 s) (terpri s)) clause-set (if (dolist (atom (dp-clause-set-atoms clause-set) t) (unless (and (integerp (dp-atom-name atom)) (plusp (dp-atom-name atom))) (return nil))) nil #'dp-atom-number))) (t (dp-clauses #'(lambda (clause) (prin1 clause s) (terpri s)) clause-set)))) nil) (defun ASSERT-DP-CLAUSE-SET-P (clause-set) (cl:assert (dp-clause-set-p clause-set) () "~S is not a dp-clause-set." clause-set)) (defun ATOM-NAMED (x clause-set &key (if-does-not-exist :error)) (cl:assert (not (null x)) () "~A cannot be used as an atomic formula." x) (let ((table (dp-clause-set-atom-hash-table clause-set))) (or (gethash x table) (ecase if-does-not-exist (:create (let ((atom (make-dp-atom :name x :number (incf (dp-clause-set-number-of-atoms clause-set))))) (if (dp-clause-set-atoms clause-set) (let ((temp (dp-clause-set-atoms-last clause-set))) (setf (cdr temp) (setf (dp-clause-set-atoms-last clause-set) (cons atom nil)))) (setf (dp-clause-set-atoms clause-set) (setf (dp-clause-set-atoms-last clause-set) (cons atom nil)))) (setf (gethash (dp-atom-number atom) (dp-clause-set-number-to-atom-hash-table clause-set)) atom) (setf (gethash x table) atom))) (:error (error "Unknown atom ~A." x)) ((nil) nil))))) (defun POSITIVE-LITERAL-P (lit) (cond ((numberp lit) (plusp lit)) ((and (consp lit) (eq 'not (first lit))) nil) (t t))) (defun COMPLEMENTARY-LITERAL (lit) (cond ((numberp lit) (- lit)) ((and (consp lit) (eq 'not (first lit))) (second lit)) (t (list 'not lit)))) (defun CLAUSE-CONTAINS-REPEATED-ATOM (clause) (do* ((dup nil) (lits clause (rest lits)) (lit (first lits) (first lits)) (clit (complementary-literal lit) (complementary-literal lit))) ((null (rest lits)) dup) (dolist (lit2 (rest lits)) (cond ((equal lit lit2) (setq dup t)) ((equal clit lit2) (return-from clause-contains-repeated-atom :tautology)))))) (defun DECODE-DP-CLAUSE (clause &optional decode-fun) (let ((result nil) result-last) (dolist (atom (dp-clause-negative-literals clause)) (unless (dp-atom-value atom) (collect (let ((atom (if decode-fun (funcall decode-fun atom) (dp-atom-name atom)))) (cond ((numberp atom) (- atom)) (t (list 'not atom)))) result))) (dolist (atom (dp-clause-positive-literals clause)) (unless (dp-atom-value atom) (collect (if decode-fun (funcall decode-fun atom) (dp-atom-name atom)) result))) result)) (defun ENCODE-QG-ATOM (n i j k) (declare (ignore n)) `(,i * ,j = ,k)) (defun NEGATE (atom) `(not ,atom)) (defvar USE-ROW-AND-COLUMN-SURJECTIVITY t) (defun QG (v &key (isomorphism-reducing-constraint 'last-column) not-necessarily-idempotent (clause-set (make-dp-clause-set))) (cond ((not not-necessarily-idempotent) (loop for i from 1 upto v do (dp-insert (list (encode-qg-atom v i i i)) clause-set)))) (unless (eq isomorphism-reducing-constraint 'none) (loop for i from 1 upto v do (loop for j from 1 upto v when (< (1+ j) i) do (dp-insert (list (negate (ecase isomorphism-reducing-constraint (first-row (encode-qg-atom v 1 i j)) (last-row (encode-qg-atom v v i j)) (first-column (encode-qg-atom v i 1 j)) (last-column (encode-qg-atom v i v j)) (first-value (encode-qg-atom v i j 1)) (last-value (encode-qg-atom v i j v))))) clause-set)))) (loop for i from 1 upto v do (loop for j from 1 upto v do (dp-insert (loop for k from 1 upto v collect (encode-qg-atom v i j k)) clause-set))) (when use-row-and-column-surjectivity (loop for i from 1 upto v do (loop for j from 1 upto v do (dp-insert (loop for k from 1 upto v collect (encode-qg-atom v i k j)) clause-set) (dp-insert (loop for k from 1 upto v collect (encode-qg-atom v k i j)) clause-set)))) (loop for i from 1 upto v do (loop for j from 1 upto v do (loop for k1 from 1 upto v do (loop for k2 from (1+ k1) upto v do (dp-insert (list (negate (encode-qg-atom v i j k1)) (negate (encode-qg-atom v i j k2))) clause-set) (dp-insert (list (negate (encode-qg-atom v i k1 j)) (negate (encode-qg-atom v i k2 j))) clause-set) (dp-insert (list (negate (encode-qg-atom v k1 i j)) (negate (encode-qg-atom v k2 i j))) clause-set))))) clause-set) (defun ADD-QG1-CONSTRAINT (clause-set v) (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for c from a upto v ;symmetric in a,c, so skip c in [1,a) do (loop for d from 1 upto v unless (and (= a c) (= b d)) do (loop for ab from 1 upto v do (loop for x from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v c d ab)) (negate (encode-qg-atom v x b a)) (negate (encode-qg-atom v x d c))) clause-set))))))) clause-set) (defun ADD-QG2-CONSTRAINT (clause-set v) (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for c from a upto v ;symmetric in a,c, so skip c in [1,a) do (loop for d from 1 upto v unless (and (= a c) (= b d)) do (loop for ab from 1 upto v do (loop for x from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v c d ab)) (negate (encode-qg-atom v b x a)) (negate (encode-qg-atom v d x c))) clause-set))))))) clause-set) (defun ADD-QG3-CONSTRAINT (clause-set v no-extra-equation-clauses) (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for ab from 1 upto v do (loop for ba from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v b a ba)) (encode-qg-atom v ab ba a)) clause-set) (unless no-extra-equation-clauses (dp-insert (list (encode-qg-atom v a b ab) (negate (encode-qg-atom v b a ba)) (negate (encode-qg-atom v ab ba a))) clause-set) (dp-insert (list (negate (encode-qg-atom v a b ab)) (encode-qg-atom v b a ba) (negate (encode-qg-atom v ab ba a))) clause-set)))))) ;; Slaney: if a.ax=x or xa.a=x then a=x (loop for a from 1 upto v do (loop for x from 1 upto v unless (= a x) do (loop for u from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a x u)) (negate (encode-qg-atom v a u x))) clause-set) (dp-insert (list (negate (encode-qg-atom v x a u)) (negate (encode-qg-atom v u a x))) clause-set)))) clause-set) (defun ADD-QG4-CONSTRAINT (clause-set v no-extra-equation-clauses) (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for ab from 1 upto v do (loop for ba from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v b a ba)) (encode-qg-atom v ba ab a)) clause-set) (unless no-extra-equation-clauses (dp-insert (list (encode-qg-atom v a b ab) (negate (encode-qg-atom v b a ba)) (negate (encode-qg-atom v ba ab a))) clause-set) (dp-insert (list (negate (encode-qg-atom v a b ab)) (encode-qg-atom v b a ba) (negate (encode-qg-atom v ba ab a))) clause-set)))))) clause-set) (defun ADD-QG5-CONSTRAINT (clause-set v no-extra-equation-clauses) (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for ba from 1 upto v do (loop for ba.b from 1 upto v do (dp-insert (list (negate (encode-qg-atom v b a ba)) (negate (encode-qg-atom v ba b ba.b)) (encode-qg-atom v ba.b b a)) clause-set) ;; suggested by Fujita ;; also Slaney's y(xy.y)=x and (y.xy)y=x (6/28/93) (unless no-extra-equation-clauses (dp-insert (list (encode-qg-atom v b a ba) (negate (encode-qg-atom v ba b ba.b)) (negate (encode-qg-atom v ba.b b a))) clause-set) (dp-insert (list (negate (encode-qg-atom v b a ba)) (encode-qg-atom v ba b ba.b) (negate (encode-qg-atom v ba.b b a))) clause-set)))))) clause-set) (defun ADD-QG6-CONSTRAINT (clause-set v) (loop for x from 1 upto v do (loop for a from 1 upto v do (loop for b from 1 upto v do (loop for ab from 1 upto v do (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v ab b x)) (encode-qg-atom v a ab x)) clause-set) (dp-insert (list (negate (encode-qg-atom v a b ab)) (negate (encode-qg-atom v a ab x)) (encode-qg-atom v ab b x)) clause-set))))) clause-set) (defun ADD-QG7A-CONSTRAINT (clause-set v no-extra-equation-clauses) ;;finds (132) conjugate equivalents, as suggested by Slaney ;;note: constraint on rightmost column not translated to conjugate equivalent, so number of models differs from qg7 ;; (xy.x)y=x (loop for x from 1 upto v do (loop for y from 1 upto v do (loop for xy from 1 upto v do (loop for xy.x from 1 upto v do (dp-insert (list (negate (encode-qg-atom v x y xy)) (negate (encode-qg-atom v xy x xy.x)) (encode-qg-atom v xy.x y x)) clause-set) (unless no-extra-equation-clauses (dp-insert (list (encode-qg-atom v x y xy) (negate (encode-qg-atom v xy x xy.x)) (negate (encode-qg-atom v xy.x y x))) clause-set) (dp-insert (list (negate (encode-qg-atom v x y xy)) (encode-qg-atom v xy x xy.x) (negate (encode-qg-atom v xy.x y x))) clause-set)))))) ;; (xy.y).xy=x (loop for x from 1 upto v do (loop for y from 1 upto v do (loop for xy from 1 upto v do (loop for xy.y from 1 upto v do (dp-insert (list (negate (encode-qg-atom v x y xy)) (negate (encode-qg-atom v xy y xy.y)) (encode-qg-atom v xy.y xy x)) clause-set))))) clause-set) (defun QG1 (v &key (isomorphism-reducing-constraint 'last-column) not-necessarily-idempotent) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint :not-necessarily-idempotent not-necessarily-idempotent))) (add-qg1-constraint clause-set v) clause-set)) (defun QG2 (v &key (isomorphism-reducing-constraint 'last-column) not-necessarily-idempotent) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint :not-necessarily-idempotent not-necessarily-idempotent))) (add-qg2-constraint clause-set v) clause-set)) (defun QG3 (v &key (isomorphism-reducing-constraint 'last-value) not-necessarily-idempotent (no-extra-equation-clauses t)) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint :not-necessarily-idempotent not-necessarily-idempotent))) (add-qg3-constraint clause-set v no-extra-equation-clauses) clause-set)) (defun QG4 (v &key (isomorphism-reducing-constraint 'last-value) not-necessarily-idempotent (no-extra-equation-clauses t)) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint :not-necessarily-idempotent not-necessarily-idempotent))) (add-qg4-constraint clause-set v no-extra-equation-clauses) clause-set)) (defun QG5 (v &key (isomorphism-reducing-constraint 'last-column) not-necessarily-idempotent (no-extra-equation-clauses nil)) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint :not-necessarily-idempotent not-necessarily-idempotent))) (add-qg5-constraint clause-set v no-extra-equation-clauses) clause-set)) (defun QG6 (v &key (isomorphism-reducing-constraint 'last-column)) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint))) (add-qg6-constraint clause-set v) clause-set)) (defun QG7A (v &key (isomorphism-reducing-constraint 'last-column) (no-extra-equation-clauses t)) (let ((clause-set (qg v :isomorphism-reducing-constraint isomorphism-reducing-constraint))) (add-qg7a-constraint clause-set v no-extra-equation-clauses) clause-set)) (dp-output-clauses-to-file "qg1-07.cnf" (qg1 7)) (dp-output-clauses-to-file "qg1-08.cnf" (qg1 8)) (dp-output-clauses-to-file "qg2-07.cnf" (qg2 7)) (dp-output-clauses-to-file "qg2-08.cnf" (qg2 8)) (dp-output-clauses-to-file "qg3-08.cnf" (qg3 8)) (dp-output-clauses-to-file "qg3-09.cnf" (qg3 9)) (dp-output-clauses-to-file "qg4-08.cnf" (qg4 8)) (dp-output-clauses-to-file "qg4-09.cnf" (qg4 9)) (dp-output-clauses-to-file "qg5-09.cnf" (qg5 9)) (dp-output-clauses-to-file "qg5-10.cnf" (qg5 10)) (dp-output-clauses-to-file "qg5-11.cnf" (qg5 11)) (dp-output-clauses-to-file "qg5-12.cnf" (qg5 12)) (dp-output-clauses-to-file "qg5-13.cnf" (qg5 13)) (dp-output-clauses-to-file "qg6-09.cnf" (qg6 9)) (dp-output-clauses-to-file "qg6-10.cnf" (qg6 10)) (dp-output-clauses-to-file "qg6-11.cnf" (qg6 11)) (dp-output-clauses-to-file "qg6-12.cnf" (qg6 12)) (dp-output-clauses-to-file "qg7-09.cnf" (qg7a 9)) (dp-output-clauses-to-file "qg7-10.cnf" (qg7a 10)) (dp-output-clauses-to-file "qg7-11.cnf" (qg7a 11)) (dp-output-clauses-to-file "qg7-12.cnf" (qg7a 12)) (dp-output-clauses-to-file "qg7-13.cnf" (qg7a 13)) ;;; qga.lsp EOF