<?xml version="1.0"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc editing="no"?>
<?rfc private="Nine by Nine"?>

<rfc docName="Swish">

  <front>
    <title abbrev="Swish">Semantic Web Inference Scripting with Haskell</title>
    <author initials="G." surname="Klyne" fullname="Graham Klyne">
      <organization abbrev="Nine by Nine">Nine by Nine</organization>
      <address>
        <postal></postal>
        <email>GK-swish@ninebynine.org</email>
        <uri>http://www.ninebynine.net/</uri>
      </address>
    </author>
    <date day="11" month="Feb" year="2004"/>
    <keyword>Inference</keyword>
    <keyword>RDF</keyword>
    <keyword>Notation3</keyword>
    <keyword>Semantic Web</keyword>
    <keyword>Haskell</keyword>
    <keyword>W3C</keyword>
    <keyword>XML</keyword>
    <abstract>
      <t>This memo describes the software package Swish, which is
         being developed to conduct experiments in using the
         programming language Haskell as a basis for scripting
         inference-based processing of Semantic Web data.
      </t>
    </abstract>
    <note title="&copy; 2003, 2004 G. Klyne;  All rights reserved.">
      <t>$Id: swish-0.2.1.xml,v 1.4 2004/02/11 17:54:25 graham Exp $</t>
    </note>
  </front>

  <middle>

    <!-- Introduction -->
    <section anchor="Introduction" title="Introduction">
      <t>This memo describes Swish, a software package that is intended
         to provide a framework for building programs in Haskell that
         perform inference on RDF <xref target="W3C.rdf-syntax"/> data.
      </t>
      <t>Swish was primarily intended to be used as a starting point for 
         developing new RDF applications in Haskell, but it also includes
         a stand-alone program that can be used to perform some simple
         scripted manipulation of RDF data. 
         Currently, only the Notation 3 <xref target="ref-notation3"/> 
         serialization form is supported, but I'd like to add support 
         for full RDF/XML in due course.
      </t>
      <t>The software can be downloaded from the web by following links from 
         <eref target="http://www.ninebynine.org/RDFNotes/Swish/Intro.html"/>.
         This software is made generally available under the GNU General 
         Public Licence (GPL), version 2 (or later), a full copy of 
         which is available at 
         <eref target="http://www.gnu.org/licenses/gpl.html"/>, and
         also as file GPL.TXT in the Swish software distribution.
         Other licensing arrangements may be negotiated with the
         author:  see LICENSING.TXT in the Swish software distribution.
      </t>
    </section>

    <!-- Background -->
    <section anchor="sect-Background" title="Background">
      <t>The Swish software package was developed as a result of
         experience using CWM <xref target="ref-cwm"/>, 
         an off-the-shelf general-purpose RDF processing program, 
         for evaluating simple inference rules on network access 
         control information expressed in RDF 
         <xref target="ref-netaccess"/>.  
         Specifically, while the general inference capabilities 
         of CWM were almost sufficient for the network access 
         application, some capabilities were required that are
         unlikely to be provided by any completely general-purpose 
         tool; e.g. analysis of IP network addresses by subnet 
         and host address.  
      </t>
      <t>Additionally, the framework for datatyped literals 
         currently proposed by the RDFcore working group 
         <xref target="ref-rdfcore"/> is quite open-ended, 
         and it is not specified  how generic applications may 
         provide support for new or non-standard datatypes.
      </t>
      <t>In light of these considerations, I sought ways of combining
         the full expressive capability of a general purpose programming 
         language with the declarative style of inference rules and
         formal specifications.
         Using Haskell <xref target="ref-haskell"/>,
         a pure functional programming language, 
         is the approach I have adopted.
      </t>
      <t>To use Haskell as a basis for performing inference on RDF data,
         certain capabilities are neded:
         <list style="symbols">
           <t>a means to store and access RDF data in Haskell,</t>
           <t>a capability to read RDF data using Haskell, and</t>
           <t>a capability to write RDF data using Haskell.</t>
         </list>
         Swish aims to provide these capabilities.  Further, it provides
         capabilities to compare RDF graphs (insensitive to possible 
         renaming of blank nodes), and to merge RDF graphs, renaming
         blank nodes as necessary to prevent unintended semantic 
         consequences <xref target="ref-rdf-semantics"/>.
      </t>
      <t>I anticipate that the main use for Swish will be as a 
         support library for new utilities that apply predefined
         RDF inference rules.  Where CWM is a general-purpose tool
         for manipulating RDF, I expect to use Swish as a toolkit for 
         creating tools to deal with specific RDF processing requirements.
         In time, this may lead to identification of some useful 
         capabilities that can guide the design of future 
         general-purpose RDF processing tools.
         Swish also includes a self-contained program that can be used
         to perform simple operations on RDF data and to script simple 
         inferences processing, thus providing a degree of CWM-like 
         functionality in a ready-to-use program.
      </t>
      <t>The programming language Haskell was chosen for a number of 
         reasons:
         <list style="symbols">
           <t>it is a pure functional language supporting a style 
              of programming that is directly based on a specification
              that is being implemented,</t>
           <t>it is non-strict, employing lazy evaluation, 
              meaning that, expressions are generally not evaluated 
              unless and until their value is needed;  this further
              supports a style of programming that is close to the
              typical form of mathematical-style of description
              that is often used to specify RDF inference rules, and
           </t>
           <t>it is relatively mature, with good-quality 
              implementations available for a variety of platforms,
              supported by an active and extensive user community,
              and performance for compiled code that is comparable
              with that of more conventional programming languages.
           </t>
         </list>
         More information about Haskell can be found at
         <xref target="ref-haskell"/>.
         A useful paper discussing some particular characteristics of 
         functional programming languages is <xref target="ref-whyfp"/>.
      </t>
    </section>

    <!-- Introduction to Swish -->
    <section anchor='sec-swish-introduction' 
             title='Introduction to Swish'>

      <t>Swish is a framework for performing deductions in RDF data 
        using a variety of techniques. 
        Swish is conceived as a toolkit for experimenting with RDF 
        inference, and for implementing stand-alone RDF file processors 
        It explores Haskell as "a scripting language for the Semantic Web".
        </t>

      <t>Swish is a work-in-progress, and currently incorporates:
        <list style='symbols'>
          <t>Notation3 input and output;
            </t>
          <t>RDF graph isomorphism testing and merging;
            </t>
          <t>inference operations in forward chaining, backward chaining and 
            proof-checking modes;
            </t>
          <t>simple Horn-style rule implementations, extendable through variable 
            binding modifiers and filters
            </t>
          <t>class restriction rule implementation primarily for 
            datatype-aware inferences <xref target='ref-datatypenotes' />,
            </t>
          <t>built-in RDF formal semantics entailment rule implementation, and
            </t>
          <t>a complete, ready-to-run, command-line and script-driven programm.
            </t>
          </list>
        </t>

      <section anchor='sec-Notation3IO' title='Notation 3 input and output'>

        <t>Swish contains a Notation3 parser and formatter. 
          </t>

        <t>The parser does not recognize all of the very latest
          additions to Notation3, but seems to be able to deal with a
          good number of Notation3 files that appear in the wild.
          </t>

        <t>The formatter is fairly primitive, focusing on round-
          tripping: generating Notation3 data that can be accepted by
          the parser.
          </t>

      </section>

      <section anchor='sec-RDF-isomorphism-merging' 
               title='RDF graph isomorphism testing and merging'>

        <t>Swish has logic for performing RDF graph isomorphism testing 
          (graphs are considered equivalent if they can be made exactly 
          equal by some reallocation of bnode identifiers). 
          This is used mainly for software testing purposes.
          </t>

        <t>Sometimes, for diagnostic purposes, it is useful to have some 
          idea of the actual differences betwen a pair of non-identical 
          graphs.  Swish provides a capability to display such differences.
          </t>

        <t>Swish also incorporates logic for merging graphs, renaming
          bnode identifiers as needed to avoid merging of bnodes from
          different graphs.
          </t>

      </section>

      <section anchor='sec-inference-framework' 
               title='Inference framework based on logical inference rule concept'>

        <t>The Swish inference framework uses as its foundation a 
          generic concept of an inference rule, 
          having the following characteristics:
          <list style='symbols'>
            <t>A scoped name (a namespace and a local name).
              </t>
            <t>a function for forward chaining application of the rule. 
              Applied to some collection of antecedent expressions, 
              it returns a collection of consequent expressions that 
              can be deduced from the input by the rule. 
              There are no constraints imposed on the form of 
              computation that may be used to obtain the results.
              </t>
            <t>A function for backward chaining application of the rule. 
              Applied to a single goal expression, it returns a number 
              of alternative sets of expressions, such that satisfaction 
              of any one of the alternatives is sufficient to deduce 
              the given goal using the rule.
              </t>
            <t>A proof-checking function. 
              Applied to a collection of antecedents and a suggested 
              conclusion, returns an indication of whether the rule 
              justifies drawing the conclusion from the antecedents.
              (One version of this function also returns an 
              explanation if the proof is not valid.)
              </t>
            </list>
          </t>

        <t>Not every rule is required to fully support both forward 
          and backward chaining, but all are expected to support the 
          proof-checking mode.
          </t>

        <t>The underlying rule definition is not specific to RDF 
          graphs, and is polymorphic in the type of expression to 
          which the rule applies.  
          Other modules in the Swish framework specialize the 
          rule to apply to RDF graphs.
          </t>

        <t>Axioms and rules are collected into rulesets. 
          A collection of one or more rulesets can be used as a 
          proof context
          </t>

      </section>

      <section anchor='sec-horn-rules' title='RDF Horn-style rule implementation'>

      <t>Swish provides a generic implementation of the rule 
        framework that deduces a single specific conclusion from a 
        simple conjunction of antecedent RDF graphs. 
        </t>

      <t>The antecedent and consequent graphs are specified as 
        graph patterns that may contain variable nodes in place 
        of any of the RDF nodes or properties. 
        The deduction is considerd to be true for any substitution 
        of the variale nodes through the whole rule 
        (i.e. the variable nodes are universally quantified 
        within the scope of the rule).
        </t>

      <t>These rules can be used in both forward- and backward- 
        chaining modes. Backward chaining may involve the 
        introduction of new bnodes (existential variables). 
        [[[Note: the code does not currently properly handle the 
        scoping of such introduced existential variables -- to do 
        this will require an extension to the RDF graph structure 
        used.]]]
        </t>

      <t>This kind of rule is implemented by a combination of 
        simple graph query and back substitution. 
        (Both forward and backward chaining operate similarly in 
        this respect, but the details do vary.)
        </t>

      <t>The basic query/substitution operation of simple rules 
        can be modified through the use of variable binding 
        modifiers and variable binding filters. These are used 
        to manipulate the variable bindings obtained from the 
        query phase, before performing the substitution phase. 
        In a simple case, a variable binding filter (which 
        is just a special case of a variable binding modifier) 
        may cause some of the variable bindings to be discarded
        if they do not satisfy certain criteria; 
        e.g. some rules are applicable only to certain forms of 
        RDF graph node.  
        </t>

      <t>More complex variable binding modifier may actually add 
        new variable bindings to those obtained from the query 
        phase;  e.g. the RDF "allocated to" rule that appears 
        in the RDF formal semantics specification is handled by 
        such means. The early design of Swish also anticipated 
        that datatype-specific operations (e.g. integer addition) 
        might be introduced through this mechanism.
        </t>

      </section>

      <section anchor='sec-class-restriction-rules' 
               title='Class restriction rule implementation'>

        <t>A second style of general purpose inference rule 
          implementation provided by Swish is based on the notion 
          of a class restriction, the basic idea of which is 
          described by Pan and Horrocks 
          <xref target='ref-WebOntDatatypeGroups' />
          as a generalization of the Owl notion of a 
          class restriction.
          </t>

        <t>This form of inference rule has been implemented 
          because it appears to be a more useful way of 
          accessing datatype-related inferences. 
          My analysis <xref target='ref-datatypenotes' /> is that 
          this form allows a cleaner separation of datatype-specific 
          inference functionality from application-specific use of 
          the datatype properties. 
          </t>

        <t>Datatype inference capabilities built into Swish can, 
          in principle, be accessed from RDF data without the need 
          of any new parsing capability beyond standard RDF.
          </t>

      </section>

      <section anchor='sec-RDF-entailment-rules' 
               title='RDF formal semantics entailment rule implementation'>

      <t>Built-in to Swish is an implementation of almost all of the 
        entailment rules described in the RDF Semantics specification. 
        With the exception of subgraph entailment and simple entailment, 
        these are all implemented as instances of the generic 
        Horn-style rule with variable binding modifiers, described above. 
        Subgraph entailment and simple entailment are implemented by 
        special-purpose inference rules written in Haskell.
        (Some of the axiom and rule implementations are slightly 
        restricted to avoid infinite graphs being generated by their 
        application.)
        </t>

      <t>The intent of these implementations is that they permit 
        the Swish program to be used to check proofs based on the 
        RDF core semantics.
        </t>

      <t>The entailment rule whose implementation is not yet provided
        is equvalence of values with differing datatypes
        (rule 'rdfD3' in <xref target='ref-rdf-semantics' />).
        </t>

      </section>

      <section anchor='sec-datatype-framework' 
               title='Framework for datatypes'>

      <t>Swish implements a datatype model based on that defined 
        for RDF (and XML schema datatypes).
        For each datatype, it embodies:
        <list style='symbols'>
          <t>An identifying URI.
            </t>
          <t>A lexical space of representations that may appear 
            in RDF literals (lexical forms).
            </t>
          <t>A value space of things denoted by the datatyped 
            RDF literals (datatype values).
            </t>
          <t>A mapping between the lexical forms and 
            datatype values.
            </t>
          </list>
        </t>

      <t>To these, Swish adds:
        <list style='symbols'>
          <t>A ruleset containing datatype axioms and datatype rules.
            </t>
          <t>A number if named relations (constraints) on datatype 
            values (e.g. xsd_integer:sum a b c is a relation on 
            three integers such that a=b+c). 
            These may be accessed in the definition of 
            GeneralRestriction rules that are used to generate 
            class restriction inference rules 
            (see "Web Ontology Reasoning with Datatype Groups" 
            <xref target='ref-WebOntDatatypeGroups' />).
            </t>
          <t>A number of named variable binding modifier values 
            that may be used to extend the behaviour of simple 
            Horn-style rule definitions.
            </t>
          </list>
        </t>

      <t>The last two provide overlapping functionality, 
        in that they provide alternative ways to incorporate 
        datatype computations into an inference process 
        (e.g. arithmetic operations). 
        One of the goals of this software is to allow 
        experimentation with different styles of inference 
        primitive.  
        The advantage of the class restriction approach is that 
        it provides access to datatype computations within 
        the basic syntactic framework of RDF; 
        the variable binding modifier approach requires the 
        introduction of syntactic construct for formulae to 
        define the antecedent and consequent graphs for 
        Horn-style rules.
        </t>

      </section>

      <section anchor='sec-SwishProgram' title='Swish main program'>

      <t>The Swish main program can be run as a stand-alone 
        executable (when compiled using GHC, or by using the 
        RunHugs utility), or from an invocation of the runSwish 
        function from within a Hugs or GHCi interactive session.
        </t>

      <t>Facilities available through command line options include:
        <list style='symbols'>
          <t>Notation 3 syntax checking.
            </t>
          <t>RDF graph comparison.
            </t>
          <t>RDF graph merging.
            </t>
          <t>Running a Swish script file.
            </t>
          </list>
        </t>

      <t>A script file provides access to a range of Swish 
        inference capabilities, shown in the example below,
        in <xref target='sec-script-example' /> below.
        </t>

      </section>

    </section>

    <!-- Description of software -->
    <section anchor="sect-swish-description" title="Description of Swish software">
      <t>Swish comprises a number of modules that can be invoked by
         Haskell programs, and a stand-alone command-line utility that 
         can be used to perform some basic processing of RDF data.
      </t>
      <t>The Haskell source code for the stand-alone utility may also be 
         used as a starting point for similar utilities that perform 
         specific application processing of RDF data.
      </t>
      <section anchor="sect-swish-parts" title="Swish software components">
        <t>The following components are specific to Swish, and are found in 
           a subdirectory called HaskellRDF:
           <list style="symbols">
             <t>Swish.hs, SwishMain.hs, SwishMonad.hs, SwishCommands.hs:
                Swish is a command line utility that performs some simple
                RDF processing tasks:  checking Notation 3 syntax, comparing
                RDF graphs, merging RDF graphs.  The source code may also
                be used as a basis for creating new RDF processing 
                utilities.
                </t>
             <t>SwishScript.hs: a module that is incporporated into the command 
                line utility noted above to perform scripted inferences and proof
                checking in RDF data.
                </t>
             <t>Vocabulary.hs:
                defines various URIs, namespaces and names used internally 
                by Swish.
                </t>
             <t>BuiltInDatatypes.hs,
                BuiltInRules.hs,
                BuiltInMap.hs:
                provide access to rulesets, axioms, inference rules, 
                datatypes, etc., that are built in to the Swish program.
                New built-in functionality is hooked in through these modules.
                </t>
             <t>RDFGraph.hs, RDFGraphShowM:  
                these defines data types and methods for RDF graphs.
                RDFGraph defines a datatype RDFLabel (URIs, bnodes, 
                RDF literals and some other extensions for future use),
                and datatype NSGraph that implements the graph class 
                interface.
                (NSGraph is similar to GraphMem but adds prefix and 
                formula lists to the content of a graph, and also defines
                a graph merge function that merges graphs with renaming of
                bnodes as needed to preserve semantics.)
                RDFGraph is a type synonym for NSGraph RDFLabel.
                </t>
             <t>N3Parser.hs:  a Notation3 parser that converts string
                into an RDFGraph value.  The parser is built using the 
                Parsec library (except the URI parser that is currently 
                based on some private parsing components).
                </t>
             <t>N3Formatter.hs:  a Notation3 formatter that converts an 
                RDFGraph value to a string, or to a ShowS function.  
                The formatter uses a monad to track formatter state.
                Currently, the formatter is pretty primitive, and is
                intended to minimally satisfy the round-tripping of RDF
                graphs via Notation3 format (also using N3Parser).
                Future versions may try to generate more human-friendly
                output.
                </t>
             <t>GraphClass.hs:  some basic definitions for a type class
                for representing and manipulating labelled directed 
                graphs.
                </t>
             <t>GraphMem.hs:  a graph implementation based on a simple 
                in-memory list structure.  There is much scope for 
                performance improvement by replacing the list structure
                with a more efficiently accessed structure.  (Ralf Hinze
                <eref target="http://www.informatik.uni-bonn.de/~ralf/"/>
                has some interesting options for this;  I like the idea 
                of using a splay trees.)  
                This code needs a reworking to properly separate the
                graph container structure from the graph node type.
                </t>
             <t>GraphMatch.hs: graph comparison function.  This function
                tests two graphs for isomorphism, taking account of nodes
                that are "variable" (i.e. may be freely renamed without 
                changing the fundmanetal graph structure).  The code
                implements an algorithm by Jeremy Carroll
                <xref target="ref-graphcomp"/>.
                </t>
             <t>GraphPartition.hs: graph partitioning functions.
                This module defines data types for an alternative way of storing
                an RDF graph as a number of trees which jointly span the graph.
                Each tree is rooted in a node that is used as the origin
                of some arc, and each branch corresponds to an arc of the graph.
                The selection of root nodes is intended to make it easier to 
                isolate different parts of the graph:  all fixed (named) nodes,
                and any variable (blank) nodes that appear as the origin of more 
                than one arc.  Functions are provided by this module to construct
                a partitioned graph from a list of arcs and to isolate the 
                differences between two partitioned graphs.
                </t>
             <t>RDFQuery.hs,
                RDFVarBinding.hs,
                VarBinding.hs:
                these modules provide basic RDF graph query functionality,
                which is an important basis for many of the inference
                capabilities.  A query against an RDF graph is used to 
                determine a set of variable bindings, which are used to 
                construct subsequent inferences.
                </t>
             <t>Rule.hs,
                Proof.hs,
                Ruleset.hs,
                RDFProof.hs,
                RDFRuleset.hs,
                RDFProofContext.hs:
                these modules represent the core of the RDF inference
                framework.  Modules Rule, Proof and Ruleset define a 
                generic dediction and proof framework that is not at all
                specific to RDF.  The remaining modules specialize and 
                extend that framework to deal with deduction over RDF
                graph values.
                </t>
             <t>Datatype.hs,
                ClassRestrictionRule.hs,
                MapXsdInteger.hs,
                RDFDatatype.hs:
                these modules define a framework for inference involving
                datatyped literals in RDF.
                (For design notes, see: <xref target='ref-datatypenotes' />.)
                The datatype framework is defined by module Datatype.hs.
                The framework supports two separate styles of datatype-aware 
                inferencing, for experimental purposes.
                </t>
             <t>RDFDatatypeXsdInteger.hs,
                RDFDatatypeXsdString.hs:
                These are two actual datatype implementations 
                (see also MapXsdInteger.hs noted above).
                The string datatype is a minimal implementation required 
                to support equivalence of xsd:string and plain literals 
                without language tags 
                (but, of course, may be extended in the future).
                The integer datatype is a fairly complete implementation,
                and demonstrates full use of the datatype inference framework.
                </t>
             <t>SwishTest.hs,
                BuiltInMapTest.hs,
                ClassRestrictionRuleTest.hs,
                GraphTest.hs,
                N3FormatterTest.hs,
                N3ParserTest.hs,
                RDFDatatypeXsdIntegerTest.hs,
                RDFGraphTest.hs,
                RDFProofContextTest.hs,
                RDFProofTest.hs,
                RDFQueryTest.hs,
                RDFRulesetTest.hs:
                these are all test modules, and are not part of any
                Swish application.  They use the HUnit library to 
                run a series of unit tests on the various Swish 
                components.  Each of these contains a stand-alone
                program that runs a series of test cases.
                </t>
             <t>SwishTestAll.hs is a consolidated test program that performs
                all of the unit tests from all of the test modules, including
                the generic test modules.  (This can take some time to run.)
                </t>
             <t>Data/*.n3: subdirectory Data of the HaskellRDF
                directory contains a number of Notation3 data files that
                are used to test the Swish utility, and in particular
                are assumed to be present by the SwishTest program.
                </t>
             <t>SwishTest.ss:  
                a simple script file that is used for testing the scripted
                inference and RDF graph handling in Swish.
                </t>
             <t>VehicleCapacity.ss:  
                a simple script file that demonstrates Swish datatype inferencing.
                </t>
             <t>TestSwish.bat:  
                a Windows batch file that is used for running the Swish 
                test cases.  This might be used as the basis for creating
                a similar command script on Unix/Linux systems.
                [[[Since the test code was modified to support the consolidated
                test program SwishTestAll, this batch file is not usable in the 
                current release, because of a problem with the GHC -main-is
                option.  A future revision of GHC should correct this.]]]
                </t>
             <t>MakeSwish.bat:  
                a Windows batch file that is used to built a Swish executable
                program and test programs from the sources using using GHC.
                This might be used as the basis for creating a similar 
                command script on Unix/Linux systems.
                </t>
             <t>ghcc.bat:  
                this file is used to build software on a Windows operating system 
                using the Glasgow Haskell Compiler (GHC).  It is used by the
                MakeSwush file (above), embodies information about the local
                installation, and will need to be edited to reflect the 
                location of GHC and the support libraries.
                The batch files have been tested under Windows 2000, and should 
                work on any recent Windows operating system (NT, 2K, XP, 98, 95)
                Examination of these files should also provide 
                information needed to build and run the software on
                non-Windows operating systems.
                </t>
             <t>.ghci:  is the Glasgow Haskell Compiler options configuration 
                file that I use.  If used, it will need some editing to 
                reflect the local configuration.
                </t>
             <t>A small number of other files contain further information 
                about the software and/or related topics.
                </t>
             <t>swish-0.2.1.xml, swish-0.2.1.html:
                Swish documentation files (this document).
                The .xml file is the XML2RFC <xref target='ref-XML2RFC' /> 
                source, and .html is the corresponding generated HTML.
                </t>
           </list>
        </t>
        <t>Currently, the only supported RDF graph serialization format 
           is Notation3, but future developments may add support
           for other formats.  RDF/XML would clearly be most desirable.
           Meanwhile, utilities such as CWM <xref target="ref-cwm"/>
           can be used convert RDF/XML to and from Notation 3 format.
        </t>
      </section>

      <section anchor="sect-general-parts" title="Generic software components">
        <t>The following generic components are not specific to Swish, 
          and are found in a subdirectory called HaskellUtils:
          <list style="symbols">
             <t>ParseURI.hs, ProcessURI.hs:  URI handling code, including 
                methods to deduce and process relative URI references.
                The code is based on an early draft of the revised URI 
                specification <xref target="ref-rfc2396bis"/>, and may
                be subject to revision as that specification progresses.
                </t>
             <t>Parse.hs:  Simple parser code, based on some example 
                programs in Simon Thompson's book 
                The Craft of Functional Programming
                <xref target="ref-thompson"/>.
                This was written to support the URI handler, which was 
                my very first program in Haskell, and suffers from my 
                early confusion about how to use Haskell.
                In due course, the URI parser will be revised to use the 
                Parsec library, and this code will be retired.
                </t>
             <t>LookupMap.hs:  class and function definitions for lookup
                tables, which are used in various ways throughout the
                RDF graph handling code.  (The Swish package would 
                benefit from greatly from this code using a hash table 
                or some other more serious lookup algorithm.)
                </t>
             <t>Namespace.hs, QName.hs:
                classes and functions for scoped names based on the XML
                namespace model (with prefixes, namespace URIs and local 
                names.)
                </t>
             <t>ListHelpers.hs, 
                MiscHelpers.hs, 
                TraceHelpers.hs, 
                DateTime.hs,
                ErrorM.hs, 
                FunctorM.hs,
                ShowM.hs, 
                AccumulateM.hs, 
                PartOrderedCollection.hs, 
                RegexParser.hs: 
                various helper functions.
                </t>
             <t>Test modules:
                DateTimeTest.hs,
                LookupMapTest.hs,
                NamespaceTest.hs,
                ParseTest.hs,
                ParseURITest.hs,
                QNameTest.hs
                URITest.hs,
                VarBindingTest.hs:
                HUnit test modules for selected generic function modules.
               </t>
            </list>
          </t>
        <t>There are also some work-in-progress modules in subdirectories of
          HaskellUtils that are intended to be offered as replacements for
          modules in the hierarchical library that ships with GHC and Hugs.
          Currently, Swish does not use these modules.
          </t>
      </section>

      <section anchor="sect-swish-cmdline" title="Swish command format">
        <t>The Swish utility is a command-line utility that performs
           some simple RDF processing functions.  The capabilities provided
           are with a view to testing the underlying RDF library software
           rather than performing any particular application purpose.
        </t>
        <t>A Swish command contains a one or more command line options that
           are processed from left-to-right.
           The Swish program maintains an internal graph workspace, which
           is updated or referenced as the command options are processed.
        </t>
        <t>Swish command options:
           <list style="hanging">
             <t hangText="-?">
                Displays a summary of the command line options.
             </t>
             <t hangText="-n3">
                Indicates that Notation3 be used for subsequent input 
                and output.  (Currently, this is the only format option, 
                and is selected by default.)
             </t>
             <t hangText="-i[=file]">
                read file into the graph workspace, 
                replacing any existing graph.
                If the filename is omitted, the graph is read from
                standard input.
             </t>
             <t hangText="-m[=file]">
                read and merge file with the graph workspace.
                Blank nodes in the input file are renamed as necessary
                to avoid node identifiers already used by the existing
                graph.
                If the filename is omitted, the graph is read from
                standard input.
             </t>
             <t hangText="-c[=file]">
                read file and compare the resulting graph with the workspace.
                Graph comparison is done in a fashion that treats isomorphic
                graphs as equivalence, and is insensitive to renaming of
                blank nodes.  This is intended to match the definition
                of graph equivalence in the RDF abstract syntax 
                specification <xref target="W3C.rdf-concepts"/>.
                If the filename is omitted, the graph is read from
                standard input.
                If the graphs are unequal, the exit status code is 1.
             </t>
             <t hangText="-d[=file]">
                read a file and compare the resulting graph with the workspace,
                diusplaying a list of differences between the graphs.
                This is a diagnostic facility, intended to help developers or
                RDF authors to identify specifically where RDF graphs may differ.
             </t>
             <t hangText="-o[=file]">
                write the graph workspace to a file.
                If the filename is omitted, the graph is written to
                the standard output.
             </t>
             <t hangText="-s[=file]">
                executes a script from the named file.  The script file 
                format is described below.
             </t>
          </list>
        </t>
        <t>The Swish program terminates with a status code that 
           indicates the final status of the operation(s) performed.
           Haskell distinguishes between a success status code whose
           value is not specified, assumed to be system dependent,
           and a failure code which is associated with an integer
           value.  
           The status code values returned by Swish are:
           <list style="hanging">
            <t hangText="Success">
                Operation completed successfully; graphs compare equal.
             </t>
            <t hangText="1">
                Graphs compare different.
             </t>
            <t hangText="2">
                Input data file incorrect format.
             </t>
            <t hangText="3">
                File access problem.
             </t>
            <t hangText="4">
                Incorrect option in command line.
             </t>
            <t hangText="5">
                Error in script file.
             </t>
          </list>
        </t>
        <t>Here are some example Swish command lines:
           <list style="symbols">
            <t>swish -n3 -i=file
             <vspace/>
                Read 'file' as Notation3, and report any syntax errors.
             </t>
            <t>swich -n3 -i=file1 -c=file2
             <vspace/>
                Read 'file1' and 'file2' as Notation3, report any syntax 
                errors, and if both are OK, compare the resulting 
                graphs, indicating whether or not they are equivalent.
             </t>
            <t>swish -n3 -i=file1 -o=file2
             <vspace/>
                Read 'file1' as Notation3, report any syntax errors, 
                and output the resulting graph as reformatted Notation3.
                (The output will generally be different form the input,
                and may be unpretty.
                It may be used to test round-tripping of Notation 3 data.)
             </t>
          </list>
        </t>
      </section>
      <section anchor="sect-swish-api" title="Function interfaces">
        <t>[[[To be provided;  until then see the source files,
           notably SwishCommands.hs, GraphClass.hs, RDFGraph.hs,
           and the various test modules.]]]
        </t>
      </section>
    </section>

    <!-- Script file format -->
    <section anchor="sect-swishscript" title="Swish script file format">
      <t>The script syntax is loosely based on Notation3, 
        but it is a quite different language, 
        except that embedded graphs (enclosed in {...}) are 
        presented using Notation3 syntax.
        </t>

      <t>A script file provides access to a range of Swish inference 
        capabilities. 
        The following script file commands are currently provided:
        <list style="hanging">
          <t hangText="@prefix">
            <vspace />
            <spanx style='code'>@prefix  pref : &lt;uri&gt; .</spanx>
            <vspace blankLines='1' />
            Define a namespace prefix and URI.  
            <vspace blankLines='1' />
            The prefix thus defined is available for use in any
            subsequent script command, and also in any graphs
            contained within the script file.
            (So, prefix declarations do not need to be repeated
            for each graph contained within the script.)
            Graphs read from external files must contain their own
            prefix declarations.
            <vspace blankLines='1' />
            </t>
          <t hangText="Define named graph or list">
            <vspace />
            <spanx style='code'>name :- graph</spanx>
            <vspace />
            <spanx style='code'>name :- ( graph* )</spanx>
            <vspace blankLines='1' />
            where <spanx style='code'>graph</spanx> is a Notation
            3 graph expression enclosed in braces, 
            or a <spanx style='code'>name</spanx>.
            A <spanx style='code'>name</spanx> is a qname 
            (<spanx style='code'>prefix:local</spanx>) or a
            URI enclosed in angle brackets.
            <vspace blankLines='1' />
            Defines a named graph or list of graphs.
            <vspace blankLines='1' />
            </t>
          <t hangText="@read">
            <vspace />
            <spanx style='code'>@read name  &lt;uri&gt;?</spanx>
            <vspace blankLines='1' />
            Read and name a graph from a given filename or 
            standard input.
            (Input from an http: URI is not yet implemented.)
            <vspace blankLines='1' />
            </t>
          <t hangText="@write">
            <vspace />
            <spanx style='code'>@write name  &lt;uri&gt;? ; comment</spanx>
            <vspace blankLines='1' />
            Write a named graph to a named file or to standard output.
            The comment text is included at the start of the output.
            (Output to an http: URI is not yet implemented.)
            <vspace blankLines='1' />
            </t>
          <t hangText="@merge">
            <vspace />
            <spanx style='code'>@merge ( name* ) =&gt; name</spanx>
            <vspace blankLines='1' />
            Create a new named graph that is the merge two or more graphs, 
            renaming bnodes as required to avoid node-merging.
            <vspace blankLines='1' />
            </t>
          <t hangText="@compare">
            <vspace />
            <spanx style='code'>@compare name name</spanx>
            <vspace blankLines='1' />
            Compare two graphs for isomorphism, 
            setting the Swish exit status to reflect the result.
            <vspace blankLines='1' />
            </t>
          <t hangText="@asserteq">
            <vspace />
            <spanx style='code'>@asserteq name name ; comment</spanx>
            <vspace blankLines='1' />
            Test two graphs or lists of graphs for isomorphism, 
            reporting if they differ.  
            The comment text is included with any report generated.
            <vspace blankLines='1' />
            </t>
          <t hangText="@assertin">
            <vspace />
            <spanx style='code'>@assertin name name ; comment</spanx>
            <vspace blankLines='1' />
            Test if a graph is isomorphic to a member of a list of graphs,
            reporting if no match is found.
            The comment text is included with any report generated.
            <vspace blankLines='1' />
            </t>
          <t hangText="@rule">
            <vspace />
            <spanx style='code'>@rule name :- ( name* ) =&gt; name</spanx>
            <vspace />
            <spanx style='code'>@rule name :- ( name* ) =&gt; name | ( (name var*)* )</spanx>
            <vspace blankLines='1' />
            Define a named Horn-style rule.  
            <vspace blankLines='1' />
            The list of names preceding <spanx style='code'>=&gt;</spanx> 
            are the antecedent graphs (which may contain 
            variable nodes of the form <spanx style='code'>?var</spanx>.
            <vspace blankLines='1' />
            The name following <spanx style='code'>=&gt;</spanx> 
            is the consequent graph (which may also contain 
            variable nodes of the form <spanx style='code'>?var</spanx>).
            <vspace blankLines='1' />
            The final part, if present, is a list of variable binding 
            modifiers, each of which consists of a name and a list of 
            variables <spanx style='code'>?var</spanx> to which the modifier
            is applied.  Variable binding modifiers are built in to Swish,
            and are used to incorporate datatype value inferences into a rule.
            <vspace blankLines='1' />
            </t>
          <t hangText="@ruleset">
            <vspace />
            <spanx style='code'>@ruleset name :- ( name* ) ; ( name* )</spanx>
            <vspace blankLines='1' />
            Define a named ruleset (a collection of axioms and rules).
            The first list of names are the axioms that are part of the
            ruleset, and the second list are the rules.
            <vspace blankLines='1' />
            </t>
          <t hangText="@constraints">
            <vspace />
            <spanx style='code'>@constraints name :- ( name* ) | ( name* )</spanx>
            <vspace blankLines='1' />
            Define a named ruleset containing class-restriction rules based on 
            a datatype value constraint (see 
            <eref target="http://www.ninebynine.org/RDFNotes/RDF-Datatype-inference.html#sec-choice-constraint-classes">section 4.5</eref>
            of <xref target='ref-datatypenotes' />).
            The first list of names is a list of graphs that together comprise 
            the class-restriction definitions (rule names are the
            names of the corresponding restriction classes).
            The second list of names is a list of datatypes whose datatype
            relations are referenced by the class restriction definitions.
            <vspace blankLines='1' />
            </t>
          <t hangText="@proof">
            <vspace />
            <spanx style='code'>@proof name ( name* )</spanx>
            <vspace />
            <spanx style='code'>  @input name</spanx>
            <vspace />
            <spanx style='code'>  @step name ( name* ) => name</spanx>
            <vspace />
            <spanx style='code'>   :</spanx>
            <vspace />
            <spanx style='code'>  @result name</spanx>
            <vspace blankLines='1' />
            Check a proof, reporting the step that fails, if any.
            See also: @input, @step, @result.
            <vspace blankLines='1' />
            The <spanx style='code'>@proof</spanx> line names the 
            proof and specifies a list rulesets (proof context) used.
            The remaining lines specify the input expression, proof steps
            and final result that is demonstrated by the proof.
            <vspace blankLines='1' />
            </t>
          <t hangText="@input">
            <vspace />
            In a proof, indicates an input expression upon which the 
            proof is based.  
            Exactly one of these immediately follows the 
            <spanx style='code'>@proof</spanx> command.
            <vspace blankLines='1' />
            </t>
          <t hangText="@step">
            <vspace />
            In a proof, defines a step of the proof.
            Any number of these immediately follow the @input command.
            <vspace blankLines='1' />
            It indicates the name of the rule applied for this step,
            a list of antecedent graphs, and a named graph that is deduced
            by this step.  
            <vspace blankLines='1' />
            (For convenience, the deduced graph may introduce 
            a new named graph using an expression of the form:
            <spanx style='code'>name :- { statements }</spanx>.)
            <vspace blankLines='1' />
            </t>
          <t hangText="@result">
            <vspace />
            In a proof, introduces the goal of the proof, and completes
            a proof definition.
            Exactly one of these immediately follows the @step commands.
            <vspace blankLines='1' />
            (For convenience, the result statement may introduce 
            a new named graph using an expression of the form:
            <spanx style='code'>name :- { statements }</spanx>.)
            <vspace blankLines='1' />
            </t>
          <t hangText="@fwdchain">
            <vspace />
            <spanx style='code'>@fwdchain name name ( name* ) =&gt; name</spanx>
            <vspace blankLines='1' />
            Define a new graph obtained by forward-chaining a rule.
            The first name is the ruleset to be used.
            The second name is the rule name.
            The list of names are the antecedent graphs to which the
            rule is applied.
            The name following the <spanx style='code'>=&gt;</spanx>
            names a new graph that is the result of formward chaining
            from the given antecedents using the indicated rule.
            <vspace blankLines='1' />
            </t>
          <t hangText="@bwdchain">
            <vspace />
            <spanx style='code'>@bwdchain name name name &lt;= name</spanx>
            <vspace blankLines='1' />
            Define a new list of alternative graphs obtained by 
            backward-chaining a rule.
            The first name is the ruleset to be used.
            The second name is the rule name.
            The third name (before <spanx style='code'>&lt;=</spanx>) 
            is the name of a goal graph from which to backward chain.
            The final name (after <spanx style='code'>&lt;=</spanx>) 
            names a new list of graphs, each of which is an alternative
            antecedent from which the given goal can be deduced using
            the indicated rule.
            <vspace blankLines='1' />
            </t>
        </list>
      </t>

      <section anchor='sec-script-example' 
               title='Script file example'>

        <figure>
          <preamble>
            This example of a script file demonstrates use of most 
            of the features described above.
            </preamble>
<artwork><![CDATA[
# -- Example Swish script --
#
# Comment lines start with a '#'
#
# The script syntax is loosely based on Notation3, but it is a quite 
# different language, except that embedded graphs (enclosed in {...})
# are encoded using Notation3 syntax.
#
# -- Prefix declarations --
#
# As well as being used for all labels defined and used by the script
# itself, these are applied to all graph expressions within the script 
# file, and to graphs created by scripted inferences, 
# but are not applied to any graphs read in from an external source.

@prefix ex:  <http://id.ninebynine.org/wip/2003/swishtest/> .
@prefix pv:  <http://id.ninebynine.org/wip/2003/swishtest/pv/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix xsd_integer: <http://id.ninebynine.org/2003/XMLSchema/integer#> .
@prefix rs_rdf:  <http://id.ninebynine.org/2003/Ruleset/rdf#> .
@prefix rs_rdfs: <http://id.ninebynine.org/2003/Ruleset/rdfs#> .
@prefix :   <http://id.ninebynine.org/default/> .

# Additionally, prefix declarations are provided automatically for:
#    @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#    @prefix rdfs:  <file:///E:/Download/www.w3.org/2000/01/rdf-schema#> .
#    @prefix rdfd:  <http://id.ninebynine.org/2003/rdfext/rdfd#> .
#    @prefix rdfo:  <http://id.ninebynine.org/2003/rdfext/rdfo#> .
#    @prefix owl:   <http://www.w3.org/2002/07/owl#> .


# -- Simple named graph declarations --

ex:Rule01Ant :- { ?p ex:son ?o . }

ex:Rule01Con :- { ?o a ex:Male ; ex:parent ?p . }

ex:TomSonDick :- { :Tom ex:son :Dick . }

ex:TomSonHarry :- { :Tom ex:son :Harry . }


# -- Named rule definition --

@rule ex:Rule01 :- ( ex:Rule01Ant ) => ex:Rule01Con


# -- Named ruleset definition --
#
# A 'ruleset' is a collection of axioms and rules.
#
# Currently, the ruleset is identified using the namespace alone;
# i.e. the 'rules' in 'ex:rules' below is not used.  
# This is under review.

@ruleset ex:rules :- (ex:TomSonDick ex:TomSonHarry) ; (ex:Rule01)

# -- Forward application of rule --
#
# The rule is identified here by ruleset and a name within the ruleset.

@fwdchain ex:rules ex:Rule01 { :Tom ex:son :Charles . } => ex:Rule01fwd

# -- Compare graphs --
#
# Compare result of inference with expected result.
# This is a graph isomorphism test rather than strict equality, 
# to allow for bnode renaming.
# If the graphs are not equal, a message is generated
# The comment (';' to end of line) is included in any message 
# generated

ex:ExpectedRule01fwd :- { :Charles a ex:Male ; ex:parent :Tom . }  

@asserteq ex:Rule01fwd ex:ExpectedRule01fwd
   ; Infer that Charles is male and has parent Tom

# -- Display graph --
#
# Write graph as Notation3 to standard output.
# The comment is included in the output.

@write ex:Rule01fwd ; Charles is male and has parent Tom

# -- Write graph to file --
#
# The comment is included at the head of the file.
# (TODO: support for output to Web using HTTP.)

@write ex:Rule01fwd <Example1.n3> ; Charles is male and has parent Tom

# -- Read graph from file --
#
# Creates a new named graph in the Swish environment.
# (TODO: support for input from Web using HTTP.)

@read ex:Rule01inp <Example1.n3>

# -- Proof check --
#
# This proof uses the built-in RDF and RDFS rulesets, 
# which are the RDF- and RDFS- entailment rules described in the RDF
# formal semantics document.
#
# To prove:
#     ex:foo ex:prop "a" .
# RDFS-entails
#     ex:foo ex:prop _:x .
#     _:x rdf:type rdfs:Resource .
#
# If the proof is not valid according to the axioms and rules of the 
# ruleset(s) used and antecedents given, then an error is reported 
# indicating the failed proof step.

ex:Input01 :- { ex:foo ex:prop "a" . }

ex:Result :- { ex:foo ex:prop _:a . _:a rdf:type rdfs:Resource . }

@proof ex:Proof01 ( rs_rdf:rules rs_rdfs:rules )
  @input  ex:Input01
  @step   rs_rdfs:r3 ( rs_rdfs:a10 rs_rdfs:a39 )
          => ex:Step01a :- { rdfs:Literal rdf:type rdfs:Class . }
  @step   rs_rdfs:r8 ( ex:Step01a )
          => ex:Step01b :- { rdfs:Literal rdfs:subClassOf rdfs:Resource . }
  @step   rs_rdfs:r1 ( ex:Input01 )
          => ex:Step01c :- { ex:foo ex:prop _:a . _:a rdf:type rdfs:Literal . }
  @step   rs_rdfs:r9 ( ex:Step01b ex:Step01c )
          => ex:Step01d :- { _:a rdf:type rdfs:Resource . }
  @step   rs_rdf:se  ( ex:Step01c ex:Step01d )   => ex:Result
  @result ex:Result

# -- Restriction based datatype inferencing --
#
# Datatype inferencing based on a general class restriction and
# a predefined relation (per idea noted by Pan and Horrocks).

ex:VehicleRule :-
  { :PassengerVehicle a rdfd:GeneralRestriction ;
      rdfd:onProperties (:totalCapacity :seatedCapacity :standingCapacity) ;
      rdfd:constraint xsd_integer:sum ;
      rdfd:maxCardinality "1"^^xsd:nonNegativeInteger . }

# Define a new ruleset based on a declaration of a constraint class
# and reference to built-in datatype.
# The datatype constraint xsd_integer:sum is part of the definition 
# of datatype xsd:integer that is cited in the constraint ruleset
# declaration.  It relates named properties of a class instance.

@constraints pv:rules :- ( ex:VehicleRule ) | xsd:integer

# Input data for test cases:

ex:Test01Inp :-
  { _:a1 a :PassengerVehicle ;
      :seatedCapacity "30"^^xsd:integer ;
      :standingCapacity "20"^^xsd:integer . }

# Forward chaining test case:

ex:Test01Fwd :- { _:a1 :totalCapacity "50"^^xsd:integer . }

@fwdchain pv:rules :PassengerVehicle ex:Test01Inp => :t1f
@asserteq :t1f ex:Test01Fwd  ; Forward chain test

# Backward chaining test case:
#
# Note that the result of backward chaining is a list of alternatives,
# any one of which is sufficient to derive the given conclusion.

ex:Test01Bwd0 :-
  { _:a1 a :PassengerVehicle .
    _:a1 :totalCapacity "50"^^xsd:integer .
    _:a1 :seatedCapacity "30"^^xsd:integer . }

ex:Test01Bwd1 :-
  { _:a1 a :PassengerVehicle .
    _:a1 :totalCapacity "50"^^xsd:integer .
    _:a1 :standingCapacity "20"^^xsd:integer . }

# Declare list of graphs:

ex:Test01Bwd :- ( ex:Test01Bwd0 ex:Test01Bwd1 )

@bwdchain pv:rules :PassengerVehicle ex:Test01Inp <= :t1b

@asserteq :t1b ex:Test01Bwd  ; Backward chain test

# Can test for graph membership in a list

@assertin ex:Test01Bwd0 :t1b ; Backward chain component test (0)
@assertin ex:Test01Bwd1 :t1b ; Backward chain component test (1)

# -- Merge graphs --
#
# Merging renames bnodes to avoid collisions.

@merge ( ex:Test01Bwd0 ex:Test01Bwd1 ) => ex:Merged

# This form of comparison sets the Swish exit status based on the result.

ex:ExpectedMerged :-
  { _:a1 a :PassengerVehicle .
    _:a1 :totalCapacity "50"^^xsd:integer .
    _:a1 :seatedCapacity "30"^^xsd:integer .
    _:a2 a :PassengerVehicle .
    _:a2 :totalCapacity "50"^^xsd:integer .
    _:a2 :standingCapacity "20"^^xsd:integer . }

@compare ex:Merged ex:ExpectedMerged

# End of example script
]]></artwork>
          <postamble>
            </postamble>
          </figure>

      </section>

    </section>

    <!-- Installation -->
    <section anchor="sect-Installation" title="Software installation">
      <t>The Swish software is distributed as a single ZIP archive.
         Start installation by creating an empty directory for the 
         software, and extracting the content of the ZIP archive into
         that directory.  Select a ZIP option that uses directory 
         information from the archive so that the sub-directory 
         structure is preserved.
      </t>
      <t>The ZIP archive should unpack into two main subdirectories of
         the installation directory:  HaskellRDF contains Swish, 
         RDF-specific software modules and test data.  HaskellUtils 
         contains generic software modules that may be used by other 
         programs.  When compiling or running Haskell programs, this
         directory is assumed to be on the list of directories that
         are searched for library sounce code.
         </t>
      <t>The following sections deal with how get get the software 
         running in different Haskell environments.  The instructions
         relate to MS Windows operating systems, but it should be
         fairly obvious how to adapt the procedures for Unix/Linux 
         systems.
      </t>
      <section anchor="sect-install-req" title="System requirements">
        <t>Swish is written entirely in Haskell, and should work with 
           any Haskell system that supports Haskell 98 together with 
           the extensions noted below.  The software has been tested 
           using Hugs <xref target="ref-hugs"/> (version November 2003), 
           Glasgow Haskell Compiler (GHC) <xref target="ref-ghc"/> 
           (version 6.2) and the interactive version of GHC (GHCi).
        </t>
        <t>The required extensions to standard Haskell-98 are:
           <list style="symbols">
            <t>Multi-parameter classes.</t>
            <t>Hierarchical libraries.</t>
            <t>Control.Monad.Trans and Control.Monad.State libraries,
                as distributed with GHC or Hugs.</t>
          </list>
        </t>
        <t>Some freely available additional Haskell libraries are used, 
           as described later.  For convenience, these are included
           with the Swish software distribution, but are not themselves
           part of the Swish software for licensing purpose.  More details
           are given later.
        </t>
        <t>My development has been performed mostly using Hugs on a 
           1.3GHz PC with 256Mb of memory (more recently, 768Mb).
           For most purposes, this has been more than adequate.  
           Some of the larger test cases, and the more perverse graph 
           comparisons, may take several minutes to run on this platform
           (SwishTest takes about 20 minutes).  In practice, I think 
           the applications are likely to be more demanding than basic
           requirements of Swish itself.
        </t>
        <t>The consolidated test program cannot be compiled using Hugs as
           distributed, but the individual test cases can all be run.
           To run the consolidated test program, Hugs must be re-build
           (from source) with an enlarged code storage area.  
           Such a version, compiled for Win32 platforms, is available at: 
           <eref target="http://www.ninebynine.org/Software/FatHugs.html" />
        </t>

      </section>
      <section anchor="sect-install-files" title="Installation files">
        <t>The Swish software distribution includes the following files,
           where subdirectories are indicated relative to the installation 
           directory:
           <list style="hanging">
            <t hangText="HaskellRDF subdirectory">
               <t>Swish-0.2.1.html, Swish-0.2.1.xml:  
                  this documentation file, and XML source code.
               </t>
               <t>*.hs: 
                  Haskell source files (see software overview above).
               </t>
               <t>*Test.hs: 
                  unit test Haskell source files.
               </t>
               <t>*.ss: 
                  Swish scripting test file(s).
               </t>
               <t>*.bat:
                  MS-Windows command files for building
                  and testing the software using GHC.
               </t>
               <t>*.txt:
                  additional information, including licensing details.
               </t>
            </t>
            <t hangText="HaskellUtils subdirectory">
               <t>*.hs: 
                  Haskell source files (see software overview above).
               </t>
               <t>*Test.hs: 
                  unit test Haskell source files.
               </t>
            </t>
            <t hangText="HaskellRDF/Data subdirectory">
              Contains Notation3 data files used by the 
              SwishTest program.
             </t>
            <t hangText="HaskellRDF/Parsec subdirectory">
              Contains the Parsec library used by Swish.
             </t>
            <t hangText="HaskellRDF/HUnit subdirectory">
              Contains the HUnit library used by Swish test modules.
             </t>
            <t hangText="HaskellRDF/Sort subdirectory">
              Contains the Quicksort library used by Swish.
              (References to this module can be removed, and the
              standard Haskell function List.sort used in place
              of QuickSort.)
             </t>
            <t hangText="HaskellRDF/Dfa subdirectory">
              Contains the Deterministic Finite-state Automoton
              library used by Swish.  (Currently, this is used only
              for checking the syntax of an integer literal.)
              </t>
          </list>
        </t>
      </section>

      <section anchor="sect-install-sys" title="System dependent details">
        <section anchor="sect-install-hugs" title="Installation using Hugs">
          <t>Running the Swish software under Hugs is straightforward.
             The Hugs option -98 must be specified.
          </t>
          <t>Special steps that might help include:
             <list style="symbols">
              <t>Edit the Hugs registry key to include additional
                 directories for the HaskellUtils, Parsec, HUnit, Sort 
                 and Dfa libraries.
                 </t>
              <t>Edit the Hugs registry key to increase the Hugs heap
                 size (Hugs -h option) for some of the test cases.  
                 (Since doing that I've done some code tuning, 
                 which may mean the number below is unnecessarily high.)
                 </t>
              <t>I have applied changes by using RegEdt32 to modify the
                 registry key 
                 HKEY_CURRENT_USER\Software\Haskell\Hugs\Nov 2003\Options
                 or
                 HKEY_CURRENT_USER\Software\Haskell\Hugs\FatHugs-20040105\Options
                 though some of these changes can be applied using the 
                 Hugs :set command.  By saving these changes in the 
                 registry, I can run Hugs directly from my editor,
                 or by activiating a source file in file manager,
                 and have all the right options applied.
                 </t>
              <t>To run a program in Hugs, use the :load command to
                 load the main program module;  if the library paths
                 are set correctly, all other files required will be
                 automatically located and loaded.  When a program is
                 loaded, type evaluate 'main' to execute it.
                 The Swish program itself is an exception to the above:
                 it is not designed to be run from an interactive shell.
                 To achieve the same effect, load SwishTest or SwishMain 
                 into Hugs, and evaluate
                 <figure anchor="fig-hugs-runswish">
                   <preamble/>
                   <artwork>runSwish "command options"</artwork>
                   <postamble/>
                 </figure>
                 noting that the command line must be supplied as a 
                 Haskell string expression (e.g. in double quotes).
               </t>
            </list>
          </t>
          <t>The full settings reported by my Hugs installation are:
             <figure anchor="fig-hugs-options">
              <preamble/>
              <artwork>
Current settings: +fewuiRWXN -stgGl.qQkoOIHT -h5000000 -p"%s> " -r$$ -c40
Search path     : -P.;{Hugs}/libraries;{Hugs}/oldlib;
                      {Hugs}/libraries/win32;
                      {Hugs}/libraries/Parsec;
                      {Hugs}/libraries/Dfa;
                      {Hugs}/libraries/Sort;
                      {Hugs}/libraries/Hunit;
                      ../HaskellUtils
Project Path    :
Source suffixes : -S.hs;.lhs
Editor setting  : -E"C:\\Program Files\\TextPad 4\\TextPad.exe"
Preprocessor    : -F
Compatibility   : Hugs Extensions (-98)
               </artwork>
              <postamble/>
            </figure>
          </t>
        </section>
        <section anchor="sect-install-ghci" title="Installation using GHCi">
          <t>Running the Swish software under GHCi is almost as easy
             as using Hugs.  GHCi command line options used include
             '-fglasgow-exts' and 
             '-i..\HaskellUtils; F:\Haskell\Lib\HUnit; F:\Haskell\Lib\Parsec; F:\Haskell\Lib\Sort; F:\Haskell\Lib\Dfa'
             (adjusted according to the directories containing the library files).
             Working under MS-Windows, 
             I find it convenient to create a desktop shortcut to run GHCi,
             specifying the Swish source directory and other options as
             properties of the shortcut.
          </t>
          <t>To run a program in the GHCi command interpreter, follow
             the same procedure that is described for running a program
             under Hugs.  The GHCi and Hugs command shells are very 
             similar.
          </t>
          <t>There is a GHCi initialization file '.ghci' included with the
             Swish software distribution, which,
             if placed in the appropriate startup directory, is read 
             automatically by GHCi and defines some convenient commands
             for running the non-interactive GHC compiler from within
             the GHCi shell.  This file will need editing to reflect the
             actual directories used for the Swish software.
          </t>
        </section>
        <section anchor="sect-install-ghc" title="Installation using GHC">
          <t>MS-Windows command scripts have been prepared to compile
             and run the Swish software in an MS-Windows command
             window.  It should be straightforward to create Unix
             equivalents using information from these.  
             The relevant files are:
             <list style="symbols">
              <t>MakeSwish.bat, to compile and link all the programs.</t>
              <t>ghcc.bat, a helper file used by MakeSwish.bat to
                  compile and link a single program.</t>
              <t>TestSwish.bat, to run the various test programs.</t>
            </list>
             The file ghcc.bat assumes a standard GHC installation,
             with the GHC compiler on the current search path. 
             It will probably need to be edited to reflect the 
             actual locations of the support libraries used.
          </t>
          <t>Once the programs have been compiled and linked, 
             they can be run in the usual way by using entering the
             program name at a command prompt.  The test programs
             do not expect any command line options and run to completion.
             The program Swish.exe takes command line options as 
             descriped <xref target="sect-swish-cmdline">above</xref>.
          </t>
          <t/>
        </section>
      </section>
      <section anchor="sect-install-test" title="Installation testing">
        <t>A Swish installation under GHC can be tested by running
           the program TestSwishAll.  
           [[[The stand-alone test programs used by the command script 
           TestSwish.bat cannot be built with the current release of GHC]]], 
           and ensuring that all tests complete with zero errors.  
           On a 1.7GHz PC running Windows 2000, the tests take a few 
           minutes to complete.
        </t>
        <t>To test the installation from an interactive shell, the test
           programs need to be loaded and executed individually.  
           Alternatively, the consolidated test program, SwishTestAll,
           can be loaded and run under GHCi, or under Hugs with an
           enlarged code storage area, as noted above.
           To confirm a successful installation, it is probably 
           sufficient to load SwishMain, and evaluate the following 
           expression, which should complete quite quickly 
           (about 30 seconds under Hugs on a 1.3GHz PC):
           </t>

         <figure anchor="fig-runswishscript-cmd">
           <preamble/>
<artwork>
runSwish "-s=SwishScript.ss"
</artwork>
           </figure>

         <figure anchor="fig-runswishscript-out">
           <preamble>
             The output should indicate that two proofs were 
             checked OK:
             </preamble>
<artwork>
Proof satisfied: ex:Proof01
Proof satisfied: ex:Proof02
</artwork>
          </figure>

        <t>For a more complete test, run SwishTest which takes about 
          20 minutes on the same system.
          </t>

        <t>(For comparison, when compiled with GHC to a stand-alone 
          application, SwishTest runs in about 1-2 minutes.  
          This suggests that for serious inference work, Swish should 
          be compiled with GHC.)
          </t>

      </section>

      <section anchor="sect-install-libs" title="Additional libraries used">
        <t>Swish uses some additional libraries that are not part of the
           Swish software, but which are included with the Swish software 
           distribution for the convenience of users.
        </t>
        <t>Please note that these support libraries are distributed under 
           their own licensing terms and conditions, which I have reproduced 
           below where available.  Please contact the respective authors
           for further information.
        </t>
        <section anchor="sect-install-parsec" title="Parsec">
          <t>Parsec <xref target="ref-parsec"/>
             is a monadic parser combinator library for Haskell.
             I found it to be excellently documented and generally easy 
             to use.  It also serves as a useful introduction, 
             to using monads in Haskell.
          </t>
          <section anchor="sect-install-parsec-lic" title="Parsec licence">
            <t>
            Copyright 1999-2000, Daan Leijen. All rights reserved.
            </t>
            <t>
            Redistribution and use in source and binary forms, with or
            without modification, are permitted provided that the following
            conditions are met:
            <list style="symbols">
                <t>Redistributions of source code must retain the above
                 copyright notice, this list of conditions and the
                 following disclaimer.
              </t>
                <t>Redistributions in binary form must reproduce the above
                 copyright notice, this list of conditions and the
                 following disclaimer in the documentation and/or other
                 materials provided with the distribution.
              </t>
              </list>
            </t>
            <t>
            This software is provided by the copyright holders "as is" and
            any express or implied warranties, including, but not limited
            to, the implied warranties of merchantability and fitness for a
            particular purpose are disclaimed. In no event shall the
            copyright holders be liable for any direct, indirect,
            incidental, special, exemplary, or consequential damages (
            including, but not limited to, procurement of substitute goods
            or services; loss of use, data, or profits; or business
            interruption) however caused and on any theory of liability,
            whether in contract, strict liability, or tort (including
            negligence or otherwise) arising in any way out of the use of
            this software, even if advised of the possibility of such
            damage.
            </t>
          </section>
        </section>
        <section anchor="sect-install-quicksort" title="Quicksort">
          <t>Quicksort is part of a collection of sorting functions in
             haskell, published by Ralf Hinze <xref target="ref-sort"/>.
          </t>
          <t>At the time of writing, I can find no claim for copyright 
             or distribution licensing terms.
          </t>
        </section>
        <section anchor="sect-install-hunit" title="HUnit">
          <t>HUnit <xref target="ref-hunit"/>
             is a unit testing framework for Haskell,
             loosely modelled on the JUnit framework that is 
             popular with Java programmers.
          </t>
          <t>Swish application code does not use HUnit, but the test
             programs do make extensive use of it.
          </t>
          <section anchor="sect-install-hunit-lic" title="HUnit licence">
            <t>HUnit is Copyright (c) Dean Herington, 2002, all rights
               reserved, and is distributed as free software under the
               following license.
            </t>
            <t>Redistribution and use in source and binary forms, with or
               without modification, are permitted provided that the
               following conditions are met:
               <list style="symbols">
                <t>Redistributions of source code must retain the above
                    copyright notice, this list of conditions, and the
                    following disclaimer.
                 </t>
                <t>Redistributions in binary form must reproduce the above
                    copyright notice, this list of conditions, and the
                    following disclaimer in the documentation and/or other
                    materials provided with the distribution.
                 </t>
                <t>The names of the copyright holders may not be used to
                    endorse or promote products derived from this software
                    without specific prior written permission.
                 </t>
              </list>
            </t>
            <t>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS"
               AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
               LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
               FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT
               SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT,
               INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
               DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
               SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
               OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
               LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (
               INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
               THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
               OF SUCH DAMAGE.
            </t>
          </section>
        </section>

        <section anchor="sect-install-dfa" title="Dfa">
          <t>DFA is a deterministic finite state automaton based pattern
            matching engine, written by Andrew Bromage and available
            from Sourceforge <xref target="ref-dfa"/>.
            </t>
          <section anchor='sect-install-dfa-lic' title='Dfa licence'>

            <t>DFA is copyright of Andrew Bromage,
              and is distributed as free software under the
              following license:
              <list style="empty">
                <t>Copyright © 2003 Andrew J. Bromage
                  </t>
                <t>This program is free software; you can
                  redistribute it and/or modify it under the terms of
                  the GNU Lesser General Public License as published
                  by the Free Software Foundation; either version 2
                  of the License, or (at your option) any later
                  version.
                  </t>
                <t>This program is distributed in the hope that it
                  will be useful, but WITHOUT ANY WARRANTY; without
                  even the implied warranty of MERCHANTABILITY or
                  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                  Lesser General Public License for more details.
                  </t>
                <t>You should have received a copy of the GNU Lesser
                  General Public License along with this program; if
                  not, write to the Free Software Foundation, Inc.,
                  59 Temple Place, Suite 330, Boston, MA  02111-1307
                  USA
                  </t>
                </list>
              </t>

            <t>A copy of version 2.1 of this licence is included
              in the Swish distribution in file lgpl.txt.
              </t>

          </section>
        </section>
      </section>
    </section>

    <!-- Extending Swish -->
    <section anchor='sec-extending-swish' 
             title='Extending Swish'>

      <t>Swish is designed to be readily extensible in the following 
        ways. For the most part, these extensions involve the addition 
        of new Haskell code, and very small changes to existing code.
        </t>

      <section anchor='sec-add-datatype' 
               title='Adding datatypes'>

        <t>The primary means for extending Swish capabilities is 
          anticipated to be the addition of new datatypes.
          </t>

        <t>A new datatype can be added as a single module, 
          written in Haskell, following the pattern of an 
          existing datatype module.
          </t>

        <t>If only one of the available datatype inference styles 
          is required to be supported, then the other can be left 
          undefined.  If an application attempts to use a datatype 
          inference style that is not defined, 
          a program run-time error will occur.
          </t>

      </section>

      <section anchor='sec-add-ruleset' 
               title='Adding rulesets, axioms and inference rules'>

        <t>A ruleset is a named collection of axioms and inference rules. 
          A ruleset might be built into a Swish-derived program to express 
          some body of  domain knowledge.  
          All built-in rulesets are accessible in the Swish script language
          (this is how the standard RDF and RDFS entailment rules are 
          accessed).
          </t>

      </section>

      <section anchor='sec-add-inference' 
               title='Adding new forms of inference rule'>

        <t>Swish contains two built-in styles of generic inference rule:
          <list style='symbols'>
            <t>simple Horn style rules, with antecedent and consequent 
              expressions, and optional variable binding modifiers or 
              filters.
              </t>
            <t>general class restriction rules, in which specified 
              properties of a class are asserted to be in a specified 
              relation, per <xref target='ref-WebOntDatatypeGroups' />.
              </t>
            </list>
          </t>

        <t>It also contains a small number of specific hand-coded
          inference rules to describe some RDF core semantics:
          <list style='symbols'>
            <t>RDF subgraph entailment (rs_rdf:sub)
              </t>
            <t>RDF simple (instance) entailment (rs_rdf:se)
              </t>
            </list>
          </t>

        <t>It would be entirely possible to write a complete new 
          style of inference rule in Haskell, and expose it to the 
          script processor via a new ruleset.  
          There are, however, some limitations to doing generic 
          inference rule patterns in this way, as the script 
          processor would have to be enhanced to provide a way to 
          instantiate rules based on such a generic pattern.
          </t>

      </section>

      <section anchor='sec-add-commands' 
               title='Adding new script language commands'>

        <t>The script processor has a fairly simple modular structure, 
          with a parser that compiles the script to a higher order monadic 
          function (incorporating the IO monad), and then evaluates that 
          function. 
          Adding new functions would be reasonably easy for an experienced 
          Haskell programmer, but it does require an understanding of the 
          way that Haskell uses monads for managing state and I/O.
          </t>

        <t>A "compiled" script, returned by the script parser, 
          is an instance of the 'SwishStateIO' monad. 
          This is a function that can be executed simply by applying it
          to an initial state value.
          </t>

      </section>

      <section anchor='sec-new-program' 
               title='New program using the existing libraries'>

        <t>For specific applications, it may be most effective to 
          ditch the script processor and simply write a new Haskell 
          main program to perform the required processing. 
          This could be done based on the existing SwishStateIO monad, 
          or by using that as an example to guide the definition of an 
          application-specific monad, and using the existing code as 
          a starting point for the new program. 
          Using the existing code in this way means that the details 
          of command line access and setting up the Haskell I/O 
          environment are mostly taken care of.
          </t>

        <t>The parsing, formatting and inference functions are all 
          defined as pure functions, so there should be no difficulty 
          in taking these and incorporating them into some other 
          Haskell program.
          </t>

        <t>The script parser itself is also a pure function, so it 
          could be used to compile an application-specific script 
          that is embedded within a program, and then to execute 
          that script with an appropriate initial state.
          </t>

      </section>

    </section>

    <!-- Conclusions -->
    <section anchor="sect-Conclusions" 
             title="Conclusions and future work">

      <t>Swish is very much a work-in-progress, and the present
        release is another step along a path with many
        possible options for future developments.
        </t>

      <t>This step in the development of Swish adds some 
        RDF inference tools, including support for 
        datatype-aware deductions.  
        My intent is to revisit my earlier work 
        <xref target="ref-netaccess"/>, and learn how that work may be 
        served by the inference framework that has been introduced.
        Version 0.2.1 introduces a graph partitioning module, which
        provides the basis of a facility in Swish to isolate and 
        display differences between graphs.  
        It is intended that future versions will use this as the 
        basis of smarter Notation 3 and XML output formatting.
        </t>

      <t>The Swish code itself is far from perfect, and there
        is much additional functionality and improvement that
        can be made.
        But it does pass an extensive array of tests, and I believe
        it is quite stable and functional.
        </t>

      <t>The following are some features that I would like to
        see added to Swish:
        <list style='symbols'>
          <t>RDF/XML input and output.
            </t>
          <t>Improved Notation 3 output.
            </t>
          <t>Bring the design fully into line with final RDFCore 
            specifications.
            </t>
          <t>Implement more datatypes.
            </t>
          <t>HTTP input and output (in addition to local file I/O).
            </t>
          <t>Provide for iterated application of rules, to convergence
            (e.g. like the CWM '--think' option 
            <xref target='ref-cwm' />).
            </t>
          <t>Implement automated proof discovery/inference strategies.
            </t>
          <t>Integration with RDF storage systems (e.g. using 
            Haskell FFI, Java interface or some network protocol 
            interface).
            </t>
          <t>Extend script language capabilities.
            </t>
          <t>Focus on a single framework for datatype inference
            (rather than supporting two distinct mechanisms).
            </t>
          <t>Performance improvements (notably: graph representation, 
            LookupMap implementation, backward chaining with datatype 
            restrictions).
            </t>
          <t>Many code style improvements.
            </t>
          <t>API documentation 
            (using Haddock and embedded comments in the code).
            </t>
          </list>
        </t>

      <t>The software distribution contains a file named TODO.TXT,
        which lists in greater detail a number of specific possible 
        enhancements that have been identified to date.
        </t>

    </section>

    <!-- Acknowledgements -->
    <section title="Acknowledgements">
      <t>I would like to thank the following, whose previous work has
         been most helpful to me (though, of course, they bear no
         responsibility for the shortcomings of my work):
         <list style="symbols">
          <t>The Haskell community <xref target="ref-haskell"/> for
            not just one, but at least two, really solid Haskell 
            language implementations, a good range of supporting 
            libraries, and many points of useful advice offered
            though the Haskell mailing list.
            </t>
          <t>Dean Herington for his HUnit testing framework.
            </t>
          <t>Daan Leijen, for his Parsec library.
            </t>
          <t>Andrew Bromage for his DFA module, (which provides a 
            convenient way to validate datatype lexical forms.
            </t>
        </list>
      </t>
      <t>This document has been authored in XML using the format described
         in RFC 2629 <xref target="RFC2629"/>, and converted to HTML using
         the XML2RFC utility developed by Marshall Rose
         (<eref target="http://xml.resource.org/"/>).
      </t>
    </section>
  </middle>
  <!-- End of main document -->

  <!-- Appendices -->
  <back>
    <references>

      <reference anchor="W3C.rdf-syntax" target="http://www.w3.org/TR/rdf-syntax-grammar/">
        <front>
          <title>RDF/XML Syntax Specification (Revised)</title>
          <author initials="D." surname="Beckett" fullname="Dave Beckett">
            <organization>University of Bristol</organization>
          </author>
          <date day="10" month="February" year="2004"/>
        </front>
        <seriesInfo name="W3C Recommendation" value="rdf-syntax-grammar"/>
        <format type="HTML" target="http://www.w3.org/TR/2004/REC-rdf-syntax-grammar-20040210/" />
      </reference>

      <reference anchor="W3C.rdf-schema" target="http://www.w3.org/TR/rdf-schema/">
        <front>
          <title>RDF Vocabulary Description Language 1.0: RDF Schema</title>
          <author initials="D." surname="Brickley" fullname="Dan Brickley">
            <organization>University of Bristol</organization>
          </author>
          <author initials="R.V." surname="Guha" fullname="R.V. Guha">
            <organization>Epinions</organization>
          </author>
          <date day="10" month="February" year="2004"/>
        </front>
        <seriesInfo name="W3C Recommendation" value="rdf-schema"/>
        <format type="HTML" target="http://www.w3.org/TR/2004/REC-rdf-schema-20040210/" />
      </reference>

      <reference anchor="ref-rdf-semantics" target="http://www.w3.org/TR/rdf-mt">
        <front>
          <title>RDF Semantics</title>
          <author initials="P" surname="Hayes" fullname="Patrick Hayes">
              <organization />
          </author>
          <date month="December" day="15" year="2003" />
        </front>
        <seriesInfo name="W3C Recommendation" value="rdf-mt" />
        <format type="HTML" target="http://www.w3.org/TR/2004/REC-rdf-mt-20040210/" />
      </reference>

      <reference anchor="W3C.rdf-concepts" 
                 target="http://www.w3.org/TR/rdf-concepts/">
        <front>
          <title>Resource Description Framework (RDF): Concepts and Abstract Syntax</title>
          <author initials="G" surname="Klyne" fullname="Graham Klyne">
            <organization/>
          </author>
          <author initials="J" surname="Carroll" fullname="Jeremy J. Carroll">
            <organization/>
          </author>
          <date month="December" day="15" year="2003"/>
        </front>
        <seriesInfo name="W3C Recommendation" value="rdf-concepts"/>
        <format type="HTML" target="http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/"/>
      </reference>

      <?rfc include="reference.RFC.2629.xml"?>

      <reference anchor="ref-notation3" target="http://www.w3.org/DesignIssues/Notation3.html">
        <front>
          <title>Notation3: Logic and Rules on RDF</title>
          <author initials="T." surname="Berners-Lee" fullname="Tim Berners-Lee">
            <organization>W3C/MIT</organization>
          </author>
          <date month="" year="1998"/>
        </front>
        <seriesInfo name="Design Issues" 
                    value="Ideas about Web Architecture - yet another notation"/>
      </reference>

      <reference anchor="ref-cwm" target="http://www.w3.org/2000/10/swap/doc/cwm.html">
        <front>
          <title>Cwm (closed world machine)</title>
          <author initials="T." surname="Berners-Lee" fullname="Tim Berners-Lee">
            <organization>W3C</organization>
          </author>
          <date month="September" year="2002"/>
        </front>
      </reference>

      <reference anchor="ref-graphcomp" target="http://www.hpl.hp.com/semweb/publications.htm#Matching%20RDF%20Graphs">
        <front>
          <title abbrev="Matching RDF Graphs">Matching RDF Graphs</title>
          <author initials="J." surname="Carroll" fullname="Jeremy Carroll">
            <organization abbrev="HP">Hewlett Packard Laboratories</organization>
          </author>
          <date day="" month="July" year="2001"/>
        </front>
      </reference>

      <reference anchor='ref-rfc2396bis' target="http://www.apache.org/~fielding/uri/rev-2002/draft-fielding-uri-rfc2396bis-01.html">
        <front>
          <title abbrev='URI Generic Syntax'>Uniform Resource Identifier (URI): Generic Syntax</title>
          <author initials='T.' surname='Berners-Lee' fullname='Tim Berners-Lee'>
            <organization abbrev="MIT/LCS">World Wide Web Consortium</organization>
            <address>
              <postal>
                <street>MIT/LCS, Room NE43-356</street>
                <street>200 Technology Square</street>
                <city>Cambridge</city>
                <region>MA</region>
                <code>02139</code>
                <country>USA</country>
              </postal>
              <phone>+1-617-253-5702</phone>
              <facsimile>+1-617-258-5999</facsimile>
              <email>timbl@w3.org</email>
              <uri>http://www.w3.org/People/Berners-Lee/</uri>
            </address>
          </author>
          <author initials='R.' surname='Fielding' fullname='Roy T. Fielding'>
            <organization abbrev="Day Software">Day Software</organization>
            <address>
              <postal>
                <street>2 Corporate Plaza, Suite 150</street>
                <city>Newport Beach</city>
                <region>CA</region>
                <code>92660</code>
                <country>USA</country>
              </postal>
              <phone>+1-949-999-2523</phone>
              <facsimile>+1-949-644-5064</facsimile>
              <email>roy.fielding@day.com</email>
              <uri>http://www.apache.org/~fielding/</uri>
            </address>
          </author>
          <author initials='L.' surname='Masinter' fullname='Larry Masinter'>
            <organization abbrev="Adobe">Adobe Systems Incorporated</organization>
            <address>
              <postal>
                <street>345 Park Ave</street>
                <city>San Jose</city>
                <region>CA</region>
                <code>95110</code>
                <country>USA</country>
              </postal>
              <phone>+1-408-536-3024</phone>
              <email>LMM@acm.org</email>
              <uri>http://larry.masinter.net/</uri>
            </address>
          </author>
          <date month='May' year='2003'></date>
          </front>
      </reference>

      <reference anchor="ref-rdfcore" target="http://www.w3.org/2001/sw/RDFCore/">
        <front>
          <title abbrev="W3C RDFcore working group">World Wide Web Consortium: RDFcore working group</title>
          <author>
            <organization></organization>
          </author>
          <date day="" month="" year=""/>
        </front>
      </reference>

      <reference anchor="ref-datatypenotes" 
                 target="http://www.ninebynine.org/RDFNotes/RDF-Datatype-inference.html">
        <front>
          <title abbrev="RDF Datatype-aware inference">Using datatype-aware inferences with RDF</title>
          <author initials="G." surname="Klyne" fullname="Graham Klyne">
            <organization abbrev="Nine by Nine">Nine by Nine</organization>
          </author>
          <date day="5" month="November" year="2003"/>
        </front>
      </reference>

      <reference anchor="ref-WebOntDatatypeGroups" 
                 target="http://www.cs.man.ac.uk/~horrocks/Publications/download/2003/PaHo03a.pdf">
        <front>
          <title>Web Ontology Reasoning with Datatype Groups</title>
          <author initials="I." surname="Horrocks" fullname="Ian Horrocks">
            <organization>
              Department of Computer Science, 
              University of Manchester
              </organization>
          </author>
          <author initials="J.Z." surname="Pan" fullname="Jeff Z. Pan">
            <organization>
              Department of Computer Science, 
              University of Manchester
              </organization>
          </author>
          <date month="" year="2003"/>
        </front>
      </reference>

      <reference anchor="ref-haskell" target="http://www.haskell.org/">
        <front>
          <title abbrev="Haskell community web site">Haskell community web site</title>
          <author>
            <organization></organization>
          </author>
          <date day="" month="" year=""/>
        </front>
      </reference>

      <reference anchor="ref-hugs" target="http://www.haskell.org/hugs/">
        <front>
          <title abbrev="Hugs98">Hugs online: Hugs98 web site</title>
          <author>
            <organization></organization>
          </author>
          <date day="" month="" year=""/>
        </front>
      </reference>

      <reference anchor="ref-ghc" target="http://www.haskell.org/ghc/">
        <front>
          <title abbrev="The Glasgow Haskell Compiler">The Glasgow Haskell Compiler (GHC) web site</title>
          <author>
            <organization></organization>
          </author>
          <date day="" month="" year=""/>
        </front>
      </reference>

      <reference anchor="ref-parsec" target="http://www.cs.uu.nl/~daan/parsec.html">
        <front>
          <title abbrev="Parsec">Daan online: Parsec</title>
          <author initials="D." surname="Leijen" fullname="Daan Leijen">
            <organization abbrev="Utrecht University">Utrecht University</organization>
          </author>
          <date day="" month="Oct" year="2001"/>
        </front>
      </reference>

      <reference anchor="ref-hunit" target="http://hunit.sourceforge.net/">
        <front>
          <title abbrev="HUnit">HUnit - Haskell Unit Testing</title>
          <author initials="D." surname="Herington" fullname="Dean Herington">
            <organization/>
          </author>
          <date day="" month="Feb" year="2002"/>
        </front>
      </reference>

      <reference anchor="ref-sort" target="http://www.informatik.uni-bonn.de/~ralf/software.html#sort">
        <front>
          <title abbrev="Sort">A library of sorting routines</title>
          <author initials="R." surname="Ralf" fullname="Ralf Hinze">
            <organization abbrev="Bonn University">Institute of Computer Science, Bonn University</organization>
          </author>
          <date day="" month="Apr" year="2002"/>
        </front>
      </reference>

      <reference anchor="ref-dfa" 
                 target="http://cvs.sourceforge.net/viewcvs.py/haskell-libs/libs/text/">
        <front>
          <title abbrev="DFA">DFA: Deterministic Finite-state Automaton</title>
          <author initials="A." surname="Andrew" fullname="Bromage">
            <organization></organization>
          </author>
          <date day="" month="Oct" year="2003"/>
        </front>
      </reference>

      <reference anchor="ref-whyfp" target="http://www.math.chalmers.se/~rjmh/Papers/whyfp.html">
        <front>
          <title abbrev="Why Functional Programming Matters">Why Functional Programming Matters</title>
          <author initials="J." surname="Hughes" fullname="John Hughes">
            <organization abbrev="Chalmers University">Chalmers University of Technology </organization>
          </author>
          <date day="" month="" year="1984"/>
        </front>
      </reference>

      <reference anchor="ref-thompson" target="http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/">
        <front>
          <title abbrev="The Craft of Functional Programming">Haskell: The Craft of Functional Programming, Second Edition</title>
          <author initials="S." surname="Thompson" fullname="Simon Thompson">
            <organization abbrev="University of Kent">University of Kent</organization>
          </author>
          <date day="" month="" year="1999"/>
        </front>
        <seriesInfo name="Addison-Wesley" value="ISBN 0-201-34275-8"/>
      </reference>

      <reference anchor="ref-netaccess" target="http://www.ninebynine.org/SWAD-E/Scenario-HomeNetwork/HomeNetworkConfig.html">
        <front>
          <title abbrev="Home Network Configuration">Using RDF for Home Network Configuration</title>
          <author initials="G." surname="Klyne" fullname="Graham Klyne">
            <organization abbrev="Nine by Nine">Nine by Nine</organization>
          </author>
          <date day="22" month="December" year="2002"/>
        </front>
      </reference>

      <reference anchor="ref-SWAD-E" target="http://www.w3.org/2001/sw/Europe/">
        <front>
          <title>European Semantic Web Advanced Development</title>
          <author initials="D." surname="Brickley" fullname="Dan Brickley">
            <organization>W3C/ILRT</organization>
          </author>
          <author initials="K." surname="Sharp" fullname="Kate Sharp">
            <organization>ILRT</organization>
          </author>
          <date month="" year="2002"/>
        </front>
      </reference>

      <reference anchor="ref-swad-e-calendaring" target="http://www.w3.org/2001/sw/Europe/reports/dev_workshop_report_2/">
        <front>
          <title>SWAD-Europe: Developer Workshop Report 2 - Semantic Web calendaring</title>
          <author initials="L." surname="Miller" fullname="Libby Miller">
            <organization>ILRT</organization>
          </author>
          <date month="" year="2002"/>
        </front>
      </reference>

<reference anchor="ref-XML2RFC" 
           target="http://xml.resource.org/">
  <front>
    <title>xml2rfc at xml.resource.org</title>
    <author initials="M. T." surname="Rose" fullname="Marshall Rose">
      <organization>Dover Beach Consulting</organization>
    </author>
    <date month="" year=""/>
  </front>
</reference>

<!--
      <reference anchor="refxxxx" target="xxxx">
        <front>
          <title>xxxx</title>
          <author initials="A." surname="BBBB" fullname="CCCC">
            <organization>DDDD</organization>
          </author>
          <date month="mmmm" year="yyyy"/>
        </front>
        <seriesInfo name="seriesname" value="seriesdocid"/>
      </reference>
-->

    </references>

    <section title="Revision history">
      <t>
        <list style="hanging">
          <t hangText="2003-05-30:">
            <list style="symbols">
              <t>Document initially created.
              </t>
            </list>
          </t>
          <t hangText="2003-12-19:">
            <list style="symbols">
              <t>Document updated for Swish 0.2.0.
              </t>
            </list>
          </t>
          <t hangText="2004-02-11:">
            <list style="symbols">
              <t>Document updated for Swish 0.2.1:
              </t>
              <t>Implemented consolidated test program (needs recompiled Hugs).
                All modules compile with GHC 6.2 and Hugs Nov-2003 releases.
              </t>
              <t>Reorganized source code into HaskellRDF and Haskell Utils directories.
              </t>
              <t>Added graph-difference capability.
              </t>
              <t>Updated RDF references to W3C Recommendation of 2004-02-10.
              </t>
            </list>
          </t>
        </list>
      </t>
    </section>

    <section title="Unresolved issues">
    <t>
      <list style="symbols">
        <t>See file TODO.TXT</t>
      </list>
    </t>
    </section>

    <section title="CVS revision log">
      <t>
        <figure anchor="fig-cvs-log">
          <preamble/>
          <artwork>
$Log: swish-0.2.1.xml,v $
Revision 1.4  2004/02/11 17:54:25  graham
Fix some typos.

Revision 1.3  2004/02/11 17:47:07  graham
Refer to TestSwishAll rather then TestSwish.bat.

Revision 1.2  2004/02/11 17:42:04  graham
Re-arrange some artwork text.

Revision 1.1  2004/02/11 17:37:48  graham
Update for Swish 0.2.1

Revision 1.5  2003/12/20 13:24:53  graham
Fix up files to compile and test with GHCi 5.04.3

Revision 1.4  2003/12/20 12:00:14  graham
Introduced new TraceHelpers module for Hugs-2003 compatibility.

Revision 1.3  2003/12/19 21:29:33  graham
Minor edits

Revision 1.2  2003/12/19 16:34:26  graham
Fix up document details

Revision 1.1  2003/12/19 15:50:20  graham
Updated documentation for Swish 0.2

Revision 1.6  2003/06/03 16:17:44  graham
Fix another typo

Revision 1.5  2003/06/03 11:31:13  graham
Fix typos in documentation

Revision 1.4  2003/05/31 00:11:21  graham
Fix various typos and omissions

Revision 1.3  2003/05/30 19:12:57  graham
Fixed some document typos and added RDF semantics reference

Revision 1.2  2003/05/30 18:37:25  graham
First formatted version of Swish documentation

Revision 1.1  2003/05/30 16:41:22  graham
Swish documentation, initial version.

           </artwork>
          <postamble/>
        </figure>
      </t>
    </section>
  </back>
</rfc>
