Commit 283c94d3 authored by Marco Antoniotti's avatar Marco Antoniotti

Initial adding and commit of files.

parents
*.*fasl
*.*fsl
*~
.DS_Store
THUM*.DBE
ACKNOWLEDGEMENTS
================
A lot of people deserve thanks for improving CL-UNIFICATION.
The Lisp NYC group has endured presentations of this code and provided
feedback.
The following individuals have provided feedback and (precious) bug
fixes.
Boldyrev, Ivan
Brown, Robert
Korablin, Vladimir V.
Leuner, John
McManus, Russell
Scott, Peter
Werner, Norman
Copyright (c) 2004-2014 Marco Antoniotti
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in all
copies of this software.
IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE TO ANY PARTY FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR(S),
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE AUTHOR(S) UNIVERSITY, COMPANY AND/OR AFFILIATION SPECIFICALLY
DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
THE AUTHOR(S) HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
This diff is collapsed.
CL-UNIFICATION INSTALLATION
===========================
There are several ways to install CL-UNIFICATION.
Quicklisp
---------
CL-UNIFICATION is in quicklisp. The easiest way to install it is by
issuing
(ql:quickload "CL-UNIFICATION")
The package comes with a MK:DEFSYSTEM definition:
"cl-unification.system".
Issuing
(mk:load-system "CL-UNIFICATION")
or
(mk:compile-system "CL-UNIFICATION")
will make the UNIFY package available.
ASDF
----
There is also an ASDF system definition for those who use this system.
Issuing
(asdf:oos 'asdf:load-op "CL-UNIFICATION")
should make the library available in your environment.
### ASDF-INSTALL
If your CL implementation is ASDF-INSTALL aware, you should also be
able to just say
(asdf-install:install "CL-UNIFICATION")
provided that the package is unpacked in an ASDF-INSTALL known
directory.
Enjoy
CL-UNIFICATION
==============
Marco Antoniotti (c) 2004-2015
The directory containing this file you are reading should contain the
code and the documentation of the CL-UNIFICATION package.
The package is a full-blown library to "unify" arbitrary CL objects
while constructing bindings for placeholders (unification variables)
in a "template" sublanguage.
Enjoy.
20150105
;;;; -*- Mode: Lisp -*-
;;;; apply-substitutions.lisp --
;;;; General CL structures unifier.
;;;; Substitution definitions.
;;;;
;;;; See the file COPYING for copyright and licensing information.
(in-package "CL.EXT.DACF.UNIFICATION") ; DACF = Data And Control Flow.
;;;---------------------------------------------------------------------------
;;; Substitution application.
;;; apply-substitution --
;;;
;;; EXCLUDE-VARS are variables that will just pass through (a list for
;;; the time being).
(defgeneric apply-substitution (substitution item &optional exclude-vars))
(defmethod apply-substitution ((s environment) (n number) &optional exclude-vars)
(declare (ignore exclude-vars))
n)
(defmethod apply-substitution ((substitution environment) (s symbol)
&optional (exclude-vars ()))
(declare (type list exclude-vars))
(cond ((variable-any-p s) s)
((variablep s)
(if (member s exclude-vars :test #'eq)
s
(multiple-value-bind (val foundp)
(find-variable-value s substitution)
(cond (foundp (apply-substitution substitution val exclude-vars))
(t (warn "~S is a free variable in the current environment."
s)
s))))
)
(t s)))
(defmethod apply-substitution ((substitution environment) (l cons)
&optional (exclude-vars ()))
(declare (type list exclude-vars))
(cons (apply-substitution substitution (first l) exclude-vars)
(apply-substitution substitution (rest l) exclude-vars)))
(defmethod apply-substitution ((substitution environment) (l null)
&optional exclude-vars)
(declare (ignore exclude-vars))
'())
;;; compose-substitions --
;;; The definition is a direct translation of TPL's definition at page 318.
;;; Usually these are done by directly composing and currying
;;; functions in ML/Haskell derivatives, but that is just being "lazy".
;;; The current definition may be too "eager", but the "correct"
;;; semantics should be preserved.
(defun compose-substitutions (env2 env1) ; note the order.
(declare (type environment env2 env1))
(loop for env1-frame in (environment-frames env1)
collect
(loop for (var . term) in (frame-bindings env1-frame)
collect (make-binding var (apply-substitution env2 term))
into result-bindings
finally (return (make-frame result-bindings)))
into frames
finally (return (make-environment :frames frames))))
;;; ground-term --
(defun ground-term (term &optional (substitution (make-empty-environment)))
(apply-substitution substitution term))
;;;; end of file -- apply-substitutions.lisp --
;;;; -*- Mode: Lisp -*-
;;;; cl-unification-lib.asd --
;;;; ASDF system file.
;;;;
;;;; See file COPYING for copyright and licensing information.
(asdf:defsystem :cl-unification-lib
:author "Marco Antoniotti"
:components ((:module "lib-dependent"
:components ((:file "cl-ppcre-template"))))
:depends-on ("cl-ppcre" "cl-unification"))
;;;; end of file -- cl-unification-lib.asd --
;;;; -*- Mode: Lisp -*-
;;;; unification-package.lisp --
;;;; Package definition for the CL-UNIFICATION library.
;;;;
;;;; See file COPYING for copyright and licensing information.
(defpackage "IT.UNIMIB.DISCO.MA.CL.EXT.DACF.UNIFICATION" (:use "CL")
(:nicknames "CL.EXT.DACF.UNIFICATION" "UNIFY" "unify" "CL-UNIFICATION")
(:documentation "The CL.EXT.DACF.UNIFICATION Package.
This package contains all the definitions necessary for the general
Common Lisp unifier to work.
The package also has the \"UNIFY\" nickname.")
(:export
"*UNIFY-STRING-CASE-SENSITIVE-P*"
"UNIFY"
"APPLY-SUBSTITUTION"
"UNIFICATION-FAILURE"
"UNIFICATION-VARIABLE-UNBOUND"
)
(:export
"ENVIRONMENT"
"ENVIRONMENT-P"
"MAKE-EMPTY-ENVIRONMENT"
"EMPTY-ENVIRONMENT-P"
"MAKE-SHARED-ENVIRONMENT"
"COPY-ENVIRONMENT"
"PUSH-FRAME"
"POP-FRAME"
"BINDING-VARIABLE"
"BINDING-VALUE"
"EXTEND-ENVIRONMENT"
"FILL-ENVIRONMENT"
"FILL-ENVIRONMENT*"
"FIND-VARIABLE-VALUE"
"V?"
"NEW-VAR"
"VARIABLEP"
"VARIABLE-ANY-P"
)
(:export
"MATCH"
"MATCHF"
"MATCHING"
"MATCH-CASE"
"MATCHF-CASE"
)
(:export
"UNIFY*"
"UNIFY-EQUATIONS"
"UNIFY-EQUATIONS*")
(:export
"MAKE-TEMPLATE"
"TEMPLATE"
"TEMPLATE-P"
"TEMPLATE-SPEC"
"COLLECT-TEMPLATE-VARS"
)
(:export
"EXPRESSION-TEMPLATE"
"ELEMENT-TEMPLATE"
"AREF-TEMPLATE"
"ELT-TEMPLATE"
"NTH-TEMPLATE"
"NTHCDR-TEMPLATE"
"TYPE-TEMPLATE"
"ARRAY-TEMPLATE"
"NIL-TEMPLATE"
"NUMBER-TEMPLATE"
"SYMBOL-TEMPLATE"
"STANDARD-OBJECT-TEMPLATE"
"STRUCTURE-OBJECT-TEMPLATE"
"EXPRESSION-TEMPLATE-P"
"ELEMENT-TEMPLATE-P"
"AREF-TEMPLATE-P"
"ELT-TEMPLATE-P"
"NTH-TEMPLATE-P"
"NTHCDR-TEMPLATE-P"
"TYPE-TEMPLATE-P"
"ARRAY-TEMPLATE-P"
"NIL-TEMPLATE-P"
"NUMBER-TEMPLATE-P"
"SYMBOL-TEMPLATE-P"
"STANDARD-OBJECT-TEMPLATE-P"
"STRUCTURE-OBJECT-TEMPLATE-P"
)
#+cl-ppcre
(:export
"REGULAR-EXPRESSION-TEMPLATE"
"REGULAR-EXPRESSION-TEMPLATE-P"
"REGULAR-EXPRESSION"
"REGEXP")
)
;;;; end of file -- unification-package.lisp --
;;;; -*- Mode: Lisp -*-
;;;; cl-unification-test.asd
(in-package #:asdf)
;; Tests implemented using the ptester framework are run at *load* time, so
;; we tell ASDF that loading a file containing ptester code is never done.
;; This causes ASDF to run all the tests whenever ASDF:LOAD-SYSTEM or
;; ASDF:TEST-SYSTEM is called with argument CL-UNIFICATION-TEST.
(defclass ptester-source-file (cl-source-file)
()
(:documentation "A Common Lisp source file containing ptester code."))
(defmethod operation-done-p ((operation load-op) (component ptester-source-file))
nil)
(in-package #:common-lisp-user)
(defpackage #:cl-unification-test-system
(:use #:common-lisp #:asdf))
(in-package #:cl-unification-test-system)
(defsystem #:cl-unification-test
:depends-on (:cl-unification :ptester)
:components
((:module "test"
:components
((:ptester-source-file "unification-tests")))))
;;;; end of file -- cl-unification-test.asd
;;;; -*- Mode: Lisp -*-
;;;; cl-unification.asd --
;;;; ASDF system file.
;;;; See file COPYING for copyright licensing information.
;;;;===========================================================================
;;;; Simple stuff that should be built in ASDF.
(defpackage "CL-UNIFICATION-SYSTEM" (:use "CL" "ASDF"))
(in-package "CL-UNIFICATION-SYSTEM")
(defclass asdf-system-definition-file (asdf:cl-source-file) ())
(defmethod source-file-type ((c asdf-system-definition-file) (s module)) "asd")
(asdf:defsystem :cl-unification
:author "Marco Antoniotti"
:in-order-to ((test-op (test-op :cl-unification-test)))
:serial t
:components ((:file "cl-unification-pkg")
(:file "variables")
(:file "substitutions")
(:file "lambda-list-parsing")
(:file "templates-hierarchy")
(:file "unifier")
(:file "match-block")
(:file "apply-substitution")
#+asdf-with-optional-dependencies
(:module "lib-dependent"
:pathname "lib-dependent"
:depends-on ("templates-hierarchy" "unifier")
:components ((:file "cl-ppcre-template"
:depends-on (cl-ppcre))
))
#-asdf-with-optional-dependencies
(asdf-system-definition-file
"cl-unification-lib")
))
;;;; end of file -- cl-unification.asd --
;;;; -*- Mode: Lisp -*-
;;;; cl-unification.system --
;;;; MK:DEFSYSTEM system file.
;;;; See file COPYING for copyright and licensing information.
(mk:defsystem "CL-UNIFICATION"
:source-extension "lisp"
:components ((:file "cl-unification-pkg")
(:file "variables"
:depends-on ("cl-unification-pkg"))
(:file "substitutions"
:depends-on ("variables"))
(:file "lambda-list-parsing"
:depends-on ("cl-unification-pkg"))
(:file "templates-hierarchy"
:depends-on ("variables"))
(:file "unifier"
:depends-on ("templates-hierarchy"
"substitutions"
"lambda-list-parsing"))
(:file "match-block"
:depends-on ("unifier"))
(:file "apply-substitution"
:depends-on ("unifier"))
(:module "lib-dependent"
:depends-on ("unifier")
:components ((:subsystem "cl-ppcre-template"
:non-required-p t
)
))
))
;;; end of file -- cl-unification.system --
<html>
<head>
<title>CL Control Flow</title>
<link rel="stylesheet" href="main.css">
</head>
<body marginheight="0" marginwidth="0" leftmargin="0" topmargin="0" bgcolor="#ffffff">
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" vspace="0" hspace="0">
<tr>
<td colspan="3">
<div class="header"
style="font-family:=Verdana,Arial,Helvetica; font-size: 18px; color: #41286f;">
<strong><i>CL Extensions: CONTROL FLOW</i><string>
<div class="navigation">
<a href="index.html" class="navigation-link-selected">Home</a>
| <a href="downloads.html" class="navigation-link">Downloads</a>
| <a href="links.html" class="navigation-link">Links</a>
</div>
</div>
<div class="black-line"><img src="images/shim.gif" height="1" width="1"></div>
<div class="middle-bar"><img src="images/shim.gif" height="5" width="1"></div>
<div class="black-line"><img src="images/shim.gif" height="1" width="1"></div>
</td>
</tr>
<tr height="100%">
<td height="100%">&nbsp;</td>
<td valign="top" width="80%" height="100%">
<div class="content">
<div class="text" style="padding-top: 10px;">
<h1>Control Flow</h1>
<p>In order to make the use of the UNIFICATION library easier, a few
utility macros are provided. The macros MATCH, MATCHING, and
MATCH-CASE can be used to unify two (or more) objects and then to
build a lexical environment where the variables present in the to
objects (or templates) are bound to the values resulting from the
application of UNIFY.</p>
<p>
<ul>
<li>MATCH is a "single shot" macro. It does one unification and
executes forms in an appropriate lexical environment.</li>
<li>MATCH-CASE is equivalent to CASE. It tries to match a single
object (or template) against a set of clauses. The forms associated
to the first clause for which there is a successful unification, are
then executed within an appropriate lexical environment.</li>
<li>MATCHING is equivalent to COND. Each clause contains a
<em>head</em> consisting of two objects to be unified. The first
clause whose head unifies sucessfully has its associated forms
executed within an appropriate lexical environment.</li>
</ul>
</p>
<p>There are also the macro MATCHF and MATCHF-CASE, which do not
evaluate the pattern; they can be used to produce more streamlined
code.</p>
<h1>Examples</h1>
<p>These macros allow the construction of interesting <em>pattern
matching</em> like code.</p>
<p>
<pre>
(defun factorial (x)
(<b>match-case</b> (x)
(0 1)
(#T(number ?n) (* ?n (factorial (1- ?n))))
(otherwise (error "Incorrect match for ~S." x))))
</pre>
</p>
<p>Or consider the more interesting piece of code from a not-so
hypothetical Red-Black tree implementation (<em>cfr.</em>&nbsp;[<a
href="#O98">O98</a>].) The function BALANCE is the key part of the
rebalancing act played by Red-Black trees.</p>
<p>
<pre>
(defstruct (tree-node (:conc-name tn-)
(:constructor mk-tn (color left elem right)))
color
left
elem
right)
(defun balance (&rest balancing-arguments)
(<b>match-case</b> (balancing-arguments)
((:black #T(tree-node tn-color :red
tn-left #T(tree-node tn-color :red
tn-left ?a
tn-elem ?x
tn-right ?b)
tn-elem ?y
tn-right ?c)
?z
?d)
(mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
((:black #T(tree-node tn-color :red
tn-left ?a
tn-elem ?x
tn-right #T(tree-node tn-color :red
tn-left ?b
tn-elem ?y
tn-right ?c))
?z
?d)
(mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
((:black ?a
?x
#T(tree-node tn-color :red
tn-left #T(tree-node tn-color :red
tn-left ?b
tn-elem ?y
tn-right ?c)
tn-elem ?z
tn-right ?d))
(mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
((:black ?a
?x
#T(tree-node tn-color :red
tn-left ?b
tn-elem ?y
tn-left #T(tree-node tn-color :red
tn-left ?c
tn-elem ?z
tn-right ?d)))
(mk-tn :red (mk-tn :black ?a ?x ?b) ?y (mk-tn :black ?c ?z ?d)))
((?color ?left ?elem ?right)
(mk-tn ?color ?left ?elem ?right))))
</pre>
</p>
<p>This version of BALANCE is more verbose than the one given in [<a
href="#O98">O98</a>], but it preserves the general elegance of the
ML implementation.</p>
<h1>Control Flow Dictionary</h1>
<ul>
<li><a href="match-macro.html"><i>Macros</i> <b>MATCH</b> and <b>MATCHF</b></a>
<li><a href="match-case-macro.html"><i>Macros</i> <b>MATCH-CASE</b>
and <b>MATCHF-CASE</b></a>
<li><a href="matching-macro.html"><i>Macro</i> <b>MATCHING</b></a>
</ul>
<h1>Notes</h1>
<h2>Other Forms</h2>
<p>It would be obvious to add the macros EMATCH-CASE and
CMATCH-CASE, for symmetry with ECASE and CCASE. Also, MATCHING
could be renamed to MATCH-COND.</p>
<h2>Current Implementation Details</h2>
<p>The current implementations of MATCHING and MATCH-CASE do not
handle user supplied environments yet.</p>
<h2>References</h2>
<p>
<a name="O98">[O98]</a> C. Okasaki, <i>Purely Functional Data
Structures</i>, Cambridge University Press, 1998.
<!--
;;; Copyright (c) 2004-2013 Marco Antoniotti, All rigths reserved.
;;;
;;; Permission to use, modify, and redistribute this code is hereby
;;; granted.
;;; The code is provided AS IS with NO warranty whatsoever. The author
;;; will not be held liable etc etc etc etc etc.
-->
<!--
<h2>Site Map</h2>
<p>Enjoy!</p>
<hr>
<p>Questions? Queries? Suggestions? Comments? Please direct them
at <a href="mailto:marcoxa_PROVA_A_SPAMMARME@alu.org">me</a>.
</p>
-->
</div>
</div>
</td>
<!-- <td height="100%">&nbsp;</td> -->
</tr>
<tr height="100%">
<td height="100%">&nbsp;</td>
<td valign="top" width="80%" height="100%">
<div class="content">
<div class="text" style="padding-top: 10px;">
<!-- <h1>News</h1>
<p>News in chronological order, most recent on top.
</p>
<ul>
<li><strong>2004-10-30</strong><br>
Document created
</li>
</ul>
-->
</div>
</div>
</td>
<td height="100%">&nbsp;</td>
</tr>
<tr>
<td colspan="3" valign="bottom" align="right">
<div class="copyright">
&copy; 2003-2013, Marco Antoniotti, all rights reserved.
</div>
</td>
</tr>
</table>
</body>
</html>
This diff is collapsed.
<html>
<head>
<title>CL Unification: Class AREF-TEMPLATE</title>
<link rel="stylesheet" href="../main.css">
</head>
<body marginheight="0" marginwidth="0" leftmargin="0" topmargin="0" bgcolor="#ffffff">
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" vspace="0" hspace="0">
<tr>
<td colspan="3">
<div class="header"
style="font-family:=Verdana,Arial,Helvetica; font-size: 18px; color: #41286f;">
<strong><i>CL Unification: Class AREF-TEMPLATE</title></i></strong>
<div class="navigation">
<a href="index.html" class="navigation-link">Home</a>
| <a href="../unification-dictionary.html" class="navigation-link">Dictionary</a>
| <a href="element-template-class.html" class="navigation-link">Previous</a>
| <a href="elt-template-class.html" class="navigation-link">Next</a>
| <a href="downloads.html" class="navigation-link">Downloads</a>
| <a href="links.html" class="navigation-link">Links</a>
</div>
</div>
<div class="black-line"><img src="images/shim.gif" height="1" width="1"></div>
<div class="middle-bar"><img src="images/shim.gif" height="5" width="1"></div>
<div class="black-line"><img src="images/shim.gif" height="1" width="1"></div>
</td>
</tr>
<tr height="100%">
<td height="100%">&nbsp;</td>
<td valign="top" width="80%"