Logtalk is no longer distributed with YAP. Please use the Logtalk standalone installer for a smooth integration with YAP.
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@2264 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
parent
39e72437b0
commit
ea139a37c6
@ -1,97 +0,0 @@
|
||||
|
||||
@misc{logtalkweb,
|
||||
author = "Paulo Moura",
|
||||
title = "Logtalk web site",
|
||||
howpublished = "\url{http://logtalk.org/}"
|
||||
}
|
||||
|
||||
|
||||
@inproceedings{pmoura07,
|
||||
author = "Paulo Moura and Paul Crocker and Paulo Nunes",
|
||||
title = "{Multi-threading programming in Logtalk}",
|
||||
crossref = "ciclops07",
|
||||
pages = "87--101",
|
||||
}
|
||||
|
||||
|
||||
@proceedings{ciclops07,
|
||||
title = "7th Colloquium on Implementation of Constraint LOgic Programming Systems",
|
||||
publisher = "University of Oporto",
|
||||
address = "Oporto, Portugal",
|
||||
editor = "Salvador Abreu and Vitor Santos Costa",
|
||||
month = sep,
|
||||
year = 2007
|
||||
}
|
||||
|
||||
|
||||
@inproceedings{pmoura06,
|
||||
author = "Paulo Moura and Vincent Marchetti",
|
||||
title = "{Logtalk Processing of STEP Part 21 Files}",
|
||||
crossref = "iclp06",
|
||||
pages = "453--454",
|
||||
}
|
||||
|
||||
|
||||
@proceedings{iclp06,
|
||||
title = "International Conference on Logic Programming 2006",
|
||||
booktitle = "International Conference on Logic Programming 2006",
|
||||
series = "Lecture Notes in Computer Science",
|
||||
publisher = "Springer-Verlag",
|
||||
address = "Berlin Heidelberg",
|
||||
editor = "S. Etalle and M. Truszczy\'nski",
|
||||
number = 4079,
|
||||
month = aug,
|
||||
year = 2006
|
||||
}
|
||||
|
||||
|
||||
@phdthesis{pmoura03,
|
||||
author = "Paulo Moura",
|
||||
title = "{Logtalk - Design of an Object-Oriented Logic Programming Language}",
|
||||
school = "Department of Computer Science, University of Beira Interior, Portugal",
|
||||
month = sep,
|
||||
year = 2003,
|
||||
howpublished = "\url{http://logtalk.org/papers/thesis.pdf}"
|
||||
}
|
||||
|
||||
|
||||
@unpublished{pmoura00c,
|
||||
Author = "Paulo Moura",
|
||||
Title = "{Category-Based Composition in Object-Oriented Languages}",
|
||||
month = nov,
|
||||
year = 2000,
|
||||
howpublished = "\url{http://logtalk.org/papers/categories_ecoop.pdf}",
|
||||
annote = "Submitted to ECOOP 2001"
|
||||
}
|
||||
|
||||
|
||||
@techreport{pmoura00b,
|
||||
author = "Paulo Moura",
|
||||
title = "{Logtalk 2.6 Documentation}",
|
||||
institution = "University of Beira Interior, Portugal",
|
||||
number = "DMI 2000/1",
|
||||
month = jul,
|
||||
year = 2000,
|
||||
howpublished = "\url{http://logtalk.org/files/trdmi20001a4.pdf.gz}"
|
||||
}
|
||||
|
||||
|
||||
@unpublished{pmoura00a,
|
||||
Author = "Paulo Moura",
|
||||
Title = "{Category-Based Composition in Object-Oriented Languages}",
|
||||
month = apr,
|
||||
year = 2000,
|
||||
howpublished = "\url{http://logtalk.org/papers/categories_oopsla.pdf}",
|
||||
annote = "Submitted to OOPSLA 2000"
|
||||
}
|
||||
|
||||
|
||||
@article{pmoura99,
|
||||
author = "Paulo Moura",
|
||||
title = "{Porting Prolog: Notes on porting a Prolog program to 22 Prolog compilers or the relevance of the ISO Prolog standard}",
|
||||
journal = "Association of Logic Programming Newsletter",
|
||||
volume = 12,
|
||||
number = 2,
|
||||
month = may,
|
||||
year = 1999
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.8
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
This file contains detailed instructions for customizing your Logtalk
|
||||
installation and working environment. Customization is mostly done on
|
||||
a per-user basis by editing files on the Logtalk user folder (whose
|
||||
path is stored on the LOGTALKUSER environment variable; the folder itself
|
||||
can be created by running the "cplgtdirs" shell command).
|
||||
|
||||
|
||||
1. SETTING LIBRARY PATHS
|
||||
|
||||
In Logtalk, a library is simply a directory containing source files. Library
|
||||
paths can be declared using a dynamic predicate. This allows compiling and
|
||||
loading of libraries and library files to be performed without worries about
|
||||
library paths.
|
||||
|
||||
Inside your Logtalk user folder, you will find a "libpaths" folder containing
|
||||
a sample file which, when loaded, defines the library paths for the Logtalk
|
||||
standard library and for all the supplied examples. This file may need to be
|
||||
edited to match both your Logtalk installation and your Prolog compiler and
|
||||
operating-system requirements. For details, see the "libpaths/NOTES.txt" file.
|
||||
|
||||
|
||||
2. CUSTOMIZING PROLOG CONFIGURATION FILES
|
||||
|
||||
Logtalk interfaces with a specific Prolog compiler via a configuration file
|
||||
that can be found on the "configs" folder inside your Logtalk user folder.
|
||||
These configuration files can be customized by changing the default values
|
||||
of the flags that are used by Logtalk when compiling source files. For a
|
||||
full description of these flags, consult the "Running and debugging Logtalk
|
||||
programs" section of the User Manual. Some of the default flags that you may
|
||||
want to change include: "smart_compilation", "startup_message", "altdirs",
|
||||
"tmpdir", "portability", "underscore_variables", and the documentation-related
|
||||
flags ("xmldocs", "xmldir", "xslfile", "xmlspec", and "xmlsref"). Be sure
|
||||
to read the "configs/NOTES.txt" file for Prolog specific notes; some Prolog
|
||||
compilers do not support the whole range of compilation flag values.
|
||||
|
||||
|
||||
3. CUSTOMIZING DOCUMENTATION PROCESSING SCRIPTS AND SUPPORTING FILES
|
||||
|
||||
Inside your Logtalk user folder, you will find a "xml" folder containing a
|
||||
set of shell scripts, CSS and XSLT style-sheets, and DTD and XML Schema files
|
||||
for processing the XML documenting files that are automatically generated
|
||||
when you compile source files. You may want to customize the CSS and XSLT
|
||||
files to modify the layout or style of the resulting PDF/(X)HTML files or to
|
||||
write new scripts and transformations to generate other formats. You may also
|
||||
edit the file "custom.ent" in order to specify XML entities for your personal
|
||||
data that can be used on Logtalk documenting directives. For details, see the
|
||||
"xml/NOTES.txt" file.
|
||||
|
||||
|
||||
4. ADDING SUPPORT FOR EDITING LOGTALK SOURCE FILES TO TEXT EDITORS
|
||||
|
||||
Inside your Logtalk user folder, you will find a "wenv" folder, containing
|
||||
configuration files for several text editors, which add support for syntax
|
||||
highlighting and other text editing services for Logtalk source files.
|
||||
For details, see the "wenv/NOTES.txt" file.
|
@ -1,153 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.8
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
The recommended way of installing Logtalk is to use, whenever possible, one
|
||||
of the provided installers. This file contains detailed instructions for
|
||||
manual installation and configuration of Logtalk. You should also consult
|
||||
the "scripts/NOTES.txt" and "integration/NOTES.txt" files for a description
|
||||
of a set of shell scripts that might be used for Logtalk installation on
|
||||
some operating-systems and for easy Logtalk integration with popular Prolog
|
||||
compilers.
|
||||
|
||||
Note that the broad compatibility of Logtalk, both with Prolog compilers and
|
||||
operating-systems, together with all the possible user scenarios, means that
|
||||
installation can vary from very simple by running a couple of scripts to the
|
||||
need of patching both Logtalk and Prolog compilers to workaround the lack of
|
||||
strong Prolog standards.
|
||||
|
||||
|
||||
1. LOGTALK BASIC INSTALLATION
|
||||
|
||||
Installing Logtalk can be as simple as decompressing the downloaded archive
|
||||
and copying the resulting directory to a suitable location. This location
|
||||
depends on the working environment and on the number of users. The Logtalk
|
||||
directory can reside in any user accessible location. Whenever possible, it
|
||||
is recommended that Logtalk be installed by a user with administrative rights,
|
||||
as described below. This leads to a setup where each Logtalk user may freely
|
||||
try and modify the provided examples, library, and configuration files with
|
||||
the option of, at any time, restoring the files to its original state by
|
||||
simply running one of the provided scripts.
|
||||
|
||||
|
||||
* Installing for a single user with no administrative rights:
|
||||
|
||||
In the case of a single user with no administrative rights, the Logtalk
|
||||
directory may simply be copied to the user home directory.
|
||||
|
||||
|
||||
* Installing for one or more users by a user with administrative rights:
|
||||
|
||||
In the case of installation by a user with administrative rights, the Logtalk
|
||||
directory can be copied to any location that its accessible by all the users
|
||||
(assuming that copying the Logtalk directory to each user home directory is,
|
||||
for some reason, not feasible or desired).
|
||||
|
||||
The "scripts" sub-directory contains shell scripts for easy installation of
|
||||
Logtalk on POSIX operating systems (see the "scripts/NOTES.txt" file for
|
||||
details). Starting from the Logtalk directory, type:
|
||||
|
||||
% cd scripts
|
||||
% sudo ./install.sh
|
||||
|
||||
This installation script makes all files read-only for non-admin users in
|
||||
order to avoid user tempering. This is a convenient setup for computer labs,
|
||||
given that making directories world-writable is a security risk.
|
||||
|
||||
|
||||
2. SETTING LOGTALK ENVIRONMENT VARIABLES
|
||||
|
||||
You need to set two environment variables, LOGTALKHOME and LOGTALKUSER. The
|
||||
environment variable LOGTALKHOME should be set to the Logtalk installation
|
||||
directory. The environment variable LOGTALKUSER should point to a directory
|
||||
in your home directory where you want to store the user-specific Logtalk files
|
||||
(by default, ~/logtalk). Both environment variables may be set for all users
|
||||
by a user with administration privileges. The two environment variables can
|
||||
have the same value if you are the only Logtalk user on your computer and if
|
||||
you have full permissions to the Logtalk installation directory. In addition,
|
||||
you may want to add the Logtalk sub-directory "xml", which contains useful
|
||||
scripts for processing XML documenting files, to your execution path.
|
||||
|
||||
>> POSIX systems:
|
||||
|
||||
If you use a csh shell, add the following line to your ~/.cshrc file:
|
||||
|
||||
setenv LOGTALKHOME /your/logtalk/installation/directory
|
||||
setenv LOGTALKUSER $HOME/logtalk
|
||||
setenv PATH $PATH:$LOGTALKHOME/xml:$LOGTALKHOME/scripts
|
||||
|
||||
If you use a bash shell, add the following lines to your ~/.profile file:
|
||||
|
||||
LOGTALKHOME=/your/logtalk/installation/directory
|
||||
LOGTALKUSER=$HOME/logtalk
|
||||
PATH=$PATH:$LOGTALKHOME/xml:$LOGTALKHOME/scripts
|
||||
export PATH LOGTALKHOME LOGTALKUSER
|
||||
|
||||
When using the provided shell script for installing Logtalk, a symbolic link
|
||||
to the Logtalk installation directory is automatically created. The link is
|
||||
named "logtalk". In this case, you may use this symbolic link to define the
|
||||
LOGTALKHOME environment variable in order to avoid breaking it when upgrading
|
||||
Logtalk.
|
||||
|
||||
>> Windows systems:
|
||||
|
||||
In Windows 2000/XP, environment variables are defined using the System
|
||||
properties control panel. If you are a system administrator, the Windows
|
||||
GUI installer sets the LOGTALKHOME environment variable for all users and
|
||||
also sets the LOGTALKUSER environment variable for the administrator user
|
||||
running the installer.
|
||||
|
||||
|
||||
3. END-USER SETUP (COPYING LOGTALK USER-MODIFIABLE FILES TO USERS HOME DIRS)
|
||||
|
||||
If you installed Logtalk on your home directory, then skip this step if you
|
||||
have set both Logtalk environment variables (LOGTALKHOME and LOGTALKUSER) to
|
||||
point to the same directory.
|
||||
|
||||
Each user must make a local copy of the Logtalk user-modifiable files to its
|
||||
home directory. This setup allows each user to easily and independently
|
||||
customize Logtalk to its needs. These copies can be easily made by instructing
|
||||
end-users to simply run the shell scripts "cplgtdirs.*" (which are described
|
||||
in the "scripts/NOTES.txt" file).
|
||||
|
||||
>> POSIX systems:
|
||||
|
||||
% cplgtdirs
|
||||
|
||||
>> Windows:
|
||||
|
||||
C:\> cplgtdirs
|
||||
|
||||
The local copies made by the "cplgtdirs" scripts have both read and write
|
||||
permissions for the user running the script. When used with one of the
|
||||
back-end Prolog compilers for which an integration script is provided on
|
||||
the "integration" directory, this setup as the advantage of allowing each
|
||||
end-user to independently customize default compilation options and library
|
||||
paths.
|
||||
|
||||
Windows (non-admin) users may also use the Logtalk GUI installer to setup
|
||||
their Logtalk user folder and the LOGTALKUSER environment variable.
|
||||
|
||||
|
||||
4. CREATING NEW PROLOG TOP-LEVELS FOR AUTOMATIC LOADING OF LOGTALK
|
||||
|
||||
Most Prolog compilers allows the user to define an initialization file
|
||||
that is automatically consulted at startup. These initialization files
|
||||
may contain directives for loading other files, such as the Logtalk
|
||||
configuration file and the Logtalk compiler. The "$LOGTALKHOME/integration"
|
||||
sub-directory contains several pre-made scripts (named "*lgt.*") for running
|
||||
Logtalk with selected back-end Prolog compilers. You can use these scripts
|
||||
as examples when creating initialization files for other Prolog compilers.
|
||||
Be sure to read the "configs/NOTES.txt" file notes on the Prolog compilers
|
||||
that you intend to use. You may also simply follow the steps described in
|
||||
the "QUICK_START.txt" file.
|
||||
|
||||
|
||||
5. CUSTOMIZING LOGTALK
|
||||
|
||||
Please see the file "CUSTOMIZE.txt" for details on how to customize your
|
||||
Logtalk installation and working environment.
|
@ -1,201 +0,0 @@
|
||||
The Artistic License 2.0
|
||||
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
This license establishes the terms under which a given free software
|
||||
Package may be copied, modified, distributed, and/or redistributed.
|
||||
The intent is that the Copyright Holder maintains some artistic
|
||||
control over the development of that Package while still keeping the
|
||||
Package available as open source and free software.
|
||||
|
||||
You are always permitted to make arrangements wholly outside of this
|
||||
license directly with the Copyright Holder of a given Package. If the
|
||||
terms of this license do not permit the full use that you propose to
|
||||
make of the Package, you should contact the Copyright Holder and seek
|
||||
a different licensing arrangement.
|
||||
|
||||
Definitions
|
||||
|
||||
"Copyright Holder" means the individual(s) or organization(s)
|
||||
named in the copyright notice for the entire Package.
|
||||
|
||||
"Contributor" means any party that has contributed code or other
|
||||
material to the Package, in accordance with the Copyright Holder's
|
||||
procedures.
|
||||
|
||||
"You" and "your" means any person who would like to copy,
|
||||
distribute, or modify the Package.
|
||||
|
||||
"Package" means the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection and/or of
|
||||
those files. A given Package may consist of either the Standard
|
||||
Version, or a Modified Version.
|
||||
|
||||
"Distribute" means providing a copy of the Package or making it
|
||||
accessible to anyone else, or in the case of a company or
|
||||
organization, to others outside of your company or organization.
|
||||
|
||||
"Distributor Fee" means any fee that you charge for Distributing
|
||||
this Package or providing support for this Package to another
|
||||
party. It does not mean licensing fees.
|
||||
|
||||
"Standard Version" refers to the Package if it has not been
|
||||
modified, or has been modified only in ways explicitly requested
|
||||
by the Copyright Holder.
|
||||
|
||||
"Modified Version" means the Package, if it has been changed, and
|
||||
such changes were not explicitly requested by the Copyright
|
||||
Holder.
|
||||
|
||||
"Original License" means this Artistic License as Distributed with
|
||||
the Standard Version of the Package, in its current version or as
|
||||
it may be modified by The Perl Foundation in the future.
|
||||
|
||||
"Source" form means the source code, documentation source, and
|
||||
configuration files for the Package.
|
||||
|
||||
"Compiled" form means the compiled bytecode, object code, binary,
|
||||
or any other form resulting from mechanical transformation or
|
||||
translation of the Source form.
|
||||
|
||||
|
||||
Permission for Use and Modification Without Distribution
|
||||
|
||||
(1) You are permitted to use the Standard Version and create and use
|
||||
Modified Versions for any purpose without restriction, provided that
|
||||
you do not Distribute the Modified Version.
|
||||
|
||||
|
||||
Permissions for Redistribution of the Standard Version
|
||||
|
||||
(2) You may Distribute verbatim copies of the Source form of the
|
||||
Standard Version of this Package in any medium without restriction,
|
||||
either gratis or for a Distributor Fee, provided that you duplicate
|
||||
all of the original copyright notices and associated disclaimers. At
|
||||
your discretion, such verbatim copies may or may not include a
|
||||
Compiled form of the Package.
|
||||
|
||||
(3) You may apply any bug fixes, portability changes, and other
|
||||
modifications made available from the Copyright Holder. The resulting
|
||||
Package will still be considered the Standard Version, and as such
|
||||
will be subject to the Original License.
|
||||
|
||||
|
||||
Distribution of Modified Versions of the Package as Source
|
||||
|
||||
(4) You may Distribute your Modified Version as Source (either gratis
|
||||
or for a Distributor Fee, and with or without a Compiled form of the
|
||||
Modified Version) provided that you clearly document how it differs
|
||||
from the Standard Version, including, but not limited to, documenting
|
||||
any non-standard features, executables, or modules, and provided that
|
||||
you do at least ONE of the following:
|
||||
|
||||
(a) make the Modified Version available to the Copyright Holder
|
||||
of the Standard Version, under the Original License, so that the
|
||||
Copyright Holder may include your modifications in the Standard
|
||||
Version.
|
||||
|
||||
(b) ensure that installation of your Modified Version does not
|
||||
prevent the user installing or running the Standard Version. In
|
||||
addition, the Modified Version must bear a name that is different
|
||||
from the name of the Standard Version.
|
||||
|
||||
(c) allow anyone who receives a copy of the Modified Version to
|
||||
make the Source form of the Modified Version available to others
|
||||
under
|
||||
|
||||
(i) the Original License or
|
||||
|
||||
(ii) a license that permits the licensee to freely copy,
|
||||
modify and redistribute the Modified Version using the same
|
||||
licensing terms that apply to the copy that the licensee
|
||||
received, and requires that the Source form of the Modified
|
||||
Version, and of any works derived from it, be made freely
|
||||
available in that license fees are prohibited but Distributor
|
||||
Fees are allowed.
|
||||
|
||||
|
||||
Distribution of Compiled Forms of the Standard Version
|
||||
or Modified Versions without the Source
|
||||
|
||||
(5) You may Distribute Compiled forms of the Standard Version without
|
||||
the Source, provided that you include complete instructions on how to
|
||||
get the Source of the Standard Version. Such instructions must be
|
||||
valid at the time of your distribution. If these instructions, at any
|
||||
time while you are carrying out such distribution, become invalid, you
|
||||
must provide new instructions on demand or cease further distribution.
|
||||
If you provide valid instructions or cease distribution within thirty
|
||||
days after you become aware that the instructions are invalid, then
|
||||
you do not forfeit any of your rights under this license.
|
||||
|
||||
(6) You may Distribute a Modified Version in Compiled form without
|
||||
the Source, provided that you comply with Section 4 with respect to
|
||||
the Source of the Modified Version.
|
||||
|
||||
|
||||
Aggregating or Linking the Package
|
||||
|
||||
(7) You may aggregate the Package (either the Standard Version or
|
||||
Modified Version) with other packages and Distribute the resulting
|
||||
aggregation provided that you do not charge a licensing fee for the
|
||||
Package. Distributor Fees are permitted, and licensing fees for other
|
||||
components in the aggregation are permitted. The terms of this license
|
||||
apply to the use and Distribution of the Standard or Modified Versions
|
||||
as included in the aggregation.
|
||||
|
||||
(8) You are permitted to link Modified and Standard Versions with
|
||||
other works, to embed the Package in a larger work of your own, or to
|
||||
build stand-alone binary or bytecode versions of applications that
|
||||
include the Package, and Distribute the result without restriction,
|
||||
provided the result does not expose a direct interface to the Package.
|
||||
|
||||
|
||||
Items That are Not Considered Part of a Modified Version
|
||||
|
||||
(9) Works (including, but not limited to, modules and scripts) that
|
||||
merely extend or make use of the Package, do not, by themselves, cause
|
||||
the Package to be a Modified Version. In addition, such works are not
|
||||
considered parts of the Package itself, and are not subject to the
|
||||
terms of this license.
|
||||
|
||||
|
||||
General Provisions
|
||||
|
||||
(10) Any use, modification, and distribution of the Standard or
|
||||
Modified Versions is governed by this Artistic License. By using,
|
||||
modifying or distributing the Package, you accept this license. Do not
|
||||
use, modify, or distribute the Package, if you do not accept this
|
||||
license.
|
||||
|
||||
(11) If your Modified Version has been derived from a Modified
|
||||
Version made by someone other than you, you are nevertheless required
|
||||
to ensure that your Modified Version complies with the requirements of
|
||||
this license.
|
||||
|
||||
(12) This license does not grant you the right to use any trademark,
|
||||
service mark, tradename, or logo of the Copyright Holder.
|
||||
|
||||
(13) This license includes the non-exclusive, worldwide,
|
||||
free-of-charge patent license to make, have made, use, offer to sell,
|
||||
sell, import and otherwise transfer the Package with respect to any
|
||||
patent claims licensable by the Copyright Holder that are necessarily
|
||||
infringed by the Package. If you institute patent litigation
|
||||
(including a cross-claim or counterclaim) against any party alleging
|
||||
that the Package constitutes direct or contributory patent
|
||||
infringement, then this Artistic License to you shall terminate on the
|
||||
date that such litigation is filed.
|
||||
|
||||
(14) Disclaimer of Warranty:
|
||||
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
|
||||
IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
|
||||
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,127 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.8
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
Quick start
|
||||
===========
|
||||
|
||||
|
||||
Starting up Logtalk
|
||||
-------------------
|
||||
|
||||
1. Install Logtalk by using either the installer provided for your
|
||||
operating-system (when available) or by following the instructions
|
||||
on the "INSTALL.txt" file. Depending on your operating-system, working
|
||||
environment, and favorite Prolog compiler, you may already have a
|
||||
script or a shortcut installed for easily running Logtalk with your
|
||||
favorite Prolog compiler. In this case, skip the instructions below
|
||||
for starting up Logtalk and go straight to the instructions on running
|
||||
the examples.
|
||||
|
||||
On POSIX operating-systems, the following shell scripts are installed
|
||||
by default for running Logtalk with selected back-end Prolog compilers
|
||||
(which must be properly installed for running the scripts!):
|
||||
|
||||
B-Prolog: bplgt (first run must use sudo)
|
||||
CIAO: ciaolgt (first run must use sudo)
|
||||
CxProlog: cxlgt
|
||||
ECLiPSe: eclipselgt
|
||||
GNU Prolog: gplgt
|
||||
K-Prolog: plclgt
|
||||
SICStus Prolog: sicstuslgt
|
||||
SWI-Prolog: swilgt
|
||||
XSB: xsblgt (first run must use sudo)
|
||||
YAP: yaplgt
|
||||
|
||||
On Windows systems, shortcuts for running Logtalk with selected back-end
|
||||
Prolog compilers are created on the "Start Menu/Programs/Logtalk" menu.
|
||||
If you get an unexpected failure when using one of the Prolog integration
|
||||
scripts, consult the "configs/NOTES.txt" file for compatibility notes.
|
||||
|
||||
2. Open the "manuals/index.html" file with a web browser.
|
||||
|
||||
3. Select the "Tutorial" link. This will provide you with a basic
|
||||
understanding of the main Logtalk concepts.
|
||||
|
||||
4. Go back to the "index.html" file, select the "User Manual" link,
|
||||
then the "Installing Logtalk" and "Running and debugging Logtalk
|
||||
programs" links. This will provide you with a basic understanding of
|
||||
how to start Logtalk as well as how to compile and load Logtalk code.
|
||||
|
||||
|
||||
In case a manual installation is necessary, and assuming that Logtalk
|
||||
supports your Prolog compiler, apply the following steps:
|
||||
|
||||
1. Read the "NOTES.txt" file in the "configs" sub-directory to check if
|
||||
any patch or workaround is needed for your compiler.
|
||||
|
||||
2. Start your Prolog compiler.
|
||||
|
||||
3. Change the current working directory of your Prolog session to the
|
||||
Logtalk installation directory. If you don't know which predicate to
|
||||
use, check the "configs/NOTES.txt" file or your Prolog compiler reference
|
||||
manual.
|
||||
|
||||
4. Compile and load the config file for your Prolog compiler.
|
||||
|
||||
5. Compile and load the Logtalk compiler/runtime found on the "compiler"
|
||||
sub-directory.
|
||||
|
||||
6. Adapt, if needed, the file "libpaths/libpaths.pl" to match your Logtalk
|
||||
installation, Prolog compiler, operating-system, and then compile and
|
||||
load it.
|
||||
|
||||
Note that both the configuration files, the compiler/runtime files, and the
|
||||
library paths file are Prolog files. The predicate used to load these files
|
||||
depends on your Prolog compiler (consult your Prolog compiler documentation
|
||||
or take a look at the definition of the predicate '$lgt_load_prolog_code'/1
|
||||
in the config file. For most command-line compilers, you could type at the
|
||||
Prolog prompt something like:
|
||||
|
||||
| ?- ['configs/foo.config', 'compiler/logtalk.pl', 'libpaths/libpaths.pl'].
|
||||
|
||||
Replace the file name "foo.config" with the appropriate config file name for
|
||||
your compiler.
|
||||
|
||||
|
||||
Running the examples
|
||||
--------------------
|
||||
|
||||
You may now try some of the provided examples:
|
||||
|
||||
1. Open the "examples" sub-directory. There you find several sub-directories
|
||||
with ready to run examples and a "NOTES.txt" file containing general
|
||||
instructions and a brief description of each example. Select and open one
|
||||
of the examples sub-directory.
|
||||
|
||||
2. Read the example "NOTES.txt" file for a description of the example.
|
||||
|
||||
3. Open the "SCRIPT.txt" file for instructions on how to load the example
|
||||
and for sample queries that you may try by copying-and-pasting them to
|
||||
your Prolog interpreter top-level.
|
||||
|
||||
|
||||
Writing your own programs
|
||||
_________________________
|
||||
|
||||
Ready to start writing your own programs?
|
||||
|
||||
1. Read the User Manual sections on "Programming in Logtalk" and "Running
|
||||
and debugging Logtalk programs".
|
||||
|
||||
2. Take a look at the "wenv" sub-directory. There you will find syntax
|
||||
configuration files for popular text editors which enable syntax coloring
|
||||
and other text services when editing Logtalk source files.
|
||||
|
||||
3. Create a sub-directory with a suitable name to hold all the files of
|
||||
your application. You may want to add the directory path to the "libpaths.pl"
|
||||
file mentioned above in order to easily load your application.
|
||||
|
||||
4. Copy to this sub-directory a loader file from one of the example
|
||||
directories and modify it to load your own source files.
|
||||
|
||||
5. Have fun!
|
@ -1,25 +0,0 @@
|
||||
=================================================================
|
||||
Logtalk - Object oriented extension to Prolog
|
||||
Release 2.24.0
|
||||
|
||||
Copyright (c) 1998-2001 Paulo Moura. All Rights Reserved.
|
||||
=================================================================
|
||||
|
||||
|
||||
This version of Logtalk included in the YAP distribuition does not
|
||||
contain configuration files for other Prolog compilers. Also, the
|
||||
Logtalk compiler/pre-processor is contained in the library/logtalk
|
||||
directory.
|
||||
|
||||
Logtalk can be loaded from YAP either as described in the included
|
||||
Logtalk documentation or by using the call:
|
||||
|
||||
| ?- use_module(library(logtalk)).
|
||||
|
||||
This will provide you with the minimal support for compiling and
|
||||
running Logtalk programs. For improved Logtalk + YAP integration,
|
||||
please follow the instructions on the Logtalk INSTALL file.
|
||||
|
||||
Note that, although we load Logtalk using the use_module/1 built-in
|
||||
predicate, the system is not packaged as a module nor does it use
|
||||
modules in its implementation.
|
@ -1,124 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.8
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
CONTENTS
|
||||
|
||||
1. License
|
||||
2. Home of Logtalk package
|
||||
3. Registration
|
||||
4. Support
|
||||
5. Installation
|
||||
6. Customization
|
||||
7. Quick start
|
||||
8. Documentation
|
||||
9. Upgrading
|
||||
10. Citations
|
||||
11. Contributions
|
||||
|
||||
|
||||
1. LICENSE
|
||||
|
||||
The overall copyright and permission notice for Logtalk can be found
|
||||
in the "LICENSE.txt" file in this directory. Logtalk follows the
|
||||
Artistic License 2.0. The copyright notice and license applies to all
|
||||
files in this release (including sources, documentation, and examples)
|
||||
unless otherwise explicitly stated.
|
||||
|
||||
|
||||
2. HOME OF LOGTALK PACKAGE
|
||||
|
||||
The latest release of the Logtalk package is always available at the URL:
|
||||
|
||||
http://logtalk.org/
|
||||
|
||||
At this address you can also find additional documentation and information
|
||||
about Logtalk.
|
||||
|
||||
|
||||
3. REGISTRATION
|
||||
|
||||
To register as a Logtalk user either use the registration form found at
|
||||
the Logtalk web site, http://logtalk.org/regform.html, or send an email
|
||||
message to:
|
||||
|
||||
registration@logtalk.org
|
||||
|
||||
with the following information:
|
||||
|
||||
email address, full name, organization, organization type (education,
|
||||
commercial, government, ...), prolog compilers used (optional),
|
||||
platforms (mac, pc, unix,...) (optional)
|
||||
|
||||
|
||||
4. SUPPORT
|
||||
|
||||
For support options, please consult the page http://logtalk.org/support.html.
|
||||
|
||||
|
||||
5. INSTALLATION
|
||||
|
||||
Logtalk can be installed either from sources by running a few shell scripts
|
||||
or by using one of the provided installers, depending on your operating
|
||||
system. For manual installation, see the file "INSTALL.txt" for detailed
|
||||
instructions.
|
||||
|
||||
See the user manual for a description of the source files organization
|
||||
and for using instructions (to read the user manual open the file
|
||||
"manuals/index.html" with a web browser). Most files are formatted
|
||||
using four-space tabs.
|
||||
|
||||
|
||||
6. CUSTOMIZATION
|
||||
|
||||
The file "CUSTOMIZE.txt" provides detailed instructions for customizing the
|
||||
Logtalk installation and working environment.
|
||||
|
||||
|
||||
7. QUICK START
|
||||
|
||||
The file "QUICK_START.txt" provides quick instructions for those of you in
|
||||
a hurry to run Logtalk, provided that your favorite Prolog compiler is
|
||||
supported.
|
||||
|
||||
|
||||
8. DOCUMENTATION
|
||||
|
||||
The reference and user manuals and the tutorial are provided in XHTML format
|
||||
and can be found in the "manuals" directory.
|
||||
|
||||
The file "RELEASE_NOTES.txt" contains descriptions of all Logtalk updates
|
||||
since the first public version. Read it carefully if you have been using a
|
||||
previous Logtalk version.
|
||||
|
||||
|
||||
9. UPGRADING
|
||||
|
||||
If you are upgrading from a previous Logtalk version, please check the file
|
||||
"UPGRADING.txt" for instructions on how to upgrade your programs or your
|
||||
custom configuration files to run under this new version.
|
||||
|
||||
|
||||
10. CITATIONS
|
||||
|
||||
If you find Logtalk useful, please include a citation on your publications.
|
||||
Consult the file "BIBLIOGRAPHY.bib" for bibliographic references in BibTeX
|
||||
format (the Logtalk technical report published on 2000 or the 2003 PhD thesis
|
||||
on Logtalk are good choices).
|
||||
|
||||
|
||||
11. CONTRIBUTIONS
|
||||
|
||||
Contributions, constructive criticisms, code, bug reports, and suggestions
|
||||
are always welcome. If you want to contribute to this project, drop me a
|
||||
line to the support address given above.
|
||||
|
||||
|
||||
Happy Logtalking!
|
||||
|
||||
Paulo Moura
|
||||
pmoura@logtalk.org
|
File diff suppressed because it is too large
Load Diff
@ -1,175 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.8
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
Upgrading from Logtalk 1.x
|
||||
==========================
|
||||
|
||||
Logtalk 2.x is not compatible with programs written for Logtalk 1.x.
|
||||
However, you should be able to translate most programs to make them
|
||||
run under Logtalk 2.x. Most of the examples provided with Logtalk 1.x
|
||||
have been rewritten to run under Logtalk 2.x. You may use them as
|
||||
translation examples.
|
||||
|
||||
|
||||
Upgrading from a previous Logtalk 2.x versions
|
||||
==============================================
|
||||
|
||||
Changes in the Logtalk compiler between releases may render Prolog config
|
||||
files from older versions incompatible with new ones. You may need to update
|
||||
your local Logtalk user files by running e.g. the "cplgtdirs" shell script.
|
||||
|
||||
If your Logtalk programs depend on some of the example files, it is
|
||||
advisable that you check your code against the new version before
|
||||
throwing away the older release.
|
||||
|
||||
Logtalk source files will need to be recompiled because of the changes
|
||||
done in the version 2.5.0 to improve message sending performance.
|
||||
|
||||
Logtalk version 2.7.0 provides the first cut of the Logtalk standard library.
|
||||
Most examples have been rewritten to take advantage of the library.
|
||||
|
||||
Logtalk version 2.8.0 introduces a small change on the logtalk_compile/1-2
|
||||
and logtalk_load/1-2 predicates that may imply updating your loader utility
|
||||
files: the first argument is now always a list of entities even if we want
|
||||
to compile or load a single entity.
|
||||
|
||||
Logtalk version 2.9.0 changes compiled code functors postfixes from "_sdcl"
|
||||
and "_sdef" to "_idcl" and "_idef", implying recompilation of all objects,
|
||||
protocols, and categories.
|
||||
|
||||
Logtalk version 2.10.0 changes some of the semantics of object dynamic
|
||||
predicates. See the release notes for a description of the changes.
|
||||
|
||||
Logtalk version 2.14.4 removes the definition of the deprecated built-in
|
||||
predicate logtalk_version/3 (use current_logtalk_flag/3 instead).
|
||||
|
||||
Logtalk version 2.14.5 changes compiled code in order to correct a bug
|
||||
where sending messages such as true/0 to an unknown object will succeeded
|
||||
instead of throwing the expected exception, implying recompilation of all
|
||||
objects, protocols, and categories.
|
||||
|
||||
Logtalk version 2.14.7 changes compiled code in order to optimize the
|
||||
code generated by the compilation of dynamic predicate clauses.
|
||||
|
||||
Logtalk version 2.15.0 changes the "authors" key in the directive info/1 to
|
||||
"author". All the XSLT, DTD, and XSD files have been update to conform to
|
||||
this change. If you use the directive info/1 in your programs, you will need
|
||||
to apply this change to take advantage of automatic generation of documenting
|
||||
files.
|
||||
|
||||
Logtalk version 2.15.3 changes the format of the runtime entity tables,
|
||||
implying recompilation of all objects, protocols, and categories.
|
||||
|
||||
Logtalk version 2.15.6 renamed the compiler flag "named_anonymous_vars" to
|
||||
"underscore_variables" and changed the possible option values form "on/off" to
|
||||
"dont_care/singletons".
|
||||
|
||||
Logtalk 2.16.0 improves support for the declaration and use of operators
|
||||
local to objects and categories. Recompilation of any objects and categories
|
||||
containing operator declarations is needed in order to take advantage of the
|
||||
improvements made.
|
||||
|
||||
Logtalk 2.16.1 now checks for attempts to redefined built-in Logtalk control
|
||||
constructs when compiling source files. These checks may generate compilation
|
||||
errors on files containing bugs that are not detected on previous versions of
|
||||
the compiler.
|
||||
|
||||
Logtalk version 2.16.2 changed the possible option values of the read-only
|
||||
compiler flag "startup_message" to "none", "banner", and "flags". Default
|
||||
value is "flags" (print both banner and default flag values).
|
||||
|
||||
Logtalk version 2.17.1 removes predicate nth/3 from library entities listp,
|
||||
list, and difflist (replaced by the predicates nth0/3 and nth1/3).
|
||||
|
||||
Logtalk version 2.20.0 updates the semantics of the uses/1 entity directive
|
||||
to accept as argument a single object identifier (this change is needed in
|
||||
order to ensure compatibility with the new uses/2 predicate directive).
|
||||
|
||||
Logtalk version 2.21.2 adds a new clause to the code generated when compiling
|
||||
entity in order to support the new alias/1 predicate property, implying
|
||||
recompilation of all objects, protocols, and categories.
|
||||
|
||||
Logtalk version 2.22.0 adds support for using the notation <library>(<file>)
|
||||
when compiling and loading source files. Logtalk applications using this new
|
||||
notation will need to be modified in order to run in previous Logtalk versions.
|
||||
In addition, the exceptions generated by the predicates logtalk_compile/1-2
|
||||
and logtalk_load/1-2 have been updated to take into account this new feature.
|
||||
|
||||
Logtalk version 2.22.2 adds stricter checking for the documenting directives
|
||||
(info/1 and info/2), which can lead to compilation errors on entities which
|
||||
compiled successfully on previous Logtalk versions.
|
||||
|
||||
Logtalk version 2.22.5 adds new predicates to all config files (consult the
|
||||
release notes for details). If you are using custom config files, be sure to
|
||||
update them by coping the definition of the new predicates.
|
||||
|
||||
Logtalk version 2.23.0 features new, optimized implementations of the database
|
||||
built-in methods, implying the recompilation of all objects, protocols, and
|
||||
categories.
|
||||
|
||||
Logtalk version 2.25.0 drops support for source metafiles and .mlgt file name
|
||||
extension as this version features a new, file-based compiler supporting the
|
||||
definition of any number of entities in a single file. Older code using source
|
||||
metafiles will need to rename the file name extensions from .mlgt to .lgt.
|
||||
|
||||
Logtalk version 2.25.1 updates the compiler to generate XML documenting files
|
||||
whose names always contain the arity of the entity identifier appended at the
|
||||
end (using the format "_arity"). This change implied updates to the lgt2xml.*
|
||||
and lgt2html.* shell scripts which render them incompatible with the XML files
|
||||
generated by previous Logtalk versions.
|
||||
|
||||
Logtalk version 2.27.0 changes representation of declared predicates in order
|
||||
to support the new predicate property non_terminal/1, implying recompilation
|
||||
of all objects, protocols, and categories.
|
||||
|
||||
Logtalk version 2.27.1 optimizes the generation of predicate definition and
|
||||
declaration linking clauses, resulting in small performance improvements and
|
||||
in space savings for the Prolog code generated when compiling Logtalk entities.
|
||||
Recompilation of all objects, protocols, and categories is necessary in order
|
||||
to take advantage of this optimizations.
|
||||
|
||||
Logtalk 2.28.0 changes representation of meta-predicates, implying the
|
||||
recompilation of all objects, protocols, and categories that define them.
|
||||
In addition, in order to close some security holes where meta-predicates
|
||||
could be used to bypass predicate scope declarations, meta-predicates that
|
||||
use closures must be re-implemented to use the new call/N Logtalk built-in
|
||||
predicate. The directive metapredicate/1 is now deprecated, the directive
|
||||
meta_predicate/1 should be used instead. There are also changes to the
|
||||
config files that render the Logtalk runtime incompatible with the config
|
||||
files of previous versions.
|
||||
|
||||
Logtalk 2.29.0 makes some incompatible changes to the experimental support
|
||||
for multi-threading programming that may imply updating any application that
|
||||
uses the multi-threading predicates. The default value of the compiler flag
|
||||
events/1 is now off. Applications using event-driven programming must either
|
||||
turn this flag on or compile source files with the events(on) option. The
|
||||
library protocol "event_handlersp" is now deprecated; new code should use
|
||||
instead the built-in "monitoring" protocol. The new support for "threaded"
|
||||
and "synchronized" entity properties implies recompilation of all objects
|
||||
and categories.
|
||||
|
||||
Logtalk 2.29.2 removes the built-in predicate threaded_discard/1.
|
||||
|
||||
Logtalk 2.29.5 adds a new compiler option, "reload", whose default value is
|
||||
defined in the config files. This makes previous config files incompatible
|
||||
with this new Logtalk version.
|
||||
|
||||
Logtalk 2.30.0 adds two new compiler options, "xmldir" and "tmpdir", allowing
|
||||
a per-project definition of directories for storing XML documenting files and
|
||||
for storing intermediate compilation files (e.g. Prolog files). Removed from
|
||||
the config files the predicate '$lgt_alt_directory'/2. Older config files are
|
||||
incompatible with this new Logtalk version.
|
||||
|
||||
Logtalk 2.30.6 renamed the compiler flags "supports_break_predicate",
|
||||
"supports_encoding_dir", and "underscore_vars" to, respectively,
|
||||
"break_predicate", "encoding_directive", and "underscore_variables". Changed
|
||||
the possible values of the "encoding_directive" compiler option (see manual).
|
||||
Older config files are not compatible with this new Logtalk version.
|
||||
|
||||
Logtalk 2.30.7 adds a new compiler flag "context_switching_calls".
|
||||
Older config files are not compatible with this new Logtalk version.
|
@ -1,26 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
This folder contains code contributions from Logtalk users. Here is
|
||||
a short description of each included contribution:
|
||||
|
||||
iso8601.lgt
|
||||
Contributed by: Daniel L. Dudley
|
||||
|
||||
This is a partial implementation of the ISO 8601 standard,
|
||||
providing a library of date predicates. The time predicates
|
||||
are not yet implemented. The best way to get acquainted with
|
||||
this library is for you to compile the object and then run
|
||||
one of the documentation helper scripts to transform the
|
||||
resulting XML file into (X)HTML or PDF documentation. Your
|
||||
feedback is appreciated.
|
||||
|
||||
xml_parser
|
||||
Contributed by: John Fletcher
|
||||
|
||||
This folder contains a Logtalk version of John Fletcher's
|
||||
Prolog XML parser (http://www.zen37763.zen.co.uk/xml.pl.html).
|
@ -1,664 +0,0 @@
|
||||
/******************************************************************************
|
||||
|
||||
Library: ISO8601.PL
|
||||
Copyright (c) 2004-2005 Daniel L. Dudley
|
||||
|
||||
Purpose: ISO 8601 (and European civil calendar) compliant library of date
|
||||
and time (clock) related predicates. That is, an ISO 8601 handler.
|
||||
|
||||
Author: Daniel L. Dudley
|
||||
Created: 2004-02-18
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
:- object(iso8601).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Daniel L. Dudley',
|
||||
date is 2005/04/11,
|
||||
comment is 'ISO 8601 (and European civil calendar) compliant library of date predicates.',
|
||||
remarks is [
|
||||
'Scope:' - 'This object currently provides a powerful, versatile and efficient set of date-handling predicates, which--thanks to Logtalk--may be used as is on a wide range of Prolog compilers. Besides taking time to familiarize oneself with each predicate, the user should take note of the following information.',
|
||||
'Validation of dates: ' - 'Date parts are not validated--that is the caller''s responsibility! However, not being quite heartless yet, we do provide a predicate for this purpose.',
|
||||
'Date arithmetic:' - 'Many of the examples illustrate a simplified method of doing date arithmetic. Note, however, that we do not generally recommend this practice--it is all too easy to make mistakes. The safest way of finding the day difference between two dates is to first convert the dates to their Julian day numbers and then subtract one from the other. Similarly, the safe way to add or subtract a day offset to a particular date is to first convert the date to its Julian day number, add or subtract the day offset, and then convert the result to its corresponding date.',
|
||||
'BC years' - 'ISO 8601 specifies that the Gregorian calendar be used, yet requires that years prior to 1 AD be handled arithmetically, i.e., the year we know as 1 BC is year 0, 2 BC is year -1, 3 BC is year -2 and so on. We do not follow ISO 8601 with regard to the handling of BC years. Our date predicates will accept and interpret an input year 0 as 1 BC; however, a negative year, Year, should always be interpreted as abs(Year) =:= Year BC. We believe that the average person will find our handling of BC years more user-friendly than the ISO 8601 one, but we encourage feedback from users with a view to a possible change in future versions.',
|
||||
'Week numbers:' - 'It is possible for a day (date) to have a week number that belongs to another year. Up to three of the first days of a calendar year may belong to the last week (number) of the prior calendar year, and up to three days of the last days of a calendar year may belong to the first week (number) of the next calendar year. It for this reason that the Week parameter in date/6-7 is a compound term, namely week(WeekNo,ActualYear).',
|
||||
'Computation of Gregorian Easter Sunday:' - 'The algorithm is based upon the "Gaussian rule". Proleptic use is limited to years > 1582 AD, that is, after the introduction of the Gregorian calendar.',
|
||||
'Some Christian feast day offsets from Easter Sunday:' - 'Carnival Monday: -48 days, Mardi Gras (Shrove Tuesday): -47 days, Ash Wednesday: -46 days, Palm Sunday: -7 days, Easter Friday: -2 days, Easter Saturday: -1 day, Easter Monday: +1 day, Ascension of Christ: +39 days, Whitsunday: +49 days, Whitmonday: +50 days, Feast of Corpus Christi: +60 days.'
|
||||
]]).
|
||||
|
||||
% CORE PREDICATES:
|
||||
|
||||
:- public(date/4).
|
||||
:- mode(date(?integer, ?integer, ?integer, ?integer), zero_or_one).
|
||||
:- info(date/4, [
|
||||
comment is 'Get the system date and/or its Julian Day # or convert a Julian Day # to/from given date parts.',
|
||||
arguments is [
|
||||
'JD' - 'Julian day serial number',
|
||||
'Year' - '0 or negative if converted BC year, positive otherwise',
|
||||
'Month' - 'Normally an integer between 1 and 12 inclusive',
|
||||
'Day' - 'Normally an integer between 1 and 31 inclusive depending upon month'],
|
||||
examples is [
|
||||
'Current date (i.e., today):' - date(JD,Y,M,D) - {JD = 2453471, Y = 2005, M = 4, D = 10},
|
||||
'Convert a date to its Julian day number:' - date(JD,2000,2,29) - {JD = 2451604},
|
||||
'Convert a Julian day number to its date:' - date(2451604,Yr,Mth,Day) - {Yr = 2000, Mth = 2, Day = 29},
|
||||
'What is the date of day # 60 in year 2000?' - date(J,2000,1,60) - {J = 2451604},
|
||||
'What is the Julian of the 1st day prior to 2000-1-1?' - date(J,2000,1,0) - {J = 2451544},
|
||||
'What is the Julian of the 60th day prior to 2000-1-1?' - date(J,2000,1,-59) - {J = 2451485},
|
||||
'Illegal date is auto-adjusted (see also next query)' - date(JD,1900,2,29) - {JD = 2415080},
|
||||
'This is the correct date!' - date(2415080,Y,M,D) - {Y = 1900, M = 3, D = 1}]]).
|
||||
|
||||
:- public(date/5).
|
||||
:- mode(date(?integer, ?integer, ?integer, ?integer, ?integer), zero_or_one).
|
||||
:- info(date/5, [
|
||||
comment is 'Ditto date/4 + get/check its day-of-week #.',
|
||||
arguments is [
|
||||
'JD' - 'Julian day serial number',
|
||||
'Year' - '0 or negative if converted BC year, positive otherwise',
|
||||
'Month' - 'Normally an integer between 1 and 12 inclusive',
|
||||
'Day' - 'Normally an integer between 1 and 31 inclusive depending upon month',
|
||||
'DoW' - 'Day of week, where Monday=1, Tuesday=2, ..., Sunday=7'],
|
||||
examples is [
|
||||
'Get the Julian and the day-of-week # of a date:' - date(JD,2000,2,29,DoW) - {JD = 2451604, DoW = 2},
|
||||
'Check the validity of a given date (day-of-week is 2, not 4):' - date(JD,2002,3,5,4) - {no},
|
||||
'Get the Julian day of a given date if it is a Sunday:' - date(JD,2004,2,29,7) - {JD = 2453065},
|
||||
'Get the date and day-of-week # of a Julian:' - date(2451545,Y,M,D,DoW) - {Y = 2000, M = 1, D = 1, DoW = 6}]]).
|
||||
|
||||
:- public(date/6).
|
||||
:- mode(date(?integer, ?integer, ?integer, ?integer, ?integer, ?compound), zero_or_one).
|
||||
:- info(date/6, [
|
||||
comment is 'Ditto date/5 + get/check its week #.',
|
||||
arguments is [
|
||||
'JD' - 'Julian day serial number',
|
||||
'Year' - '0 or negative if converted BC year, positive otherwise',
|
||||
'Month' - 'Normally an integer between 1 and 12 inclusive',
|
||||
'Day' - 'Normally an integer between 1 and 31 inclusive depending upon month',
|
||||
'DoW' - 'Day of week, where Monday=1, Tuesday=2, ..., Sunday=7',
|
||||
'Week' - 'Compound term, week(WeekNo,ActualYear), of a day'],
|
||||
examples is [
|
||||
'Get the day-of-week and week number of a date:' - date(_,2000,1,1,DoW,Wk) - {DoW = 6, Wk = week(52,1999)},
|
||||
'Get the week number and year of this week:' - date(_,_,_,_,_,Wk) - {Wk = week(7, 2004)},
|
||||
'Get the Julian number and the week of a date if it is a Sunday:' - date(JD,2004,2,29,7,Wk) - {JD = 2453065, Wk = week(9,2004)},
|
||||
'Get the day-of-week and week of a Julian day number:' - date(2453066,_,_,_,DoW,Wk) - {DoW = 1, Wk = week(10,2004)},
|
||||
'Check that given date data matches:' - date(_,2004,3,1,1,week(10,2004)) - {yes},
|
||||
'What is the date of a day of week (default is 1) in given week # and year?' - date(_,Y,M,D,DoW,week(26,2004)) - {Y = 2004, M = 6, D = 21, DoW = 1},
|
||||
'Ditto for Sunday:' - date(_,Y,M,D,7,week(1,2005)) - {Y = 2005, M = 1, D = 9},
|
||||
'Ditto for Tuesday in following week:' - date(_,Y,M,D,9,week(1,2005)) - {Y = 2005, M = 1, D = 11},
|
||||
'Ditto for Thursday in the prior week:' - date(_,Y,M,D,4,week(0,2005)) - {Y = 2004, M = 12, D = 30},
|
||||
'Ditto for Tuesday two weeks prior:' - date(_,Y,M,D,2,week(-1,2005)) - {Y = 2004, M = 12, D = 21},
|
||||
'Ditto for Saturday:' - date(_,Y,M,D,6,week(53,2004)) - {Y = 2005, M = 1, D = 1},
|
||||
'Ditto for Monday (note automatic compensation of nonexistent week number):' - date(_,Y,M,D,1,week(60,2004)) - {Y = 2005, M = 2, D = 14}]]).
|
||||
|
||||
:- public(date/7).
|
||||
:- mode(date(?integer, ?integer, ?integer, ?integer, ?integer, ?compound, ?integer), zero_or_one).
|
||||
:- info(date/7, [
|
||||
comment is 'Ditto date/6 + get/check its day-of-year #.',
|
||||
arguments is [
|
||||
'JD' - 'Julian day serial number',
|
||||
'Year' - '0 or negative if converted BC year, positive otherwise',
|
||||
'Month' - 'Normally an integer between 1 and 12 inclusive',
|
||||
'Day' - 'Normally an integer between 1 and 31 inclusive depending upon month',
|
||||
'DoW' - 'Day of week, where Monday=1, Tuesday=2, ..., Sunday=7',
|
||||
'Week' - 'Compound term, week(WeekNo,ActualYear), of a day',
|
||||
'DoY' - 'Day of year (NB! calendar year, not week # year)'],
|
||||
examples is [
|
||||
'Get the date and day-of-year of a Julian number:' - date(2451649,Year,Month,Day,_,_,DoY) - {Year = 2000, Month = 4, Day = 14, DoY = 105},
|
||||
'Get the Julian number, week number and day-of-year of a date, confirming that it is a Sunday:' - date(JD,2004,2,29,7,Wk,DoY) - {JD = 2453065, Wk = week(9,2004), DoY = 60},
|
||||
'Confirm that a date is, in fact, a specific day-of-year:' - date(_,2004,3,1,_,_,61) - {yes},
|
||||
'Get the Julian number, week day and day-of-year of a date:' - date(JD,2004,10,18,DoW,_,DoY) - {JD = 2453297, DoW = 1, DoY = 292},
|
||||
'Get today''s day-of-year:' - date(_,_,_,_,_,_,DoY) - {DoY = 54},
|
||||
'Get all missing date data (excl. Julian number) for the 60th calendar day of 2004:' - date(_,2004,Month,Day,DoW,Week,60) - {Month = 2, Day = 29, DoW = 7, Week = week(9,2004)},
|
||||
'Match given date data and, if true, return the missing data (excl. Julian number):' - date(_,2004,3,Day,DoW,Week,61) - {Day = 1, DoW = 1, Week = week(10,2004)},
|
||||
'Ditto (the 61st day-of-year cannot be both day 1 and 2 of the month):' - date(_,2004,Month,2,DoW,Week,61) - {no}]]).
|
||||
|
||||
:- public(date_string/3).
|
||||
:- mode(date_string(+atom, +integer, ?atom), zero_or_one).
|
||||
:- mode(date_string(+atom, ?list, ?atom), zero_or_one).
|
||||
:- info(date_string/3, [
|
||||
comment is 'Conversion between an ISO 8601 compliant date string and its components (truncated and expanded date representations are currently unsupported). Note that date components are not validated; that is the caller''s responsibility!',
|
||||
arguments is [
|
||||
'Format' - 'ISO 8601 format',
|
||||
'Components' - 'When bound and String is free, either a Julian number or a [Year,Month,Day] term; it binds to the system day/date if free When free and String is bound, it binds to an integer list representing the numeric elements of String',
|
||||
'String' - 'ISO 8601 formatted string correspondent to Components'],
|
||||
examples is [
|
||||
'Date, complete, basic (section 5.2.1.1):' - date_string('YYYYMMDD',[2004,2,29],Str) - {Str = '20040229'},
|
||||
'Date, complete, basic (section 5.2.1.1):' - date_string('YYYYMMDD',Day,'20040229') - {Day = [2004,2,29]},
|
||||
'Date, complete, extended (section 5.2.1.1):' - date_string('YYYY-MM-DD',[2003,12,16],Str) - {Str = '2003-12-16'},
|
||||
'Date, complete, extended (section 5.2.1.1):' - date_string('YYYY-MM-DD',Day,'2003-12-16') - {Day = [2003,12,16]},
|
||||
'Date, complete, extended (section 5.2.1.1):' - date_string('YYYY-MM-DD',_,Str) - {Str = '2004-02-17'},
|
||||
'Date, complete, extended (section 5.2.1.1):' - date_string('YYYY-MM-DD',Day,'2004-02-17') - {Day = [2004,2,17]},
|
||||
'Date, reduced, month (section 5.2.1.2 a):' - date_string('YYYY-MM',[2004,9,18],Str) - {Str = '2004-09'},
|
||||
'Date, reduced, month (section 5.2.1.2 a):' - date_string('YYYY-MM',Day,'2004-09') - {Day = [2004,9]},
|
||||
'Date, reduced, year (section 5.2.1.2 b):' - date_string('YYYY',[1900,7,24],Str) - {Str = '1900'},
|
||||
'Date, reduced, year (section 5.2.1.2 b):' - date_string('YYYY',Day,'1900') - {Day = [1900]},
|
||||
'Date, reduced, century (section 5.2.1.2 c):' - date_string('YY',2456557,Str) - {Str = '20'},
|
||||
'Date, reduced, century (section 5.2.1.2 c):' - date_string('YY',Day,'20') - {Day = [20]},
|
||||
'Date, ordinal, complete (section 5.2.2.1):' - date_string('YYYYDDD',[2005,3,25],Str) - {Str = '2005084'},
|
||||
'Date, ordinal, complete (section 5.2.2.1):' - date_string('YYYYDDD',Day,'2005084') - {Day = [2005,84]},
|
||||
'Date, ordinal, extended (section 5.2.2.1):' - date_string('YYYY-DDD',[1854,12,4],Str) - {Str = '1854-338'},
|
||||
'Date, ordinal, extended (section 5.2.2.1):' - date_string('YYYY-DDD',Day,'1854-338') - {Day = [1854,338]},
|
||||
'Week, complete, basic (section 5.2.3.1):' - date_string('YYYYWwwD',[2000,1,2],Str) - {Str = '1999W527'},
|
||||
'Week, complete, basic (section 5.2.3.1):' - date_string('YYYYWwwD',Day,'1999W527') - {Day = [1999,52,7]},
|
||||
'Week, complete, extended (section 5.2.3.1):' - date_string('YYYY-Www-D',[2003,12,29],Str) - {Str = '2004-W01-1'},
|
||||
'Week, complete, extended (section 5.2.3.1):' - date_string('YYYY-Www-D',Day,'2004-W01-1') - {Day = [2004,1,1]},
|
||||
'Week, complete, extended (section 5.2.3.1):' - date_string('YYYY-Www-D',2453167,Str) - {Str = '2004-W24-4'},
|
||||
'Week, complete, extended (section 5.2.3.1):' - date_string('YYYY-Www-D',Day,'2004-W24-4') - {Day = [2004,24,4]},
|
||||
'Week, reduced, basic (section 5.2.3.2):' - date_string('YYYYWww',[2004,2,29],Str) - {Str = '2004W09'},
|
||||
'Week, reduced, basic (section 5.2.3.2):' - date_string('YYYYWww',Day,'2004W09') - {Day = [2004,9]},
|
||||
'Week, reduced, extended (section 5.2.3.2):' - date_string('YYYY-Www',[2004,2,29],Str) - {Str = '2004-W09'},
|
||||
'Week, reduced, extended (section 5.2.3.2):' - date_string('YYYY-Www',Day,'2004-W09') - {Day = [2004,9]}]]).
|
||||
|
||||
% MISCELLANEOUS PREDICATES (GOODIES):
|
||||
|
||||
:- public(valid_date/3).
|
||||
:- mode(valid_date(+integer, +integer, +integer), zero_or_one).
|
||||
:- info(valid_date/3, [
|
||||
comment is 'Validate a given date in the Gregorian calendar.',
|
||||
argnames is ['Year', 'Month', 'Day'],
|
||||
examples is [
|
||||
'Yes, the recent millenium was a leap year:' - valid_date(2000,2,29) - {yes},
|
||||
'2004 was also a leap year:' - valid_date(2004,2,29) - {yes},
|
||||
'Only 30 days in April:' - valid_date(2004,4,31) - {no},
|
||||
'1 BC was a leap year:' - valid_date(-1,2,29) - {yes}
|
||||
]]).
|
||||
|
||||
:- public(leap_year/1).
|
||||
:- mode(leap_year(?integer), zero_or_one).
|
||||
:- info(leap_year/1, [
|
||||
comment is 'Succeed if given year is a leap year in the Gregorian calendar.',
|
||||
arguments is [
|
||||
'Year' - 'The Gregorian calendar year to investigate. If free, it binds to the system year'],
|
||||
examples is [
|
||||
'No, the prior centenary was not a leap year:' - leap_year(1900) - {no},
|
||||
'The recent millenium:' - leap_year(2000) - {yes},
|
||||
'This year:' - leap_year(Year) - {Year = 2004},
|
||||
'This year (equivalent to prior query):' - leap_year(_) - {yes},
|
||||
'Next centennial:' - leap_year(2100) - {no},
|
||||
'Year 0, equivalent to 1 BC:' - leap_year(0) - {yes},
|
||||
'1 BC' - leap_year(-1) - {yes},
|
||||
'4 BC' - leap_year(-4) - {no},
|
||||
'5 BC' - leap_year(-5) - {yes}
|
||||
]]).
|
||||
|
||||
:- public(calendar_month/3).
|
||||
:- mode(calendar_month(?integer, ?integer, -compound), zero_or_one).
|
||||
:- info(calendar_month/3, [
|
||||
comment is 'Compute a calendar month.',
|
||||
arguments is [
|
||||
'Year' - 'The calendar year',
|
||||
'Month' - 'The calendar month',
|
||||
'Calendar' - 'A compound term, m/3, composed of three main arguments specifying year, month, and a list of week and week day numbers (calendar body).'],
|
||||
examples is [
|
||||
'Compute the calendar of March, 2005:' - calendar_month(2005, 3, Calendar) - {Calendar = m(2005, 3,[w( 9, [ 0, 1, 2, 3, 4, 5, 6]),w(10, [ 7, 8, 9, 10, 11, 12, 13]),w(11, [14, 15, 16, 17, 18, 19, 20]),w(12, [21, 22, 23, 24, 25, 26, 27]),w(13, [28, 29, 30, 31, 0, 0, 0]),w( 0, [ 0, 0, 0, 0, 0, 0, 0])])}]]).
|
||||
|
||||
:- public(easter_day/3).
|
||||
:- mode(easter_day(?integer, -integer, -integer), zero_or_one).
|
||||
:- info(easter_day/3, [
|
||||
comment is 'Compute a Gregorian Easter Sunday.',
|
||||
arguments is [
|
||||
'Year' - 'Integer specifying the year to be investigated',
|
||||
'Month' - 'Month in which Easter Sunday falls for given year',
|
||||
'Day'- 'Day of month in which Easter Sunday falls for given year'],
|
||||
examples is [
|
||||
'Compute Easter Sunday for a particular year:' - easter_day(2006,Month,Day) - {Month=4, Day=16},
|
||||
'Compute Easter Sunday for the current year:' - easter_day(Y,M,D) - {Y = 2005, M = 3, D = 27}
|
||||
]]).
|
||||
|
||||
|
||||
/************************
|
||||
ISO 8601 DATE PREDICATES
|
||||
************************/
|
||||
|
||||
%==============================================================================
|
||||
% date(?JD, ?Year, ?Month, ?Day)
|
||||
|
||||
date(JD,Year,Month,Day) :-
|
||||
( var(JD), var(Year), var(Month), var(Day)
|
||||
-> % GET THE SYSTEM DATE AND ITS JULIAN DAY SERIAL NUMBER:
|
||||
{'$lgt_current_date'(Year, Month, Day)}
|
||||
; true
|
||||
),
|
||||
( var(JD), nonvar(Year), nonvar(Month), nonvar(Day)
|
||||
-> % CORRIGATE BC/AD CALENDAR YEARS TO FIT 0-BASED ALGORITHM:
|
||||
(Year < 0 -> Year1 is Year + 1 ; Year1 = Year),
|
||||
% CONVERT DATE PARTS TO JULIAN DAY SERIAL NUMBER:
|
||||
A is (14 - Month) // 12,
|
||||
Y is Year1 + 4800 - A,
|
||||
M is Month + (12 * A) - 3,
|
||||
D is Day + ((153 * M + 2) // 5) + (365 * Y) + (Y // 4),
|
||||
JD is D - (Y // 100) + (Y // 400) - 32045
|
||||
; nonvar(JD),
|
||||
% CONVERT JULIAN DAY SERIAL NUMBER TO DATE PARTS:
|
||||
A is JD + 32045,
|
||||
B is (4 * (A + 36524)) // 146097 - 1,
|
||||
C is A - ((146097 * B) // 4),
|
||||
D is ((4 * (C + 365)) // 1461) - 1,
|
||||
E is C - ((1461 * D) // 4),
|
||||
M is ((5 * (E - 1)) + 2) // 153,
|
||||
Day is E - (((153 * M) + 2) // 5),
|
||||
Month is M + (3 - (12 * (M // 10))),
|
||||
Year1 is ((100 * B) + D - 4800 + (M // 10)),
|
||||
% CORRIGATE 0-BASED ALGORITHM RESULT TO BC/AD CALENDAR YEARS:
|
||||
(Year1 < 1 -> Year is Year1 - 1 ; Year = Year1)
|
||||
).
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% date(?JD, ?Year, ?Month, ?Day, ?DoW)
|
||||
|
||||
date(JD,Year,Month,Day,DoW) :-
|
||||
date(JD,Year,Month,Day),
|
||||
DoW is (JD mod 7) + 1.
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% date(?JD, ?Year, ?Month, ?Day, ?DoW, ?Week)
|
||||
|
||||
date(JD,Year,Month,Day,DoW,week(Wk,Yr)) :-
|
||||
( var(JD), var(Year), var(Month), var(Day), nonvar(Wk), nonvar(Yr)
|
||||
-> (var(DoW) -> DoW = 1 ; true),
|
||||
date(JD1,Yr,1,1,DoW1),
|
||||
(DoW1 > 4 -> Offset = 0 ; Offset = 1),
|
||||
JD is JD1 + ((Wk - Offset) * 7) + DoW - DoW1,
|
||||
date(JD,Year,Month,Day)
|
||||
; date(JD,Year,Month,Day,DoW),
|
||||
D4 is (((JD + 31741 - (JD mod 7)) mod 146097) mod 36524) mod 1461,
|
||||
L is D4 // 1460,
|
||||
Wk is (((D4 - L) mod 365) + L) // 7 + 1,
|
||||
% CORRIGATE YEAR AS NECESSARY:
|
||||
( Month =:= 1, (Day =:= 1 ; Day =:= 2 ; Day =:= 3), Wk > 1
|
||||
-> Yr is Year - 1
|
||||
; ( Month =:= 12, (Day =:= 29 ; Day =:= 30 ; Day =:= 31), Wk =:= 1
|
||||
-> Yr is Year + 1
|
||||
; Yr = Year
|
||||
)
|
||||
)
|
||||
).
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% date(?JD, ?Year, ?Month, ?Day, ?DoW, ?Week, ?DoY)
|
||||
|
||||
date(JD,Year,Month,Day,DoW,Week,DoY) :-
|
||||
( var(JD), nonvar(Year), (var(Month) ; var(Day)), nonvar(DoY)
|
||||
-> date(JD1,Year,1,0),
|
||||
JD is JD1 + DoY,
|
||||
date(JD,Year,Month,Day,DoW,Week)
|
||||
; date(JD,Year,Month,Day,DoW,Week),
|
||||
date(JD1,Year,1,0),
|
||||
DoY is JD - JD1
|
||||
).
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% date_string(+Format, ?Day, ?String)
|
||||
|
||||
date_string('YYYYMMDD',Day,String) :- % DATE
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,M0,M1,D0,D1]),
|
||||
number_chars(Y,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(M,[M0,M1]),
|
||||
number_chars(D,[D0,D1]),
|
||||
Day = [Y,M,D]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; date(Day,Y,M,D)),
|
||||
prepend_zeros(2,D,D1),
|
||||
prepend_zeros(2,M,M1),
|
||||
number_codes(Y,Y1),
|
||||
list_of_lists_to_atom([Y1,M1,D1],String)
|
||||
).
|
||||
date_string('YYYY-MM-DD',Day,String) :- % DATE
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,M0,M1,_,D0,D1]),
|
||||
number_chars(Y,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(M,[M0,M1]),
|
||||
number_chars(D,[D0,D1]),
|
||||
Day = [Y,M,D]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; date(Day,Y,M,D)),
|
||||
prepend_zeros(2,D,D1),
|
||||
prepend_zeros(2,M,M1),
|
||||
number_codes(Y,Y1),
|
||||
list_of_lists_to_atom([Y1,[45],M1,[45],D1],String)
|
||||
).
|
||||
date_string('YYYY-MM',Day,String) :- % YEAR & MONTH
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,M0,M1]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Month,[M0,M1]),
|
||||
Day = [Year,Month]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,_) ; true),
|
||||
(Day = [Y,M,_] -> nonvar(Y), nonvar(M) ; date(Day,Y,M,_)),
|
||||
prepend_zeros(2,M,M1),
|
||||
number_codes(Y,Y1),
|
||||
list_of_lists_to_atom([Y1,[45],M1],String)
|
||||
).
|
||||
date_string('YYYY',Day,String) :- % YEAR
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
Day = [Year]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,_,_) ; true),
|
||||
(Day = [Y|_] -> nonvar(Y) ; date(Day,Y,_,_)),
|
||||
number_codes(Y,Codes),
|
||||
atom_codes(String,Codes)
|
||||
).
|
||||
date_string('YY',Day,String) :- % CENTURY
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[C0,C1]),
|
||||
number_chars(Century,[C0,C1]),
|
||||
Day = [Century]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,_,_) ; true),
|
||||
(Day = [Y|_] -> nonvar(Y) ; date(Day,Y,_,_)),
|
||||
Y1 is Y // 100,
|
||||
number_codes(Y1,Codes),
|
||||
atom_codes(String,Codes)
|
||||
).
|
||||
date_string('YYYYDDD',Day,String) :- % YEAR & DAY-OF-YEAR
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,D0,D1,D2]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(DoY,[D0,D1,D2]),
|
||||
Day = [Year,DoY]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,_,_,DoY),
|
||||
prepend_zeros(3,DoY,DoY1),
|
||||
number_codes(Y,Y1),
|
||||
list_of_lists_to_atom([Y1,DoY1],String)
|
||||
).
|
||||
date_string('YYYY-DDD',Day,String) :- % YEAR & DAY-OF-YEAR
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,D0,D1,D2]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(DoY,[D0,D1,D2]),
|
||||
Day = [Year,DoY]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,_,_,DoY),
|
||||
prepend_zeros(3,DoY,DoY1),
|
||||
number_codes(Y,Y1),
|
||||
list_of_lists_to_atom([Y1,[45],DoY1],String)
|
||||
).
|
||||
date_string('YYYYWwwD',Day,String) :- % YEAR, WEEK & DAY-OF-WEEK
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,W0,W1,DoW0]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Week,[W0,W1]),
|
||||
number_chars(DoW,[DoW0]),
|
||||
Day = [Year,Week,DoW]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,DoW,week(Wk,Yr)),
|
||||
number_codes(Yr,Y1),
|
||||
prepend_zeros(2,Wk,Wk1),
|
||||
number_codes(DoW,DoW1),
|
||||
List = [Y1,[87],Wk1,DoW1],
|
||||
list_of_lists_to_atom(List,String)
|
||||
).
|
||||
date_string('YYYY-Www-D',Day,String) :- % YEAR, WEEK & DAY-OF-WEEK
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,_,W0,W1,_,DoW0]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Week,[W0,W1]),
|
||||
number_chars(DoW,[DoW0]),
|
||||
Day = [Year,Week,DoW]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,DoW,week(Wk,Yr)),
|
||||
number_codes(Yr,Y1),
|
||||
prepend_zeros(2,Wk,Wk1),
|
||||
number_codes(DoW,DoW1),
|
||||
List = [Y1,[45,87],Wk1,[45],DoW1],
|
||||
list_of_lists_to_atom(List,String)
|
||||
).
|
||||
date_string('YYYYWww',Day,String) :- % YEAR & WEEK
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,W0,W1]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Week,[W0,W1]),
|
||||
Day = [Year,Week]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,_,week(Wk,Yr)),
|
||||
number_codes(Yr,Y1),
|
||||
prepend_zeros(2,Wk,Wk1),
|
||||
List = [Y1,[87],Wk1],
|
||||
list_of_lists_to_atom(List,String)
|
||||
).
|
||||
date_string('YYYY-Www',Day,String) :- % YEAR & WEEK
|
||||
( nonvar(String)
|
||||
-> atom_chars(String,[Y0,Y1,Y2,Y3,_,_,W0,W1]),
|
||||
number_chars(Year,[Y0,Y1,Y2,Y3]),
|
||||
number_chars(Week,[W0,W1]),
|
||||
Day = [Year,Week]
|
||||
; ((var(Day) ; Day = [Y|_], var(Y)) -> date(_,Y,M,D) ; true),
|
||||
(Day = [Y,M,D] -> nonvar(Y), nonvar(M), nonvar(D) ; JD = Day),
|
||||
date(JD,Y,M,D,_,week(Wk,Yr)),
|
||||
number_codes(Yr,Y1),
|
||||
prepend_zeros(2,Wk,Wk1),
|
||||
List = [Y1,[45,87],Wk1],
|
||||
list_of_lists_to_atom(List,String)
|
||||
).
|
||||
|
||||
|
||||
%-----------------------------------
|
||||
% prepend_zeros(+Digits, +N, -Codes)
|
||||
% Purpose: prepend zeros to a given integer
|
||||
% Parameters:
|
||||
% Digits: required number of digits to be entered into Codes
|
||||
% N: integer to which zeros are prepended
|
||||
% Codes: the resulting list of codes
|
||||
% Called by: date_string/3
|
||||
% Examples:
|
||||
% ?- prepend_zeros(2,2,Codes). => Codes = [48,50]
|
||||
% ?- prepend_zeros(2,22,Codes). => Codes = [50,50]
|
||||
% ?- prepend_zeros(3,2,Codes). => Codes = [48,48,50]
|
||||
% ?- prepend_zeros(3,22,Codes). => Codes = [48,50,50]
|
||||
|
||||
prepend_zeros(2, I, Codes) :-
|
||||
number_codes(I, ICodes),
|
||||
two_codes(ICodes, Codes).
|
||||
prepend_zeros(3, I, Codes) :-
|
||||
number_codes(I, ICodes),
|
||||
three_codes(ICodes, Codes).
|
||||
|
||||
two_codes([A], [48, A]) :- !.
|
||||
two_codes([A, B], [A, B]).
|
||||
|
||||
three_codes([A], [48, 48, A]) :- !.
|
||||
three_codes([A, B], [48, A, B]) :- !.
|
||||
three_codes([A, B, C], [A, B, C]).
|
||||
|
||||
%---------------------------------------
|
||||
% list_of_lists_to_atom(+Llist, -String)
|
||||
% Purpose: Convert a list of code lists to a string
|
||||
% Called by: date_string/3
|
||||
|
||||
list_of_lists_to_atom(Llist,String) :-
|
||||
flatten(Llist,Codes),
|
||||
atom_codes(String,Codes).
|
||||
|
||||
%------------------------------
|
||||
% flatten(+Llist, -Codes)
|
||||
% Purpose: Convert a list of lists to a list of codes
|
||||
% Note: custom, simplified version
|
||||
% Called by: list_of_lists_to_atom/2
|
||||
|
||||
flatten([], []).
|
||||
flatten([[]| Ls], F) :-
|
||||
!,
|
||||
flatten(Ls, F).
|
||||
flatten([[H| T]| Ls], [H| Fs]) :-
|
||||
flatten([T| Ls], Fs).
|
||||
|
||||
|
||||
|
||||
/**********************************
|
||||
MISCELLANEOUS PREDICATES (GOODIES)
|
||||
**********************************/
|
||||
|
||||
%==============================================================================
|
||||
% valid_date(+Year, +Month, +Day)
|
||||
|
||||
valid_date(Year,Month,Day) :-
|
||||
Month > 0, Month < 13,
|
||||
Day > 0,
|
||||
( Month =:= 2
|
||||
-> (leap_year(Year) -> Days = 29 ; Days = 28)
|
||||
; days_in_month(Month,Days)
|
||||
),
|
||||
Day =< Days.
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% leap_year(+Year)
|
||||
|
||||
leap_year(Year) :-
|
||||
(var(Year) -> date(_,Year,_,_) ; true),
|
||||
(Year < 0 -> Year1 is Year + 1 ; Year1 = Year),
|
||||
0 =:= Year1 mod 4,
|
||||
(\+ 0 =:= Year1 mod 100 -> true ; 0 =:= Year1 mod 400).
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% calendar_month(?Year, ?Month, -Calendar)
|
||||
|
||||
calendar_month(Year,Month,m(Year,Month,Weeks)) :-
|
||||
(var(Year), var(Month) -> date(_,Year,Month,_) ; true),
|
||||
% COMPUTE THE BODY (A 6 ROW BY 8 COLUMN TABLE OF WEEK AND DAY NUMBERS):
|
||||
date(JD,Year,Month,1,DoW,week(Week,_)),
|
||||
Lead0s is DoW - 1, % number of leading zeros required
|
||||
( Month =:= 2
|
||||
-> (leap_year(Year) -> Days = 29 ; Days = 28)
|
||||
; days_in_month(Month,Days)
|
||||
),
|
||||
Delta is 42 - (Lead0s + Days), % number of trailing zeros required
|
||||
zeros(Delta,[],Append), % zeros to be appended to day list
|
||||
day_list(Days,Append,DList), % create padded daylist
|
||||
zeros(Lead0s,DList,DayList), % prepend zeros to padded day list
|
||||
Julian is JD - Lead0s,
|
||||
week_list(6,Julian,Week,DayList,Weeks).
|
||||
|
||||
%-------------------------------
|
||||
% zeros(+Counter, +Build, -List)
|
||||
% Purpose: Prepend or append a list of 0's (zeros) to a given list
|
||||
% Called by: calendar_month/3
|
||||
|
||||
zeros(0,L,L):- !.
|
||||
zeros(DoW,Build,List) :-
|
||||
Next is DoW - 1,
|
||||
zeros(Next,[0|Build],List).
|
||||
|
||||
%-------------------------------------
|
||||
% day_list(+Counter, +Build, -DayList)
|
||||
% Purpose: Return a list of day #s
|
||||
% Called by: calendar_month/3
|
||||
|
||||
day_list(0,DayList,DayList) :- !.
|
||||
day_list(N,SoFar,DayList) :-
|
||||
N1 is N - 1,
|
||||
day_list(N1,[N|SoFar],DayList).
|
||||
|
||||
%-------------------------------------------
|
||||
% week_list(+N, +JD, +Week, +Days, -WeekList)
|
||||
% Purpose: Return a list of week and day #s
|
||||
% Called by: calendar_month/3
|
||||
|
||||
week_list(0,_,_,_,[]).
|
||||
week_list(N,JD,Week,Days,[X|Weeks]) :-
|
||||
Days = [F1,F2,F3,F4,F5,F6,F7|Days1],
|
||||
( N < 3,
|
||||
F1 =:= 0
|
||||
-> Wk = 0
|
||||
; Wk = Week
|
||||
),
|
||||
X = w(Wk,[F1,F2,F3,F4,F5,F6,F7]),
|
||||
JD1 is JD + 7,
|
||||
( Week > 51
|
||||
-> date(JD1,_,_,_,_,week(Week1,_))
|
||||
; Week1 is Week + 1
|
||||
),
|
||||
N1 is N - 1,
|
||||
week_list(N1,JD1,Week1,Days1,Weeks).
|
||||
|
||||
|
||||
%==============================================================================
|
||||
% easter_day(?Year, -Month, -Day)
|
||||
|
||||
easter_day(Year,Month,Day):-
|
||||
(nonvar(Year) -> true ; date(_,Year,_,_)),
|
||||
Year > 1582,
|
||||
A is Year mod 19,
|
||||
B is Year mod 4,
|
||||
C is Year mod 7,
|
||||
calc_M_and_N(Year,M,N),
|
||||
D is (19 * A + M) mod 30,
|
||||
E is ((2 * B) + (4 * C) + (6 * D) + N) mod 7,
|
||||
R is 22 + D + E,
|
||||
calc_month_and_day(R,Month,Day1),
|
||||
corr_day(Day1,Month,A,D,E,Day).
|
||||
|
||||
%----------------------------
|
||||
% calc_M_and_N(+Year, -M, -N)
|
||||
% Purpose: Calculate intermediate values M and N
|
||||
% Called by: easter_day/3
|
||||
|
||||
calc_M_and_N(Year,M,N):-
|
||||
T is Year // 100,
|
||||
P is (13 + 8 * T) // 25,
|
||||
Q is T // 4,
|
||||
M is (15 + T - P - Q) mod 30,
|
||||
N is (T - (T // 4) + 4) mod 7.
|
||||
|
||||
%-------------------------------------
|
||||
% calc_month_and_day(+R, -Month, -Day)
|
||||
% Purpose: Calculate the Easter Sunday month and likely day
|
||||
% Called by: easter_day/3
|
||||
|
||||
calc_month_and_day(R,4,Day):- % April
|
||||
R > 31,
|
||||
!,
|
||||
Day is R - 31.
|
||||
calc_month_and_day(R,3,R). % March
|
||||
|
||||
%---------------------------------------------------
|
||||
% corr_day(+PossDay, +Month, +A, +D, +E, -ActualDay)
|
||||
% Purpose: Calculate the actual Easter Sunday
|
||||
% Called by: easter_day/3
|
||||
|
||||
corr_day(_,4,_,29,6,19):- % April, Gregorian exception 1
|
||||
!.
|
||||
corr_day(_,4,A,28,6,18):- % April, Gregorian exception 2
|
||||
A > 10,
|
||||
!.
|
||||
corr_day(Day,_,_,_,_,Day). % Otherwise
|
||||
|
||||
|
||||
|
||||
/************************
|
||||
LOCAL UTILITY PREDICATES
|
||||
************************/
|
||||
|
||||
%------------------------------------
|
||||
% days_in_month(+Month, -DaysInMonth)
|
||||
% Purpose: Return the number of days in a given month
|
||||
% Called by: valid_date/3, calendar_month/3
|
||||
|
||||
days_in_month( 1, 31).
|
||||
days_in_month( 2, 28).
|
||||
days_in_month( 3, 31).
|
||||
days_in_month( 4, 30).
|
||||
days_in_month( 5, 31).
|
||||
days_in_month( 6, 30).
|
||||
days_in_month( 7, 31).
|
||||
days_in_month( 8, 31).
|
||||
days_in_month( 9, 30).
|
||||
days_in_month(10, 31).
|
||||
days_in_month(11, 30).
|
||||
days_in_month(12, 31).
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,19 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
This folder contains a Logtalk version of John Fletcher's Prolog XML
|
||||
parser:
|
||||
|
||||
http://www.zen37763.zen.co.uk/xml.pl.html
|
||||
|
||||
To load this XML parser and for sample queries, please see the SCRIPT
|
||||
file.
|
||||
|
||||
For a detailed description of this XML parser, please see the comments
|
||||
in the "xml.lgt" source file or convert the automatically generated
|
||||
documentation to HTML or PDF.
|
@ -1,34 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the necessary library support files (if not
|
||||
% already loaded):
|
||||
|
||||
| ?- logtalk_load(library(types_loader)).
|
||||
...
|
||||
|
||||
|
||||
% now you are ready for loading the XML parser:
|
||||
|
||||
| ?- logtalk_load(xml_parser(loader)).
|
||||
...
|
||||
|
||||
|
||||
% let's try some examples (the goals generate XML files named qi.xml):
|
||||
|
||||
| ?- logtalk_load(xml_parser(examples)).
|
||||
...
|
||||
|
||||
| ?- test(q1).
|
||||
...
|
||||
|
||||
| ?- test(q2).
|
||||
...
|
||||
|
||||
| ?- test(q12).
|
||||
...
|
@ -1,36 +0,0 @@
|
||||
<bib>
|
||||
<book year="1994">
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<author><last>Stevens</last><first>W.</first></author>
|
||||
<publisher>Addison-Wesley</publisher>
|
||||
<price> 65.95</price>
|
||||
</book>
|
||||
|
||||
<book year="1992">
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<author><last>Stevens</last><first>W.</first></author>
|
||||
<publisher>Addison-Wesley</publisher>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
|
||||
<book year="2000">
|
||||
<title>Data on the Web</title>
|
||||
<author><last>Abiteboul</last><first>Serge</first></author>
|
||||
<author><last>Buneman</last><first>Peter</first></author>
|
||||
<author><last>Suciu</last><first>Dan</first></author>
|
||||
<publisher>Morgan Kaufmann Publishers</publisher>
|
||||
<price>39.95</price>
|
||||
</book>
|
||||
|
||||
<book year="1999">
|
||||
<title>The Economics of Technology and Content for Digital TV</title>
|
||||
<editor>
|
||||
<last>Gerbarg</last><first>Darcy</first>
|
||||
<affiliation>CITI</affiliation>
|
||||
</editor>
|
||||
<publisher>Kluwer Academic Publishers</publisher>
|
||||
<price>129.95</price>
|
||||
</book>
|
||||
|
||||
</bib>
|
||||
|
@ -1,15 +0,0 @@
|
||||
<chapter>
|
||||
<title>Data Model</title>
|
||||
<section>
|
||||
<title>Syntax For Data Model</title>
|
||||
</section>
|
||||
<section>
|
||||
<title>XML</title>
|
||||
<section>
|
||||
<title>Basic Syntax</title>
|
||||
</section>
|
||||
<section>
|
||||
<title>XML and Semistructured Data</title>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
@ -1,387 +0,0 @@
|
||||
/* Using xml.pl to solve XML Query Cases - An Example
|
||||
*
|
||||
* The following is a complete example to illustrate how the module can be used;
|
||||
* it exercises both the input and output parsing modes of xml::parse/[2,3], and
|
||||
* illustrates the use of xml::subterm/2 to access the nodes of a "document value
|
||||
* model". It's written for Quintus Prolog, but should port to other Prologs
|
||||
* easily.
|
||||
*
|
||||
* The entry-point of the program is the test/1 predicate.
|
||||
*
|
||||
* test( +QueryId ) executes a Prolog implementation of a Query from Use Case
|
||||
* "XMP": Experiences and Exemplars, in the W3C's XML Query Use Cases, which
|
||||
* "contains several example queries that illustrate requirements gathered from
|
||||
* the database and document communities".
|
||||
* <http://www.w3.org/TR/2002/WD-xmlquery-use-cases-20021115/#xmp>
|
||||
*
|
||||
* QueryId is one of q1…q12 selecting which of the 12 use cases is executed.
|
||||
* The XML output is written to the file [QueryId].xml in the current directory.
|
||||
*
|
||||
* xml::pp/1 is used to display the resulting "document value model"
|
||||
% data-structures on the user output (stdout) stream.
|
||||
*/
|
||||
test( Query ) :-
|
||||
xml_query( Query, ResultElement ),
|
||||
% Parse output XML into the Output chars
|
||||
xml::parse( Codes, xml([], [ResultElement]) ),
|
||||
atom_concat( Query, '.xml', OutputFile ),
|
||||
% Write OutputFile from the Output list of chars
|
||||
open( OutputFile, write, Output ),
|
||||
put_codes( Codes, Output ),
|
||||
close( Output ),
|
||||
% Pretty print OutputXML
|
||||
write( 'Output XML' ), nl,
|
||||
xml::pp( xml([], [ResultElement]) ).
|
||||
|
||||
/* xml_query( +QueryNo, ?OutputXML ) when OutputXML is an XML Document Value Model
|
||||
* produced by running an example taken, identified by QueryNo from the XML Query
|
||||
* "XMP" use case.
|
||||
*/
|
||||
|
||||
% Q1: List books published by Addison-Wesley after 1991, including their year and
|
||||
% title.
|
||||
|
||||
xml_query( q1, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Publisher, publisher ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [year=Year], [Title]),
|
||||
(
|
||||
xml::subterm( Bibliography, element(book, Attributes, Content) ),
|
||||
xml::subterm( Content, Publisher ),
|
||||
xml::subterm( Publisher, Text ),
|
||||
text_value( Text, "Addison-Wesley" ),
|
||||
list::member( year=Year, Attributes ),
|
||||
number_codes( YearNo, Year ),
|
||||
YearNo > 1991,
|
||||
xml::subterm( Content, Title )
|
||||
),
|
||||
Books
|
||||
).
|
||||
|
||||
% Q2: Create a flat list of all the title-author pairs, with each pair enclosed
|
||||
% in a "result" element.
|
||||
|
||||
xml_query( q2, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(result, [], [Title,Author]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
xml::subterm( Book, Author )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q3: For each book in the bibliography, list the title and authors, grouped
|
||||
% inside a "result" element.
|
||||
|
||||
xml_query( q3, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(result, [], [Title|Authors]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
findall( Author, xml::subterm(Book, Author), Authors )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q4: For each author in the bibliography, list the author's name and the titles
|
||||
% of all books by that author, grouped inside a "result" element.
|
||||
|
||||
xml_query( q4, element(results, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall( Author, xml::subterm(Bibliography, Author), AuthorBag ),
|
||||
sort( AuthorBag, Authors ),
|
||||
findall(
|
||||
element(result, [], [Author|Titles]),
|
||||
(
|
||||
list::member( Author, Authors ),
|
||||
findall( Title, (
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Author ),
|
||||
xml::subterm( Book, Title )
|
||||
),
|
||||
Titles
|
||||
)
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q5: For each book found at both bn.com and amazon.com, list the title of the
|
||||
% book and its price from each source.
|
||||
|
||||
xml_query( q5, element('books-with-prices', [], BooksWithPrices) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Book, book ),
|
||||
element_name( Review, entry ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
input_document( 'reviews.xml', Reviews ),
|
||||
findall(
|
||||
element('book-with-prices', [], [
|
||||
Title,
|
||||
element('price-bn',[], BNPrice ),
|
||||
element('price-amazon',[], AmazonPrice )
|
||||
] ),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
xml::subterm( Reviews, Review ),
|
||||
xml::subterm( Review, Title ),
|
||||
xml::subterm( Book, element(price,_, BNPrice) ),
|
||||
xml::subterm( Review, element(price,_, AmazonPrice) )
|
||||
),
|
||||
BooksWithPrices
|
||||
).
|
||||
|
||||
% Q6: For each book that has at least one author, list the title and first two
|
||||
% authors, and an empty "et-al" element if the book has additional authors.
|
||||
|
||||
xml_query( q6, element(bib, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,FirstAuthor|Authors]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
findall( Author, xml::subterm(Book, Author), [FirstAuthor|Others] ),
|
||||
other_authors( Others, Authors )
|
||||
),
|
||||
Results
|
||||
).
|
||||
|
||||
% Q7: List the titles and years of all books published by Addison-Wesley after
|
||||
% 1991, in alphabetic order.
|
||||
|
||||
xml_query( q7, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Publisher, publisher ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
Title-element(book, [year=Year], [Title]),
|
||||
(
|
||||
xml::subterm( Bibliography, element(book, Attributes, Book) ),
|
||||
xml::subterm( Book, Publisher ),
|
||||
xml::subterm( Publisher, Text ),
|
||||
text_value( Text, "Addison-Wesley" ),
|
||||
list::member( year=Year, Attributes ),
|
||||
number_codes( YearNo, Year ),
|
||||
YearNo > 1991,
|
||||
xml::subterm( Book, Title )
|
||||
),
|
||||
TitleBooks
|
||||
),
|
||||
keysort( TitleBooks, TitleBookSet ),
|
||||
range( TitleBookSet, Books ).
|
||||
|
||||
% Q8: Find books in which the name of some element ends with the string "or" and
|
||||
% the same element contains the string "Suciu" somewhere in its content. For each
|
||||
% such book, return the title and the qualifying element.
|
||||
|
||||
xml_query( q8, element(bib, [], Books) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Book, book ),
|
||||
element_name( QualifyingElement, QualifyingName ),
|
||||
list::append( "Suciu", _Back, Suffix ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,QualifyingElement]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, QualifyingElement ),
|
||||
atom_codes( QualifyingName, QNChars ),
|
||||
list::append( _QNPrefix, "or", QNChars ),
|
||||
xml::subterm( QualifyingElement, TextItem ),
|
||||
text_value( TextItem, TextValue ),
|
||||
list::append( _Prefix, Suffix, TextValue ),
|
||||
xml::subterm( Book, Title )
|
||||
),
|
||||
Books
|
||||
).
|
||||
|
||||
% Q9: In the document "books.xml", find all section or chapter titles that
|
||||
% contain the word "XML", regardless of the level of nesting.
|
||||
|
||||
xml_query( q9, element(results, [], Titles) ) :-
|
||||
element_name( Title, title ),
|
||||
list::append( "XML", _Back, Suffix ),
|
||||
input_document( 'books.xml', Books ),
|
||||
findall(
|
||||
Title,
|
||||
(
|
||||
xml::subterm( Books, Title ),
|
||||
xml::subterm( Title, TextItem ),
|
||||
text_value( TextItem, TextValue ),
|
||||
list::append( _Prefix, Suffix, TextValue )
|
||||
),
|
||||
Titles
|
||||
).
|
||||
|
||||
% Q10: In the document "prices.xml", find the minimum price for each book, in the
|
||||
% form of a "minprice" element with the book title as its title attribute.
|
||||
|
||||
xml_query( q10, element(results, [], MinPrices) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Price, price ),
|
||||
input_document( 'prices.xml', Prices ),
|
||||
findall( Title, xml::subterm(Prices, Title), TitleBag ),
|
||||
sort( TitleBag, TitleSet ),
|
||||
element_name( Book, book ),
|
||||
findall(
|
||||
element(minprice, [title=TitleString], [MinPrice]),
|
||||
(
|
||||
list::member( Title, TitleSet ),
|
||||
xml::subterm( Title, TitleText ),
|
||||
text_value( TitleText, TitleString ),
|
||||
findall( PriceValue-Price, (
|
||||
xml::subterm( Prices, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
xml::subterm( Book, Price ),
|
||||
xml::subterm( Price, Text ),
|
||||
text_value( Text, PriceChars ),
|
||||
number_codes( PriceValue, PriceChars )
|
||||
),
|
||||
PriceValues
|
||||
),
|
||||
minimum( PriceValues, PriceValue-MinPrice )
|
||||
),
|
||||
MinPrices
|
||||
).
|
||||
|
||||
% Q11: For each book with an author, return the book with its title and authors.
|
||||
% For each book with an editor, return a reference with the book title and the
|
||||
% editor's affiliation.
|
||||
|
||||
xml_query( q11, element(bib, [], Results) ) :-
|
||||
element_name( Title, title ),
|
||||
element_name( Author, author ),
|
||||
element_name( Book, book ),
|
||||
element_name( Editor, editor ),
|
||||
element_name( Affiliation, affiliation ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element(book, [], [Title,FirstAuthor|Authors]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
findall( Author, xml::subterm(Book, Author), [FirstAuthor|Authors] )
|
||||
),
|
||||
Books
|
||||
),
|
||||
findall(
|
||||
element(reference, [], [Title,Affiliation]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book ),
|
||||
xml::subterm( Book, Title ),
|
||||
xml::subterm( Book, Editor ),
|
||||
xml::subterm( Editor, Affiliation )
|
||||
),
|
||||
References
|
||||
),
|
||||
list::append( Books, References, Results ).
|
||||
|
||||
% Q12: Find pairs of books that have different titles but the same set of authors
|
||||
% (possibly in a different order).
|
||||
|
||||
xml_query( q12, element(bib, [], Pairs) ) :-
|
||||
element_name( Author, author ),
|
||||
element_name( Book1, book ),
|
||||
element_name( Book2, book ),
|
||||
element_name( Title1, title ),
|
||||
element_name( Title2, title ),
|
||||
input_document( 'bib.xml', Bibliography ),
|
||||
findall(
|
||||
element('book-pair', [], [Title1,Title2]),
|
||||
(
|
||||
xml::subterm( Bibliography, Book1 ),
|
||||
findall( Author, xml::subterm(Book1, Author), AuthorBag1 ),
|
||||
sort( AuthorBag1, AuthorSet ),
|
||||
xml::subterm( Bibliography, Book2 ),
|
||||
Book2 @< Book1,
|
||||
findall( Author, xml::subterm(Book2, Author), AuthorBag2 ),
|
||||
sort( AuthorBag2, AuthorSet ),
|
||||
xml::subterm( Book1, Title1 ),
|
||||
xml::subterm( Book2, Title2 )
|
||||
),
|
||||
Pairs
|
||||
).
|
||||
|
||||
% Auxilliary Predicates
|
||||
|
||||
other_authors( [], [] ).
|
||||
other_authors( [Author|Authors], [Author|EtAl] ) :-
|
||||
et_al( Authors, EtAl ).
|
||||
|
||||
et_al( [], [] ).
|
||||
et_al( [_|_], [element('et-al',[],[])] ).
|
||||
|
||||
text_value( [pcdata(Text)], Text ).
|
||||
text_value( [cdata(Text)], Text ).
|
||||
|
||||
element_name( element(Name, _Attributes, _Content), Name ).
|
||||
|
||||
|
||||
/* range( +Pairs, ?Range ) when Pairs is a list of key-datum pairs and Range
|
||||
* is the list of data.
|
||||
*/
|
||||
range( [], [] ).
|
||||
range( [_Key-Datum|Pairs], [Datum|Data] ) :-
|
||||
range( Pairs, Data ).
|
||||
|
||||
/* minimum( +List, ?Min ) is true if Min is the least member of List in the
|
||||
* standard order.
|
||||
*/
|
||||
minimum( [H|T], Min ):-
|
||||
minimum1( T, H, Min ).
|
||||
|
||||
minimum1( [], Min, Min ).
|
||||
minimum1( [H|T], Min0, Min ) :-
|
||||
compare( Relation, H, Min0 ),
|
||||
minimum2( Relation, H, Min0, T, Min ).
|
||||
|
||||
minimum2( '=', Min0, Min0, T, Min ) :-
|
||||
minimum1( T, Min0, Min ).
|
||||
minimum2( '<', Min0, _Min1, T, Min ) :-
|
||||
minimum1( T, Min0, Min ).
|
||||
minimum2( '>', _Min0, Min1, T, Min ) :-
|
||||
minimum1( T, Min1, Min ).
|
||||
|
||||
/* input_document( +File, ?XML ) reads File and parses the input into the
|
||||
* "Document Value Model" XML.
|
||||
*/
|
||||
input_document( File, XML ) :-
|
||||
% Read InputFile as a list of chars
|
||||
open( File, read, Input ),
|
||||
get_codes( Input, Codes ),
|
||||
close( Input ),
|
||||
% Parse the Input chars into the term XML
|
||||
xml::parse( Codes, XML ).
|
||||
|
||||
|
||||
put_codes( [], _ ).
|
||||
put_codes( [Code|Codes], Output ) :-
|
||||
put_code( Output, Code ),
|
||||
put_codes( Codes, Output ).
|
||||
|
||||
|
||||
get_codes( Input, [Code|Codes] ) :-
|
||||
\+ at_end_of_stream( Input ),
|
||||
get_code( Input, Code ),
|
||||
get_codes( Input, Codes ).
|
||||
get_codes( _, [] ).
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(xml)).
|
@ -1,32 +0,0 @@
|
||||
<prices>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>65.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<source>www.amazon.com</source>
|
||||
<price>34.95</price>
|
||||
</book>
|
||||
<book>
|
||||
<title>Data on the Web</title>
|
||||
<source>www.bn.com</source>
|
||||
<price>39.95</price>
|
||||
</book>
|
||||
</prices>
|
@ -1,25 +0,0 @@
|
||||
|
||||
<reviews>
|
||||
<entry>
|
||||
<title>Data on the Web</title>
|
||||
<price>34.95</price>
|
||||
<review>
|
||||
A very good discussion of semi-structured database
|
||||
systems and XML.
|
||||
</review>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Advanced Programming in the Unix environment</title>
|
||||
<price>65.95</price>
|
||||
<review>
|
||||
A clear and detailed discussion of UNIX programming.
|
||||
</review>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>TCP/IP Illustrated</title>
|
||||
<price>65.95</price>
|
||||
<review>
|
||||
One of the best books on TCP/IP.
|
||||
</review>
|
||||
</entry>
|
||||
</reviews>
|
File diff suppressed because it is too large
Load Diff
@ -1,209 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
This folder contains several examples of Logtalk programs. A brief
|
||||
description of each example is included below.
|
||||
|
||||
Each example folder contains a "NOTES.txt" file and a loader helper
|
||||
file that may be used to load all the example entities. In addition,
|
||||
most examples contain a "SCRIPT.txt" file with instructions on how to
|
||||
load the example and sample queries for your to try.
|
||||
|
||||
Most of these examples need objects, protocols, and categories that
|
||||
are defined in the Logtalk standard library or in other examples. See
|
||||
the "NOTES.txt" files inside the library folder, plus the "NOTES.txt"
|
||||
and "SCRIPT.txt" files inside each example folder.
|
||||
|
||||
Some examples may redefine objects already loaded from other examples.
|
||||
You may want to restart Logtalk after trying each example.
|
||||
|
||||
Some of the examples have been adopted from public available Prolog
|
||||
code or from known Prolog text books and are copyrighted by the respective
|
||||
authors.
|
||||
|
||||
These are programming examples, meaning that you should study the source
|
||||
files to fully understand them. However, note that some examples purpose
|
||||
is to illustrate general principles rather than being adequate, efficient
|
||||
solutions for deployment code.
|
||||
|
||||
All examples are formatted using four spaces tabs.
|
||||
|
||||
By default, compiling an example generates a XML documenting file for
|
||||
each compiled entity (object, category, or protocol). See the "xml"
|
||||
folder for instructions on how to browse the XML files for on-line
|
||||
reading or how to convert the files to a print-ready format such as PDF.
|
||||
|
||||
|
||||
Here is a short description of each included example:
|
||||
|
||||
aliases
|
||||
example of using the alias/3 predicate directive to provide
|
||||
alternative names to inherited predicates in order to improve
|
||||
readability or to solve multi-inheritance conflicts
|
||||
|
||||
assignvars
|
||||
example of using assignable variables in the context of parametric
|
||||
objects in order to represent object state
|
||||
|
||||
benchmarks
|
||||
simple benchmarks for helping measuring performance of Logtalk
|
||||
message sending between Prolog compilers and for comparing
|
||||
performance of message sending calls with predicate calls in
|
||||
plain Prolog
|
||||
|
||||
birds
|
||||
bird identification expert system
|
||||
(example adopted from the Adventure in Prolog Amzi! book)
|
||||
|
||||
bottles
|
||||
99 bottles of beer on the wall! Sing along!
|
||||
|
||||
bricks
|
||||
example of representation and handling of relations using events;
|
||||
illustrates how to use events to avoid breaking object encapsulation
|
||||
|
||||
classvars
|
||||
example of implementation of class variables
|
||||
(as found in Smalltalk; i.e. shared instance variables)
|
||||
|
||||
dcgs
|
||||
examples of using DCG rules inside objects and categories
|
||||
|
||||
diamonds
|
||||
examples of problems and solutions for the "diamond problem"
|
||||
(multi-inheritance conflicts and ambiguities)
|
||||
|
||||
dynpred
|
||||
example of using some of the built-in database handling methods
|
||||
in order to implement dynamic object state
|
||||
|
||||
encodings
|
||||
very simple example of using the new, experimental encoding/1
|
||||
directive (requires Logtalk to be run with the SWI-Prolog compiler)
|
||||
|
||||
engines
|
||||
example of category composition (importation of categories by
|
||||
other categories) using car engines
|
||||
|
||||
errors
|
||||
example showing the Logtalk compiler warning and error reporting
|
||||
for common programming errors
|
||||
|
||||
hello_world
|
||||
the unavoidable "hello world" programming example
|
||||
|
||||
hooks
|
||||
simple example of using compiler hook objects and predicates
|
||||
|
||||
inheritance
|
||||
examples of public, protected, and private inheritance using both
|
||||
prototypes and classes/instances
|
||||
|
||||
instmethods
|
||||
example of instance defined methods; also illustrates the use of
|
||||
"super calls" to call overridden method definitions
|
||||
|
||||
lo
|
||||
examples adopted from the Francis G. McCabe L&O system
|
||||
|
||||
logic
|
||||
example of a translator of first-order predicate logic propositions
|
||||
to conjunctive normal form and to clausal form
|
||||
|
||||
lpa
|
||||
examples adopted from the LPA Prolog++ system
|
||||
|
||||
metapredicates
|
||||
example of using meta-predicates in Logtalk objects
|
||||
|
||||
metainterpreters
|
||||
some examples of simple meta-interpreters defined as categories
|
||||
that can be imported by "database" objects
|
||||
|
||||
mi
|
||||
simple multi-inheritance examples
|
||||
|
||||
miscellaneous
|
||||
unsorted examples
|
||||
|
||||
modules
|
||||
simple example of compiling Prolog module files as objects
|
||||
|
||||
msglog
|
||||
example of using events and monitors for recording, replaying,
|
||||
and printing user messages
|
||||
|
||||
operators
|
||||
example of using operators local to objects and categories
|
||||
|
||||
parametric
|
||||
simple example of parametric objects
|
||||
|
||||
poem
|
||||
examples adopted from the Ben Staveley-Taylor POEM system
|
||||
|
||||
points
|
||||
example adopted from SICStus Objects documentation; defines
|
||||
a simple class hierarchy of points illustrating how to use
|
||||
categories as object components
|
||||
|
||||
polygons
|
||||
example of representation and handling of relations using events
|
||||
|
||||
profiling
|
||||
examples of using of events and monitors to implement profilers
|
||||
|
||||
proxies
|
||||
example of using parametric object proxies for an efficient
|
||||
representation of objects with read-only state
|
||||
|
||||
puzzles
|
||||
several examples of logical puzzles
|
||||
|
||||
reflection
|
||||
example of a simple class-based reflective system
|
||||
|
||||
relations
|
||||
objects implementing predicates for dealing with relations and
|
||||
constrained relations between objects; used by other examples
|
||||
|
||||
roots
|
||||
objects, protocols, and categories needed by most of the other
|
||||
examples; illustrates how you can define object creation and
|
||||
abolishing methods, complete with initialization and termination
|
||||
options
|
||||
|
||||
searching
|
||||
state-space searching framework
|
||||
(example adopted from Ivan Bratko's "Prolog Programming for
|
||||
Artificial Intelligence" book)
|
||||
|
||||
shapes
|
||||
simple geometric shapes implemented as both a prototype hierarchy
|
||||
and a class hierarchy
|
||||
|
||||
sicstus
|
||||
examples adopted from SICStus Objects documentation
|
||||
|
||||
symdiff
|
||||
example of using parametric objects to implement symbolic
|
||||
expression differentiation and simplification
|
||||
|
||||
tabling
|
||||
simple example of using tabling directives within objects
|
||||
|
||||
testing
|
||||
some examples of writing unit tests
|
||||
|
||||
threads
|
||||
several simple examples of multi-threading programming
|
||||
(requires Logtalk to be run with either YAP or SWI-Prolog)
|
||||
|
||||
viewpoints
|
||||
example on how to implement property sharing and value sharing
|
||||
with prototypes
|
@ -1,13 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT
|
||||
file.
|
||||
|
||||
For a description of this example, please see the comments in the
|
||||
aliases.lgt source file.
|
@ -1,84 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(aliases(loader)).
|
||||
...
|
||||
|
||||
|
||||
% check the object square(_) public protocol:
|
||||
|
||||
| ?- square(_)::current_predicate(Predicate).
|
||||
|
||||
Predicate = side/1 ;
|
||||
Predicate = width/1 ;
|
||||
Predicate = height/1 ;
|
||||
Predicate = area/1
|
||||
yes
|
||||
|
||||
|
||||
% test the side/1 alias:
|
||||
|
||||
| ?- square(2)::side(Side).
|
||||
|
||||
Side = 2
|
||||
yes
|
||||
|
||||
| ?- square(2)::predicate_property(side(_), Property).
|
||||
|
||||
Property = public ;
|
||||
Property = static ;
|
||||
Property = declared_in(rectangle(_G264, _G265)) ;
|
||||
Property = defined_in(rectangle(_G297, _G298)) ;
|
||||
Property = alias(width(_G182))
|
||||
yes
|
||||
|
||||
| ?- square(2)::predicate_property(width(_), Property).
|
||||
|
||||
Property = public ;
|
||||
Property = static ;
|
||||
Property = declared_in(rectangle(_G262, _G263)) ;
|
||||
Property = defined_in(rectangle(_G293, _G294))
|
||||
yes
|
||||
|
||||
|
||||
% check the object circle(_) public protocol:
|
||||
|
||||
| ?- circle(_)::current_predicate(Predicate).
|
||||
|
||||
Predicate = r/1 ;
|
||||
Predicate = rx/1 ;
|
||||
Predicate = ry/1 ;
|
||||
Predicate = area/1
|
||||
yes
|
||||
|
||||
|
||||
% test the r/1 alias:
|
||||
|
||||
| ?- circle(3)::r(Radius).
|
||||
|
||||
Radius = 3
|
||||
yes
|
||||
|
||||
| ?- circle(3)::predicate_property(r(_), Property).
|
||||
|
||||
Property = public ;
|
||||
Property = static ;
|
||||
Property = declared_in(ellipse(_G266, _G267)) ;
|
||||
Property = defined_in(ellipse(_G299, _G300)) ;
|
||||
Property = alias(rx(_G177))
|
||||
yes
|
||||
|
||||
| ?- circle(3)::predicate_property(rx(_), Property).
|
||||
|
||||
Property = public ;
|
||||
Property = static ;
|
||||
Property = declared_in(ellipse(_G261, _G262)) ;
|
||||
Property = defined_in(ellipse(_G292, _G293))
|
||||
yes
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
This example illustrates the use of the predicate directive alias/3 for
|
||||
defining alternative names for inherited predicates.
|
||||
*/
|
||||
|
||||
|
||||
% first, we define a simple parametric object for representing rectangles:
|
||||
|
||||
:- object(rectangle(_Width, _Height)).
|
||||
|
||||
:- public(width/1).
|
||||
:- public(height/1).
|
||||
:- public(area/1).
|
||||
|
||||
width(Width) :-
|
||||
parameter(1, Width).
|
||||
|
||||
height(Height) :-
|
||||
parameter(2, Height).
|
||||
|
||||
area(Area) :-
|
||||
::width(Width),
|
||||
::height(Height),
|
||||
Area is Width*Height.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% next, we define a square object which adds an alias, side/1, for the
|
||||
% inherited predicate width/1:
|
||||
|
||||
:- object(square(Side),
|
||||
extends(rectangle(Side, Side))).
|
||||
|
||||
:- alias(rectangle(_, _), width/1, side/1).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% a similar example can be defined using ellipses and circles:
|
||||
|
||||
:- object(ellipse(_RX, _RY)).
|
||||
|
||||
:- public(rx/1).
|
||||
:- public(ry/1).
|
||||
:- public(area/1).
|
||||
|
||||
rx(Rx) :-
|
||||
parameter(1, Rx).
|
||||
|
||||
ry(Ry) :-
|
||||
parameter(2, Ry).
|
||||
|
||||
area(Area) :-
|
||||
::rx(Rx),
|
||||
::ry(Ry),
|
||||
Area is Rx*Ry*3.1415927.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% in this case, we define an alias named r/1 for the inherited
|
||||
% predicate rx/1:
|
||||
|
||||
:- object(circle(Radius),
|
||||
extends(ellipse(Radius, Radius))).
|
||||
|
||||
:- alias(ellipse(_, _), rx/1, r/1).
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(aliases)).
|
@ -1,20 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This example illustrates the use of assignable variables and parametric
|
||||
objects as alternative implementation to dynamic object predicates for
|
||||
storing (backtracable) object state. For more information on assignable
|
||||
variables please consult the URL:
|
||||
|
||||
http://www.kprolog.com/en/logical_assignment/
|
||||
|
||||
The objects in this example make use of the library category "assignvars".
|
||||
This category contains an adaptation of the pure logical subset implementation
|
||||
of assignable variables by Nobukuni Kino, which can be found on the URL above.
|
@ -1,69 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the "assignvars" category and the example:
|
||||
|
||||
| ?- logtalk_load(assignvars(loader)).
|
||||
...
|
||||
|
||||
|
||||
% rectangle example:
|
||||
|
||||
?- rectangle(2, 3, _)::(init, position(X0, Y0), move(3, 7), position(X1, Y1), move(2, 5), position(X2, Y2)).
|
||||
|
||||
X0 = 0
|
||||
Y0 = 0
|
||||
X1 = 3
|
||||
Y1 = 7
|
||||
X2 = 2
|
||||
Y2 = 5
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% finite state machine example:
|
||||
|
||||
| ?- fsm(T, I, F), fsm(T, I, F)::recognise([0,1,1,2,1,2,0]).
|
||||
|
||||
red-0-red
|
||||
red-1-green
|
||||
green-1-yellow
|
||||
yellow-2-red
|
||||
red-1-green
|
||||
green-2-red
|
||||
red-0-red
|
||||
|
||||
T = [red-0-red, red-1-green, red-2-red, yellow-0-red, yellow-1-green, yellow-2-red, green-0-yellow, ... -... -yellow, ... -...]
|
||||
I = red
|
||||
F = [red]
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% finite state machine example:
|
||||
|
||||
| ?- fsm(T, I, F), !, fsm(T, I, F)::recognise([0,1,1,2,1,2,1,0]).
|
||||
|
||||
red-0-red
|
||||
red-1-green
|
||||
green-1-yellow
|
||||
yellow-2-red
|
||||
red-1-green
|
||||
green-2-red
|
||||
red-1-green
|
||||
green-0-yellow
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
backtracking...
|
||||
|
||||
No
|
@ -1,63 +0,0 @@
|
||||
|
||||
|
||||
% fsm(Transitions, Initial, Final)
|
||||
%
|
||||
% fsm(-list, -nonvar, -list)
|
||||
|
||||
fsm([red-0-red, red-1-green, red-2-red, % a simple finite state machine example
|
||||
yellow-0-red, yellow-1-green, yellow-2-red,
|
||||
green-0-yellow, green-1-yellow, green-2-red],
|
||||
red,
|
||||
[red]).
|
||||
|
||||
|
||||
:- object(fsm(_Transitions, _Initial, _Final),
|
||||
imports(private::assignvars)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2005/1/8,
|
||||
comment is 'A simple implementation of finite-state machines using assignable variables and parametric objects. Adapted from a similar example by Nobukuni Kino.',
|
||||
parnames is ['Transitions', 'Initial state', 'Final states']]).
|
||||
|
||||
:- public(recognise/1).
|
||||
:- mode(recognise(+list), zero_or_more).
|
||||
:- info(recognise/1,
|
||||
[comment is 'Recognise a list of events.',
|
||||
argnames is ['Events']]).
|
||||
|
||||
recognise(Events) :-
|
||||
parameter(2, Initial),
|
||||
::assignable(Current, Initial),
|
||||
recognise(Events, Current).
|
||||
|
||||
recognise([], State) :-
|
||||
::State => Current,
|
||||
final_state(Current).
|
||||
recognise([Event| Events], State) :-
|
||||
::State => Current,
|
||||
transition(Event, Current, Next),
|
||||
(write(Current-Event-Next), nl
|
||||
;
|
||||
write('backtracking...'), nl, fail),
|
||||
::State <= Next,
|
||||
recognise(Events, State).
|
||||
|
||||
transition(Event, Current, Next) :-
|
||||
parameter(1, Transitions),
|
||||
transition(Transitions, Event, Current, Next).
|
||||
|
||||
transition([Current-Event-Next| _], Event, Current, Next).
|
||||
transition([_| Transitions], Event, Current, Next):-
|
||||
transition(Transitions, Event, Current, Next).
|
||||
|
||||
final_state(State) :-
|
||||
parameter(3, Final),
|
||||
final_state(Final, State).
|
||||
|
||||
final_state([State| _], State).
|
||||
final_state([_| States], State) :-
|
||||
final_state(States, State).
|
||||
|
||||
:- end_object.
|
@ -1,4 +0,0 @@
|
||||
|
||||
:- initialization((
|
||||
logtalk_load(library(assignvars), [reload(skip)]), % allow for static binding
|
||||
logtalk_load([fsm3, rectangle3]))).
|
@ -1,52 +0,0 @@
|
||||
|
||||
:- object(rectangle(_Width, _Height, _Position),
|
||||
imports(private::assignvars)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2005/1/8,
|
||||
comment is 'A simple implementation of a geometric rectangle using assignable variables and parametric objects.',
|
||||
parnames is ['Width', 'Height', 'Position']]).
|
||||
|
||||
:- public(init/0).
|
||||
:- mode(init, one).
|
||||
:- info(init/0,
|
||||
[comment is 'Initialize rectangle position.']).
|
||||
|
||||
:- public(area/1).
|
||||
:- mode(area(-integer), one).
|
||||
:- info(area/1,
|
||||
[comment is 'Rectangle area.',
|
||||
argnames is ['Area']]).
|
||||
|
||||
:- public(move/2).
|
||||
:- mode(move(+integer, +integer), one).
|
||||
:- info(move/2, [
|
||||
comment is 'Moves a rectangle to a new position.',
|
||||
argnames is ['X', 'Y']]).
|
||||
|
||||
:- public(position/2).
|
||||
:- mode(position(?integer, ?integer), zero_or_one).
|
||||
:- info(position/2, [
|
||||
comment is 'Rectangle current position.',
|
||||
argnames is ['X', 'Y']]).
|
||||
|
||||
init :-
|
||||
parameter(3, Position),
|
||||
::assignable(Position, (0, 0)).
|
||||
|
||||
area(Area) :-
|
||||
parameter(1, Width),
|
||||
parameter(2, Height),
|
||||
Area is Width*Height.
|
||||
|
||||
move(X, Y) :-
|
||||
parameter(3, Position),
|
||||
::Position <= (X, Y).
|
||||
|
||||
position(X, Y) :-
|
||||
parameter(3, Position),
|
||||
::Position => (X, Y).
|
||||
|
||||
:- end_object.
|
@ -1,83 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This folder provides simple benchmark tests for comparing Logtalk message
|
||||
sending performance with direct predicates calls in plain Prolog.
|
||||
These benchmarks may also be used for comparing Logtalk message sending
|
||||
performance across Prolog compilers.
|
||||
|
||||
This example is made of four loader files and five source files:
|
||||
|
||||
loader_events.lgt
|
||||
loads all source files with event support turned on
|
||||
loader_no_events.lgt
|
||||
loads all source files with event support turned off
|
||||
loader_static_binding.lgt
|
||||
loads all source files with event support turned off and using
|
||||
static binding
|
||||
loader.lgt
|
||||
the same as the loader_static_binding.lgt file
|
||||
|
||||
benchmarks.lgt
|
||||
contains the benchmark goals and testing predicates
|
||||
plain.lgt
|
||||
contains a definition for a list length predicate and a predicate
|
||||
for testing performance of the built-in predicates assertz/1 and
|
||||
retract/1
|
||||
module.pl (not loaded by default; see below)
|
||||
contains the same definition of a list length predicate
|
||||
encapsulated in a module
|
||||
objects.lgt
|
||||
contains an object encapsulating the same definition of a list
|
||||
length predicate, plus two descendant objects to simulate a small
|
||||
hierarchy (used for testing calls to imported category predicates)
|
||||
database.lgt
|
||||
contains predicates for testing the performance of the built-in
|
||||
database methods assertz/1 and retract/1
|
||||
category.lgt
|
||||
contains a single predicate used when comparing performance of
|
||||
calls to imported category predicates using direct calls and using
|
||||
messages to "self"
|
||||
|
||||
You may have noticed above that the benchmark predicates and the predicates
|
||||
for plain Prolog testing are both encapsulated in Logtalk source files. The
|
||||
Logtalk compiler just copies the plain Prolog code to the generated Prolog
|
||||
files. The reason for using the .lgt extension for these files is simply to
|
||||
make it possible to load all the example code using calls to the predicates
|
||||
logtalk_load/1-2.
|
||||
|
||||
By default, the benchmark tests on the SCRIPT file use a list of 20 elements
|
||||
as an argument to the list length predicates. When dynamic binding is used,
|
||||
increasing the list length leads to decreasing performance differences between
|
||||
plain Prolog and Logtalk as the list length computation time far outweighs the
|
||||
overhead of the message sending mechanism. Likewise, decreasing the list
|
||||
length leads to increasing performance differences between plain Prolog and
|
||||
Logtalk (up to the point you will be measuring the Logtalk message sending
|
||||
mechanism overhead compared to plain Prolog predicate calls). In real-life
|
||||
applications, only testing can give you a balanced view on the trade-offs
|
||||
between plain Prolog performance and Logtalk programming features.
|
||||
|
||||
By default, the loader files used to load the example code do not load the
|
||||
module.pl file. Edit these files if your Prolog compiler supports a module
|
||||
system and you want to run some comparative performance tests between plain
|
||||
Prolog, Prolog modules, and Logtalk objects. Note that you may need to edit
|
||||
the code on the module.pl file to make any necessary compatibility changes
|
||||
for your Prolog compiler module system. For most Prolog module systems, the
|
||||
performance of module calls is close or even identical to the performance of
|
||||
plain Prolog calls when using imported predicates and implicit qualification.
|
||||
When using explicit module qualification, performance can be significantly
|
||||
worse.
|
||||
|
||||
When static binding is used, messages to objects are, whenever possible,
|
||||
translated to direct predicate calls. Thus performance should be about the
|
||||
same as in plain Prolog predicate calls. However, due to the overhead of
|
||||
three extra arguments per object predicate (used for passing the execution
|
||||
context), the performance of Logtalk optimized calls might be slightly
|
||||
worse than the equivalent plain Prolog predicate calls.
|
@ -1,78 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example by choosing one of the loader files
|
||||
% (you must quit and restart Logtalk for each testing scenario):
|
||||
|
||||
|
||||
% run benchmarks with event support turned on:
|
||||
|
||||
| ?- logtalk_load(benchmarks(loader_events)).
|
||||
...
|
||||
|
||||
|
||||
% run benchmarks with event support turned off:
|
||||
|
||||
| ?- logtalk_load(benchmarks(loader_no_events)).
|
||||
...
|
||||
|
||||
|
||||
% run benchmarks with event support turned off and using static binding:
|
||||
|
||||
| ?- logtalk_load(benchmarks(loader_static_binding)).
|
||||
...
|
||||
|
||||
|
||||
% list all the benchmark tests:
|
||||
|
||||
| ?- benchmarks::benchmark(Id, Goal).
|
||||
|
||||
Goal = my_length([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],_)
|
||||
Id = s1 ? ;
|
||||
|
||||
Goal = object::length([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],_)
|
||||
Id = s2 ? ;
|
||||
|
||||
Goal = leaf::obj_local
|
||||
Id = c1 ? ;
|
||||
|
||||
Goal = leaf::ctg_direct
|
||||
Id = c2 ? ;
|
||||
|
||||
Goal = leaf::ctg_self
|
||||
Id = c3 ? ;
|
||||
|
||||
Goal = create_object(xpto,[],[],[]),abolish_object(xpto)
|
||||
Id = d1 ? ;
|
||||
|
||||
Goal = plain_dyndb
|
||||
Id = d2 ? ;
|
||||
|
||||
Goal = database::this_dyndb
|
||||
Id = d3 ? ;
|
||||
|
||||
Goal = database::self_dyndb
|
||||
Id = d4 ? ;
|
||||
|
||||
Goal = database::obj_dyndb
|
||||
Id = d5
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% run all the benchmark tests the default number of times:
|
||||
|
||||
| ?- benchmarks::run.
|
||||
...
|
||||
|
||||
|
||||
% or run specific benchmark tests individually, for example:
|
||||
|
||||
|
||||
| ?- benchmarks::run(s1, 1000000).
|
||||
...
|
@ -1,122 +0,0 @@
|
||||
|
||||
% benchmark a goal using a default number of repetitions and printing some
|
||||
% useful statistics
|
||||
|
||||
benchmark(Goal) :-
|
||||
N = 100000,
|
||||
benchmark(Goal, N, Looptime, Goaltime, Average, Speed),
|
||||
report(Goal, N, Looptime, Goaltime, Average, Speed).
|
||||
|
||||
|
||||
benchmark(Goal, N) :-
|
||||
benchmark(Goal, N, Looptime, Goaltime, Average, Speed),
|
||||
report(Goal, N, Looptime, Goaltime, Average, Speed).
|
||||
|
||||
|
||||
benchmark(Goal, N, Looptime, Goaltime, Average, Speed) :-
|
||||
'$lgt_cpu_time'(Seconds1), % defined in the config files
|
||||
do_benchmark(N, true),
|
||||
'$lgt_cpu_time'(Seconds2),
|
||||
Looptime is Seconds2 - Seconds1,
|
||||
'$lgt_cpu_time'(Seconds3),
|
||||
do_benchmark(N, Goal),
|
||||
'$lgt_cpu_time'(Seconds4),
|
||||
Goaltime is Seconds4 - Seconds3,
|
||||
Average is (Goaltime - Looptime)/N,
|
||||
Speed is 1.0/Average.
|
||||
|
||||
|
||||
report(Id, Goal, N, Looptime, Goaltime, Average, Speed) :-
|
||||
write(Id), write(': '),
|
||||
report(Goal, N, Looptime, Goaltime, Average, Speed).
|
||||
|
||||
|
||||
report(Goal, N, Looptime, Goaltime, Average, Speed) :-
|
||||
writeq(Goal), nl,
|
||||
write('Number of repetitions: '), write(N), nl,
|
||||
write('Loop time: '), write(Looptime), nl,
|
||||
write('Goal time: '), write(Goaltime), nl,
|
||||
write('Average time per call: '), write(Average), nl,
|
||||
write('Number of calls per second: '), write(Speed), nl,
|
||||
nl.
|
||||
|
||||
|
||||
% repeat a goal N times using a failure-driven loop to avoid the interference
|
||||
% of Prolog compiler memory management mechanism (such as garbage collection)
|
||||
% on the results
|
||||
|
||||
do_benchmark(N, Goal) :-
|
||||
repeat(N), % another option would be to use a between/3 built-in predicate
|
||||
call(Goal),
|
||||
fail.
|
||||
|
||||
do_benchmark(_, _).
|
||||
|
||||
|
||||
% some Prolog compilers define the predicate repeat/1 as a built-in predicate;
|
||||
% if that's the case of the Prolog compiler you are using, then comment out
|
||||
% the definition that follows
|
||||
|
||||
repeat(_).
|
||||
|
||||
repeat(N) :-
|
||||
N > 1,
|
||||
N2 is N - 1,
|
||||
repeat(N2).
|
||||
|
||||
|
||||
% generate a list containing the first N non-negative integers
|
||||
|
||||
generate_list(N, List) :-
|
||||
N >= 0,
|
||||
generate_list(0, N, List).
|
||||
|
||||
|
||||
generate_list(N, N, []) :-
|
||||
!.
|
||||
|
||||
generate_list(M, N, [M| Ms]) :-
|
||||
M < N,
|
||||
M2 is M + 1,
|
||||
generate_list(M2, N, Ms).
|
||||
|
||||
|
||||
% utility predicate for running all benchmark tests
|
||||
|
||||
benchmarks :-
|
||||
N = 100000,
|
||||
benchmark_goal(Id, Goal),
|
||||
benchmark(Goal, N, Looptime, Goaltime, Average, Speed),
|
||||
report(Id, Goal, N, Looptime, Goaltime, Average, Speed),
|
||||
fail.
|
||||
|
||||
benchmarks.
|
||||
|
||||
|
||||
% some benchmark tests for static code:
|
||||
|
||||
benchmark_goal('S1', my_length(List, _)) :-
|
||||
generate_list(30, List).
|
||||
|
||||
benchmark_goal('S2', object::length(List, _)) :-
|
||||
generate_list(30, List).
|
||||
|
||||
benchmark_goal('S3', '$lgt_send_to_object_nv'(object, length(List, _), user)) :-
|
||||
generate_list(30, List).
|
||||
|
||||
benchmark_goal('S4', '$lgt_send_to_object_ne_nv'(object, length(List, _), user)) :-
|
||||
generate_list(30, List).
|
||||
|
||||
|
||||
% some benchmark tests for dynamic code:
|
||||
|
||||
benchmark_goal('D1', (create_object(xpto, [], [], []), abolish_object(xpto))).
|
||||
|
||||
benchmark_goal('D2', db_test_plain).
|
||||
|
||||
benchmark_goal('D3', '$lgt_send_to_object_ne_nv'(database, db_test_this, user)).
|
||||
|
||||
benchmark_goal('D4', '$lgt_send_to_object_ne_nv'(database, db_test_self, user)).
|
||||
|
||||
benchmark_goal('D5', '$lgt_send_to_object_ne_nv'(database, db_test_obj, user)).
|
||||
|
@ -1,162 +0,0 @@
|
||||
|
||||
:- object(benchmarks).
|
||||
|
||||
:- info([
|
||||
version is 3.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/06/11,
|
||||
comment is 'Benchmark utility predicates and standard set of benchmarks.']).
|
||||
|
||||
:- public(run/0).
|
||||
:- mode(run, one).
|
||||
:- info(run/0, [
|
||||
comment is 'Runs all benchmarks the default number of times.']).
|
||||
|
||||
:- public(run/1).
|
||||
:- mode(run(+integer), one).
|
||||
:- info(run/1, [
|
||||
comment is 'Runs all benchmarks the specified number of times.',
|
||||
argnames is ['N']]).
|
||||
|
||||
:- public(run/2).
|
||||
:- mode(run(+atom, +integer), one).
|
||||
:- info(run/2, [
|
||||
comment is 'Runs a specific benchmark the specified number of times.',
|
||||
argnames is ['Id', 'N']]).
|
||||
|
||||
:- public(benchmark/2).
|
||||
:- mode(move(?atom, -callable), zero_or_more).
|
||||
:- info(move/2, [
|
||||
comment is 'Table of benchmark identifiers and benchmark goals.',
|
||||
argnames is ['Id', 'Goal']]).
|
||||
|
||||
% run all benchmarks the default number of times:
|
||||
run :-
|
||||
run(100000).
|
||||
|
||||
% run all benchmark tests N times:
|
||||
run(N) :-
|
||||
benchmark(Id, Goal),
|
||||
run(Id, N, Looptime, Goaltime, Average, Speed),
|
||||
report(Id, Goal, N, Looptime, Goaltime, Average, Speed),
|
||||
fail.
|
||||
run(_).
|
||||
|
||||
% run a specific benchmark test:
|
||||
run(Id, N) :-
|
||||
benchmark(Id, Goal),
|
||||
run(Id, N, Looptime, Goaltime, Average, Speed),
|
||||
report(Id, Goal, N, Looptime, Goaltime, Average, Speed).
|
||||
|
||||
run(Id, N, Looptime, Goaltime, Average, Speed) :-
|
||||
{'$lgt_cpu_time'(Seconds1)}, % defined in the config files
|
||||
do_benchmark(empty_loop, N),
|
||||
{'$lgt_cpu_time'(Seconds2)},
|
||||
Looptime is Seconds2 - Seconds1,
|
||||
{'$lgt_cpu_time'(Seconds3)},
|
||||
do_benchmark(Id, N),
|
||||
{'$lgt_cpu_time'(Seconds4)},
|
||||
Goaltime is Seconds4 - Seconds3,
|
||||
Average is (Goaltime - Looptime)/N,
|
||||
Speed is 1.0/Average.
|
||||
|
||||
report(Id, Goal, N, Looptime, Goaltime, Average, Speed) :-
|
||||
write(Id), write(': '),
|
||||
writeq(Goal), nl,
|
||||
write('Number of repetitions: '), write(N), nl,
|
||||
write('Loop time: '), write(Looptime), nl,
|
||||
write('Goal time: '), write(Goaltime), nl,
|
||||
write('Average time per call: '), write(Average), nl,
|
||||
write('Number of calls per second: '), write(Speed), nl,
|
||||
nl.
|
||||
|
||||
% some benchmark tests for static code:
|
||||
benchmark(s1, my_length(List, _)) :-
|
||||
{generate_list(20, List)}.
|
||||
benchmark(s2, object::length(List, _)) :-
|
||||
{generate_list(20, List)}.
|
||||
|
||||
% some benchmark tests for category predicate calls:
|
||||
benchmark(c1, leaf::obj_local).
|
||||
benchmark(c2, leaf::ctg_direct).
|
||||
benchmark(c3, leaf::ctg_self).
|
||||
|
||||
% some benchmark tests for dynamic code:
|
||||
benchmark(d1, (create_object(xpto, [], [], []), abolish_object(xpto))).
|
||||
benchmark(d2, plain_dyndb(_)).
|
||||
benchmark(d3, database::this_dyndb(_)).
|
||||
benchmark(d4, database::self_dyndb(_)).
|
||||
benchmark(d5, database::obj_dyndb(_)).
|
||||
|
||||
% repeat a goal N times without using call/1 and using a failure-driven loop to
|
||||
% avoid the interference of Prolog compiler memory management mechanism (such as
|
||||
% garbage collection) on the results
|
||||
do_benchmark(empty_loop, N) :-
|
||||
{my_repeat(N)},
|
||||
fail.
|
||||
do_benchmark(empty_loop, _).
|
||||
|
||||
do_benchmark(s1, N) :-
|
||||
{generate_list(20, List)},
|
||||
{my_repeat(N)},
|
||||
{my_length(List, _)},
|
||||
fail.
|
||||
do_benchmark(s1, _).
|
||||
|
||||
do_benchmark(s2, N) :-
|
||||
{generate_list(20, List)},
|
||||
{my_repeat(N)},
|
||||
object::length(List, _),
|
||||
fail.
|
||||
do_benchmark(s2, _).
|
||||
|
||||
do_benchmark(c1, N) :-
|
||||
{my_repeat(N)},
|
||||
leaf::obj_local,
|
||||
fail.
|
||||
do_benchmark(c1, _).
|
||||
|
||||
do_benchmark(c2, N) :-
|
||||
{my_repeat(N)},
|
||||
leaf::ctg_direct,
|
||||
fail.
|
||||
do_benchmark(c2, _).
|
||||
|
||||
do_benchmark(c3, N) :-
|
||||
{my_repeat(N)},
|
||||
leaf::ctg_self,
|
||||
fail.
|
||||
do_benchmark(c3, _).
|
||||
|
||||
do_benchmark(d1, N) :-
|
||||
{my_repeat(N)},
|
||||
create_object(xpto, [], [], []),
|
||||
abolish_object(xpto),
|
||||
fail.
|
||||
do_benchmark(d1, _).
|
||||
|
||||
do_benchmark(d2, N) :-
|
||||
{my_repeat(N)},
|
||||
{plain_dyndb(N)},
|
||||
fail.
|
||||
do_benchmark(d2, _).
|
||||
|
||||
do_benchmark(d3, N) :-
|
||||
{my_repeat(N)},
|
||||
database::this_dyndb(N),
|
||||
fail.
|
||||
do_benchmark(d3, _).
|
||||
|
||||
do_benchmark(d4, N) :-
|
||||
{my_repeat(N)},
|
||||
database::self_dyndb(N),
|
||||
fail.
|
||||
do_benchmark(d4, _).
|
||||
|
||||
do_benchmark(d5, N) :-
|
||||
{my_repeat(N)},
|
||||
database::obj_dyndb(N),
|
||||
fail.
|
||||
do_benchmark(d5, _).
|
||||
|
||||
:- end_object.
|
@ -1,24 +0,0 @@
|
||||
|
||||
:- category(category).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/06/10,
|
||||
comment is 'Defines a simple predicate for comparing performance of calls from within an object to imported category predicates.']).
|
||||
|
||||
:- public(ctg_pred/0).
|
||||
|
||||
ctg_pred :-
|
||||
{generate_list(20, List)},
|
||||
length(List, _).
|
||||
|
||||
length(List, Length) :-
|
||||
length(List, 0, Length).
|
||||
|
||||
length([], Length, Length).
|
||||
length([_| Tail], Acc, Length) :-
|
||||
Acc2 is Acc + 1,
|
||||
length(Tail, Acc2, Length).
|
||||
|
||||
:- end_category.
|
@ -1,47 +0,0 @@
|
||||
|
||||
:- object(database).
|
||||
|
||||
:- info([
|
||||
version is 2.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/04/17,
|
||||
comment is 'Dynamic database benchmark utility predicates.']).
|
||||
|
||||
:- public(this_dyndb/1).
|
||||
:- mode(this_dyndb(+nonvar), one).
|
||||
:- info(this_dyndb/1, [
|
||||
comment is 'Asserts and retracts a predicate in "this".',
|
||||
argnames is ['Term']]).
|
||||
|
||||
:- public(self_dyndb/1).
|
||||
:- mode(self_dyndb(+nonvar), one).
|
||||
:- info(self_dyndb/1, [
|
||||
comment is 'Asserts and retracts a predicate using ::/1.',
|
||||
argnames is ['Term']]).
|
||||
|
||||
:- public(obj_dyndb/1).
|
||||
:- mode(obj_dyndb(+nonvar), one).
|
||||
:- info(obj_dyndb/1, [
|
||||
comment is 'Asserts and retracts a predicate using ::/2.',
|
||||
argnames is ['Term']]).
|
||||
|
||||
:- private([pred_this/1, pred_self/1, pred_obj/1]).
|
||||
:- dynamic([pred_this/1, pred_self/1, pred_obj/1]).
|
||||
|
||||
% direct calls to assertz/1 and retract/1:
|
||||
this_dyndb(N) :-
|
||||
assertz(pred_this(N)),
|
||||
retract(pred_this(N)).
|
||||
|
||||
% calls to assertz/1 and retract/1 using ::/1:
|
||||
self_dyndb(N) :-
|
||||
::assertz(pred_self(N)),
|
||||
::retract(pred_self(N)).
|
||||
|
||||
% calls to assertz/1 and retract/1 using ::/2:
|
||||
obj_dyndb(N) :-
|
||||
this(This),
|
||||
This::assertz(pred_obj(N)),
|
||||
This::retract(pred_obj(N)).
|
||||
|
||||
:- end_object.
|
@ -1,8 +0,0 @@
|
||||
|
||||
% uncomment the next line if your Prolog compiler supports modules
|
||||
%:- ensure_loaded(module).
|
||||
|
||||
:- initialization((
|
||||
logtalk_load([category], [events(off), reload(skip)]),
|
||||
logtalk_load([objects, database], [events(off), reload(skip)]),
|
||||
logtalk_load([plain, benchmarks], [events(off)]))).
|
@ -1,6 +0,0 @@
|
||||
|
||||
% uncomment the next line if your Prolog compiler supports modules
|
||||
%:- ensure_loaded(module).
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([category, objects, database, plain, benchmarks], [events(on)])).
|
@ -1,6 +0,0 @@
|
||||
|
||||
% uncomment the next line if your Prolog compiler supports modules
|
||||
%:- ensure_loaded(module).
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([category, objects, database, plain, benchmarks], [events(off)])).
|
@ -1,8 +0,0 @@
|
||||
|
||||
% uncomment the next line if your Prolog compiler supports modules
|
||||
%:- ensure_loaded(module).
|
||||
|
||||
:- initialization((
|
||||
logtalk_load([category], [events(off), reload(skip)]),
|
||||
logtalk_load([objects, database], [events(off), reload(skip)]),
|
||||
logtalk_load([plain, benchmarks], [events(off)]))).
|
@ -1,28 +0,0 @@
|
||||
|
||||
% you may need to update the module directive that follows for
|
||||
% compatibility with your Prolog compiler module system
|
||||
|
||||
:- module(module, [mod_length/2]).
|
||||
|
||||
|
||||
mod_length(List, Length) :-
|
||||
( integer(Length) ->
|
||||
Length >= 0,
|
||||
mod_make_list(Length, List)
|
||||
; mod_length(List, 0, Length)
|
||||
).
|
||||
|
||||
|
||||
mod_make_list(0, []):-
|
||||
!.
|
||||
|
||||
mod_make_list(N, [_| Tail]):-
|
||||
M is N-1,
|
||||
mod_make_list(M, Tail).
|
||||
|
||||
|
||||
mod_length([], Length, Length).
|
||||
|
||||
mod_length([_| Tail], Acc, Length) :-
|
||||
Acc2 is Acc + 1,
|
||||
mod_length(Tail, Acc2, Length).
|
@ -1,24 +0,0 @@
|
||||
|
||||
:- object(object).
|
||||
|
||||
:- public(length/2).
|
||||
|
||||
length(List, Length) :-
|
||||
integer(Length) ->
|
||||
Length >= 0,
|
||||
make_list(Length, List)
|
||||
;
|
||||
length(List, 0, Length).
|
||||
|
||||
make_list(0, []) :-
|
||||
!.
|
||||
make_list(N, [_| Tail]):-
|
||||
M is N-1,
|
||||
make_list(M, Tail).
|
||||
|
||||
length([], Length, Length).
|
||||
length([_| Tail], Acc, Length) :-
|
||||
Acc2 is Acc + 1,
|
||||
length(Tail, Acc2, Length).
|
||||
|
||||
:- end_object.
|
@ -1,65 +0,0 @@
|
||||
|
||||
:- object(object,
|
||||
imports(category)).
|
||||
|
||||
:- info([
|
||||
version is 3.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/06/11,
|
||||
comment is 'Example object for benchmarking library predicate calls and imported category predicate calls.']).
|
||||
|
||||
:- public(length/2).
|
||||
|
||||
length(List, Length) :-
|
||||
length(List, 0, Length).
|
||||
|
||||
length([], Length, Length).
|
||||
length([_| Tail], Acc, Length) :-
|
||||
Acc2 is Acc + 1,
|
||||
length(Tail, Acc2, Length).
|
||||
|
||||
:- public(ctg_self/0).
|
||||
% call an imported category predicate by sending a message to self;
|
||||
% performance will depend on the distance between "self" and "this"
|
||||
% (always uses dynamic binding)
|
||||
ctg_self :-
|
||||
::ctg_pred.
|
||||
|
||||
:- public(ctg_direct/0).
|
||||
% call an imported category predicate directly by using the :/1 control construct;
|
||||
% (static binding may be used, depending on how the category is compiled)
|
||||
ctg_direct :-
|
||||
:ctg_pred.
|
||||
|
||||
:- public(obj_local/0).
|
||||
% call a local object predicate directly; used for comparing performance with
|
||||
% calls to category predicates using the ::/1 and :/1 control constructs
|
||||
obj_local :-
|
||||
{generate_list(20, List)},
|
||||
length(List, _).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(descendant,
|
||||
extends(object)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/04/17,
|
||||
comment is 'Example object used for simulating a small hierarchy.']).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(leaf,
|
||||
extends(descendant)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/04/17,
|
||||
comment is 'Example object used for simulating a small hierarchy.']).
|
||||
|
||||
:- end_object.
|
@ -1,42 +0,0 @@
|
||||
|
||||
my_length(List, Length) :-
|
||||
my_length(List, 0, Length).
|
||||
|
||||
my_length([], Length, Length).
|
||||
my_length([_| Tail], Acc, Length) :-
|
||||
Acc2 is Acc + 1,
|
||||
my_length(Tail, Acc2, Length).
|
||||
|
||||
|
||||
:- dynamic(pred_plain/1).
|
||||
|
||||
plain_dyndb(N) :-
|
||||
assertz(pred_plain(N)),
|
||||
retract(pred_plain(N)).
|
||||
|
||||
|
||||
my_between(Lower, _, Lower).
|
||||
my_between(Lower, Upper, Integer) :-
|
||||
Lower < Upper,
|
||||
Next is Lower + 1,
|
||||
my_between(Next, Upper, Integer).
|
||||
|
||||
|
||||
my_repeat(_).
|
||||
my_repeat(N) :-
|
||||
N > 1,
|
||||
N2 is N - 1,
|
||||
my_repeat(N2).
|
||||
|
||||
|
||||
% generate a list containing the first N non-negative integers
|
||||
|
||||
generate_list(N, List) :-
|
||||
generate_list(0, N, List).
|
||||
|
||||
generate_list(N, N, []) :-
|
||||
!.
|
||||
generate_list(M, N, [M| Ms]) :-
|
||||
M < N,
|
||||
M2 is M + 1,
|
||||
generate_list(M2, N, Ms).
|
@ -1,58 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This folder contains an example of a bird identification expert system
|
||||
adopted with permission from the book "Adventure in Prolog" by Amzi! inc.
|
||||
The book is available on-line in HTML format at the URL:
|
||||
|
||||
http://www.amzi.com
|
||||
|
||||
Please refer to the book for more information on the original example.
|
||||
|
||||
|
||||
The bird identification hierarchy is organized as a prototype hierarchy
|
||||
as follows:
|
||||
|
||||
<order>
|
||||
<family>
|
||||
<bird>
|
||||
|
||||
order
|
||||
falconiforms
|
||||
falcon
|
||||
peregrine_falcon
|
||||
sparrow_hawk
|
||||
vulture
|
||||
california_condor
|
||||
turkey_vulture
|
||||
passerformes
|
||||
flycatcher
|
||||
ash_throated_flycatcher
|
||||
great_crested_flycatcher
|
||||
swallow
|
||||
barn_swallow
|
||||
cliff_swallow
|
||||
purple_martin
|
||||
tubenose
|
||||
fulmar
|
||||
albatross
|
||||
black_footed_albatross
|
||||
laysan_albatross
|
||||
waterfowl
|
||||
duck
|
||||
female_mallard
|
||||
male_mallard
|
||||
pintail
|
||||
goose
|
||||
canada_goose
|
||||
snow_goose
|
||||
swan
|
||||
trumpeter_swan
|
||||
whistling_swan
|
@ -1,78 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example and the required library files:
|
||||
|
||||
| ?- logtalk_load(birds(loader)).
|
||||
...
|
||||
|
||||
|
||||
% ask the expert system for help in identifying a bird:
|
||||
|
||||
| ?- expert::identify.
|
||||
Bird identification expert system
|
||||
|
||||
bill:sharp_hooked? (yes or no): yes.
|
||||
eats:birds? (yes or no): yes.
|
||||
feet:curved_talons? (yes or no): yes.
|
||||
head:large? (yes or no): yes.
|
||||
|
||||
What is the value for tail?
|
||||
1 : narrow_at_tip
|
||||
2 : forked
|
||||
3 : long_rusty
|
||||
4 : square
|
||||
5 : other
|
||||
Enter the number of choice> 1.
|
||||
|
||||
wings:long_pointed? (yes or no): yes.
|
||||
|
||||
Possible identification : peregrine_falcon
|
||||
|
||||
No (more) candidates found.
|
||||
|
||||
(16379 ms) yes
|
||||
|
||||
|
||||
% identify another bird:
|
||||
|
||||
| ?- expert::identify.
|
||||
Bird identification expert system
|
||||
|
||||
bill:sharp_hooked? (yes or no): no.
|
||||
bill:flat? (yes or no): no.
|
||||
bill:short? (yes or no): no.
|
||||
bill:hooked? (yes or no): yes.
|
||||
|
||||
What is the value for flight?
|
||||
1 : ponderous
|
||||
2 : powerful
|
||||
3 : agile
|
||||
4 : flap_glide
|
||||
5 : other
|
||||
Enter the number of choice> 2.
|
||||
|
||||
color:dark? (yes or no): yes.
|
||||
live:at_sea? (yes or no): yes.
|
||||
nostrils:external_tubular? (yes or no): yes.
|
||||
|
||||
What is the value for size?
|
||||
1 : large
|
||||
2 : plump
|
||||
3 : medium
|
||||
4 : small
|
||||
Enter the number of choice> 1.
|
||||
|
||||
wings:long_narrow? (yes or no): yes.
|
||||
|
||||
Possible identification : black_footed_albatross
|
||||
|
||||
No (more) candidates found.
|
||||
|
||||
(34624 ms) yes
|
||||
| ?-
|
@ -1,320 +0,0 @@
|
||||
|
||||
:- object(order,
|
||||
imports(descriptors, proto_hierarchy)).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
|
||||
:- object(falconiforms,
|
||||
imports(descriptors),
|
||||
extends(order)).
|
||||
|
||||
order(falconiforms).
|
||||
eats(meat).
|
||||
feet(curved_talons).
|
||||
bill(sharp_hooked).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(falcon,
|
||||
imports(descriptors),
|
||||
extends(falconiforms)).
|
||||
|
||||
family(falcon).
|
||||
wings(long_pointed).
|
||||
head(large).
|
||||
tail(narrow_at_tip).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(peregrine_falcon,
|
||||
imports(descriptors),
|
||||
extends(falcon)).
|
||||
|
||||
eats(birds).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(sparrow_hawk,
|
||||
imports(descriptors),
|
||||
extends(falcon)).
|
||||
|
||||
eats(insects).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(vulture,
|
||||
imports(descriptors),
|
||||
extends(falconiforms)).
|
||||
|
||||
family(vulture).
|
||||
feed(scavange).
|
||||
wings(broad).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(california_condor,
|
||||
imports(descriptors),
|
||||
extends(vulture)).
|
||||
|
||||
flight_profile(flat).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(turkey_vulture,
|
||||
imports(descriptors),
|
||||
extends(vulture)).
|
||||
|
||||
flight_profile(v_shaped).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
|
||||
:- object(passerformes,
|
||||
imports(descriptors),
|
||||
extends(order)).
|
||||
|
||||
order(passerformes).
|
||||
feet(one_long_backward_toe).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(flycatcher,
|
||||
imports(descriptors),
|
||||
extends(passerformes)).
|
||||
|
||||
family(flycatcher).
|
||||
bill(flat).
|
||||
eats(flying_insects).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(ash_throated_flycatcher,
|
||||
imports(descriptors),
|
||||
extends(flycatcher)).
|
||||
|
||||
throat(white).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(great_crested_flycatcher,
|
||||
imports(descriptors),
|
||||
extends(flycatcher)).
|
||||
|
||||
tail(long_rusty).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(swallow,
|
||||
imports(descriptors),
|
||||
extends(passerformes)).
|
||||
|
||||
family(swallow).
|
||||
wings(long_pointed).
|
||||
tail(forked).
|
||||
bill(short).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(barn_swallow,
|
||||
imports(descriptors),
|
||||
extends(swallow)).
|
||||
|
||||
tail(forked).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(cliff_swallow,
|
||||
imports(descriptors),
|
||||
extends(swallow)).
|
||||
|
||||
tail(square).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(purple_martin,
|
||||
imports(descriptors),
|
||||
extends(swallow)).
|
||||
|
||||
color(dark).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
|
||||
:- object(tubenose,
|
||||
imports(descriptors),
|
||||
extends(order)).
|
||||
|
||||
order(tubenose).
|
||||
nostrils(external_tubular).
|
||||
live(at_sea).
|
||||
bill(hooked).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(fulmar,
|
||||
imports(descriptors),
|
||||
extends(tubenose)).
|
||||
|
||||
size(medium).
|
||||
flight(flap_glide).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(albatross,
|
||||
imports(descriptors),
|
||||
extends(tubenose)).
|
||||
|
||||
family(albatross).
|
||||
size(large).
|
||||
wings(long_narrow).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(black_footed_albatross,
|
||||
imports(descriptors),
|
||||
extends(albatross)).
|
||||
|
||||
color(dark).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(laysan_albatross,
|
||||
imports(descriptors),
|
||||
extends(albatross)).
|
||||
|
||||
color(white).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
|
||||
:- object(waterfowl,
|
||||
imports(descriptors),
|
||||
extends(order)).
|
||||
|
||||
order(waterfowl).
|
||||
feet(webbed).
|
||||
bill(flat).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(duck,
|
||||
imports(descriptors),
|
||||
extends(waterfowl)).
|
||||
|
||||
family(duck).
|
||||
feed(on_water_surface).
|
||||
flight(agile).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(female_mallard,
|
||||
imports(descriptors),
|
||||
extends(duck)).
|
||||
|
||||
voice(quack).
|
||||
color(mottled_brown).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(male_mallard,
|
||||
imports(descriptors),
|
||||
extends(duck)).
|
||||
|
||||
voice(quack).
|
||||
head(green).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(pintail,
|
||||
imports(descriptors),
|
||||
extends(duck)).
|
||||
|
||||
voice(short_whistle).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(goose,
|
||||
imports(descriptors),
|
||||
extends(waterfowl)).
|
||||
|
||||
family(goose).
|
||||
size(plump).
|
||||
flight(powerful).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(canada_goose,
|
||||
imports(descriptors),
|
||||
extends(goose)).
|
||||
|
||||
head(black).
|
||||
cheek(white).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(snow_goose,
|
||||
imports(descriptors),
|
||||
extends(goose)).
|
||||
|
||||
color(white).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(swan,
|
||||
imports(descriptors),
|
||||
extends(waterfowl)).
|
||||
|
||||
family(swan).
|
||||
neck(long).
|
||||
color(white).
|
||||
flight(ponderous).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(trumpeter_swan,
|
||||
imports(descriptors),
|
||||
extends(swan)).
|
||||
|
||||
voice(loud_trumpeting).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(whistling_swan,
|
||||
imports(descriptors),
|
||||
extends(swan)).
|
||||
|
||||
voice(muffled_musical_whistle).
|
||||
|
||||
:- end_object.
|
@ -1,56 +0,0 @@
|
||||
|
||||
:- category(descriptors).
|
||||
|
||||
|
||||
:- info([
|
||||
author is 'Paulo Moura',
|
||||
version is 1.0,
|
||||
date is 2000/2/18,
|
||||
comment is 'Bird descriptors predicates.',
|
||||
source is 'Example adopted from an Amzi! Inc Prolog book.']).
|
||||
|
||||
|
||||
:- public([
|
||||
bill/1,
|
||||
cheek/1,
|
||||
color/1,
|
||||
eats/1,
|
||||
family/1,
|
||||
feed/1,
|
||||
feet/1,
|
||||
flight/1,
|
||||
flight_profile/1,
|
||||
head/1,
|
||||
live/1,
|
||||
neck/1,
|
||||
nostrils/1,
|
||||
order/1,
|
||||
size/1,
|
||||
tail/1,
|
||||
throat/1,
|
||||
voice/1,
|
||||
wings/1]).
|
||||
|
||||
:- public(descriptor/1).
|
||||
|
||||
|
||||
descriptor(bill/1).
|
||||
descriptor(cheek/1).
|
||||
descriptor(color/1).
|
||||
descriptor(eats/1).
|
||||
descriptor(feed/1).
|
||||
descriptor(feet/1).
|
||||
descriptor(flight/1).
|
||||
descriptor(flight_profile/1).
|
||||
descriptor(head/1).
|
||||
descriptor(live/1).
|
||||
descriptor(neck/1).
|
||||
descriptor(nostrils/1).
|
||||
descriptor(size/1).
|
||||
descriptor(tail/1).
|
||||
descriptor(throat/1).
|
||||
descriptor(voice/1).
|
||||
descriptor(wings/1).
|
||||
|
||||
|
||||
:- end_category.
|
@ -1,167 +0,0 @@
|
||||
|
||||
:- object(expert,
|
||||
imports(protected::descriptors)).
|
||||
|
||||
|
||||
:- info([
|
||||
author is 'Paulo Moura',
|
||||
version is 1.1,
|
||||
date is 2005/3/6,
|
||||
comment is 'Expert system for bird identification.',
|
||||
source is 'Example adopted from an Amzi! Inc Prolog book.']).
|
||||
|
||||
|
||||
:- public(identify/0).
|
||||
|
||||
:- mode(identify, one).
|
||||
|
||||
:- info(identify/0,
|
||||
[comment is 'Starts a bird identification session.']).
|
||||
|
||||
|
||||
:- private(known_/3).
|
||||
:- dynamic(known_/3).
|
||||
|
||||
:- mode(known_(?nonvar, ?nonvar, ?nonvar), zero_or_more).
|
||||
|
||||
:- info(known_/3, [
|
||||
comment is 'Table of already known facts.',
|
||||
argnames is ['Answer', 'Attribute', 'Value']]).
|
||||
|
||||
|
||||
identify :-
|
||||
::retractall(known_(_, _, _)),
|
||||
write('Bird identification expert system'), nl, nl,
|
||||
forall(
|
||||
(order::leaf(Bird), check(Bird)),
|
||||
(nl, write('Possible identification: '), write(Bird), nl)),
|
||||
nl, write('No (more) candidates found.').
|
||||
|
||||
|
||||
check(Bird) :-
|
||||
forall(
|
||||
(::descriptor(Functor/Arity),
|
||||
functor(Predicate, Functor, Arity),
|
||||
Bird::Predicate),
|
||||
call(Predicate)).
|
||||
|
||||
|
||||
bill(X):-
|
||||
ask(bill, X).
|
||||
|
||||
cheek(X):-
|
||||
ask(cheek, X).
|
||||
|
||||
color(X):-
|
||||
ask(color, X).
|
||||
|
||||
eats(X):-
|
||||
ask(eats, X).
|
||||
|
||||
feed(X):-
|
||||
ask(feed,X).
|
||||
|
||||
feet(X):-
|
||||
ask(feet, X).
|
||||
|
||||
flight(X):-
|
||||
menuask(flight, X, [ponderous, powerful, agile, flap_glide, other]).
|
||||
|
||||
flight_profile(X):-
|
||||
menuask(flight_profile, X, [flat, v_shaped, other]).
|
||||
|
||||
head(X):-
|
||||
ask(head,X).
|
||||
|
||||
live(X) :-
|
||||
ask(live, X).
|
||||
|
||||
neck(X):-
|
||||
ask(neck, X).
|
||||
|
||||
nostrils(X):-
|
||||
ask(nostrils, X).
|
||||
|
||||
size(X):-
|
||||
menuask(size, X, [large, plump, medium, small]).
|
||||
|
||||
tail(X):-
|
||||
menuask(tail, X, [narrow_at_tip, forked, long_rusty, square, other]).
|
||||
|
||||
throat(X):-
|
||||
ask(throat, X).
|
||||
|
||||
voice(X):-
|
||||
ask(voice,X).
|
||||
|
||||
wings(X):-
|
||||
ask(wings, X).
|
||||
|
||||
|
||||
ask(Attribute,Value):-
|
||||
::known_(yes, Attribute, Value),
|
||||
!.
|
||||
|
||||
ask(Attribute,Value):-
|
||||
::known_(_, Attribute, Value),
|
||||
!, fail.
|
||||
|
||||
ask(Attribute,_):-
|
||||
::known_(yes, Attribute, _),
|
||||
!, fail.
|
||||
|
||||
ask(Attribute, Value):-
|
||||
write(Attribute), write(': '), write(Value),
|
||||
write('? (yes or no): '),
|
||||
read(Answer),
|
||||
::asserta(known_(Answer, Attribute, Value)),
|
||||
Answer = yes.
|
||||
|
||||
|
||||
menuask(Attribute,Value, _):-
|
||||
::known_(yes, Attribute, Value),
|
||||
!.
|
||||
|
||||
menuask(Attribute, _, _):-
|
||||
::known_(yes, Attribute, _),
|
||||
!, fail.
|
||||
|
||||
menuask(Attribute, AskValue, Menu):-
|
||||
nl, write('What is the value for '), write(Attribute), write('?'), nl,
|
||||
display_menu(Menu),
|
||||
write('Enter the number of choice> '),
|
||||
read(Num),nl,
|
||||
pick_menu(Num, AnswerValue, Menu),
|
||||
::asserta(known_(yes,Attribute,AnswerValue)),
|
||||
AskValue = AnswerValue.
|
||||
|
||||
|
||||
display_menu(Menu):-
|
||||
display_menu(Menu, 1).
|
||||
|
||||
|
||||
display_menu([], _).
|
||||
|
||||
display_menu([Item| Rest], N):-
|
||||
write(N), write(' : '), write(Item), nl,
|
||||
NN is N + 1,
|
||||
display_menu(Rest, NN).
|
||||
|
||||
|
||||
pick_menu(N, Val, Menu):-
|
||||
integer(N),
|
||||
pic_menu(1, N, Val, Menu), !.
|
||||
|
||||
pick_menu(Val, Val, _).
|
||||
|
||||
|
||||
pic_menu(_, _, none_of_the_above, []).
|
||||
|
||||
pic_menu(N, N, Item, [Item| _]).
|
||||
|
||||
pic_menu(Ctr, N, Val, [_| Rest]):-
|
||||
NextCtr is Ctr + 1,
|
||||
pic_menu(NextCtr, N, Val, Rest).
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,4 +0,0 @@
|
||||
|
||||
:- initialization((
|
||||
logtalk_load(library(hierarchies_loader), [reload(skip)]), % allow for static binding
|
||||
logtalk_load([descriptors, birds, expert]))).
|
@ -1,15 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT
|
||||
file.
|
||||
|
||||
This folder contains a Logtalk version of the programming problem
|
||||
"99 bottles of beer on the wall" , contributed to the web site:
|
||||
|
||||
http://99-bottles-of-beer.net/
|
@ -1,13 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% just load the example, which contains an initialization/1 directive
|
||||
% that runs it:
|
||||
|
||||
| ?- logtalk_load(bottles(loader)).
|
||||
...
|
@ -1,31 +0,0 @@
|
||||
/*******************************************************
|
||||
* 99 Bottles of Beer
|
||||
* Paulo Moura - January 21, 2007
|
||||
* bottles.lgt
|
||||
* To execute start Logtalk and use the query
|
||||
* logtalk_load(bottles).
|
||||
*******************************************************/
|
||||
|
||||
:- object(bottles).
|
||||
|
||||
:- initialization(sing(99)).
|
||||
|
||||
sing(0) :-
|
||||
write('No more bottles of beer on the wall, no more bottles of beer.'), nl,
|
||||
write('Go to the store and buy some more, 99 bottles of beer on the wall.'), nl, nl.
|
||||
sing(N) :-
|
||||
N > 0,
|
||||
N2 is N -1,
|
||||
beers(N), write(' of beer on the wall, '), beers(N), write(' of beer.'), nl,
|
||||
write('Take one down and pass it around, '), beers(N2), write(' of beer on the wall.'), nl, nl,
|
||||
sing(N2).
|
||||
|
||||
beers(0) :-
|
||||
write('no more bottles').
|
||||
beers(1) :-
|
||||
write('1 bottle').
|
||||
beers(N) :-
|
||||
N > 1,
|
||||
write(N), write(' bottles').
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(bottles)).
|
@ -1,25 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
You will also need to load the following files in the library directory:
|
||||
events_loader, types_loader, metapredicates_loader, and hierarchies_loader.
|
||||
Alternatively, you may load the library all_loader file to load all library
|
||||
entities.
|
||||
|
||||
This folder contains an example of representation and handling of
|
||||
relations using events. We have instances of class brick and a binary
|
||||
brick_stack relation between the bricks. Every time we move a brick, we
|
||||
want the bricks on top of it to move along. If we break the stack by
|
||||
moving a middle brick, we want to automatically destroy the
|
||||
corresponding relation tuple.
|
||||
|
||||
It's instructive to use the event debugger in the Logtalk library (loader
|
||||
file debugging_loader.lgt) to better understand this example. Set spy points
|
||||
in all brick instances and then activate the debugger.
|
@ -1,215 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example and the required library files:
|
||||
|
||||
| ?- logtalk_load(bricks(loader)).
|
||||
...
|
||||
|
||||
|
||||
% create four bricks, all standing on the "ground" (use your imagination... ;-)
|
||||
|
||||
| ?- brick::(new(a, [position-(8, 1)]), new(b, [position-(6, 1)]), new(c, [position-(4, 1)]), new(d, [position-(2, 1)])).
|
||||
yes
|
||||
|
||||
% set up ascii stack monitor so we can watch the bricks moving
|
||||
|
||||
| ?- after_event_registry::set_monitor(_, move(_,_), _, stack_monitor).
|
||||
yes
|
||||
|
||||
|
||||
% make the stack
|
||||
|
||||
| ?- brick_stack::(add_tuple([c,d]), add_tuple([b,c]), add_tuple([a,b])).
|
||||
|.c......
|
||||
|.d...b.a
|
||||
---------
|
||||
|.b......
|
||||
|.c......
|
||||
|.d.....a
|
||||
---------
|
||||
|.a
|
||||
|.b
|
||||
|.c
|
||||
|.d
|
||||
---
|
||||
yes
|
||||
|
||||
|
||||
% check results
|
||||
|
||||
| ?- brick_stack::tuple(Tuple), write(Tuple), nl, fail.
|
||||
[c,d]
|
||||
[b,c]
|
||||
[a,b]
|
||||
no
|
||||
|
||||
| ?- before_event_registry::monitors(Mb), after_event_registry::monitors(Ma).
|
||||
Ma = [brick_stack, stack_monitor]
|
||||
Mb = [brick_stack]
|
||||
yes
|
||||
|
||||
|
||||
% move all stack to new position by moving bottom brick; check results
|
||||
|
||||
| ?- d::move(9, 1).
|
||||
|.a.......
|
||||
|.b.......
|
||||
|.c.......
|
||||
|........d
|
||||
----------
|
||||
|.a.......
|
||||
|.b.......
|
||||
|........c
|
||||
|........d
|
||||
----------
|
||||
|.a.......
|
||||
|........b
|
||||
|........c
|
||||
|........d
|
||||
----------
|
||||
|........a
|
||||
|........b
|
||||
|........c
|
||||
|........d
|
||||
----------
|
||||
yes
|
||||
|
||||
| ?- a::position(Xa, Ya), b::position(Xb, Yb), c::position(Xc, Yc), d::position(Xd, Yd).
|
||||
Xa = 9,
|
||||
Xb = 9,
|
||||
Xc = 9,
|
||||
Xd = 9,
|
||||
Ya = 4,
|
||||
Yb = 3,
|
||||
Yc = 2,
|
||||
Yd = 1
|
||||
yes
|
||||
|
||||
| ?- brick_stack::tuple(Tuple), write(Tuple), nl, fail.
|
||||
[c,d]
|
||||
[b,c]
|
||||
[a,b]
|
||||
no
|
||||
|
||||
|
||||
% break stack in half by moving b to the "ground"; check results
|
||||
|
||||
| ?- b::move(3, 1).
|
||||
|........a
|
||||
|.........
|
||||
|........c
|
||||
|..b.....d
|
||||
----------
|
||||
|..a.....c
|
||||
|..b.....d
|
||||
----------
|
||||
yes
|
||||
|
||||
| ?- a::position(Xa, Ya), b::position(Xb, Yb), c::position(Xc, Yc), d::position(Xd, Yd).
|
||||
Xa = 3,
|
||||
Xb = 3,
|
||||
Xc = 9,
|
||||
Xd = 9,
|
||||
Ya = 2,
|
||||
Yb = 1,
|
||||
Yc = 2,
|
||||
Yd = 1
|
||||
yes
|
||||
|
||||
| ?- brick_stack::tuple(Tuple), write(Tuple), nl, fail.
|
||||
[c,d]
|
||||
[a,b]
|
||||
no
|
||||
|
||||
|
||||
% create new brick_stack tuple ; check results
|
||||
|
||||
| ?- brick_stack::add_tuple([d, a]).
|
||||
|..d......
|
||||
|..a.....c
|
||||
|..b......
|
||||
----------
|
||||
|..c
|
||||
|..d
|
||||
|..a
|
||||
|..b
|
||||
----
|
||||
yes
|
||||
|
||||
| ?- a::position(Xa, Ya), b::position(Xb, Yb), c::position(Xc, Yc), d::position(Xd, Yd).
|
||||
Xa = 3,
|
||||
Xb = 3,
|
||||
Xc = 3,
|
||||
Xd = 3,
|
||||
Ya = 2,
|
||||
Yb = 1,
|
||||
Yc = 4,
|
||||
Yd = 3
|
||||
yes
|
||||
|
||||
| ?- brick_stack::tuple(Tuple), write(Tuple), nl, fail.
|
||||
[c,d]
|
||||
[a,b]
|
||||
[d,a]
|
||||
no
|
||||
|
||||
|
||||
% move all stack to new position by moving bottom brick; check results
|
||||
|
||||
| ?- b::move(5, 1).
|
||||
|..c..
|
||||
|..d..
|
||||
|..a..
|
||||
|....b
|
||||
------
|
||||
|..c..
|
||||
|..d..
|
||||
|....a
|
||||
|....b
|
||||
------
|
||||
|..c..
|
||||
|....d
|
||||
|....a
|
||||
|....b
|
||||
------
|
||||
|....c
|
||||
|....d
|
||||
|....a
|
||||
|....b
|
||||
------
|
||||
yes
|
||||
|
||||
| ?- a::position(Xa, Ya), b::position(Xb, Yb), c::position(Xc, Yc), d::position(Xd, Yd).
|
||||
Xa = 5,
|
||||
Xb = 5,
|
||||
Xc = 5,
|
||||
Xd = 5,
|
||||
Ya = 2,
|
||||
Yb = 1,
|
||||
Yc = 4,
|
||||
Yd = 3
|
||||
yes
|
||||
|
||||
| ?- brick_stack::tuple(Tuple), write(Tuple), nl, fail.
|
||||
[c,d]
|
||||
[a,b]
|
||||
[d,a]
|
||||
no
|
||||
|
||||
|
||||
% clean up instances, tuples and monitors
|
||||
|
||||
| ?- brick_stack::remove_all_tuples.
|
||||
yes
|
||||
|
||||
| ?- after_event_registry::del_monitors(_, _, _, stack_monitor).
|
||||
yes
|
||||
|
||||
| ?- brick::delete_all.
|
||||
yes
|
@ -1,141 +0,0 @@
|
||||
|
||||
:- object(brick,
|
||||
instantiates(class),
|
||||
specializes(object)).
|
||||
|
||||
:- info([
|
||||
version is 1.1,
|
||||
date is 2000/10/31,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Two-dimensional brick (or should I say square?) class.']).
|
||||
|
||||
:- public(position/2).
|
||||
:- mode(position(?integer, ?integer), zero_or_one).
|
||||
:- info(position/2, [
|
||||
comment is 'Brick current position.',
|
||||
argnames is ['X', 'Y']]).
|
||||
|
||||
:- private(position_/2).
|
||||
:- dynamic(position_/2).
|
||||
:- mode(position_(?integer, ?integer), zero_or_one).
|
||||
:- info(position_/2, [
|
||||
comment is 'Stores brick current position.',
|
||||
argnames is ['X', 'Y']]).
|
||||
|
||||
:- public(move/2).
|
||||
:- mode(move(+integer, +integer), one).
|
||||
:- info(move/2, [
|
||||
comment is 'Moves a brick to a new position.',
|
||||
argnames is ['X', 'Y']]).
|
||||
|
||||
position(X, Y) :-
|
||||
::position_(X, Y).
|
||||
|
||||
move(X, Y) :-
|
||||
::retractall(position_(_, _)),
|
||||
::assertz(position_(X, Y)).
|
||||
|
||||
default_init_option(position-(0, 0)).
|
||||
default_init_option(Default) :-
|
||||
^^default_init_option(Default).
|
||||
|
||||
process_init_option(position-(X, Y)) :-
|
||||
::assertz(position_(X, Y)).
|
||||
process_init_option(Option) :-
|
||||
^^process_init_option(Option).
|
||||
|
||||
valid_init_option(position-(X, Y)) :-
|
||||
!,
|
||||
integer(X),
|
||||
integer(Y).
|
||||
valid_init_option(Option) :-
|
||||
^^valid_init_option(Option).
|
||||
|
||||
instance_base_name(b).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(brick_stack,
|
||||
instantiates(constrained_relation)).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 1998/3/23,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Stack of bricks as a constrained binary relation.']).
|
||||
|
||||
descriptor_([top, bottom]).
|
||||
|
||||
domain_(top, brick).
|
||||
domain_(bottom, brick).
|
||||
|
||||
key_([top, bottom]).
|
||||
|
||||
cardinality_(top, 0, 1).
|
||||
cardinality_(bottom, 0, 1).
|
||||
|
||||
delete_option_(top, cascade).
|
||||
delete_option_(bottom, restrict).
|
||||
|
||||
add_tuple([A, B]) :-
|
||||
B::position(Xb, Yb),
|
||||
Ya2 is Yb + 1,
|
||||
{A::move(Xb, Ya2)},
|
||||
^^add_tuple([A, B]).
|
||||
|
||||
activ_points_(top, before, []).
|
||||
activ_points_(top, after, [move(_, _)]).
|
||||
|
||||
activ_points_(bottom, before, []).
|
||||
activ_points_(bottom, after, [move(_, _)]).
|
||||
|
||||
propagate(after, move(X, Y), Top, top, [Top, Bottom]) :-
|
||||
!,
|
||||
Y2 is Y - 1,
|
||||
(Bottom::position(X, Y2) ->
|
||||
true
|
||||
;
|
||||
::remove_tuple([Top, Bottom])).
|
||||
|
||||
propagate(after, move(X, Y), Bottom, bottom, [Top, Bottom]) :-
|
||||
!,
|
||||
Y2 is Y + 1,
|
||||
{Top::move(X, Y2)}.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(stack_monitor,
|
||||
implements(monitoring)).
|
||||
|
||||
:- info([
|
||||
version is 1.1,
|
||||
date is 2006/12/14,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Monitor for brick movements printing an ascii representation of each brick position.']).
|
||||
|
||||
:- uses(loop).
|
||||
:- uses(list).
|
||||
|
||||
after(_, move(_, _), _) :-
|
||||
findall(
|
||||
(Brick, X, Y),
|
||||
(instantiates_class(Brick, brick), Brick::position(X, Y)),
|
||||
Bricks),
|
||||
setof(X, Brick^Y^ (list::member((Brick,X,Y), Bricks)), Xs),
|
||||
list::last(Xs, Xmax),
|
||||
setof(Y, Brick^X^ (list::member((Brick,X,Y), Bricks)), Ys),
|
||||
list::last(Ys, Ymax),
|
||||
loop::fordownto(Y, Ymax, 1,
|
||||
(write('|'),
|
||||
loop::forto(X, 1, Xmax,
|
||||
(list::member((Brick, X, Y), Bricks) ->
|
||||
write(Brick)
|
||||
;
|
||||
write('.'))),
|
||||
nl)),
|
||||
write('-'),
|
||||
loop::forto(X, 1, Xmax, write('-')), nl.
|
||||
|
||||
:- end_object.
|
@ -1,6 +0,0 @@
|
||||
|
||||
:- initialization((
|
||||
logtalk_load(library(all_loader), [reload(skip)]), % allow for static binding
|
||||
logtalk_load(roots(loader), [reload(skip)]), % allow for static binding
|
||||
logtalk_load(relations(loader), [reload(skip)]), % allow for static binding
|
||||
logtalk_load(bricks, [events(on)]))).
|
@ -1,20 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This folder contains an example that shows how to implement class variables
|
||||
as defined in Smalltalk. The name shared instance variables is however much
|
||||
more accurate. In systems like Logtalk, which enables the use of explicit
|
||||
metaclasses, true class variables are just the class (as an object) own
|
||||
instance variables!
|
||||
|
||||
This example defines a root class (root) and three instances (instance1,
|
||||
instance2, and instance3). The root class defines a shared instance variable
|
||||
(using a dynamic predicate) and the setter and getter methods which implement
|
||||
the variable sharing behavior.
|
@ -1,38 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(classvars(loader)).
|
||||
...
|
||||
|
||||
|
||||
% get the value of the class variable for each instance:
|
||||
|
||||
| ?- instance1::cv(Value1), instance2::cv(Value2), instance3::cv(Value3).
|
||||
|
||||
Value1 = 0
|
||||
Value2 = 0
|
||||
Value3 = 0
|
||||
yes
|
||||
|
||||
|
||||
% change the value of the class variable via instance1:
|
||||
|
||||
| ?- instance1::set_cv(1).
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% get the value of the class variable for the other instances:
|
||||
|
||||
| ?- instance2::cv(Value2), instance3::cv(Value3).
|
||||
|
||||
Value2 = 1
|
||||
Value3 = 1
|
||||
yes
|
@ -1,42 +0,0 @@
|
||||
|
||||
:- object(root, % avoid infinite metaclass regression by
|
||||
instantiates(root)). % making the class its own metaclass
|
||||
|
||||
:- private(cv_/1).
|
||||
:- dynamic(cv_/1).
|
||||
:- mode(cv_(?integer), zero_or_one).
|
||||
|
||||
:- public(cv/1).
|
||||
:- mode(cv(?integer), zero_or_one).
|
||||
|
||||
:- public(set_cv/1).
|
||||
:- mode(set_cv(+integer), one).
|
||||
|
||||
cv_(0). % cv_/1 value is stored locally, in this class
|
||||
|
||||
cv(Value) :-
|
||||
cv_(Value). % retrive cv_/1 value, shared for all instances
|
||||
|
||||
set_cv(Value) :-
|
||||
retractall(cv_(_)), % retract old cv_/1 value from this class
|
||||
asserta(cv_(Value)). % assert the new value into this class
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(instance1,
|
||||
instantiates(root)).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(instance2,
|
||||
instantiates(root)).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(instance3,
|
||||
instantiates(root)).
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load(classvars)).
|
@ -1,57 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This folder contains the following examples of using DCGs inside
|
||||
objects and categories:
|
||||
|
||||
calculator
|
||||
canonical DCG example of parsing arithmetic expressions
|
||||
enigma
|
||||
solve a cellphone enigma against a dictionary of words
|
||||
bom
|
||||
bill of materials DCG example (see below for original source)
|
||||
sentences
|
||||
simple parsing of natural language sentences
|
||||
parsetree
|
||||
same as above but building and returning the parse tree
|
||||
xml
|
||||
conversion between XML and Prolog terms
|
||||
url
|
||||
parsing of URLs, decomposing them in components
|
||||
shell
|
||||
parsing of command-line shell commands
|
||||
faa
|
||||
command language DCG example (see below for original source)
|
||||
walker
|
||||
parsing of walker movements and calculation of distance
|
||||
travelled
|
||||
bypass
|
||||
using the {} DCG construct together with the {} Logtalk control
|
||||
construct
|
||||
tokenizer
|
||||
natural language tokenizer example
|
||||
macaddr
|
||||
validator for MAC addresses
|
||||
morse
|
||||
decoder for Morse code messages; illustrate how to use scope
|
||||
directives to declare grammar rule non-terminals
|
||||
|
||||
This folder contains an example ("tokenizer") adopted with permission from
|
||||
a Michael A. Covington example (http://www.ai.uga.edu/~mc/). See the file
|
||||
"tokenizer.lgt" for more details.
|
||||
|
||||
This folder contains two examples of DCGs ("bom" and "faa") adopted with
|
||||
permission from the Amzi! Prolog documentation. The documentation is
|
||||
available on-line in HTML format at the URL:
|
||||
|
||||
http://www.amzi.com/
|
||||
|
||||
Please refer to the Amzi! Prolog documentation for more information on the
|
||||
original examples.
|
@ -1,178 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(dcgs(loader)).
|
||||
...
|
||||
|
||||
|
||||
% DCG rules implementing a simple calculator:
|
||||
|
||||
| ?- calculator::parse("1+2-3*4", Result).
|
||||
|
||||
Result = -9
|
||||
yes
|
||||
|
||||
|
||||
% recognize MAC addresses:
|
||||
|
||||
| ?- macaddr::valid("00:1e:4a:ef:72:8b").
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% decode Morse code messages:
|
||||
|
||||
?- morse::phrase(morse(Message), "... --- ...").
|
||||
|
||||
Message = [sos]
|
||||
yes
|
||||
|
||||
|
||||
% solve a cellphone keypad encoded enigma:
|
||||
|
||||
| ?- enigma::solve("4 96853 5683 86 4283 346637 9484 968 8664448", Message).
|
||||
|
||||
Message = [i, would, love, to, have, dinner, with, you, tonight]
|
||||
yes
|
||||
|
||||
|
||||
% recognizing gramatically correct sentences:
|
||||
|
||||
| ?- sentence::parse([the, girl, likes, the, boy], Result).
|
||||
|
||||
Result = true
|
||||
yes
|
||||
|
||||
| ?- sentence::parse([the, girl, scares, the, boy], Result).
|
||||
|
||||
Result = false
|
||||
yes
|
||||
|
||||
|
||||
% generating parse trees for sentences:
|
||||
|
||||
| ?- parsetree::parse([the, girl, likes, the, boy], Tree).
|
||||
|
||||
Tree = s(np(d(the), n(girl)), vp(v(likes), np(d(the), n(boy))))
|
||||
yes
|
||||
|
||||
|
||||
% bill of materials example:
|
||||
|
||||
| ?- bom::parts(bike, L).
|
||||
|
||||
L = [frame, crank, pedal, pedal, chain, spokes, rim, hub, spokes, rim, hub]
|
||||
yes
|
||||
|
||||
| ?- bom::parts(wheel, L).
|
||||
|
||||
L = [spokes, rim, hub]
|
||||
yes
|
||||
|
||||
|
||||
% parsing command-line shell input:
|
||||
|
||||
| ?- shell::parse("pwd; cd ..; ls -a", L).
|
||||
|
||||
L = [pwd,'cd ..','ls -a'] ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% convert a string to a list of tokens (words, numbers, ponctuation):
|
||||
|
||||
| ?- tokenizer::tokens(" We owe $1,048,576.24 to Agent 007 for Version 3.14159! ", Tokens).
|
||||
|
||||
Tokens = [we,owe,$,1048576.24,to,agent,7,for,version,3.14159,!] ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% walker movements:
|
||||
|
||||
| ?- walker::walk([n(5), e(4), s(2), nw(8), s(5), se(1), n(4)], Ending).
|
||||
|
||||
Ending = -0.94974746830583223,6.9497474683058318 ?
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% conversion between compound terms and XML:
|
||||
|
||||
| ?- xml::convert(word(child, children), word(singular, plural), XML).
|
||||
|
||||
XML = '<word><singular>child</singular><plural>children</plural></word>'
|
||||
yes
|
||||
|
||||
| ?- xml::convert(Term, Interpretation, '<word><singular>child</singular><plural>children</plural></word>').
|
||||
|
||||
Term = word(child, children)
|
||||
Interpretation = word(singular, plural)
|
||||
yes
|
||||
|
||||
|
||||
% parsing URLs:
|
||||
|
||||
| ?- url::parse("http://logtalk.org", Components).
|
||||
|
||||
Components = [protocol(http), address([www, logtalk, org]), path([]), file('')]
|
||||
yes
|
||||
|
||||
| ?- url::parse("http://logtalk.org/", Components).
|
||||
|
||||
Components = [protocol(http), address([www, logtalk, org]), path(['']), file('')]
|
||||
yes
|
||||
|
||||
| ?- url::parse("http://logtalk.org/cvs", Components).
|
||||
|
||||
Components = [protocol(http), address([www, logtalk, org]), path([cvs]), file('')]
|
||||
yes
|
||||
|
||||
| ?- url::parse("http://logtalk.org/cvs.html", Components).
|
||||
|
||||
Components = [protocol(http), address([www, logtalk, org]), path([]), file('cvs.html')]
|
||||
yes
|
||||
|
||||
| ?- url::parse("http://193.136.64.5/files/update", Components).
|
||||
|
||||
Components = [protocol(http), address([193, 136, 64, 5]), path([files, update]), file('')]
|
||||
yes
|
||||
|
||||
|
||||
% command language example:
|
||||
|
||||
| ?- faa::main.
|
||||
Fly Amzi! Air
|
||||
enter command> list flights
|
||||
aa101
|
||||
aa102
|
||||
aa103
|
||||
enter command> book elana aa102
|
||||
enter command> book tom aa102
|
||||
enter command> list passengers aa102
|
||||
elana
|
||||
tom
|
||||
enter command> exit
|
||||
yes
|
||||
|
||||
|
||||
% double bypass using the {}/1 control constructs of grammar rules and Logtalk:
|
||||
|
||||
| ?- bypass::phrase(foo, _, _).
|
||||
|
||||
bar predicate called
|
||||
yes
|
||||
|
||||
|
||||
% run the Logtalk DCG translator on the test cases:
|
||||
|
||||
| ?- dcgtest::run.
|
||||
|
||||
...
|
@ -1,33 +0,0 @@
|
||||
|
||||
:- object(bom).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2004/5/11,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Adaptation of the bill of materials DCG example from the Amzi! Prolog manual.']).
|
||||
|
||||
:- public(parts/2).
|
||||
:- mode(parts(+atom, -list), one).
|
||||
:- info(parts/2, [
|
||||
comment is 'Returns the list of parts for building an object.',
|
||||
argnames is ['Object', 'Parts']]).
|
||||
|
||||
parts(Object, Parts) :-
|
||||
phrase(Object, Parts).
|
||||
|
||||
bike --> frame, drivechain, wheel, wheel.
|
||||
|
||||
wheel --> spokes, rim, hub.
|
||||
|
||||
drivechain --> crank, pedal, pedal, chain.
|
||||
|
||||
spokes --> [spokes].
|
||||
crank --> [crank].
|
||||
pedal --> [pedal].
|
||||
chain --> [chain].
|
||||
rim --> [rim].
|
||||
hub --> [hub].
|
||||
frame --> [frame].
|
||||
|
||||
:- end_object.
|
@ -1,15 +0,0 @@
|
||||
|
||||
bar :- % test predicate
|
||||
write('bar predicate called'), nl.
|
||||
|
||||
|
||||
:- object(bypass).
|
||||
|
||||
:- public(foo//0).
|
||||
:- mode(foo, one).
|
||||
:- info(foo//0, [
|
||||
comment is 'Just the almighty and famous old foo.']).
|
||||
|
||||
foo --> {{bar}}. % the external pair of {}'s have the usual DCG semantics;
|
||||
% the internal pair of {}'s is the Logtalk compiler bypass control construct
|
||||
:- end_object.
|
@ -1,23 +0,0 @@
|
||||
|
||||
:- object(calculator,
|
||||
implements(parsep)).
|
||||
|
||||
|
||||
parse(Expression, Value) :-
|
||||
phrase(expr(Value), Expression).
|
||||
|
||||
|
||||
expr(Z) --> term(X), "+", expr(Y), {Z is X + Y}.
|
||||
expr(Z) --> term(X), "-", expr(Y), {Z is X - Y}.
|
||||
expr(X) --> term(X).
|
||||
|
||||
term(Z) --> number(X), "*", term(Y), {Z is X * Y}.
|
||||
term(Z) --> number(X), "/", term(Y), {Z is X / Y}.
|
||||
term(Z) --> number(Z).
|
||||
|
||||
number(C) --> "+", number(C).
|
||||
number(C) --> "-", number(X), {C is -X}.
|
||||
number(X) --> [C], {0'0 =< C, C =< 0'9, X is C - 0'0}.
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,118 +0,0 @@
|
||||
|
||||
:- object(dcgtest).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2004/9/27,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Test cases for the Logtalk DCG translator.']).
|
||||
|
||||
:- public(run/0).
|
||||
:- mode(run, one).
|
||||
:- info(run/0, [
|
||||
comment is 'Runs the Logtalk DCG translator on the test cases.']).
|
||||
|
||||
run :-
|
||||
write('Testing expand_term/2 predicate ...'), nl, nl,
|
||||
gr_tr_test(N, GR, Result),
|
||||
write(N), write(': '), writeq(GR), write(' --- '),
|
||||
write(Result), write(' expected'), nl,
|
||||
( catch(
|
||||
expand_term(GR, Clause),
|
||||
Error,
|
||||
(write(' error: '), write(Error), nl, fail)) ->
|
||||
write(' '), writeq(Clause)
|
||||
; write(' expansion failed!')
|
||||
),
|
||||
nl, nl,
|
||||
fail.
|
||||
run.
|
||||
|
||||
write_error(Error) :-
|
||||
write(' ERROR: '), writeq(Error), nl, fail.
|
||||
|
||||
% terminal tests with list notation:
|
||||
gr_tr_test(101, (p --> []), success).
|
||||
gr_tr_test(102, (p --> [b]), success).
|
||||
gr_tr_test(103, (p --> [abc, xyz]), success).
|
||||
gr_tr_test(104, (p --> [abc | xyz]), error).
|
||||
gr_tr_test(105, (p --> [[], {}, 3, 3.2, a(b)]), success).
|
||||
gr_tr_test(106, (p --> [_]), success).
|
||||
|
||||
% terminal tests with string notation:
|
||||
gr_tr_test(151, (p --> "b"), success).
|
||||
gr_tr_test(152, (p --> "abc", "q"), success).
|
||||
gr_tr_test(153, (p --> "abc" ; "q"), success).
|
||||
|
||||
% simple non-terminal tests:
|
||||
gr_tr_test(201, (p --> b), success).
|
||||
gr_tr_test(202, (p --> 3), error).
|
||||
gr_tr_test(203, (p(X) --> b(X)), success).
|
||||
|
||||
% conjunction tests:
|
||||
gr_tr_test(301, (p --> b, c), success).
|
||||
gr_tr_test(311, (p --> true, c), success).
|
||||
gr_tr_test(312, (p --> fail, c), success).
|
||||
gr_tr_test(313, (p(X) --> call(X), c), success).
|
||||
|
||||
% disjunction tests:
|
||||
gr_tr_test(351, (p --> b ; c), success).
|
||||
gr_tr_test(352, (p --> q ; []), success).
|
||||
gr_tr_test(353, (p --> [a] ; [b]), success).
|
||||
|
||||
% if-then-else tests:
|
||||
gr_tr_test(401, (p --> b -> c), success).
|
||||
gr_tr_test(411, (p --> b -> c; d), success).
|
||||
gr_tr_test(421, (p --> b -> c1, c2 ; d), success).
|
||||
gr_tr_test(422, (p --> b -> c ; d1, d2), success).
|
||||
gr_tr_test(431, (p --> b1, b2 -> c ; d), success).
|
||||
gr_tr_test(441, (p --> [x] -> [] ; q), success).
|
||||
|
||||
% negation tests:
|
||||
gr_tr_test(451, (p --> \+ b, c), success).
|
||||
gr_tr_test(452, (p --> b, \+ c, d), success).
|
||||
|
||||
% cut tests:
|
||||
gr_tr_test(501, (p --> !, [a]), success).
|
||||
gr_tr_test(502, (p --> b, !, c, d), success).
|
||||
gr_tr_test(503, (p --> b, !, c ; d), success).
|
||||
gr_tr_test(504, (p --> [a], !, {fail}), success).
|
||||
gr_tr_test(505, (p(a), [X] --> !, [X, a], q), success).
|
||||
gr_tr_test(506, (p --> a, ! ; b), success).
|
||||
|
||||
% {}/1 tests:
|
||||
gr_tr_test(601, (p --> {b}), success).
|
||||
gr_tr_test(602, (p --> {3}), error).
|
||||
gr_tr_test(603, (p --> {c,d}), success).
|
||||
gr_tr_test(604, (p --> '{}'((c,d))), success).
|
||||
gr_tr_test(605, (p --> {a}, {b}, {c}), success).
|
||||
gr_tr_test(606, (p --> {q} -> [a] ; [b]), success).
|
||||
gr_tr_test(607, (p --> {q} -> [] ; b), success).
|
||||
gr_tr_test(608, (p --> [foo], {write(x)}, [bar]), success).
|
||||
gr_tr_test(609, (p --> [foo], {write(hello)},{nl}), success).
|
||||
gr_tr_test(610, (p --> [foo], {write(hello), nl}), success).
|
||||
|
||||
% "metacall" tests:
|
||||
gr_tr_test(701, (p --> X), success).
|
||||
gr_tr_test(702, (p --> _), success).
|
||||
|
||||
% non-terminals corresponding to "graphic" characters
|
||||
% or built-in operators/predicates:
|
||||
gr_tr_test(801, ('[' --> b, c), success).
|
||||
gr_tr_test(802, ((=) --> b, c), success).
|
||||
|
||||
% pushback tests:
|
||||
gr_tr_test(901, (p, [t] --> b, c), success).
|
||||
gr_tr_test(902, (p, [t] --> b, [t]), success).
|
||||
gr_tr_test(903, (p, [t] --> b, [s, t]), success).
|
||||
gr_tr_test(904, (p, [t] --> b, [s], [t]), success).
|
||||
gr_tr_test(905, (p(X), [X] --> [X]), success).
|
||||
gr_tr_test(906, (p(X, Y), [X, Y] --> [X, Y]), success).
|
||||
gr_tr_test(907, (p(a), [X] --> !, [X, a], q), success).
|
||||
gr_tr_test(908, (p, [a,b] --> [foo], {write(hello), nl}), success).
|
||||
gr_tr_test(909, (p, [t1], [t2] --> b, c), error).
|
||||
gr_tr_test(910, (p, b --> b), error).
|
||||
gr_tr_test(911, ([t], p --> b), error).
|
||||
gr_tr_test(911, ([t1], p, [t2] --> b), error).
|
||||
|
||||
:- end_object.
|
@ -1,76 +0,0 @@
|
||||
|
||||
:- object(enigma).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2006/01/22,
|
||||
comment is 'Example of using DCG rules to decrypt a enigma where words are made of numbers corresponding to the characters on a cellphone keypad.']).
|
||||
|
||||
:- public(solve/2).
|
||||
:- mode(solve(+string, -list(atom)), zero_or_one).
|
||||
:- info(solve/2, [
|
||||
comment is 'Solves a cellphone enigma against a dictionary of words.',
|
||||
argnames is ['Enigma', 'Message']]).
|
||||
|
||||
solve(Enigma, Message) :-
|
||||
phrase(message(Message), Enigma).
|
||||
|
||||
message([Word| Words]) --> separator, word(Chars), {atom_chars(Word, Chars), dictionary(Word)}, !, message(Words).
|
||||
message([]) --> separator.
|
||||
|
||||
word([Char| Chars]) --> character(Char), word(Chars).
|
||||
word([]) --> [].
|
||||
|
||||
separator --> " ", !, separator.
|
||||
separator --> [].
|
||||
|
||||
character(a) --> "2".
|
||||
character(b) --> "2".
|
||||
character(c) --> "2".
|
||||
|
||||
character(d) --> "3".
|
||||
character(e) --> "3".
|
||||
character(f) --> "3".
|
||||
|
||||
character(g) --> "4".
|
||||
character(h) --> "4".
|
||||
character(i) --> "4".
|
||||
|
||||
character(j) --> "5".
|
||||
character(k) --> "5".
|
||||
character(l) --> "5".
|
||||
|
||||
character(m) --> "6".
|
||||
character(n) --> "6".
|
||||
character(o) --> "6".
|
||||
|
||||
character(p) --> "7".
|
||||
character(q) --> "7".
|
||||
character(r) --> "7".
|
||||
character(s) --> "7".
|
||||
|
||||
character(t) --> "8".
|
||||
character(u) --> "8".
|
||||
character(v) --> "8".
|
||||
|
||||
character(w) --> "9".
|
||||
character(x) --> "9".
|
||||
character(y) --> "9".
|
||||
character(z) --> "9".
|
||||
|
||||
dictionary(dinner).
|
||||
dictionary(have).
|
||||
dictionary(i).
|
||||
dictionary(love).
|
||||
dictionary(miss).
|
||||
dictionary(much).
|
||||
dictionary(me).
|
||||
dictionary(you).
|
||||
dictionary(so).
|
||||
dictionary(to).
|
||||
dictionary(tonight).
|
||||
dictionary(with).
|
||||
dictionary(would).
|
||||
|
||||
:- end_object.
|
@ -1,94 +0,0 @@
|
||||
|
||||
:- object(faa).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2004/5/10,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Adaptation of the command language DCG example from the Amzi! Prolog manual.']).
|
||||
|
||||
:- public(main/0).
|
||||
:- mode(main, one).
|
||||
:- info(main/0, [
|
||||
comment is 'Starts iteractive command language interpreter.']).
|
||||
|
||||
:- private(booked/2).
|
||||
:- dynamic(booked/2).
|
||||
:- mode(booked(?atom, ?atom), zero_or_more).
|
||||
:- info(booked/2, [
|
||||
comment is 'Booked places in flight.',
|
||||
argnames is ['Passenger', 'Flight']]).
|
||||
|
||||
main :-
|
||||
write('Fly Amzi! Air'), nl,
|
||||
repeat,
|
||||
do_command(Command),
|
||||
Command == exit.
|
||||
|
||||
do_command(Command) :-
|
||||
write('enter command> '),
|
||||
read_tokens(Tokens),
|
||||
phrase(command(List), Tokens),
|
||||
Command =.. List,
|
||||
call(Command),
|
||||
!.
|
||||
|
||||
read_tokens(Tokens) :-
|
||||
read_codes(Codes),
|
||||
codes_to_tokens(Codes, Tokens).
|
||||
|
||||
read_codes(Codes) :-
|
||||
get_code(Code),
|
||||
read_codes(Code, Codes).
|
||||
|
||||
read_codes(10, [[]]) :-
|
||||
!.
|
||||
read_codes(13, [[]]) :-
|
||||
!.
|
||||
read_codes(32, [[]| Rest]) :-
|
||||
!, read_codes(Rest).
|
||||
read_codes(Code, [[Code| Codes]| Rest]) :-
|
||||
read_codes([Codes| Rest]).
|
||||
|
||||
codes_to_tokens([], []).
|
||||
codes_to_tokens([List| Lists], [Token| Tokens]) :-
|
||||
atom_codes(Token, List),
|
||||
codes_to_tokens(Lists, Tokens).
|
||||
|
||||
command([Op| Args]) --> operation(Op), arguments(Args).
|
||||
|
||||
arguments([Arg| Args]) --> argument(Arg), arguments(Args).
|
||||
arguments([]) --> [].
|
||||
|
||||
operation(report) --> [list].
|
||||
operation(book) --> [book].
|
||||
operation(exit) --> ([exit]; [quit]; [bye]).
|
||||
|
||||
argument(passengers) --> [passengers].
|
||||
argument(flights) --> [flights].
|
||||
|
||||
argument(Flight) --> [Flight], {flight(Flight)}.
|
||||
argument(Passenger) --> [Passenger].
|
||||
|
||||
flight(aa101).
|
||||
flight(aa102).
|
||||
flight(aa103).
|
||||
|
||||
report(flights) :-
|
||||
flight(Flight),
|
||||
write(Flight), nl,
|
||||
fail.
|
||||
report(_).
|
||||
|
||||
report(passengers, Flight) :-
|
||||
booked(Passenger, Flight),
|
||||
write(Passenger), nl,
|
||||
fail.
|
||||
report(_, _).
|
||||
|
||||
book(Passenger, Flight) :-
|
||||
assertz(booked(Passenger, Flight)).
|
||||
|
||||
exit.
|
||||
|
||||
:- end_object.
|
@ -1,19 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([
|
||||
parsep,
|
||||
calculator,
|
||||
enigma,
|
||||
parsetree,
|
||||
sentences,
|
||||
tokenizer,
|
||||
morse,
|
||||
macaddr,
|
||||
url,
|
||||
xml,
|
||||
shell,
|
||||
walker,
|
||||
bom,
|
||||
faa,
|
||||
bypass,
|
||||
dcgtest])).
|
@ -1,17 +0,0 @@
|
||||
|
||||
:- object(macaddr).
|
||||
|
||||
:- public(valid/1).
|
||||
|
||||
valid(Address) :-
|
||||
phrase(mac, Address).
|
||||
|
||||
mac --> digits, ":", digits, ":", digits, ":", digits, ":", digits, ":", digits.
|
||||
|
||||
digits --> digit, digit.
|
||||
|
||||
digit --> [C], {0'0 =< C, C =< 0'9}.
|
||||
digit --> [C], {0'a =< C, C =< 0'f}.
|
||||
digit --> [C], {0'A =< C, C =< 0'F}.
|
||||
|
||||
:- end_object.
|
@ -1,86 +0,0 @@
|
||||
|
||||
:- object(morse).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2007/06/14,
|
||||
comment is 'Morse code decoder.']).
|
||||
|
||||
:- public(morse//1).
|
||||
:- mode(morse(-list(atom)), zero_or_one).
|
||||
:- info(morse//1, [
|
||||
comment is 'Recognizes a message in Morse code, returning the corresponding list of words.',
|
||||
argnames is ['Words']]).
|
||||
|
||||
morse([Word| Words]) --> word(Characters), {atom_chars(Word, Characters)}, " ", morse(Words).
|
||||
morse([Word]) --> word(Characters), {atom_chars(Word, Characters)}.
|
||||
|
||||
word([Character| Characters]) --> character(LM), {code(Character, LM)}, " ", word(Characters).
|
||||
word([Character]) --> character(Symbols), {code(Character, Symbols)}.
|
||||
|
||||
character([Symbol| Symbols]) --> symbol([Symbol]), character(Symbols).
|
||||
character([Symbol]) --> symbol([Symbol]).
|
||||
|
||||
symbol(".") --> ".".
|
||||
symbol("-") --> "-".
|
||||
|
||||
code(a, ".-").
|
||||
code(b, "-...").
|
||||
code(c, "-.-.").
|
||||
code(d, "-..").
|
||||
code(e, ".").
|
||||
code(f, "..-.").
|
||||
code(g, "--.").
|
||||
code(h, "....").
|
||||
code(i, "..").
|
||||
code(j, ".---").
|
||||
code(k, "-.-").
|
||||
code(l, ".-..").
|
||||
code(m, "--").
|
||||
code(n, "-.").
|
||||
code(o, "---").
|
||||
code(p, ".--.").
|
||||
code(q, "--.-").
|
||||
code(r, ".-.").
|
||||
code(s, "...").
|
||||
code(t, "-").
|
||||
code(u, "..-").
|
||||
code(v, "...-").
|
||||
code(w, ".--").
|
||||
code(x, "-..-").
|
||||
code(y, "-.--").
|
||||
code(z, "--..").
|
||||
|
||||
code('1', ".----").
|
||||
code('2', "..---").
|
||||
code('3', "...--").
|
||||
code('4', "....-").
|
||||
code('5', ".....").
|
||||
code('6', "-....").
|
||||
code('7', "--...").
|
||||
code('8', "---..").
|
||||
code('9', "----.").
|
||||
code('0', "-----").
|
||||
|
||||
code('.', ".-.-.-").
|
||||
code(',', "--..--").
|
||||
code('?', "..--..").
|
||||
code('''', ".----.").
|
||||
code('!', "-.-.--").
|
||||
%code('!', "— — — ·").
|
||||
code('/', "-..-.").
|
||||
code('(', "-.--.").
|
||||
code(')', "-.--.-").
|
||||
code('&', ".-...").
|
||||
code(':', "---...").
|
||||
code(';', "-.-.-.").
|
||||
code('=', "-...-").
|
||||
code('+', ".-.-.").
|
||||
code('-', "-....-").
|
||||
code('_', "..--.-").
|
||||
code('"', ".-..-.").
|
||||
code('$', "...-..-").
|
||||
code('@', ".--.-").
|
||||
|
||||
:- end_object.
|
@ -1,20 +0,0 @@
|
||||
|
||||
:- protocol(parsep).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2003/3/17,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Parse protocol for using DCG rules.']).
|
||||
|
||||
|
||||
:- public(parse/2).
|
||||
:- mode(parse(?list, ?nonvar), zero_or_more).
|
||||
|
||||
:- info(parse/2, [
|
||||
comment is 'Parses a list using the defined set of DCG rules.',
|
||||
argnames is ['List', 'Result']]).
|
||||
|
||||
|
||||
:- end_protocol.
|
@ -1,29 +0,0 @@
|
||||
|
||||
:- object(parsetree,
|
||||
implements(parsep)).
|
||||
|
||||
|
||||
parse(List, Tree) :-
|
||||
phrase(sentence(Tree), List).
|
||||
|
||||
|
||||
sentence(s(NP,VP)) --> noun_phrase(NP), verb_phrase(VP).
|
||||
|
||||
noun_phrase(np(D,NP)) --> determiner(D), noun(NP).
|
||||
noun_phrase(NP) --> noun(NP).
|
||||
|
||||
verb_phrase(vp(V)) --> verb(V).
|
||||
verb_phrase(vp(V,NP)) --> verb(V), noun_phrase(NP).
|
||||
|
||||
|
||||
determiner(d(the)) --> [the].
|
||||
determiner(d(a)) --> [a].
|
||||
|
||||
noun(n(boy)) --> [boy].
|
||||
noun(n(girl)) --> [girl].
|
||||
|
||||
verb(v(likes)) --> [likes].
|
||||
verb(v(hates)) --> [hates].
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,53 +0,0 @@
|
||||
|
||||
|
||||
% Categories allows us to neatly organize the different "kinds"
|
||||
% of words on this example: determiners, nouns, and verbs
|
||||
|
||||
|
||||
:- category(determiners).
|
||||
|
||||
:- private(determiner//0). % private category non-terminals become private
|
||||
% non-terminals of the objects importing the category
|
||||
determiner --> [the].
|
||||
determiner --> [a].
|
||||
|
||||
:- end_category.
|
||||
|
||||
|
||||
:- category(nouns).
|
||||
|
||||
:- private(noun//0).
|
||||
|
||||
noun --> [boy].
|
||||
noun --> [girl].
|
||||
|
||||
:- end_category.
|
||||
|
||||
|
||||
:- category(verbs).
|
||||
|
||||
:- private(verb//0).
|
||||
|
||||
verb --> [likes].
|
||||
verb --> [hates].
|
||||
|
||||
:- end_category.
|
||||
|
||||
|
||||
:- object(sentence,
|
||||
implements(parsep),
|
||||
imports(determiners, nouns, verbs)).
|
||||
|
||||
parse(List, true) :-
|
||||
phrase(sentence, List).
|
||||
parse(_, false).
|
||||
|
||||
sentence --> noun_phrase, verb_phrase.
|
||||
|
||||
noun_phrase --> ::determiner, ::noun. % the ::/1 control construct is used to call grammar
|
||||
noun_phrase --> ::noun. % rules encapsulated on the imported categories
|
||||
|
||||
verb_phrase --> ::verb.
|
||||
verb_phrase --> ::verb, noun_phrase.
|
||||
|
||||
:- end_object.
|
@ -1,54 +0,0 @@
|
||||
|
||||
:- object(shell).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2004/4/29,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Simple example of command-line shell parsing.']).
|
||||
|
||||
|
||||
:- public(parse/2).
|
||||
|
||||
:- mode(parse(@list, -list), zero_or_one).
|
||||
|
||||
:- info(parse/2, [
|
||||
comment is 'Parses a sequence of commands.',
|
||||
argnames is ['Sequence', 'Commands']]).
|
||||
|
||||
|
||||
parse(Sequence, Commands) :-
|
||||
phrase(commands(Commands), Sequence).
|
||||
|
||||
|
||||
commands([C| Cs]) -->
|
||||
command(C), separator, commands(Cs).
|
||||
commands([C]) -->
|
||||
command(C).
|
||||
|
||||
separator --> ";".
|
||||
|
||||
whitespace --> " ", whitespace.
|
||||
whitespace --> [].
|
||||
|
||||
command(Cd) -->
|
||||
whitespace, "cd", whitespace, cdargs(Args), whitespace,
|
||||
{atom_concat(cd, Args, Cd)}.
|
||||
command(Ls) -->
|
||||
whitespace, "ls", whitespace, lsargs(Args), whitespace,
|
||||
{atom_concat(ls, Args, Ls)}.
|
||||
command(pwd) -->
|
||||
whitespace, "pwd", whitespace.
|
||||
|
||||
cdargs(' ~') --> "~".
|
||||
cdargs(' ..') --> "..".
|
||||
cdargs(' .') --> ".".
|
||||
cdargs('') --> [].
|
||||
|
||||
lsargs(' -l') --> "-l".
|
||||
lsargs(' -a') --> "-a".
|
||||
lsargs('') --> [].
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,114 +0,0 @@
|
||||
|
||||
% Natural Language Processing in Prolog using Definite Clause Grammar rules
|
||||
%
|
||||
% This example is a straightforward adaptation of the original plain Prolog
|
||||
% code described in the paper:
|
||||
%
|
||||
% Tokenization using DCG Rules
|
||||
% Michael A. Covington
|
||||
% Artificial Intelligence Center
|
||||
% The University of Georgia
|
||||
% Athens, Georgia 30602-7415 U.S.A.
|
||||
% 2000 April 21
|
||||
%
|
||||
% A copy of the paper is available at:
|
||||
%
|
||||
% http://www.ai.uga.edu/~mc/projpaper.ps
|
||||
%
|
||||
% Usage example:
|
||||
%
|
||||
% | ?- tokenizer::tokens(" We owe $1,048,576.24 to Agent 007 for Version 3.14159! ", Tokens).
|
||||
|
||||
:- object(tokenizer).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2006/2/11,
|
||||
author is 'Michael A. Covington',
|
||||
comment is 'Natural language tokenizer example using DCG rules.']).
|
||||
|
||||
:- public(tokens/2).
|
||||
:- mode(tokens(+string, -list), zero_or_more).
|
||||
:- info(tokens/2, [
|
||||
comment is 'Parses a string into a list of tokens.',
|
||||
argnames is ['String', 'Tokens']]).
|
||||
|
||||
tokens(String, Tokens) :-
|
||||
phrase(token_list(Tokens), String).
|
||||
|
||||
% A token list is a series of zero or more tokens.
|
||||
% Its argument consists of the list of tokens, as atoms and numbers.
|
||||
% The cut ensures that the maximum number of characters is gathered into each token.
|
||||
|
||||
token_list([T| Rest]) --> blank0, token(T), !, token_list(Rest).
|
||||
token_list([]) --> blank0.
|
||||
|
||||
% blank0 is a series of zero or more blanks.
|
||||
|
||||
blank0 --> [C], {char_type(C, blank)}, !, blank0.
|
||||
blank0 --> [].
|
||||
|
||||
% Several kinds of tokens.
|
||||
% This is where lists of characters get converted into atoms or numbers.
|
||||
|
||||
token(T) --> special(L), {atom_codes(T, L)}.
|
||||
token(T) --> word(W), {atom_codes(T, W)}.
|
||||
token(T) --> numeral(N), {number_codes(T, N)}.
|
||||
|
||||
% A word is a series of one or more letters.
|
||||
% The rules are ordered so that we first try to gather as many
|
||||
% characters into one digit_string as possible.
|
||||
|
||||
word([L| Rest]) --> letter(L), word(Rest).
|
||||
word([L]) --> letter(L).
|
||||
|
||||
% A numeral is a list of characters that constitute a number.
|
||||
% The argument of numeral(...) is the list of character codes.
|
||||
|
||||
numeral([C1, C2, C3| N]) --> ",", digit(C1), digit(C2), digit(C3), numeral(N).
|
||||
numeral([C1, C2, C3]) --> ",", digit(C1), digit(C2), digit(C3).
|
||||
numeral([C| N]) --> digit(C), numeral(N). % multiple digits
|
||||
numeral([C]) --> digit(C). % single digit
|
||||
numeral(N) --> decimal_part(N). % decimal point and more digits
|
||||
|
||||
decimal_part([46| Rest]) --> ".", digit_string(Rest).
|
||||
|
||||
digit_string([D| N]) --> digit(D), digit_string(N).
|
||||
digit_string([D]) --> digit(D).
|
||||
|
||||
% Various kinds of characters...
|
||||
|
||||
digit(C) --> [C], {char_type(C, numeric)}.
|
||||
|
||||
special([C]) --> [C], {char_type(C, special)}.
|
||||
|
||||
letter(C) --> [C], {char_type(C, lowercase)}.
|
||||
letter(C) --> [U], {char_type(U, uppercase), C is U + 32}. % Conversion to lowercase
|
||||
|
||||
% char_type(+Code, ?Type)
|
||||
% Classifies a character (ASCII code) as blank, numeric, uppercase, lowercase, or special.
|
||||
% Adapted from Covington 1994.
|
||||
|
||||
char_type(Code, Type) :- % blanks, other ctrl codes
|
||||
Code =< 32,
|
||||
!,
|
||||
Type = blank.
|
||||
|
||||
char_type(Code, Type) :- % digits
|
||||
48 =< Code, Code =< 57,
|
||||
!,
|
||||
Type = numeric.
|
||||
|
||||
char_type(Code, Type) :- % lowercase letters
|
||||
97 =< Code, Code =< 122,
|
||||
!,
|
||||
Type = lowercase.
|
||||
|
||||
char_type(Code, Type) :- % uppercase letters
|
||||
65 =< Code, Code =< 90,
|
||||
!,
|
||||
Type = uppercase.
|
||||
|
||||
char_type(_, special). % all others
|
||||
|
||||
:- end_object.
|
@ -1,67 +0,0 @@
|
||||
:- object(url).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2003/7/7,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Simple example of URL parsing.']).
|
||||
|
||||
|
||||
:- public(parse/2).
|
||||
|
||||
:- mode(parse(@list, -list), zero_or_one).
|
||||
|
||||
:- info(parse/2, [
|
||||
comment is 'Parses a URL into its components.',
|
||||
argnames is ['URL', 'Components']]).
|
||||
|
||||
|
||||
parse(URL, [protocol(Protocol), address(Address), path(Path), file(File)]) :-
|
||||
phrase(url(Protocol, Address, Path, File), URL).
|
||||
|
||||
|
||||
url(Protocol, Address, Path, File) --> protocol(Protocol), "://", address(Address), path(Path), file(File).
|
||||
|
||||
|
||||
protocol(ftp) --> "ftp".
|
||||
protocol(http) --> "http".
|
||||
protocol(https) --> "https".
|
||||
protocol(rtsp) --> "rtsp".
|
||||
|
||||
|
||||
address(Address) --> ip_number(Address).
|
||||
address([Identifier| Identifiers]) --> identifier(Identifier), dot_identifiers(Identifiers).
|
||||
|
||||
|
||||
ip_number([N1, N2, N3, N4]) --> ip_subnumber(N1), ".", ip_subnumber(N2), ".", ip_subnumber(N3), ".", ip_subnumber(N4).
|
||||
|
||||
ip_subnumber(N) --> [N1, N2, N3], {N is N3 - 0'0 + 10*(N2 - 0'0) + 100*(N1 - 0'0), N >= 0, N =< 255}.
|
||||
ip_subnumber(N) --> [N1, N2], {N is N2 - 0'0 + 10*(N1 - 0'0), N >= 0, N =< 255}.
|
||||
ip_subnumber(N) --> [N1], {N is N1 - 0'0, N >= 0, N =< 255}.
|
||||
|
||||
|
||||
identifier(Identifier) --> characters(Codes), {atom_codes(Identifier, Codes)}.
|
||||
|
||||
|
||||
characters([]) --> [].
|
||||
characters([Code| Codes]) --> [Code], {character(Code)}, characters(Codes).
|
||||
|
||||
|
||||
character(Code) :- Code @>= 0'a, Code @=< 0'z, !.
|
||||
character(Code) :- Code @>= 0'A, Code @=< 0'Z.
|
||||
|
||||
|
||||
dot_identifiers([]) --> [].
|
||||
dot_identifiers([Identifier| Identifiers]) --> ".", identifier(Identifier), dot_identifiers(Identifiers).
|
||||
|
||||
|
||||
path([]) --> [].
|
||||
path([Identifier| Path]) --> "/", identifier(Identifier), path(Path).
|
||||
|
||||
|
||||
file('') --> [].
|
||||
file(File) --> "/", identifier(Name), ".", identifier(Extension), {atom_concat(Name, '.', Aux), atom_concat(Aux, Extension, File)}.
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,43 +0,0 @@
|
||||
|
||||
:- object(walker).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2004/4/29,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Walker movements.']).
|
||||
|
||||
|
||||
:- public(walk/2).
|
||||
|
||||
:- mode(walk(@list, -position), one).
|
||||
|
||||
:- info(walk/2, [
|
||||
comment is 'Parses a sequence of walker moves, returning ending position.',
|
||||
argnames is ['Moves', 'Ending']]).
|
||||
|
||||
|
||||
walk(Moves, Ending) :-
|
||||
phrase(walk(Ending), Moves).
|
||||
|
||||
|
||||
walk(Ending) -->
|
||||
moves((0, 0), Ending).
|
||||
|
||||
moves(Start, Ending) -->
|
||||
move(Start, Temp), moves(Temp, Ending).
|
||||
moves(Ending, Ending) -->
|
||||
[].
|
||||
|
||||
move((X0, Y0), (X, Y)) --> [ n(S)], {X is X0, Y is Y0 + S}.
|
||||
move((X0, Y0), (X, Y)) --> [ne(S)], {X is X0 + S / sqrt(2), Y is Y0 + S / sqrt(2)}.
|
||||
move((X0, Y0), (X, Y)) --> [ e(S)], {X is X0 + S, Y = Y0}.
|
||||
move((X0, Y0), (X, Y)) --> [se(S)], {X is X0 + S / sqrt(2), Y is Y0 - S / sqrt(2)}.
|
||||
move((X0, Y0), (X, Y)) --> [ s(S)], {X is X0, Y is Y0 - S}.
|
||||
move((X0, Y0), (X, Y)) --> [sw(S)], {X is X0 - S / sqrt(2), Y is Y0 - S / sqrt(2)}.
|
||||
move((X0, Y0), (X, Y)) --> [ w(S)], {X is X0 - S, Y = Y0}.
|
||||
move((X0, Y0), (X, Y)) --> [nw(S)], {X is X0 - S / sqrt(2), Y is Y0 + S / sqrt(2)}.
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,78 +0,0 @@
|
||||
|
||||
:- object(xml).
|
||||
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
date is 2003/7/7,
|
||||
author is 'Paulo Moura',
|
||||
comment is 'Conversion between compound terms and XML.']).
|
||||
|
||||
|
||||
:- public(convert/3).
|
||||
|
||||
:- mode(convert(@compound, @compound, -atom), zero_or_one).
|
||||
:- mode(convert(-compound, -compound, +atom), zero_or_one).
|
||||
|
||||
:- info(convert/3, [
|
||||
comment is 'Converts between a compound term and an interpretation and XML.',
|
||||
argnames is ['Term', 'Interpretation', 'XML']]).
|
||||
|
||||
|
||||
convert(Term, Interpretation, XML) :-
|
||||
var(XML) ->
|
||||
phrase(term(Term, Interpretation), List),
|
||||
atom_codes(XML, List)
|
||||
;
|
||||
atom_codes(XML, List),
|
||||
phrase(term(Term, Interpretation), List).
|
||||
|
||||
|
||||
term(Term, Interpretation) -->
|
||||
{nonvar(Term), nonvar(Interpretation),
|
||||
Interpretation =.. [Functor| Tags], Term =.. [Functor| Args]},
|
||||
open_tag(Functor),
|
||||
arguments(Tags, Args),
|
||||
close_tag(Functor).
|
||||
|
||||
term(Term, Interpretation) -->
|
||||
{var(Term), var(Interpretation)},
|
||||
open_tag(Functor),
|
||||
arguments(Tags, Args),
|
||||
close_tag(Functor),
|
||||
{Interpretation =.. [Functor| Tags], Term =.. [Functor| Args]}.
|
||||
|
||||
|
||||
arguments([], []) -->
|
||||
[].
|
||||
|
||||
arguments([Tag| Tags], [Arg| Args]) -->
|
||||
open_tag(Tag),
|
||||
value(Arg),
|
||||
close_tag(Tag),
|
||||
arguments(Tags, Args).
|
||||
|
||||
|
||||
open_tag(Tag) -->
|
||||
"<", value(Tag), ">".
|
||||
|
||||
close_tag(Tag) -->
|
||||
"</", value(Tag), ">".
|
||||
|
||||
|
||||
value(Value) -->
|
||||
{nonvar(Value), atom_codes(Value, Codes)}, characters(Codes).
|
||||
|
||||
value(Value) -->
|
||||
{var(Value)}, characters(Codes), {atom_codes(Value, Codes)}.
|
||||
|
||||
|
||||
characters([]) --> [].
|
||||
characters([Code| Codes]) --> [Code], {character(Code)}, characters(Codes).
|
||||
|
||||
|
||||
character(Code) :- Code @>= 0'a, Code @=< 0'z, !.
|
||||
character(Code) :- Code @>= 0'A, Code @=< 0'Z.
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,50 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT
|
||||
file.
|
||||
|
||||
This example illustrates some variants of the "diamond problem"
|
||||
(multi-inheritance conflicts and ambiguities) and its respective
|
||||
solutions on Logtalk.
|
||||
|
||||
This classical problem can be simply described by constructing a
|
||||
"diamond" of objects and inheritance links as follows:
|
||||
|
||||
A -- contains default definition for a predicate m/0
|
||||
/ \
|
||||
B C -- contains redefinitions of the predicate m/0
|
||||
\ /
|
||||
D -- inherits both redefinitions of the predicate m/0
|
||||
|
||||
As such, the object D inherits two conflicting definitions for the
|
||||
predicate m/0, one from object B and one from object C. If we send
|
||||
the message m/0 to object D, is ambiguous which inherited definition
|
||||
should be used to answer it. Depending on the nature of the objects
|
||||
A, B, C, and D, the correct answer can be the redefinition of m/0 in
|
||||
object B, the redefinition m/0 in object C, or both redefinitions.
|
||||
A programming language supporting multi-inheritance should provide
|
||||
programming mechanisms allowing easy implementation of each possible
|
||||
solution.
|
||||
|
||||
Note that, in the context of Logtalk, the diamond problem may occur with
|
||||
prototype hierarchies, class hierarchies, protocol hierarchies, or when
|
||||
using category composition.
|
||||
|
||||
This example deals with three variants of the diamond problem, illustrated
|
||||
using prototype hierarchies:
|
||||
|
||||
diamond1
|
||||
illustrates the inherited definition which is visible due to the
|
||||
Logtalk predicate lookup algorithm
|
||||
diamond2
|
||||
presents a solution for making the overridden inherited definition
|
||||
the visible one
|
||||
diamond3
|
||||
presents a solution which allows both inherited definitions to be
|
||||
used in D
|
@ -1,46 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(diamonds(loader)).
|
||||
...
|
||||
|
||||
|
||||
% first variant of the "diamond problem", defined in the "diamond1" source file:
|
||||
|
||||
| ?- d1::m.
|
||||
|
||||
Redefinition of method m/0 in object b1
|
||||
yes
|
||||
|
||||
|
||||
% second variant of the "diamond problem", defined in the "diamond2" source file:
|
||||
|
||||
| ?- d2::m.
|
||||
|
||||
Redefinition of method m/0 in object c2
|
||||
yes
|
||||
|
||||
|
||||
% third variant of the "diamond problem", defined in the "diamond3" source file:
|
||||
|
||||
| ?- d3::b3_m.
|
||||
|
||||
Redefinition of method m/0 in object b3
|
||||
yes
|
||||
|
||||
| ?- d3::c3_m.
|
||||
|
||||
Redefinition of method m/0 in object c3
|
||||
yes
|
||||
|
||||
| ?- d3::m.
|
||||
|
||||
Redefinition of method m/0 in object b3
|
||||
yes
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
These objects illustrate a variant of the "diamond problem" using
|
||||
a prototype hierarchy.
|
||||
|
||||
In this simple case, the inherited definition which will be used in the
|
||||
bottom object is determined by the Logtalk predicate lookup algorithm.
|
||||
*/
|
||||
|
||||
|
||||
% root object, declaring and defining a predicate m/0:
|
||||
|
||||
:- object(a1).
|
||||
|
||||
:- public(m/0).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Default definition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% an object descending from the root object, which redefines predicate m/0:
|
||||
|
||||
:- object(b1,
|
||||
extends(a1)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% another object descending from the root object, which also redefines predicate m/0:
|
||||
|
||||
:- object(c1,
|
||||
extends(a1)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% bottom object, descending from the two previous objects and, as such, inheriting
|
||||
% two definitions for the predicate m/0:
|
||||
|
||||
:- object(d1,
|
||||
extends(b1, c1)).
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
These objects illustrate a variant of the "diamond problem" using
|
||||
a prototype hierarchy.
|
||||
|
||||
In this simple case, a solution for making the overridden definition inherited
|
||||
by the bottom object the visible one is implemented using the alias/3 predicate
|
||||
directive.
|
||||
*/
|
||||
|
||||
|
||||
% root object, declaring and defining a predicate m/0:
|
||||
|
||||
:- object(a2).
|
||||
|
||||
:- public(m/0).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Default definition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% an object descending from the root object, which redefines predicate m/0:
|
||||
|
||||
:- object(b2,
|
||||
extends(a2)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% another object descending from the root object, which also redefines predicate m/0:
|
||||
|
||||
:- object(c2,
|
||||
extends(a2)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% bottom object, descending from the two previous objects and, as such, inheriting
|
||||
% two definitions for the predicate m/0; the overridden definition inherited from
|
||||
% object "c2" is renamed using the alias/3 directive and then we redefine the
|
||||
% predicate m/0 to call the renamed definition:
|
||||
|
||||
:- object(d2,
|
||||
extends(b2, c2)).
|
||||
|
||||
:- alias(c2, m/0, c2_m/0).
|
||||
|
||||
m :-
|
||||
::c2_m.
|
||||
|
||||
:- end_object.
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
These objects illustrate a variant of the "diamond problem" using
|
||||
a prototype hierarchy.
|
||||
|
||||
In this simple case, a solution is presented for making two conflicting
|
||||
definitions inherited by the bottom object visible through the use of the
|
||||
alias/3 predicate directive.
|
||||
*/
|
||||
|
||||
|
||||
% root object, declaring and defining a predicate m/0:
|
||||
|
||||
:- object(a3).
|
||||
|
||||
:- public(m/0).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Default definition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% an object descending from the root object, which redefines predicate m/0:
|
||||
|
||||
:- object(b3,
|
||||
extends(a3)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% another object descending from the root object, which also redefines predicate m/0:
|
||||
|
||||
:- object(c3,
|
||||
extends(a3)).
|
||||
|
||||
m :-
|
||||
this(This),
|
||||
write('Redefinition of method m/0 in object '),
|
||||
write(This), nl.
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
% bottom object, descending from the two previous objects and, as such, inheriting
|
||||
% two definitions for the predicate m/0; both inherited definitions are renamed
|
||||
% using the alias/3 directive:
|
||||
|
||||
:- object(d3,
|
||||
extends(b3, c3)).
|
||||
|
||||
:- alias(b3, m/0, b3_m/0).
|
||||
:- alias(c3, m/0, c3_m/0).
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([diamond1, diamond2, diamond3])).
|
@ -1,34 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This folder contains examples of using some of the built-in database
|
||||
handling methods. Two hierarchies are provided, one prototype-based,
|
||||
and the other class-based, in order to illustrate the differences
|
||||
between asserting predicates in a class and in a prototype.
|
||||
|
||||
The following objects are defined:
|
||||
|
||||
root
|
||||
root of the prototype hierarchy; declares and defines a public,
|
||||
dynamic predicate
|
||||
descendant
|
||||
simple prototype extending the root prototype
|
||||
|
||||
class
|
||||
root of the class hierarchy; declares and defines a public predicate
|
||||
metaclass
|
||||
class metaclass
|
||||
instance
|
||||
simple instance of class class
|
||||
|
||||
prototype
|
||||
simple prototype used to illustrate how the scope of asserted
|
||||
predicates depends on the target object (this, self, or a explicit
|
||||
object)
|
@ -1,97 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(dynpred(loader)).
|
||||
...
|
||||
|
||||
|
||||
% sending to descendant the message p/1, returns the definition in root:
|
||||
|
||||
| ?- descendant::p(Value).
|
||||
|
||||
Value = root
|
||||
yes
|
||||
|
||||
|
||||
% asserting a local definition for p/1 in descendant overrides the inherited
|
||||
% definition:
|
||||
|
||||
| ?- descendant::(assertz(p(descendant)), p(Value)).
|
||||
|
||||
Value = descendant
|
||||
yes
|
||||
|
||||
|
||||
% if we retract the local definition, again the definition inherited from root
|
||||
% will be used:
|
||||
|
||||
| ?- descendant::(retractall(p(_)), p(Value)).
|
||||
|
||||
Value = root
|
||||
yes
|
||||
|
||||
|
||||
% class does not understand the message p1/1 (the predicate is declared only
|
||||
% for the class descendant instances):
|
||||
|
||||
| ?- class::p1(X).
|
||||
|
||||
error(existence_error(predicate_declaration, p1(_)), class::p1(_), user)
|
||||
|
||||
|
||||
% the same message is valid for the class instances:
|
||||
|
||||
| ?- instance::p1(X).
|
||||
|
||||
X = class
|
||||
yes
|
||||
|
||||
|
||||
% if we assert a clause for a new predicate, p2/1, in the class
|
||||
% (a side-effect being a dynamic declaration of the predicate):
|
||||
|
||||
| ?- class::assertz(p2(class)).
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% the new predicate, like p1/1, is not available for the class:
|
||||
|
||||
| ?- class::p2(Value).
|
||||
|
||||
error(existence_error(predicate_declaration, p2(_)), class::p2(_), user)
|
||||
|
||||
|
||||
% but is available for the class instances, the same way as p1/1:
|
||||
|
||||
| ?- instance::p2(X).
|
||||
|
||||
X = class
|
||||
yes
|
||||
|
||||
|
||||
% using a prototype, assert three new predicates (the method object_assert/0
|
||||
% asserts the predicate public_predicate/0 from outside the prototype; the
|
||||
% method self_assert/0 asserts the predicate protected_predicate/0 in self;
|
||||
% the method this_assert/0 asserts the predicate private_predicate/0 in this):
|
||||
|
||||
| ?- prototype::(object_assert, self_assert, this_assert).
|
||||
|
||||
yes
|
||||
|
||||
|
||||
% and check the resulting scope of each predicate:
|
||||
|
||||
| ?- prototype::dynamic_predicates.
|
||||
|
||||
public_predicate/0 - public
|
||||
protected_predicate/0 - protected
|
||||
private_predicate/0 - private
|
||||
yes
|
@ -1,21 +0,0 @@
|
||||
|
||||
:- object(metaclass, % avoid infinite metaclass regression by
|
||||
instantiates(metaclass)). % making the class its own metaclass
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(class,
|
||||
instantiates(metaclass)).
|
||||
|
||||
:- public(p1/1).
|
||||
|
||||
p1(class).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(instance,
|
||||
instantiates(class)).
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([protos, classes, prototype])).
|
@ -1,15 +0,0 @@
|
||||
|
||||
:- object(root).
|
||||
|
||||
:- public(p/1).
|
||||
:- dynamic(p/1).
|
||||
|
||||
p(root).
|
||||
|
||||
:- end_object.
|
||||
|
||||
|
||||
:- object(descendant,
|
||||
extends(root)).
|
||||
|
||||
:- end_object.
|
@ -1,42 +0,0 @@
|
||||
|
||||
:- object(prototype).
|
||||
|
||||
|
||||
:- public(object_assert/0).
|
||||
:- public(self_assert/0).
|
||||
:- public(this_assert/0).
|
||||
|
||||
:- public(dynamic_predicates/0).
|
||||
|
||||
|
||||
object_assert :-
|
||||
self(Self),
|
||||
Self::assertz(public_predicate).
|
||||
|
||||
|
||||
self_assert :-
|
||||
::assertz(protected_predicate).
|
||||
|
||||
|
||||
this_assert :-
|
||||
assertz(private_predicate).
|
||||
|
||||
|
||||
dynamic_predicates :-
|
||||
current_predicate(Functor/Arity),
|
||||
functor(Predicate, Functor, Arity),
|
||||
predicate_property(Predicate, (dynamic)),
|
||||
predicate_property(Predicate, Scope),
|
||||
scope(Scope),
|
||||
writeq(Functor/Arity), write(' - '), writeq(Scope), nl,
|
||||
fail.
|
||||
|
||||
dynamic_predicates.
|
||||
|
||||
|
||||
scope(private).
|
||||
scope(protected).
|
||||
scope((public)).
|
||||
|
||||
|
||||
:- end_object.
|
@ -1,35 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT file.
|
||||
|
||||
This is a very simple example of using the new, experimental encoding/1
|
||||
directive, which is fully based on the directive with the same name found
|
||||
on recent development releases of SWI-Prolog. Currently, this example
|
||||
requires Logtalk to be run with the SWI-Prolog compiler.
|
||||
|
||||
The "babel.lgt" source file uses UTF-8 encoding. The "latin.lgt" source
|
||||
file uses ISO-8859-1 (Latin 1) encoding. Be sure to use a text editor that
|
||||
supports these encodings when opening these files. In addition, you may
|
||||
need to configure your text editor to open the source file using the
|
||||
declared encoding. If you are using the SWI-Prolog GUI application on
|
||||
Windows, be sure to select a font which supports Unicode characters.
|
||||
|
||||
The current Logtalk version accepts any atom as an argument for the encoding/1
|
||||
directive. As, by default, Logtalk automatically generates a XML documenting
|
||||
file for each compiled entity, the following table is used to set the encoding
|
||||
of the XML file:
|
||||
|
||||
Logtalk source file XML file
|
||||
ascii us-ascii
|
||||
iso_latin_1 iso-8859-1
|
||||
unicode_be utf-16
|
||||
unicode_le utf-16
|
||||
utf8 utf-8
|
||||
|
||||
Note that the values on the left column are the ones recognized by SWI-Prolog.
|
@ -1,61 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(encodings(loader)).
|
||||
...
|
||||
|
||||
|
||||
% query the table of "Hello world!" messages:
|
||||
|
||||
| ?- babel::hello_world(Code, Text).
|
||||
|
||||
Code = el
|
||||
Text = 'Γειάσου κόσμος!' ;
|
||||
|
||||
Code = en
|
||||
Text = 'Hello world!' ;
|
||||
|
||||
Code = es
|
||||
Text = '¡Hola mundo!' ;
|
||||
|
||||
Code = ja
|
||||
Text = 'こんにちは世界!' ;
|
||||
|
||||
Code = ko
|
||||
Text = '여보세요 세계!' ;
|
||||
|
||||
Code = nl
|
||||
Text = 'Hello wereld!' ;
|
||||
|
||||
Code = pt
|
||||
Text = 'Olá mundo!' ;
|
||||
|
||||
Code = ru
|
||||
Text = 'Здравствулте! мир!' ;
|
||||
|
||||
Code = zh
|
||||
Text = '你好世界!'
|
||||
|
||||
Yes
|
||||
|
||||
|
||||
% query the table of names:
|
||||
|
||||
| ?- latin::name(Name).
|
||||
|
||||
Name = 'António Simões' ;
|
||||
|
||||
Name = 'Cátia Conceição' ;
|
||||
|
||||
Name = 'João Raínho' ;
|
||||
|
||||
Name = 'Luís Araújo'
|
||||
|
||||
Yes
|
@ -1,29 +0,0 @@
|
||||
|
||||
:- encoding(utf8). % this directive, when present, must be the first term in a source file
|
||||
|
||||
|
||||
:- object(babel).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2005/04/06,
|
||||
comment is 'Simple test of the encoding/1 directive.']).
|
||||
|
||||
:- public(hello_world/2).
|
||||
:- mode(hello_world(?atom, ?atom), zero_or_more).
|
||||
:- info(hello_world/2, [
|
||||
comment is 'Table of "hello world" messages in several languages (using ISO 639-2 two letter language codes for indexing).',
|
||||
argnames is ['Language', 'Text']]).
|
||||
|
||||
hello_world(el, 'Γειάσου κόσμος!').
|
||||
hello_world(en, 'Hello world!').
|
||||
hello_world(es, '¡Hola mundo!').
|
||||
hello_world(ja, 'こんにちは世界!').
|
||||
hello_world(ko, '여보세요 세계!').
|
||||
hello_world(nl, 'Hallo wereld!').
|
||||
hello_world(pt, 'Olá mundo!').
|
||||
hello_world(ru, 'Здравствулте! мир!').
|
||||
hello_world(zh, '你好世界!').
|
||||
|
||||
:- end_object.
|
@ -1,24 +0,0 @@
|
||||
|
||||
:- encoding(iso_latin_1). % this directive, when present, must be the first term in a source file
|
||||
|
||||
|
||||
:- object(latin).
|
||||
|
||||
:- info([
|
||||
version is 1.0,
|
||||
author is 'Paulo Moura',
|
||||
date is 2005/04/24,
|
||||
comment is 'Simple test of the encoding/1 directive.']).
|
||||
|
||||
:- public(name/1).
|
||||
:- mode(name(?atom), zero_or_more).
|
||||
:- info(name/1, [
|
||||
comment is 'Table of person names.',
|
||||
argnames is ['Name']]).
|
||||
|
||||
name('António Simões').
|
||||
name('Cátia Conceição').
|
||||
name('João Raínho').
|
||||
name('Luís Araújo').
|
||||
|
||||
:- end_object.
|
@ -1,3 +0,0 @@
|
||||
|
||||
:- initialization(
|
||||
logtalk_load([babel, latin])).
|
@ -1,13 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
To load this example and for sample queries, please see the SCRIPT
|
||||
file.
|
||||
|
||||
For a description of this example, please see the comments in the
|
||||
engines.lgt source file.
|
@ -1,62 +0,0 @@
|
||||
================================================================
|
||||
Logtalk - Open source object-oriented logic programming language
|
||||
Release 2.30.7
|
||||
|
||||
Copyright (c) 1998-2007 Paulo Moura. All Rights Reserved.
|
||||
================================================================
|
||||
|
||||
|
||||
% start by loading the example:
|
||||
|
||||
| ?- logtalk_load(engines(loader)).
|
||||
...
|
||||
|
||||
|
||||
% both cars provide the same interface, declared in the protocol
|
||||
% that is implemented by the categories imported by each object:
|
||||
|
||||
| ?- sedan::current_predicate(P).
|
||||
|
||||
P = reference/1 ;
|
||||
P = capacity/1 ;
|
||||
P = cylinders/2 ;
|
||||
P = horsepower_rpm/2 ;
|
||||
P = bore_stroke/2 ;
|
||||
P = fuel/1
|
||||
yes
|
||||
|
||||
|
||||
| ?- coupe::current_predicate(P).
|
||||
|
||||
P = reference/1 ;
|
||||
P = capacity/1 ;
|
||||
P = cylinders/2 ;
|
||||
P = horsepower_rpm/2 ;
|
||||
P = bore_stroke/2 ;
|
||||
P = fuel/1 ;
|
||||
yes
|
||||
|
||||
|
||||
% the sedan engine properties are the ones defined in the corresponding
|
||||
% imported category (classic):
|
||||
|
||||
| ?- sedan::(reference(Name), cylinders(Cylinders), horsepower_rpm(HP, RPM)).
|
||||
|
||||
Name = 'M180.940'
|
||||
Cylinders = 6
|
||||
HP = 94
|
||||
RPM = 4800
|
||||
yes
|
||||
|
||||
|
||||
% the coupe engine properties are the ones defined in the corresponding
|
||||
% imported category (sport) plus the ones inherited from the top category
|
||||
% (classic) which are not overridden:
|
||||
|
||||
| ?- coupe::(reference(Name), cylinders(Cylinders), horsepower_rpm(HP, RPM)).
|
||||
|
||||
Name = 'M180.941'
|
||||
Cylinders = 6
|
||||
HP = 110
|
||||
RPM = 5000
|
||||
yes
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user