[isidorus-cvs] r28 - in trunk: docs src src/ajax/javascripts src/json src/model src/rest_interface src/unit_tests

Lukas Giessmann lgiessmann at common-lisp.net
Mon May 4 15:02:45 UTC 2009


Author: lgiessmann
Date: Mon May  4 11:02:44 2009
New Revision: 28

Log:
added the tmcl-json-model to the json-model; added a rest-api for the json-tmcl part, so it is possible to get all tmcl-standard-constraints for a topic as a json-string; added the topicmap example "poems.xtm" with tmcl-constraints to the unit_tests folder.

Added:
   trunk/src/json/json_tmcl.lisp
   trunk/src/json/json_tmcl_constants.lisp
   trunk/src/unit_tests/poems.xtm
Modified:
   trunk/docs/xtm_json.txt
   trunk/src/ajax/javascripts/make_fragment_node.js
   trunk/src/constants.lisp
   trunk/src/isidorus.asd
   trunk/src/model/changes.lisp
   trunk/src/rest_interface/rest-interface.lisp
   trunk/src/rest_interface/set-up-json-interface.lisp

Modified: trunk/docs/xtm_json.txt
==============================================================================
--- trunk/docs/xtm_json.txt	(original)
+++ trunk/docs/xtm_json.txt	Mon May  4 11:02:44 2009
@@ -2,6 +2,7 @@
 //+ Overview:
 //+  *Part 1: XTM - data model
 //+  *Part 2: Object summaries
+//+  *Part 3: TMCL - data model
 //+-----------------------------------------------------------------------------
 
 
@@ -158,7 +159,7 @@
 
 //+-----------------------------------------------------------------------------
 //+ topicSummary
-//+    contains the topic id,subjetcIdentifiers, itemIdentities,
+//+    Contains the topic id,subjetcIdentifiers, itemIdentities,
 //+    subjectLocators, nameSummaries and occurrenceSummaries
 //+-----------------------------------------------------------------------------
 {
@@ -173,229 +174,228 @@
 
 
 
+//+-----------------------------------------------------------------------------
+//+ Part 3: TMCL - data model
+//+   This part explains how the tmcl-rules/suggestions of isidorus are
+//+   sent via HTTP as JSON-data.
+//+-----------------------------------------------------------------------------
+
+
+//+-----------------------------------------------------------------------------
+//+ exclusiveInstances
+//+    This message constains a list of topics represented as a list of topic
+//+    psis which are exclusive instances for the owner.
+//+-----------------------------------------------------------------------------
+[ [ "topic-1-psi-1", "topic-2-psi-2", "..." ], [ "topic-2-psi", "..." ], <...> ]
+
+
+//+-----------------------------------------------------------------------------
+//+ simpleConstraint
+//+    This object contains a regexp member with the regular expression of the
+//+    constraint, a cardMin member with the minimum cardinality of
+//+    the referenced element which is represented as an unsignedInt
+//+    and a cardMax member which describes the maximum cardinality of this
+//+    element, this member contains an unsigendInt or the string
+//+    "MAX_INT".
+//+-----------------------------------------------------------------------------
+{
+  "regexp" : "regular expression",
+  "cardMin" : "unsigned integer in string representation",
+  "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ subjectIdentifierConstraint
+//+    This object contains a regexp member with the regular expression of the
+//+    subjectIdentifier, a cardMin member with the minimum cardinality of
+//+    this subjectIdentifier in a topic which is represented as an unsignedInt
+//+    and a cardMax member which describes the maximum cardinality of this
+//+    subjectIdentifier, this member contains an unsigendInt or the string
+//+    "MAX_INT".
+//+-----------------------------------------------------------------------------
+<simpleConstraint>
+
+
+//+-----------------------------------------------------------------------------
+//+ subjectLocatorConstraint
+//+    This object contains a regexp member with the regular expression of the
+//+    subjectLocator, a cardMin member with the minimum cardinality of
+//+    this subjectLocator in a topic which is represented as an unsignedInt
+//+    and a cardMax member which describes the maximum cardinality of this
+//+    subjectLocator, this member contains an unsigendInt or the string
+//+    "MAX_INT".
+//+-----------------------------------------------------------------------------
+<simepleConstraint>
+
+
+//+-----------------------------------------------------------------------------
+//+ scopeConstraint
+//+    The scopeConstraint-Object contains a list of all available scopes of
+//+    for an association/name/occurrence element - this depends where this
+//+    json-onbject is contained.
+//+    The member availableScopeTypes contains a list of topics in psi-list
+//+    representation which can be used as scope.
+//+    cardMin defines the minimum number of all scopes of the parent element
+//+    (association/name/occurrence).
+//+    cardMax defines the maximum number of all scopes of the parent element.
+//+-----------------------------------------------------------------------------
+{
+  "scopeTypes" : [ [ "topic-1-psi-1", "topic-1-psi-2", "..." ], [ "topic-2-psi-1", "..." ] <...> ],
+  "cardMin" : "unsigned integer in string representation",
+  "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ topicNameConstraint
+//+    The topicNameConstraint describes how the topic's names have to be
+//+    defined.
+//+    The nameType is a topic representation in form of a list of psis of the
+//+    topic representing the name's type.
+//+    regexp defines the content of the name.
+//+    cardMin defines the minimum number of names a topic must have.
+//+    cardMax defines the maximum number of names a topic must have.
+//+    nameTypeScopes describes how many scopes there must exist and of what
+//+    type the scopes have to be .
+//+-----------------------------------------------------------------------------
+{
+  "nameType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "constraints" : [ <simpleConstraint>, < ... > ],
+  "scopeConstraints" : { <scopeConstraint> }
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ uniqueOccurrenceConstraint
+//+    This object owns a regexp member with the regular expression of the
+//+    occurrence which should be unique. So only occurrences that match the
+//+    occurrenceType and the regexp will be checked.
+//+    occurrenceType represents the topictype of the occurrence.
+//+    cardMin describes the minimum number of all matched occurrences within
+//+    all instances of this topictype's instances.
+//+    cardMax describes the maximum number of all matched occurrences within
+//+    all instances of this topictype's instances.
+//+-----------------------------------------------------------------------------
+<simpleConstraint>
 
 
+//+-----------------------------------------------------------------------------
+//+ topicOccurrenceConstraint
+//+    The topicOccurrenceConstraint describes how the topic's occurrences have
+//+    to be defined.
+//+    
+//+-----------------------------------------------------------------------------
+{
+  "occurrenceType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "constraints" : [ <simpleConstraint>, < ... > ],
+  "scopeConstraints" : { <scopeConstraint> },
+  "dataConstraint" : "datatype",
+  "uniqueConstraints" : [ <uniqueOccurrenceConstraint>, <...> ]
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ associationRoleConstraint
+//+    This object defines a list of psis of the roletype topic of which
+//+    the role is an instance of.
+//+    cardMin and cardMax defines the number of roles with the defined roletype
+//+    in an association of a certain associationtype (the objects owner).
+//+-----------------------------------------------------------------------------
+{
+  "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "cardMin" : "unsigned integer in string representation",
+  "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ rolePlayerConstraint
+//+    Defines the player of a certain role with a given type in an association
+//+    with a given type.
+//+    playerType is the psi-list representation of the player-topic.
+//+    roleType is the is a list of topic-psis representing a topic which can
+//+    be a player in the given role.
+//+    cardMin and cardMax defines the number of times the topicType (= player)
+//+    can be the player in a role of a given type (= roleTypes) in an
+//+    association of a given type (= objects owner).
+//+-----------------------------------------------------------------------------
+{
+  "playerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "cardMin" : "unsigned integer in string representation",
+  "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ otherRoleConstraint
+//+    This JSON-Object defines the number and types of (other-) roles in an
+//+    association of a given type with a role of a give type.
+//+    roleType is a allowed role with the player topicType.
+//+    otherRoleType is the second role with the player otherTopicType.
+//+    The values cardMin and cardMax defines the cardinality of otherRoleType.
+//+-----------------------------------------------------------------------------
+{
+  "playerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "roleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "otherRoleType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "otherPlayerType" : [ "topic-psi-1", "topic-psi-2", "..." ],
+  "cardMin" : "unsigned integer in string representation",
+  "cardMax" : "unsigend integer in string representation or the string MAX_INT"
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ associationConstraint
+//+    The associationConstraint describes how an association of a given type
+//+    has to be defined.
+//+    associationRoleTypeConstraint constains all available roletypes for this
+//+    association.
+//+    rolePlayerConstraint constains all players for certain roles of a given
+//+    type.
+//+    associationTypeScopes contains all available scopes for this association.
+//+-----------------------------------------------------------------------------
+{
+  "associationRoleConstraints" : [ <associationRoleConstraint>, <...> ],
+  "rolePlayerConstraints" : [ <rolePlayerConstraints>, <...> ],
+  "otherRoleConstraints" : [ <otherRoleConstraint>, <...> ],
+  "scopeConstraints" : { <scopeConstraint> }
+}
 
 
+//+-----------------------------------------------------------------------------
+//+ topicConstraint
+//+    The topicConstraint contains the members:
+//+    *subjectIdentifierConstraints which defines the subjectIdentifiers
+//+    *subjectLocatorConstraints which defines the subjectLocators
+//+    *topicNameConstraints which defines the topic names
+//+    *topicOccurrenceConstraints which defines the topic occurrences
+//+    *uniqueOccurrenceConstraints which defines the uniqueness of topic
+//+     occurrences
+//+-----------------------------------------------------------------------------
+{
+  "exclusiveInstances" : <exclusiveInstances>,
+  "subjectIdentifierConstraints" : [ <subjectIdentifierConstraint>, <...> ],
+  "subjectLocatorConstraints" : [ <subjectLocatorConstraint>, <...> ],
+  "topicNameConstraints" : [ <topoicNameConstriant>, <...> ],
+  "topicOccurrenceConstraints" : [ <topicOccurrenceConstraint>, <...> ],
+  "abstractConstraint" : <boolean>
+}
+
+
+//+-----------------------------------------------------------------------------
+//+ fragmentConstraint
+//+    This JSON-Object contains all constraints necessary for an entire
+//+    fragment but not the exclusive-instance-constraint.
+//+    The exclusive-instance-constraint should be sent before a
+//+    fragmentConstraint separately.
+//+    topicConstraint contains an object with all constraints of all baseTypes
+//+    of the mainTopic.
+//+    associationConstraints contains a list of all association constraints
+//+    depending on all baseTypes of the main topic.
+//+-----------------------------------------------------------------------------
 {
-  "topic" : {
-              "id"  :  "t403",
-              "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100" ],
-              "subjectLocators" : null,
-              "subjectIdentifiers" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ],
-              "instanceOfs" : [ [ "http : //psi.egovpt.org/types/semanticstandard" ] ],
-              "names" : [ {
-                            "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1" ],
-                            "type" : null,
-                            "scopes" : null,
-                            "value" : "ISO 19115",
-                            "variants" : [ {
-                                             "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1_v1" ],
-                                              "scopes" : [ [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#display" ] ],
-                                              "resourceRef" : null,
-                                              "resourceData" : {
-                                                                 "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
-                                                                 "value" : "Geographic Information - Metadata"
-                                                               }
-                                           },
-                                           {
-                                             "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_n1_v2" ],
-                                             "scopes" : [ [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#sort" ] ],
-                                             "resourceRef" : null,
-                                             "resourceData" : {
-                                                                "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
-                                                                "value" : "ISO-19115"
-                                                              }
-                                           }
-                                         ]
-                          }
-                        ],
-              "occurrences" : [ {
-                                  "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o1" ],
-                                  "type" : [ "http : //psi.egovpt.org/types/standardHasStatus" ],
-                                  "scopes" : null,
-                                  "resourceRef" : "http : //www.budabe.de/","resourceData" : null
-                                },
-                                {
-                                  "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o2" ],
-                                  "type" : [ "http : //psi.egovpt.org/types/description" ],
-                                  "scopes" : null,
-                                  "resourceRef" : null,
-                                  "resourceData" : {
-                                                     "datatype" : "http : //www.w3.org/2001/XMLSchema#string",
-                                                     "value" : "The ISO 19115 standard ..."
-                                                   }
-                                },
-                                {
-                                  "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o3" ],
-                                  "type" : [ "http : //psi.egovpt.org/types/standardValidFromDate" ],
-                                  "scopes" : null,
-                                  "resourceRef" : null,
-                                  "resourceData" : {
-                                                      "datatype" : "http : //www.w3.org/2001/XMLSchema#date",
-                                                      "value" : "2003-01-01"
-                                                   }
-                                },
-                                {
-                                  "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t100_o4" ],
-                                  "type" : [ "http : //psi.egovpt.org/types/links" ],
-                                  "scopes" : null,
-                                  "resourceRef" : "http : //www.editeur.org/standards/ISO19115.pdf",
-                                  "resourceData" : null
-                                }
-                        ]
-            },
-  "topicStubs" : [ {
-		     "id" : "t227",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t3a" ],
-                     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/semanticstandard" ]
-		   },
-		   {
-		     "id" : "t73",
-		     "itemIdentities" : null,
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#display" ]
-		   },
-		   {
-		     "id" : "t67",
-		     "itemIdentities" : null,
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //www.topicmaps.org/xtm/1.0/core.xtm#sort" ]
-		   },
-		   {
-		     "id" : "t291",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t51" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardHasStatus" ]
-		   },
-		   {
-		     "id" : "t307",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t53" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/description" ]
-		   },
-		   {
-		     "id" : "t315",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t54" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardValidFromDate" ]
-		   },
-		   {
-		     "id" : "t323",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t55" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/links" ]
-		   },
-		   {
-		     "id" : "t433",
-		     "itemIdentities" : null,
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/subject/GeoData" ]
-		   },
-		   {
-		     "id" : "t363",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t60" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ]
-		   },
-		   {
-		     "id" : "t371",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t61" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ]
-		   },
-		   {
-		     "id" : "t421",
-		     "itemIdentities" : null,
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/subject/Semantic+Description" ]
-		   },
-		   {
-		     "id" : "t395",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t64" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/serviceUsesStandard" ]
-		   },
-		   {
-		     "id" : "t387",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t63" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/ServiceRoleType" ]
-		   },
-		   {
-		     "id" : "t451",
-		     "itemIdentities" : null,
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/service/Google+Maps",
-					      "http : //maps.google.com" ]
-		   },
-		   {
-		     "id" : "t379",
-		     "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#t62" ],
-		     "subjectLocators" : null,
-		     "subjectIdentifiers" : [ "http : //psi.egovpt.org/types/StandardRoleType" ]
-		   }
-		 ],
-  "associations" : [ {
-		       "itemIdentities" : null,
-		       "type" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ],
-		       "scopes" : null,
-		       "roles" : [ {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
-				   },
-				   {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/subject/GeoData" ]
-				   }
-				 ]
-		     },
-		     {
-		       "itemIdentities" : null,
-		       "type" : [ "http : //psi.egovpt.org/types/standardIsAboutSubject" ],
-		       "scopes" : null,
-		       "roles" : [ {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
-				   },
-				   {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/SubjectRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/subject/Semantic+Description" ]
-				   }
-				  ]
-		     },
-		     {
-		       "itemIdentities" : [ "http : //psi.egovpt.org/itemIdentifiers#assoc_7" ],
-		       "type" : [ "http : //psi.egovpt.org/types/serviceUsesStandard" ],
-		       "scopes" : null,
-		       "roles" : [ {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/ServiceRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/service/Google+Maps",
-						    "http : //maps.google.com" ]
-				   },
-				   {
-				     "itemIdentities" : null,
-				     "type" : [ "http : //psi.egovpt.org/types/StandardRoleType" ],
-				     "topicRef" : [ "http : //psi.egovpt.org/standard/ISO+19115%3A+Geographic+Information+-+Metadata" ]
-				   }
-				  ]
-		     }
-		   ],
-  "tmIds" : [ "test-tm"]
+  "topicConstraints" : <topicConstraint>,
+  "associationsConstraints" : [ <associationConstraint>, <...> ]
 }

Modified: trunk/src/ajax/javascripts/make_fragment_node.js
==============================================================================
--- trunk/src/ajax/javascripts/make_fragment_node.js	(original)
+++ trunk/src/ajax/javascripts/make_fragment_node.js	Mon May  4 11:02:44 2009
@@ -1296,7 +1296,7 @@
     // --- the ajax-request error handler
     function onFailureHandler(xhr)
     {
-	window.alert("Something went wrong ...\n" + xhr.status + ": " + xhr.statusText);
+	
     }
     
     // --- the real ajax request
@@ -1305,6 +1305,6 @@
     var request = new Ajax.Request(requestUrl,
 				   {"method" : "get",
 				    "onSuccess" : onSuccessHandler,
-				    "onFailure" : onFailureHandler
+				    "onFailure" : function(xhr){ window.alert("Something went wrong ...\n" + xhr.status + ": " + xhr.statusText  + "\n" + xhr.responseText); }
 				   });
 }
\ No newline at end of file

Modified: trunk/src/constants.lisp
==============================================================================
--- trunk/src/constants.lisp	(original)
+++ trunk/src/constants.lisp	Mon May  4 11:02:44 2009
@@ -15,6 +15,9 @@
 	   :*isidorus-system*
 	   :*type-instance-psi*
 	   :*type-psi*
+	   :*supertype-subtype-psi*
+	   :*supertype-psi*
+	   :*subtype-psi*
 	   :*xtm2.0-ns*
 	   :*xtm1.0-ns*
 	   :*xtm1.0-xlink*))
@@ -36,4 +39,10 @@
 
 (defparameter *instance-psi* "http://psi.topicmaps.org/iso13250/model/instance")
 
+(defparameter *supertype-subtype-psi* "http://psi.topicmaps.org/iso13250/model/supertype-subtype")
+
+(defparameter *supertype-psi* "http://psi.topicmaps.org/iso13250/model/supertype")
+
+(defparameter *subtype-psi* "http://psi.topicmaps.org/iso13250/model/subtype")
+
 (defparameter *isidorus-system* (asdf:find-system "isidorus"))

Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd	(original)
+++ trunk/src/isidorus.asd	Mon May  4 11:02:44 2009
@@ -127,7 +127,10 @@
 				     "json"))
 	       (:module "json"
 	                :components ((:file "json_exporter")
-				     (:file "json_importer"))
+				     (:file "json_importer")
+				     (:file "json_tmcl_constants")
+				     (:file "json_tmcl"
+					    :depends-on ("json_tmcl_constants" "json_exporter")))
 	                :depends-on ("model" "xml"))
 	       (:module "ajax"
 			:components ((:static-file "isidorus.html")

Added: trunk/src/json/json_tmcl.lisp
==============================================================================
--- (empty file)
+++ trunk/src/json/json_tmcl.lisp	Mon May  4 11:02:44 2009
@@ -0,0 +1,1201 @@
+;;+-----------------------------------------------------------------------------
+;;+  Isidorus
+;;+  (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+;;+
+;;+  Isidorus is freely distributable under the LGPL license.
+;;+  You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+
+(defpackage :json-tmcl
+  (:use :cl :datamodel :constants :json-tmcl-constants)
+  (:export :get-constraints-of-fragment
+	   :topictype-p
+	   :abstract-p))
+
+(in-package :json-tmcl)
+
+
+;; -----------------------------------------------------------------------------
+;; --- all fragment constraints ------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-fragment(topic-psi &key (treat-as 'type))
+  (let ((associationtype (get-item-by-psi *associationtype-psi*))
+	(associationtype-constraint (get-item-by-psi *associationtype-constraint-psi*))
+	(topic
+	 (let ((psi
+		(elephant:get-instance-by-value 'PersistentIdC 'uri topic-psi)))
+	   (when psi
+	     (identified-construct psi)))))
+    (when topic
+      (let ((topic-constraints
+	     (let ((value
+		    (get-constraints-of-topic topic :treat-as treat-as)))
+	       (concatenate 'string "\"topicConstraints\":" value))))
+	(let ((available-associations ;what's with association which have only a associationrole-constraint?
+	       (get-available-associations-of-topic topic :treat-as treat-as)))
+	  (dolist (item available-associations)
+	    (topictype-p item associationtype associationtype-constraint))
+	  (let ((associations-constraints
+		 (concatenate 'string "\"associationsConstraints\":"
+			      (let ((inner-associations-constraints "["))
+				(loop for available-association in available-associations
+				   do (let ((value
+					     (get-constraints-of-association available-association)))
+					(setf inner-associations-constraints
+					      (concatenate 'string inner-associations-constraints value ","))))
+				(if (string= inner-associations-constraints "[")
+				    (setf inner-associations-constraints "null")
+				    (setf inner-associations-constraints
+					  (concatenate 'string (subseq inner-associations-constraints 0 (- (length inner-associations-constraints) 1)) "]")))))))
+	    (let ((json-string
+		   (concatenate 'string
+				"{" topic-constraints "," associations-constraints "}")))
+	      json-string)))))))
+    
+
+;; -----------------------------------------------------------------------------
+;; --- all association constraints ---------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-association (associationtype-topic)
+  "Returns a list of constraints which are describing associations of the 
+   passed associationtype-topic."
+  (let ((constraint-topics
+	 (get-all-constraint-topics-of-association associationtype-topic)))
+    (let ((associationtypescope-constraints
+	   (let ((value (get-typescope-constraints associationtype-topic :what 'association)))
+	     (concatenate 'string "\"scopeConstraints\":" value)))
+	  (associationrole-constraints
+	   (let ((value
+		  (get-associationrole-constraints (getf constraint-topics :associationrole-constraints))))
+	     (concatenate 'string "\"associationRoleConstraints\":" value)))
+	  (roleplayer-constraints
+	   (let ((value
+		  (get-roleplayer-constraints (getf constraint-topics :roleplayer-constraints))))
+	     (concatenate 'string "\"rolePlayerConstraints\":"  value)))
+	  (otherrole-constraints
+	   (let ((value
+		  (get-otherrole-constraints (getf constraint-topics :otherrole-constraints))))
+	     (concatenate 'string "\"otherRoleConstraints\":" value))))
+      (let ((json-string
+	     (concatenate 'string "{" associationrole-constraints "," roleplayer-constraints ","
+			  otherrole-constraints "," associationtypescope-constraints "}")))
+	json-string))))
+
+
+(defun get-otherrole-constraints (constraint-topics)
+  "Returns a list of the form
+   ((::role <topic> :player <topic> :otherrole <topic> :othertopic <topic> :card-min <string> :card-max <string>) <...>)
+   which describes an otherrole constraint for the parent-association of a give type."
+  (let ((applies-to (get-item-by-psi *applies-to-psi*))
+	(constraint-role (get-item-by-psi *constraint-role-psi*))
+	(topictype-role (get-item-by-psi *topictype-role-psi*))
+	(roletype-role (get-item-by-psi *roletype-role-psi*))
+	(othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
+	(otherroletype-role (get-item-by-psi *otherroletype-role-psi*))
+	(roletype (get-item-by-psi *roletype-psi*))
+	(roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+    (let ((otherrole-constraints
+	   (loop for constraint-topic in constraint-topics
+	      append (let ((players nil)
+			   (roletypes nil)
+			   (otherplayers nil)
+			   (otherroletypes nil)
+			   (constraint-list
+			    (get-constraint-topic-values constraint-topic)))
+		       (loop for role in (player-in-roles constraint-topic)
+			  when (and (eq constraint-role (instance-of role))
+				    (eq applies-to (instance-of (parent role))))
+			  do (loop for other-role in (roles (parent role))
+				do (let ((current-player (player other-role))
+					 (current-role (instance-of other-role)))
+				     (cond
+				       ((eq topictype-role current-role)
+					(push current-player players))
+				       ((eq roletype-role current-role)
+					(push current-player roletypes))
+				       ((eq othertopictype-role current-role)
+					(push current-player otherplayers))
+				       ((eq otherroletype-role current-role)
+					(push current-player otherroletypes))))))
+		       (when (and (append players roletypes otherplayers otherroletypes)
+				  (or (not players) (not roletypes) (not otherplayers) (not otherroletypes)))
+			 (error "otherroletype-constraint ~a is not complete:~%players: ~a~%roletypes: ~a~%otherplayers: ~a~%otherroletypes: ~a~%"
+				(uri (first (psis constraint-topic)))
+				(map 'list #'(lambda(x)(uri (first (psis x)))) players)
+				(map 'list #'(lambda(x)(uri (first (psis x)))) roletypes)
+				(map 'list #'(lambda(x)(uri (first (psis x)))) otherplayers)
+				(map 'list #'(lambda(x)(uri (first (psis x)))) otherroletypes)))
+		       (let ((cross-product-1
+			      (loop for player in players
+				 append (loop for roletype in roletypes
+					   collect (list :player player :role roletype))))
+			     (cross-product-2
+			      (loop for otherplayer in otherplayers
+				   append (loop for otherroletype in otherroletypes
+					     collect (list :otherplayer otherplayer :otherrole otherroletype)))))
+			 (let ((cross-product
+				(loop for tupple-1 in cross-product-1
+				     append (loop for tupple-2 in cross-product-2
+					       collect (append tupple-1 tupple-2 (list :constraint constraint-list))))))
+			   cross-product))))))
+      (let ((involved-topic-tupples
+	     (remove-duplicates
+	      (loop for otherrole-constraint in otherrole-constraints
+		 collect (let ((player (getf otherrole-constraint :player))
+			       (role-type (getf otherrole-constraint :role))
+			       (otherplayer (getf otherrole-constraint :otherplayer))
+			       (otherrole-type (getf otherrole-constraint :otherrole)))
+			   (topictype-p player)
+			   (topictype-p role-type roletype roletype-constraint)
+			   (topictype-p otherplayer)
+			   (topictype-p otherrole-type roletype roletype-constraint)
+			   (list :player player
+				 :role role-type
+				 :otherplayer otherplayer
+				 :otherrole otherrole-type)))
+	      :test #'(lambda(x y)
+			(and (eq (getf x :player) (getf y :player))
+			     (eq (getf x :role) (getf y :role))
+			     (eq (getf x :otherplayer) (getf y :otherplayer))
+			     (eq (getf x :otherrole) (getf y :otherrole)))))))
+	(let ((cleaned-otherrole-constraints "["))
+	  (loop for involved-topic-tupple in involved-topic-tupples
+	     do (let ((constraint-lists
+		       (remove-duplicate-constraints
+			(loop for otherrole-constraint in otherrole-constraints
+			   when (and (eq (getf otherrole-constraint :player) (getf involved-topic-tupple :player))
+				     (eq (getf otherrole-constraint :role) (getf involved-topic-tupple :role))
+				     (eq (getf otherrole-constraint :otherplayer) (getf involved-topic-tupple :otherplayer))
+				     (eq (getf otherrole-constraint :otherrole) (getf involved-topic-tupple :otherrole)))
+			   collect (getf otherrole-constraint :constraint)))))
+		  (when (> (length constraint-lists) 1)
+		    (error "found contrary otherrole-constraints:~%player: ~a~%role: ~a~%otherplayer: ~a~%otherrole: ~a~% ~a~%"
+			   (uri (first (psis (getf involved-topic-tupple :player))))
+			   (uri (first (psis (getf involved-topic-tupple :role))))
+			   (uri (first (psis (getf involved-topic-tupple :otherplayer))))
+			   (uri (first (psis (getf involved-topic-tupple :otherrole))))
+			   constraint-lists))
+		  (let ((json-player
+			 (concatenate 'string "\"playerType\":"
+				      (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+			(json-role
+			 (concatenate 'string "\"roleType\":"
+				      (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+			(json-otherplayer
+			 (concatenate 'string "\"otherPlayerType\":"
+				      (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :player))))
+			(json-otherrole
+			 (concatenate 'string "\"otherRoleType\":"
+				      (json-exporter::identifiers-to-json-string (getf involved-topic-tupple :role))))
+			(card-min
+			 (concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
+			(card-max
+			 (concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max))))
+		    (setf cleaned-otherrole-constraints
+			  (concatenate 'string cleaned-otherrole-constraints
+				       "{" json-player "," json-role "," json-otherplayer "," json-otherrole "," card-min "," card-max "},")))))
+	  (if (string= cleaned-otherrole-constraints "[")
+	      (setf cleaned-otherrole-constraints "null")
+	      (setf cleaned-otherrole-constraints 
+		    (concatenate 'string (subseq cleaned-otherrole-constraints 0 (- (length cleaned-otherrole-constraints) 1)) "]")))
+	  cleaned-otherrole-constraints)))))
+
+
+(defun get-roleplayer-constraints (constraint-topics)
+  "Returns a list of the form
+   ((:role <topic> :player <topic> :card-min <string> :card-max <string>) <...>)
+   which describes the cardinality of topctypes used as players in roles of given
+   types in an association of a given type which is also the parent if this list."
+  (let ((applies-to (get-item-by-psi *applies-to-psi*))
+	(constraint-role (get-item-by-psi *constraint-role-psi*))
+	(topictype-role (get-item-by-psI *topictype-role-psi*))
+	(roletype-role (get-item-by-psi *roletype-role-psi*))
+	(roletype (get-item-by-psi *roletype-psi*))
+	(roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+    (let ((roleplayer-constraints
+	   (loop for constraint-topic in constraint-topics
+	      append (let ((constraint-list
+			    (get-constraint-topic-values constraint-topic)))
+		       (let ((players
+			      (loop for role in (player-in-roles constraint-topic)
+				 when (and (eq constraint-role (instance-of role))
+					   (eq applies-to (instance-of (parent role))))
+				 append (loop for other-role in (roles (parent role))
+					   when (eq topictype-role (instance-of other-role))
+					   collect (player other-role))))
+			     (roles
+			      (loop for role in (player-in-roles constraint-topic)
+				 when (and (eq constraint-role (instance-of role))
+					   (eq applies-to (instance-of (parent role))))
+				 append (loop for other-role in (roles (parent role))
+					   when (eq roletype-role (instance-of other-role))
+					   collect (player other-role)))))
+			 (when (or (and players (not roles))
+				   (and roles (not players)))
+			   (error "roleplayer-constraint ~a is not complete:~%players: ~a~%roles: ~a~%"
+				  (uri (first (psis constraint-topic)))
+				  (map 'list #'(lambda(x)(uri (first (psis x)))) players)
+				  (map 'list #'(lambda(x)(uri (first (psis x)))) roles)))
+			 (let ((cross-product
+				(loop for player in players
+				   append (loop for role in roles
+					     collect (list :player player :role role :constraint constraint-list)))))
+			   cross-product))))))
+
+      (let ((role-player-tupples
+	     (remove-duplicates
+	      (loop for roleplayer-constraint in roleplayer-constraints
+		 collect (let ((current-player (getf roleplayer-constraint :player))
+			       (current-role (getf roleplayer-constraint :role)))
+			   (topictype-p current-player)
+			   (topictype-p current-role roletype roletype-constraint)
+			   (list :player current-player
+				 :role current-role)))
+	      :test #'(lambda(x y)
+			(and (eq (getf x :player) (getf y :player))
+			     (eq (getf x :role) (getf y :role)))))))
+			   
+	(let ((cleaned-roleplayer-constraints "["))
+	  (loop for role-player-tupple in role-player-tupples
+	     do (let ((constraint-lists
+		       (remove-duplicate-constraints
+			(loop for roleplayer-constraint in roleplayer-constraints
+			   when (and (eq (getf roleplayer-constraint :player) (getf role-player-tupple :player))
+				     (eq (getf roleplayer-constraint :role) (getf role-player-tupple :role)))
+			   collect (getf roleplayer-constraint :constraint)))))
+		  (when (> (length constraint-lists) 1)
+		    (error "found contrary roleplayer-constraints:~%role: ~a~%player: ~a~% ~a ~%"
+			   (uri (first (psis (getf role-player-tupple :role))))
+			   (uri (first (psis (getf role-player-tupple :player))))
+			   constraint-lists))
+		  (let ((json-player
+			 (concatenate 'string "\"playerType\":"
+				      (json-exporter::identifiers-to-json-string (getf role-player-tupple :player))))
+			(json-role
+			 (concatenate 'string "\"roleType\":"
+				      (json-exporter::identifiers-to-json-string (getf role-player-tupple :role))))
+			(card-min
+			 (concatenate 'string "\"cardMin\":" (getf (first constraint-lists) :card-min)))
+			(card-max
+			 (concatenate 'string "\"cardMax\":" (getf (first constraint-lists) :card-max))))
+		    (setf cleaned-roleplayer-constraints
+			  (concatenate 'string cleaned-roleplayer-constraints
+				       "{" json-player "," json-role "," card-min "," card-max "},")))))
+	  (if (string= cleaned-roleplayer-constraints "[")
+	      (setf cleaned-roleplayer-constraints "null")
+	      (setf cleaned-roleplayer-constraints 
+		    (concatenate 'string (subseq cleaned-roleplayer-constraints 0 (- (length cleaned-roleplayer-constraints) 1)) "]")))
+	  cleaned-roleplayer-constraints)))))
+
+
+(defun get-associationrole-constraints (constraint-topics)
+  "Returns a list of the form
+   ((:associationroletype <topic> :card-min <string> :card-max <string>), <...>)
+   which describes all associationrole-constraints of the passed
+   constraint-topics."
+  (let ((applies-to (get-item-by-psi *applies-to-psi*))
+	(roletype-role (get-item-by-psi *roletype-role-psi*))
+	(constraint-role (get-item-by-psi *constraint-role-psi*))
+	(roletype (get-item-by-psi *roletype-psi*))
+	(roletype-constraint (get-item-by-psi *roletype-constraint-psi*)))
+    (let ((associationrole-constraints
+	   (loop for constraint-topic in constraint-topics
+	      append (let ((constraint-list
+			    (get-constraint-topic-values constraint-topic)))
+		       (loop for role in (player-in-roles constraint-topic)
+			  when (and (eq constraint-role (instance-of role))
+				    (eq applies-to (instance-of (parent role))))
+			  append (loop for other-role in (roles (parent role))
+				    when (eq roletype-role (instance-of other-role))
+				    collect (list :associationroletype (player other-role)
+						  :constraint constraint-list)))))))
+      (let ((associationroletype-topics
+	     (remove-duplicates (map 'list #'(lambda(x)
+					       (let ((associationroletype (getf x :associationroletype)))
+						 (topictype-p associationroletype roletype roletype-constraint)
+						 associationroletype))
+				     associationrole-constraints))))
+	(let ((cleaned-associationrole-constraints "["))
+	  (loop for associationroletype-topic in associationroletype-topics
+	     do (let ((constraint-lists
+			    (remove-duplicate-constraints
+			     (loop for associationrole-constraint in associationrole-constraints
+				when (eq associationroletype-topic (getf associationrole-constraint :associationroletype))
+				collect (getf associationrole-constraint :constraint)))))
+		  (when (> (length constraint-lists) 1)
+		    (error "found contrary associationrole-constraints: ~a ~a~%" (uri (first (psis associationroletype-topic))) constraint-lists))
+		  (setf cleaned-associationrole-constraints
+			(concatenate 'string
+				     cleaned-associationrole-constraints
+				     "{\"roleType\":" (json-exporter::identifiers-to-json-string associationroletype-topic)
+				     ",\"cardMin\":" (getf (first constraint-lists) :card-min)
+				     ",\"cardMax\":" (getf (first constraint-lists) :card-max) "},"))))
+
+	  (if (string= cleaned-associationrole-constraints "[")
+	      (setf cleaned-associationrole-constraints "null")
+	      (setf cleaned-associationrole-constraints 
+		    (concatenate 'string (subseq cleaned-associationrole-constraints 0 (- (length cleaned-associationrole-constraints) 1)) "]")))
+	  cleaned-associationrole-constraints)))))
+
+
+;; -----------------------------------------------------------------------------
+;; --- all topic constraints ---------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraints-of-topic (topic-instance &key(treat-as 'type))
+    "Returns a constraint list with the constraints:
+     subjectidentifier-constraints, subjectlocator-constraints,
+     topicname-constraints, topicoccurrence-constraints and
+     uniqueoccurrence-constraints."
+  (let ((constraint-topics
+	 (get-all-constraint-topics-of-topic topic-instance :treat-as treat-as)))
+    (let ((exclusive-instance-constraints
+	   (let ((value
+		  (get-exclusive-instance-constraints (getf constraint-topics :exclusive-instance-constraints))))
+	     (concatenate 'string "\"exclusiveInstances\":" value)))
+	  (subjectidentifier-constraints
+	   (let ((value
+		  (get-simple-constraints (getf constraint-topics :subjectidentifier-constraints) :error-msg-constraint-name "subjectidentifier")))
+	     (concatenate 'string "\"subjectIdentifierConstraints\":" value)))
+	  (subjectlocator-constraints
+	   (let ((value
+		  (get-simple-constraints (getf constraint-topics :subjectlocator-constraints) :error-msg-constraint-name "subjectlocator")))
+	     (concatenate 'string "\"subjectLocatorConstraints\":" value)))
+	  (topicname-constraints
+	   (let ((value
+		  (get-topicname-constraints (getf constraint-topics :topicname-constraints))))
+	     (concatenate 'string "\"topicNameConstraints\":" value)))
+	  (topicoccurrence-constraints
+	   (let ((value
+		  (get-topicoccurrence-constraints (getf constraint-topics :topicoccurrence-constraints) 
+						   (getf constraint-topics :uniqueoccurrence-constraints))))
+	     (concatenate 'string "\"topicOccurrenceConstraints\":" value)))
+	  (abstract-constraint
+	   (concatenate 'string "\"abstractConstraint\":"
+			(if (getf constraint-topics :abstract-constraint)
+			    "true"
+			    "false"))))
+      (let ((json-string
+	     (concatenate 'string "{" exclusive-instance-constraints "," subjectidentifier-constraints
+			  "," subjectlocator-constraints "," topicname-constraints ","
+			  topicoccurrence-constraints "," abstract-constraint "}")))
+        json-string))))
+
+
+(defun get-exclusive-instance-constraints(exclusive-instances-lists)
+  "Returns a list of psis which represents some topics."
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(topictype-role (get-item-by-psi *topictype-role-psi*)))
+    (let ((topics
+	   (remove-duplicates
+	    (loop for exclusive-instances-list in exclusive-instances-lists
+	       append (let ((owner (getf exclusive-instances-list :owner))
+			    (exclusive-constraints (getf exclusive-instances-list :exclusive-constraints)))
+			(loop for exclusive-constraint in exclusive-constraints
+			   append (loop for role in (player-in-roles exclusive-constraint)
+				     when (and (eq constraint-role (instance-of role))
+					       (eq applies-to (instance-of (parent role))))
+				     append (loop for other-role in (roles (parent role))
+					       when (and (eq topictype-role (instance-of other-role))
+							 (not (eq owner (player other-role))))
+					       collect (player other-role)))))))))
+      (json:encode-json-to-string (map 'list #'(lambda(y)
+						 (map 'list #'uri y))
+				       (map 'list #'psis topics))))))
+
+
+(defun get-simple-constraints(constraint-topics &key (error-msg-constraint-name "uniqueoccurrence"))
+  "Returns a list of the form
+   ((:regexp <string> :card-min <string> :card-max <string>))
+   which contains the subjectidentifier, subjectlocator or
+   unique-occurrence constraints. This depends on the passed
+   constraint-topics."
+  (let ((all-values
+	 (remove-duplicate-constraints
+	  (loop for constraint-topic in constraint-topics
+	     collect (get-constraint-topic-values constraint-topic)))))
+    (let ((contrary-constraints (find-contrary-constraints all-values)))
+      (when contrary-constraints
+	(error "found contrary ~a-constraints: ~a~%" error-msg-constraint-name contrary-constraints)))
+    (simple-constraints-to-json all-values)))
+
+
+(defun simple-constraints-to-json(simple-constraints)
+  "Transforms a list of simple constraint lists of the form
+   ((:regexp <string> :card-min <string> :card-max <string>) <...>)
+   to a valid json list of the form
+   [{\"regexp\":\"expr\",\"cardMin\":\"123\",\"cardMax\":\"456\"}, <...>]."
+  (let ((constraints "["))
+    (loop for constraint in simple-constraints
+       do (let ((constraint (concatenate 'string "{\"regexp\":"
+					 (json:encode-json-to-string (getf constraint :regexp))
+					 ",\"cardMin\":"
+					 (json:encode-json-to-string (getf constraint :card-min))
+					 ",\"cardMax\":"
+					 (json:encode-json-to-string (getf constraint :card-max))
+					 "}")))
+	    (if (string= constraints "[")
+		(setf constraints (concatenate 'string constraints constraint))
+		(setf constraints (concatenate 'string constraints "," constraint)))))
+    (if (string= constraints "[")
+	(setf constraints "null")
+	(setf constraints (concatenate 'string constraints "]")))
+    constraints))
+
+
+(defun get-topicname-constraints(constraint-topics)
+  "Returns all topicname constraints as a list of the following form:
+   ( ( :type <nametype-topic>
+       :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
+                      <...>)
+               :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
+                          <...>))
+         <...>)."
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(nametype-role (get-item-by-psi *nametype-role-psi*))
+	(nametype (get-item-by-psi *nametype-psi*))
+	(nametype-constraint (get-item-by-psi *nametype-constraint-psi*)))
+    (let ((topicname-constraints
+	   (remove-if #'null
+		      (loop for constraint-topic in constraint-topics
+			 append (loop for role in (player-in-roles constraint-topic)
+				   when (and (eq constraint-role (instance-of role))
+					     (eq applies-to (instance-of (parent role))))
+				   append (loop for other-role in (roles (parent role))
+					     when (eq nametype-role (instance-of other-role))
+					     collect (let ((nametype-topic (player other-role))
+							   (constraint-list (get-constraint-topic-values constraint-topic)))
+						       (list :type nametype-topic :constraint constraint-list))))))))
+      
+      (let ((nametype-topics
+	     (remove-duplicates (map 'list #'(lambda(x)
+					       (let ((topicname-type
+						      (getf x :type)))
+						 (topictype-p topicname-type nametype nametype-constraint)
+						 topicname-type))
+				     topicname-constraints))))
+	(let ((cleaned-topicname-constraints "["))
+	  (loop for nametype-topic in nametype-topics
+	     do (let ((constraint-lists
+		       (remove-duplicate-constraints
+			(loop for topicname-constraint in topicname-constraints
+			   when (eq nametype-topic (getf topicname-constraint :type))
+			   collect (getf topicname-constraint :constraint)))))
+		  (let ((contrary-constraints
+			 (find-contrary-constraints constraint-lists)))
+		    (when contrary-constraints
+		      (error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
+		  (let ((typescope-constraints
+			 (let ((current-scopes
+				(get-typescope-constraints nametype-topic :what 'topicname)))
+			   (concatenate 'string "\"scopeConstraints\":" current-scopes)))
+			(json-constraint-lists
+			 (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists)))
+			(type-topic
+			 (concatenate 'string "\"nameType\":"
+				      (json-exporter::identifiers-to-json-string nametype-topic))))
+		    (setf cleaned-topicname-constraints
+			  (concatenate 'string cleaned-topicname-constraints "{" type-topic "," json-constraint-lists "," typescope-constraints "},")))))
+	  (if (string= cleaned-topicname-constraints "[")
+	      (setf cleaned-topicname-constraints "null")
+	      (setf cleaned-topicname-constraints
+		    (concatenate 'string (subseq cleaned-topicname-constraints 0 (- (length cleaned-topicname-constraints) 1)) "]")))
+	  cleaned-topicname-constraints)))))
+
+
+(defun get-topicoccurrence-constraints(constraint-topics unique-constraint-topics)
+  "Returns all topicoccurrence constraints as a list of the following form:
+   ( ( :type <occurrencetype-topic>
+       :constraints ( ( :regexp <string> :card-min <string> :card-max <string>)
+                      <...>)
+       :scopes ( ( :scope <scope-topic> :regexp <string> :card-min <string> :card-max <string>)
+                 <...>)
+       :datatype <string>
+       :uniqe ( ( :regexp <string> :dard-min <string> :card-max <string> ) )
+     <...>)."
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(occurrencetype-role (get-item-by-psi *occurrencetype-role-psi*))
+	(occurrencetype (get-item-by-psi *occurrencetype-psi*))
+	(occurrencetype-constraint (get-item-by-psi *occurrencetype-constraint-psi*)))
+    (let ((topicoccurrence-constraints
+	   (remove-if #'null
+		      (loop for constraint-topic in constraint-topics
+			 append (loop for role in (player-in-roles constraint-topic)
+				   when (and (eq constraint-role (instance-of role))
+					     (eq applies-to (instance-of (parent role))))
+				   append (loop for other-role in (roles (parent role))
+					     when (eq occurrencetype-role (instance-of other-role))
+					     collect (let ((occurrencetype-topic (player other-role))
+							   (constraint-list (get-constraint-topic-values constraint-topic)))
+						       (list :type occurrencetype-topic :constraint constraint-list))))))))
+      (let ((occurrencetype-topics
+	     (remove-duplicates (map 'list #'(lambda(x)
+					       (let ((occurrence-type (getf x :type)))
+						 (topictype-p occurrence-type occurrencetype occurrencetype-constraint)
+						 occurrence-type))
+				     topicoccurrence-constraints))))
+	(let ((cleaned-topicoccurrence-constraints "["))
+	  (loop for occurrencetype-topic in occurrencetype-topics
+	     do (let ((constraint-lists
+		       (remove-duplicate-constraints
+			(loop for topicoccurrence-constraint in topicoccurrence-constraints
+			   when (eq occurrencetype-topic (getf topicoccurrence-constraint :type))
+			   collect (getf topicoccurrence-constraint :constraint)))))
+		  (let ((contrary-constraints
+			 (find-contrary-constraints constraint-lists)))
+		    (when contrary-constraints
+		      (error "found contrary topicname-constraints: ~a~%" contrary-constraints)))
+		  (let ((type-topic
+			 (concatenate 'string "\"occurrenceType\":"
+				      (json-exporter::identifiers-to-json-string occurrencetype-topic)))
+			(typescope-constraints
+			 (let ((current-scopes
+				(get-typescope-constraints occurrencetype-topic :what 'topicoccurrence)))
+			   (concatenate 'string "\"scopeConstraints\":" current-scopes)))
+			(datatype-constraint
+			 (concatenate 'string "\"datatypeConstraint\":"
+				      (get-occurrence-datatype-constraint occurrencetype-topic)))
+			(unique-constraints
+			 (concatenate 'string "\"uniqueConstraints\":"
+				      (get-simple-constraints unique-constraint-topics)))
+			(json-constraint-lists
+			 (concatenate 'string "\"constraints\":" (simple-constraints-to-json constraint-lists))))
+		    (setf cleaned-topicoccurrence-constraints
+			  (concatenate 'string cleaned-topicoccurrence-constraints
+				       "{" type-topic "," json-constraint-lists "," typescope-constraints "," datatype-constraint "," unique-constraints "},")))))
+	  (if (string= cleaned-topicoccurrence-constraints "[")
+	      (setf cleaned-topicoccurrence-constraints "null")
+	      (setf cleaned-topicoccurrence-constraints
+		    (concatenate 'string (subseq cleaned-topicoccurrence-constraints 0 (- (length cleaned-topicoccurrence-constraints) 1)) "]")))
+	  cleaned-topicoccurrence-constraints)))))
+
+
+(defun get-occurrence-datatype-constraint(occurrencetype-topic)
+  "Return a datatype qualifier as a string."
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(occurrencetype-role (get-item-by-psi *occurrencetype-role-psi*))
+	(datatype (get-item-by-psi *datatype-psi*))
+	(occurrencedatatype-constraint (get-item-by-psi *occurrencedatatype-constraint-psi*)))
+    (let ((datatype-constraints
+	   (remove-duplicates
+	    (loop for role in (player-in-roles occurrencetype-topic)
+	       when (and (eq occurrencetype-role (instance-of role))
+			 (eq applies-to (instance-of (parent role))))
+	       append (loop for other-role in (roles (parent role))
+			 when (and (eq constraint-role (instance-of other-role))
+				   (topictype-of-p (player other-role) occurrencedatatype-constraint))
+			 collect (player other-role))))))
+      (let ((datatype-constraint
+	     (remove-duplicates
+	      (map 'list #'(lambda(constraint-topic)
+			     (loop for occurrence in (occurrences constraint-topic)
+				when (and (eq (instance-of occurrence) datatype)
+					  (slot-boundp occurrence 'charvalue))
+				return (charvalue occurrence)))
+		   datatype-constraints))))
+	(when (> (length datatype-constraint) 1)
+	  (error "found contrary occurrence-datatype-constraints: ~a~%" datatype-constraints))
+	(if datatype-constraint
+	    (json:encode-json-to-string (first datatype-constraint))
+	    nil)))))
+
+
+(defun get-typescope-constraints(element-type-topic &key(what 'topicname))
+  "Returns a list of scopes for the element-typetopic which is the type topic of
+   a topicname, a topicoccurrence or an association. To specifiy of what kind
+   of element the scopes should be there is the key-variable what.
+   It can be set to 'topicname, 'topicoccurrence or 'association.
+   The return value is of the form
+   ( :scope <scope-topic>
+     :constraint (:card-min <string> :card-max <string> ))."
+  (let ((element-type-role-and-scope-constraint
+	 (cond
+	   ((eq what 'topicname)
+	    (list (get-item-by-psi *nametype-role-psi*)
+		  (get-item-by-psi *nametypescope-constraint-psi*)))
+	   ((eq what 'topicoccurrence)
+	    (list
+	     (get-item-by-psi *occurrencetype-role-psi*)
+	     (get-item-by-psi *occurrencetypescope-constraint-psi*)))
+	   ((eq what 'association)
+	    (list
+	     (get-item-by-psi *associationtype-role-psi*)
+	     (get-item-by-psi *associationtypescope-constraint-psi*)))))
+	(scopetype-role (get-item-by-psi *scopetype-role-psi*))
+	(constraint-role (get-item-by-psi *constraint-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*)))
+    (when (and (= (length element-type-role-and-scope-constraint) 2)
+	       (first element-type-role-and-scope-constraint)
+	       (second element-type-role-and-scope-constraint))
+      (let ((type-role (first element-type-role-and-scope-constraint))
+	    (typescope-constraint (second element-type-role-and-scope-constraint)))
+	(let ((typescope-constraints
+	       (loop for role in (player-in-roles element-type-topic)
+		  when (and (eq type-role (instance-of role))
+			    (eq applies-to (instance-of (parent role))))
+		  append (loop for other-role in (roles (parent role))
+			    when (and (eq constraint-role (instance-of other-role))
+				      (topictype-of-p (player other-role) typescope-constraint))
+			    collect (let ((scopes nil)
+					  (constraint nil))
+				      (loop for c-role in (player-in-roles (player other-role))
+					 when (and (eq constraint-role (instance-of c-role))
+						   (eq applies-to (instance-of (parent c-role))))
+					 do (progn
+					      (setf constraint (get-constraint-topic-values (player c-role)))
+					      (loop for c-other-role in (roles (parent c-role))
+						 when (eq scopetype-role (instance-of c-other-role))
+						 do (push (player c-other-role) scopes))))
+				      (list :scopes scopes :constraint constraint))))))
+	  (let ((scopetype-groups
+		 (remove-duplicates (map 'list #'(lambda(x)
+						   (let ((scopes (getf x :scopes)))
+						     (when scopes
+						       scopes)))
+					 typescope-constraints)
+				    :test #'(lambda(x y)
+					      (when (and (= (length x) (length y))
+							 (= (length x) (length (intersection x y))))
+						t)))))
+	    (let ((cleaned-typescope-constraints "["))
+	      (loop for scopetype-group in scopetype-groups
+		 do (let ((constraint-lists
+			   (remove-duplicate-constraints
+			    (loop for typescope-constraint in typescope-constraints
+			       when (and (= (length (getf typescope-constraint :scopes))
+					    (length scopetype-group))
+					 (= (length (getf typescope-constraint :scopes))
+					    (length (intersection (getf typescope-constraint :scopes) scopetype-group))))
+			       collect (getf typescope-constraint :constraint)))))
+		      (when (> (length constraint-lists) 1)
+			(error "found contrary scopetype-constraints for ~a: ~a~%"
+			       (map 'list #'(lambda(x)(uri (first (psis x)))) scopetype-group)
+			       constraint-lists))
+		      (let ((card-min (getf (first constraint-lists) :card-min))
+			    (card-max (getf (first constraint-lists) :card-max)))
+			(let ((json-scopes "\"scopeTypes\":["))
+			  (dolist (item scopetype-group)
+			    (let ((json-list (json-exporter::identifiers-to-json-string item)))
+			      (setf json-scopes (concatenate 'string json-scopes json-list ","))))
+			  (setf json-scopes (subseq json-scopes 0 (- (length json-scopes) 1)))
+			  (let ((current-json-string
+				 (concatenate 'string "{" json-scopes "],\"cardMin\":\"" card-min "\",\"cardMax\":\"" card-max "\"}")))
+			    (setf cleaned-typescope-constraints 
+				  (concatenate 'string cleaned-typescope-constraints current-json-string ",")))))))
+	      (if (string= cleaned-typescope-constraints "[")
+		  (setf cleaned-typescope-constraints "null")
+		  (setf cleaned-typescope-constraints 
+			(concatenate 'string (subseq cleaned-typescope-constraints 0 (- (length cleaned-typescope-constraints) 1)) "]")))
+	      cleaned-typescope-constraints)))))))
+    
+
+;; -----------------------------------------------------------------------------
+;; --- some basic helpers ------------------------------------------------------
+;; -----------------------------------------------------------------------------
+(defun get-constraint-topic-values(topic)
+  "Returns all constraint values of the passed topic in the
+   following form (list :regexp regexp :card-min card-min :card-max card-max)"
+  (let ((regexp
+	 (get-constraint-occurrence-value topic))
+	(card-min
+	 (get-constraint-occurrence-value topic :what 'card-min))
+	(card-max
+	 (get-constraint-occurrence-value topic :what 'card-max)))
+    (when (and (string/= "MAX_INT" card-max)
+	       (> (parse-integer card-min) (parse-integer card-max)))
+      (error "card-min (~a) must be < card-max (~a)" card-min card-max))
+    (list :regexp regexp :card-min card-min :card-max card-max)))
+
+
+(defun get-constraint-occurrence-value(topic &key (what 'regexp))
+  "Checks the occurrence-value of a regexp, card-min or card-max
+   constriant-occurrence.
+   If what = 'regexp and the occurrence-value is empty there will be returned
+   the value '.*!'.
+   If what = 'card-min and the occurrence-value is empty there will be returned
+   the value '0'.
+   If what = 'card-max and the occurrence-value is empty there will be returned
+   the value 'MAX_INT'"
+  (let ((occurrence-type
+	 (get-item-by-psi
+	  (cond 
+	    ((eq what 'regexp)
+	     *regexp-psi*)
+	    ((eq what 'card-min)
+	     *card-min-psi*)
+	    ((eq what 'card-max)
+	     *card-max-psi*)
+	    (t
+	     "")))))
+    (when occurrence-type
+      (let ((occurrence-value
+	     (let ((occurrence
+		    (find occurrence-type (occurrences topic) :key #'instance-of)))
+	       (if (and occurrence
+			(slot-boundp occurrence 'charvalue)
+			(> (length  (charvalue occurrence)) 0))
+		   (charvalue occurrence)
+		   (cond
+		     ((eq what 'regexp)
+		      ".*")
+		     ((eq what 'card-min)
+		      "0")
+		     ((eq what 'card-max)
+		      "MAX_INT"))))))
+	(cond
+	  ((eq what 'card-min)
+	   (let ((is-valid
+		  (handler-case (let ((card-min
+				       (parse-integer occurrence-value)))
+				  (when (>= card-min 0)
+				    t))
+		    (condition () nil))))
+	     (unless is-valid
+	       (error "card-min in ~a is \"~a\" but should be >= 0"
+		      (uri (first (psis topic)))
+		      occurrence-value))))
+	  ((eq what 'card-max)
+	   (let ((is-valid
+		  (handler-case (let ((card-max
+				       (parse-integer occurrence-value)))
+				  (when (>= card-max 0)
+				    t))
+		    (condition () (when (string= occurrence-value "MAX_INT")
+				    t)))))
+	     (unless is-valid
+	       (error "card-max in ~a is \"~a\" but should be >= 0 or \"MAX_INT\""
+		      (uri (first (psis topic)))
+		      occurrence-value)))))
+	occurrence-value))))
+	  
+
+(defun find-contrary-constraints(constraint-lists)
+  "Returns a list which contains a list of minimum two contrary constraints
+   or nil if there are no contrary constraints.
+   The list is of the form
+   (list (list :regexp <regexp> :card-min <card-min> :card-max <card-max>) (list ...))."
+  (let ((current-constraint nil))
+    (loop for constraint-list in constraint-lists
+       do (progn
+	    (when (> (length current-constraint) 0)
+	      (return-from find-contrary-constraints current-constraint))
+	    (setf current-constraint (remove-if #'null (map 'list #'(lambda(x)
+								      (contrary-constraint-list x constraint-list))
+							    constraint-lists)))))))
+
+(defun contrary-constraint-list (lst-1 lst-2)
+  "Returns both passed lists when they have the same
+   regular expression but different card-min or card-max values."
+  (when (and (typep lst-1 'list) (typep lst-2 'list)
+	     (= 6 (length lst-1) (length lst-2)))
+    (when (and (string= (getf lst-1 :regexp) (getf lst-2 :regexp))
+	       (or (string/= (getf lst-1 :card-min) (getf lst-2 :card-min))
+		   (string/= (getf lst-1 :card-max) (getf lst-2 :card-max))))
+      (list lst-1 lst-2))))
+  
+
+(defun remove-duplicate-constraints(constraint-lists)
+  "Removes duplicate constraints of the passed constraint list.
+   This list should have the form
+   (list (list :regexp <regexp> :card-min <card-min> :card-max <card-max>) (list ...)).
+   A constraint is defined as equal whan all three value (regexp, card-min and card-max
+   are equal."
+  (remove-duplicates constraint-lists :test #'eql-constraint-list))
+
+
+
+(defun eql-constraint-list (lst-1 lst-2)
+  "Compares two constraint lists of the form (list <string> <string> string>)
+   or (list <topic> <string> <string> <string>."
+  (when (and (typep lst-1 'list) (typep lst-2 'list)
+	     (= 6 (length lst-1) (length lst-2)))
+    (and (string= (getf lst-1 :regexp) (getf lst-2 :regexp))
+	 (string= (getf lst-1 :card-min) (getf lst-2 :card-min))
+	 (string= (getf lst-1 :card-max) (getf lst-2 :card-max)))))
+
+
+;; --- checks if the given topic is a valid topictype --------------------------
+(defun get-direct-types-of-topic(topic-instance)
+  "Returns the direct types of the topic as a list passed to this function.
+   This function only returns the types of the type-instance-relationship -> TMDM 7.2"
+  (let ((type-instance (get-item-by-psi *type-instance-psi*))
+	(instance (get-item-by-psi *instance-psi*))
+	(type (get-item-by-psi *type-psi*)))
+    (let ((topic-types
+	   (loop for role in (player-in-roles topic-instance)
+	      when (eq instance (instance-of role))
+	      collect (loop for other-role in (roles (parent role))
+			 when (and (not (eq role other-role))
+				   (eq type-instance (instance-of (parent role)))
+				   (eq type (instance-of other-role)))
+			 return (player other-role)))))
+      (when topic-types
+	(remove-if #'null topic-types)))))
+
+
+(defun get-direct-supertypes-of-topic(topic-instance)
+  "Returns the direct supertypes of the topic as a list passed to this function.
+   This function only returns the types of the supertype-subtype-relationship -> TMDM 7.3"
+  (let ((supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+	(supertype (get-item-by-psi *supertype-psi*))
+	(subtype (get-item-by-psi *subtype-psi*)))
+    (let ((supertypes
+	   (loop for role in (player-in-roles topic-instance)
+	      when (eq subtype (instance-of role))
+	      append (loop for other-role in (roles (parent role))
+			 when (and (not (eq role other-role))
+				   (eq supertype-subtype (instance-of (parent role)))
+				   (eq supertype (instance-of other-role)))
+			 collect (player other-role)))))
+      (remove-if #'null supertypes))))
+
+
+(defun subtype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*)) (checked-topics nil))
+  "Returns a list of all supertypes of the passed topic if the passed topic
+   is not an instanceOf any other topic but a subtype of some supertypes
+   of topictype or it is the topictype-topic itself."
+  ;(format t "~%~%subtype-p ~a~%" (uri (first (psis topic-instance))))
+  (let ((current-checked-topics (remove-duplicates (append checked-topics (list topic-instance)))))
+
+    (when (eq topictype topic-instance)
+      (return-from subtype-p current-checked-topics))
+
+    (when (get-direct-types-of-topic topic-instance)
+      (return-from subtype-p nil))
+
+    (let ((supertypes-of-this (get-direct-supertypes-of-topic topic-instance)))
+      (when (not supertypes-of-this)
+	(return-from subtype-p nil))
+      (when supertypes-of-this
+	(loop for supertype-of-this in supertypes-of-this
+	   when (not (find supertype-of-this current-checked-topics :test #'eq))
+	   do (let ((further-supertypes (subtype-p topictype supertype-of-this current-checked-topics)))
+		(when (not further-supertypes)
+		  (return-from subtype-p nil))
+
+		(dolist (item further-supertypes)
+		  (pushnew item current-checked-topics))))))
+
+    current-checked-topics))
+    
+
+(defun topictype-p (topic-instance &optional (topictype (get-item-by-psi *topictype-psi*))
+		                             (topictype-constraint (get-item-by-psi *topictype-constraint-psi*))
+		                             (checked-topics nil))
+  "Returns a list of all instanceOf-topics and all Supertypes of this topic
+   if this topic is a valid topic (-type). I.e. the passed topic is the
+   topictype or it is an instanceOf of the topictype or it is a subtype of
+   the topictype. TMDM 7.2 + TMDM 7.3"
+  ;(format t "~%~%topictype-p ~a~%" (uri (first (psis topic-instance))))
+  (let ((current-checked-topics (append checked-topics (list topic-instance)))
+	(akos-of-this (get-direct-supertypes-of-topic topic-instance))
+	(isas-of-this (get-direct-types-of-topic topic-instance)))
+
+    (when (eq topictype topic-instance)
+      (return-from topictype-p current-checked-topics))
+
+    (when (not (union akos-of-this isas-of-this :test #'eq))
+      (when topictype-constraint
+	;(return-from topictype-p nil))
+	(error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+      (return-from topictype-p current-checked-topics))
+
+    (let ((akos-are-topictype nil))
+      (loop for ako-of-this in akos-of-this
+	 when (not (find ako-of-this current-checked-topics))
+	 do (let ((further-topics (topictype-p ako-of-this topictype topictype-constraint)))
+	      (if further-topics
+		  (progn
+		    (dolist (item further-topics)
+		      (pushnew item current-checked-topics))
+		    (pushnew ako-of-this akos-are-topictype))
+		  (when topictype-constraint
+		    ;(return-from topictype-p nil)))))
+		    (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype))))))))
+
+      (when isas-of-this
+	(let ((topictype-topics-of-isas nil))
+	  (loop for isa-of-this in isas-of-this
+	     do (let ((topic-akos (subtype-p isa-of-this topictype)))
+		  (when topic-akos
+		    (pushnew isa-of-this topictype-topics-of-isas)
+		    (pushnew isa-of-this current-checked-topics)
+		    (dolist (item topic-akos)
+		      (pushnew item current-checked-topics)))))
+	  
+	  (when (and (not topictype-topics-of-isas)
+		     (not akos-are-topictype)
+		     topictype-constraint)
+	    ;(return-from topictype-p nil))
+	    (error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))
+	  
+	  (loop for isa-of-this in isas-of-this
+	     when (and (not (find isa-of-this current-checked-topics :test #'eq))
+		       (not (find isa-of-this topictype-topics-of-isas :test #'eq)))
+	     do (let ((further-topic-types (topictype-p isa-of-this topictype topictype-constraint current-checked-topics)))
+		  (if further-topic-types
+		      (dolist (item further-topic-types)
+			(pushnew item current-checked-topics))
+		      (when topictype-constraint
+			;(return-from topictype-p nil))))))))
+			(error "~a is not a valid type for ~a" (uri (first (psis topic-instance))) (uri (first (psis topictype)))))))))))
+    current-checked-topics))
+
+
+(defun topictype-of-p (topic-instance type-instance &optional checked-topics)
+  "Returns a list of all types and supertypes of this topic if this topic is a
+   valid instance-topic of the type-topic called type-instance. TMCL 4.4.2"
+  (let ((current-checked-topics (append checked-topics (list topic-instance)))
+	(topictype (get-item-by-psi *topictype-psi*))
+	(isas-of-this (get-direct-types-of-topic topic-instance))
+	(akos-of-this (get-direct-supertypes-of-topic topic-instance)))
+
+    (when (eq topic-instance topictype)
+      t)
+
+    (when (and (not isas-of-this)
+	       (not akos-of-this))
+      (return-from topictype-of-p nil))
+
+    (loop for isa-of-this in isas-of-this
+       do (let ((found-topics (topictype-p isa-of-this)))
+	    (when (not found-topics)
+	      (return-from topictype-of-p nil))
+	    (dolist (item found-topics)
+	      (pushnew item current-checked-topics))))
+
+    (loop for ako-of-this in akos-of-this
+       when (not (find ako-of-this current-checked-topics :test #'eq))
+       do (let ((found-topics (topictype-of-p ako-of-this type-instance current-checked-topics)))
+	    (when (not found-topics)
+	      (return-from topictype-of-p nil))
+	    (dolist (item found-topics)
+	      (pushnew item current-checked-topics))))
+
+      (when (find type-instance current-checked-topics)
+	current-checked-topics)))
+
+
+;; --- gets all constraint topics ----------------------------------------------
+(defun get-direct-constraint-topics-of-topic (topic-instance)
+  "Returns all constraint topics defined for the passed topic-instance"
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(topictype-role (get-item-by-psi *topictype-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*))
+	(exclusive-instance-constraint (get-item-by-psi *exclusive-instance-psi*))
+	(subjectidentifier-constraint (get-item-by-psi *subjectidentifier-constraint-psi*))
+	(subjectlocator-constraint (get-item-by-psi *subjectlocator-constraint-psi*))
+	(topicname-constraint (get-item-by-psi *topicname-constraint-psi*))
+	(topicoccurrence-constraint (get-item-by-psi *topicoccurrence-constraint-psi*))
+	(uniqueoccurrence-constraint (get-item-by-psi *uniqueoccurrence-constraint-psi*))
+	(roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+	(otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+	(abstract-topictype-constraints nil)
+	(exclusive-instance-constraints nil)
+	(subjectidentifier-constraints nil)
+	(subjectlocator-constraints nil)
+	(topicname-constraints nil)
+	(topicoccurrence-constraints nil)
+	(uniqueoccurrence-constraints nil))
+
+    (loop for role in (player-in-roles topic-instance)
+       when (and (eq topictype-role (instance-of role))
+		 (eq applies-to (instance-of (parent role))))
+       do (loop for other-role in (roles (parent role))
+	     when (eq constraint-role (instance-of other-role))
+	     do (let ((constraint-topic (player other-role)))
+		  (cond
+		    ((topictype-of-p constraint-topic abstract-topictype-constraint)
+		     (pushnew constraint-topic abstract-topictype-constraints))
+		    ((topictype-of-p constraint-topic exclusive-instance-constraint)
+		     (pushnew constraint-topic exclusive-instance-constraints))
+		    ((topictype-of-p constraint-topic subjectidentifier-constraint)
+		     (pushnew constraint-topic subjectidentifier-constraints))
+		    ((topictype-of-p constraint-topic subjectlocator-constraint)
+		     (pushnew constraint-topic subjectlocator-constraints))
+		    ((topictype-of-p constraint-topic topicname-constraint)
+		     (pushnew constraint-topic topicname-constraints))
+		    ((topictype-of-p constraint-topic topicoccurrence-constraint)
+		     (pushnew constraint-topic topicoccurrence-constraints))
+		    ((topictype-of-p constraint-topic uniqueoccurrence-constraint)
+		     (pushnew constraint-topic uniqueoccurrence-constraints))
+		    (t
+		     (unless (or (topictype-of-p constraint-topic roleplayer-constraint)
+				 (topictype-of-p constraint-topic otherrole-constraint))
+		      (error "Constraint-Topic \"~a\" could not be handled" (uri (first (psis constraint-topic))))))))))
+    (list :abstract-topictype-constraints abstract-topictype-constraints
+	  :exclusive-instance-constraints (list :exclusive-constraints exclusive-instance-constraints
+						:owner topic-instance)
+	  :subjectidentifier-constraints subjectidentifier-constraints
+	  :subjectlocator-constraints subjectlocator-constraints
+	  :topicname-constraints topicname-constraints
+	  :topicoccurrence-constraints topicoccurrence-constraints
+	  :uniqueoccurrence-constraints uniqueoccurrence-constraints)))
+
+
+(defmethod get-all-constraint-topics-of-topic (topic-instance &key (treat-as 'type))
+  "Returns a list of constraint-topics of the topics-instance's base type(s).
+   If topic c is instanceOf a and b, there will be returned all
+   constraint-topics of the topic types a and b.
+   If treat-as is set to instance there will be only the constraints collected
+   defined for the supertypes or the types of the passed topic - all constraints
+   defined directly for the passed topic are ignored, unless the passed topic is
+   an instance of itself."
+  (let ((akos-and-isas-of-this
+	 (remove-duplicates
+	  (if (eql treat-as 'type)
+	      (topictype-p topic-instance)
+	      (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance))
+		   append (topictype-p topic))))))
+    (let ((all-abstract-topictype-constraints nil)
+	  (all-exclusive-instance-constraints nil)
+	  (all-subjectidentifier-constraints nil)
+	  (all-subjectlocator-constraints nil)
+	  (all-topicname-constraints nil)
+	  (all-topicoccurrence-constraints nil)
+	  (all-uniqueoccurrence-constraints nil))
+      (loop for topic in akos-and-isas-of-this
+	 do (let ((constraint-topics-of-topic (get-direct-constraint-topics-of-topic topic)))
+	      (when (eq topic topic-instance)
+		(dolist (item (getf constraint-topics-of-topic :abstract-topictype-constraints))
+		  (pushnew item all-abstract-topictype-constraints)))
+	      (let ((exclusive-instance-constraints
+		     (getf constraint-topics-of-topic :exclusive-instance-constraints)))
+		(when (getf exclusive-instance-constraints :exclusive-constraints)
+		  (push exclusive-instance-constraints all-exclusive-instance-constraints)))
+	      (dolist (item (getf constraint-topics-of-topic :subjectidentifier-constraints))
+		(pushnew item all-subjectidentifier-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :subjectlocator-constraints))
+		(pushnew item all-subjectlocator-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :topicname-constraints))
+		(pushnew item all-topicname-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :topicoccurrence-constraints))
+		(pushnew item all-topicoccurrence-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :uniqueoccurrence-constraints))
+		(pushnew item all-uniqueoccurrence-constraints))))
+      (list :abstract-topictype-constraints all-abstract-topictype-constraints
+	    :exclusive-instance-constraints all-exclusive-instance-constraints
+	    :subjectidentifier-constraints all-subjectidentifier-constraints
+	    :subjectlocator-constraints all-subjectlocator-constraints
+	    :topicname-constraints all-topicname-constraints
+	    :topicoccurrence-constraints all-topicoccurrence-constraints
+	    :uniqueoccurrence-constraints all-uniqueoccurrence-constraints))))
+
+
+(defun abstract-p (topic-instance)
+  "Returns t if this topic type is an abstract topic type."
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(topictype-role (get-item-by-psi *topictype-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(abstract-topictype-constraint (get-item-by-psi *abstract-topictype-constraint-psi*)))
+
+    (loop for role in (player-in-roles topic-instance)
+       when (and (eq topictype-role (instance-of role))
+		 (eq applies-to (instance-of (parent role))))
+       return (loop for other-role in (roles (parent role))
+		 when (and (eq constraint-role (instance-of other-role))
+			   (eq abstract-topictype-constraint (player other-role)))
+		 return t))))
+
+
+(defun get-direct-constraint-topics-of-association(associationtype-topic)
+  "Returns all direct constraint topics defined for associations if
+   the passed associationtype-topic"
+  (let ((constraint-role (get-item-by-psi *constraint-role-psi*))
+	(associationtype-role (get-item-by-psi *associationtype-role-psi*))
+	(applies-to (get-item-by-psi *applies-to-psi*))
+	(associationtypescope-constraint (get-item-by-psi *associationtypescope-constraint-psi*))
+	(associationrole-constraint (get-item-by-psi *associationrole-constraint-psi*))
+	(roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+	(otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+	(associationrole-constraints nil)
+	(roleplayer-constraints nil)
+	(otherrole-constraints nil))
+
+    (loop for role in (player-in-roles associationtype-topic)
+       when (and (eq associationtype-role (instance-of role))
+		 (eq applies-to (instance-of (parent role))))
+       do (loop for other-role in (roles (parent role))
+	     when (eq constraint-role (instance-of other-role))
+	     do (let ((constraint-topic (player other-role)))
+		  (cond
+		    ((topictype-of-p constraint-topic associationtypescope-constraint)
+		     t) ;do nothing
+		    ((topictype-of-p constraint-topic associationrole-constraint)
+		     (pushnew constraint-topic associationrole-constraints))
+		    ((topictype-of-p constraint-topic roleplayer-constraint)
+		     (pushnew constraint-topic roleplayer-constraints))
+		    ((topictype-of-p constraint-topic otherrole-constraint)
+		     (pushnew constraint-topic otherrole-constraints))
+		    (t
+		     (error "Constraint-Topic \"~a\" could not be handled" (uri (first (psis constraint-topic)))))))))
+
+    (list :associationrole-constraints associationrole-constraints
+	  :roleplayer-constraints roleplayer-constraints
+	  :otherrole-constraints otherrole-constraints)))
+
+
+(defun get-all-constraint-topics-of-association(associationtype-topic)
+  "Returns all constraint topics defined for associations if
+   the passed associationtype-topic."
+  (let ((akos-and-isas-of-this
+	 (topictype-p associationtype-topic (get-item-by-psi *associationtype-psi*) (get-item-by-psi *associationtype-constraint-psi*))))
+    (let ((all-associationrole-constraints nil)
+	  (all-roleplayer-constraints nil)
+	  (all-otherrole-constraints nil))
+      (loop for topic in akos-and-isas-of-this
+	 do (let ((constraint-topics-of-topic
+		   (get-direct-constraint-topics-of-association topic)))
+	      (dolist (item (getf constraint-topics-of-topic :associationrole-constraints))
+		(pushnew item all-associationrole-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :roleplayer-constraints))
+		(pushnew item all-roleplayer-constraints))
+	      (dolist (item (getf constraint-topics-of-topic :otherrole-constraints))
+		(pushnew item all-otherrole-constraints))))
+      (list :associationrole-constraints all-associationrole-constraints
+	    :roleplayer-constraints all-roleplayer-constraints
+	    :otherrole-constraints all-otherrole-constraints))))
+
+
+(defun get-available-associations-of-topic(topic-instance &key (treat-as 'type))
+  "Returns a list of topics decribing the available associationtype for the
+   passed topic."
+  (let ((applies-to (get-item-by-psi *applies-to-psi*))
+	(topictype-role (get-item-by-psi *topictype-role-psi*))
+	(constraint-role (get-item-by-psi *constraint-role-psi*))
+	(othertopictype-role (get-item-by-psi *othertopictype-role-psi*))
+	(associationtype-role (get-item-by-psi *associationtype-role-psi*))
+	(roleplayer-constraint (get-item-by-psi *roleplayer-constraint-psi*))
+	(otherrole-constraint (get-item-by-psi *otherrole-constraint-psi*))
+	(all-possible-player-topics	 
+	 (remove-duplicates
+	  (if (eql treat-as 'type)
+	      (topictype-p topic-instance)
+	      (loop for topic in (union (get-direct-types-of-topic topic-instance) (get-direct-supertypes-of-topic topic-instance))
+		 append (topictype-p topic))))))
+    
+
+    ;what's with associationrole-constraints without a player-constraint???
+    (let ((all-available-associationtypes
+	   (remove-duplicates
+	    (loop for possible-player-topic in all-possible-player-topics
+	       append (loop for role in (player-in-roles possible-player-topic)
+			 when (and (or (eq topictype-role (instance-of role))
+				       (eq othertopictype-role (instance-of role)))
+				   (eq applies-to (instance-of (parent role))))
+			 append (loop for other-role in (roles (parent role))
+				   when (and (eq constraint-role (instance-of other-role))
+					     (or (topictype-of-p (player other-role) roleplayer-constraint)
+						 (topictype-of-p (player other-role) otherrole-constraint)))
+				   append (loop for c-role in (player-in-roles (player other-role))
+					     when (and (eq constraint-role (instance-of c-role))
+						       (eq applies-to (instance-of (parent c-role))))
+					     append (loop for type-role in (roles (parent c-role))
+						       when (eq associationtype-role (instance-of type-role))
+						       collect (player type-role)))))))))
+      all-available-associationtypes)))
\ No newline at end of file

Added: trunk/src/json/json_tmcl_constants.lisp
==============================================================================
--- (empty file)
+++ trunk/src/json/json_tmcl_constants.lisp	Mon May  4 11:02:44 2009
@@ -0,0 +1,92 @@
+;;+-----------------------------------------------------------------------------
+;;+  Isidorus
+;;+  (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
+;;+
+;;+  Isidorus is freely distributable under the LGPL license.
+;;+  You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+
+(defpackage :json-tmcl-constants
+  (:use :cl)
+  (:export :*topictype-psi*
+	   :*topictype-constraint-psi*
+	   :*associationtype-psi*
+	   :*associationtype-constraint-psi*
+	   :*roletype-psi*
+	   :*roletype-constraint-psi*
+	   :*occurrencetype-psi*
+	   :*occurrencetype-constraint-psi*
+	   :*nametype-psi*
+	   :*nametype-constraint-psi*
+	   :*scopetype-psi*
+	   :*topictype-role-psi*
+	   :*applies-to-psi*
+	   :*constraint-role-psi*
+	   :*regexp-psi*
+	   :*card-min-psi*
+	   :*card-max-psi*
+	   :*datatype-psi*
+	   :*subjectidentifier-constraint-psi*
+	   :*subjectlocator-constraint-psi*
+	   :*abstract-topictype-constraint-psi*
+	   :*exclusive-instance-psi*
+	   :*topicname-constraint-psi*
+	   :*topicoccurrence-constraint-psi*
+	   :*occurrencedatatype-constraint-psi*
+	   :*uniqueoccurrence-constraint-psi*
+	   :*roleplayer-constraint-psi*
+	   :*otherrole-constraint-psi*
+	   :*nametype-role-psi*
+	   :*scopetype-role-psi*
+	   :*occurrencetype-role-psi*
+	   :*othertopictype-role-psi*
+	   :*otherroletype-role-psi*
+	   :*associationtype-role-psi*
+	   :*nametypescope-constraint-psi*
+	   :*occurrencetypescope-constraint-psi*
+	   :*associationtypescope-constraint-psi*
+	   :*associationrole-constraint-psi*
+	   :*roletype-role-psi*))
+
+(in-package :json-tmcl-constants)
+
+(defparameter *topictype-psi* "http://psi.topicmaps.org/tmcl/topic-type")
+(defparameter *topictype-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-type-constraint")
+(defparameter *associationtype-psi* "http://psi.topicmaps.org/tmcl/association-type")
+(defparameter *associationtype-constraint-psi* "http://psi.topicmaps.org/tmcl/association-type-constraint")
+(defparameter *roletype-psi* "http://psi.topicmaps.org/tmcl/role-type")
+(defparameter *roletype-constraint-psi* "http://psi.topicmaps.org/tmcl/role-type-constraint")
+(defparameter *occurrencetype-psi* "http://psi.topicmaps.org/tmcl/occurrence-type")
+(defparameter *occurrencetype-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-constraint")
+(defparameter *nametype-psi* "http://psi.topicmaps.org/tmcl/name-type")
+(defparameter *nametype-constraint-psi* "http://psi.topicmaps.org/tmcl/name-type-constraint")
+(defparameter *scopetype-psi* "http://psi.topicmaps.org/tmcl/scope-type")
+(defparameter *topictype-role-psi* "http://psi.topicmaps.org/tmcl/topic-type-role")
+(defparameter *applies-to-psi* "http://psi.topicmaps.org/tmcl/applies-to")
+(defparameter *constraint-role-psi* "http://psi.topicmaps.org/tmcl/constraint-role")
+(defparameter *regexp-psi* "http://psi.topicmaps.org/tmcl/reg-exp")
+(defparameter *card-min-psi* "http://psi.topicmaps.org/tmcl/card-min")
+(defparameter *card-max-psi* "http://psi.topicmaps.org/tmcl/card-max")
+(defparameter *datatype-psi* "http://psi.topicmaps.org/tmcl/datatype")
+(defparameter *subjectidentifier-constraint-psi* "http://psi.topicmaps.org/tmcl/subject-identifier-constraint")
+(defparameter *subjectlocator-constraint-psi* "http://psi.topicmaps.org/tmcl/subject-locator-constraint")
+(defparameter *abstract-topictype-constraint-psi* "http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint")
+(defparameter *exclusive-instance-psi* "http://psi.topicmaps.org/tmcl/exclusive-instance")
+(defparameter *topicname-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-name-constraint")
+(defparameter *topicoccurrence-constraint-psi* "http://psi.topicmaps.org/tmcl/topic-occurrence-constraint")
+(defparameter *occurrencedatatype-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint")
+(defparameter *uniqueoccurrence-constraint-psi* "http://psi.topicmaps.org/tmcl/unique-occurrence-constraint")
+(defparameter *roleplayer-constraint-psi* "http://psi.topicmaps.org/tmcl/role-player-constraint")
+(defparameter *otherrole-constraint-psi* "http://psi.topicmaps.org/tmcl/other-role-constraint")
+(defparameter *nametypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/name-type-scope-constraint")
+(defparameter *occurrencetypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint")
+(defparameter *associationtypescope-constraint-psi* "http://psi.topicmaps.org/tmcl/association-type-scope-constraint")
+(defparameter *nametype-role-psi* "http://psi.topicmaps.org/tmcl/name-type-role")
+(defparameter *scopetype-role-psi* "http://psi.topicmaps.org/tmcl/scope-type-role")
+(defparameter *occurrencetype-role-psi* "http://psi.topicmaps.org/tmcl/occurrence-type-role")
+(defparameter *othertopictype-role-psi* "http://psi.topicmaps.org/tmcl/other-topic-type-role")
+(defparameter *otherroletype-role-psi* "http://psi.topicmaps.org/tmcl/other-role-type-role")
+(defparameter *associationtype-role-psi* "http://psi.topicmaps.org/tmcl/association-type-role")
+(defparameter *associationrole-constraint-psi* "http://psi.topicmaps.org/tmcl/association-role-constraint")
+(defparameter *roletype-role-psi* "http://psi.topicmaps.org/tmcl/role-type-role")
\ No newline at end of file

Modified: trunk/src/model/changes.lisp
==============================================================================
--- trunk/src/model/changes.lisp	(original)
+++ trunk/src/model/changes.lisp	Mon May  4 11:02:44 2009
@@ -286,4 +286,13 @@
                    (elephant:get-instances-by-value 'FragmentC 'topic topic)))
               ;; maybe there are more fragments of this topic in different revisions,
               ;; so we need to search the fragment with a certain revision
-              (first (sort fragments #'> :key 'revision)))))))))
\ No newline at end of file
+              (let ((found-fragment 
+		     (if fragments
+			 (first (sort fragments #'> :key 'revision))
+			 ;; if there exist a topic but always no fragment, there will be generated a new fragment of the latest version for the searched topic
+			 (make-instance 'FragmentC
+					:revision (first (sort (versions topic) #'> :key 'start-revision))
+					:associations (find-associations-for-topic topic)
+					:referenced-topics (find-referenced-topics topic)
+					:topic topic))))
+		found-fragment))))))))
\ No newline at end of file

Modified: trunk/src/rest_interface/rest-interface.lisp
==============================================================================
--- trunk/src/rest_interface/rest-interface.lisp	(original)
+++ trunk/src/rest_interface/rest-interface.lisp	Mon May  4 11:02:44 2009
@@ -28,7 +28,11 @@
 	   :*json-get-prefix*
 	   :*json-commit-url*
 	   :*json-get-all-psis*
-	   :*json-get-summary-prefix**
+	   :*json-get-summary-prefix*
+	   :*json-get-all-type-psis*
+	   :*json-get-topic-stub-prefix*
+	   :*json-get-type-tmcl-prefix*
+	   :*json-get-instance-tmcl-prefix*
 	   :*ajax-user-interface-url*
 	   :*ajax-user-interface-file-path*
 	   :*ajax-javascript-directory-path*
@@ -110,11 +114,13 @@
 
 
 
-(defvar *acceptor*)
+(defvar *server-acceptor* nil)
 
 (defun start-tm-engine (repository-path &key (conffile "atom/conf.lisp") (host-name "localhost") (port 8000))
   "Start the Topic Map Engine on a given port, assuming a given
-hostname. Use the repository under repository-path"
+   hostname. Use the repository under repository-path"
+  (when *server-acceptor*
+    (error "Ther server is already running"))
   (setf hunchentoot:*show-lisp-errors-p* t) ;for now
   ;(setf hunchentoot:*show-lisp-backtraces-p* t) ;hunchentoot 0.15.7
   (setf hunchentoot:*hunchentoot-default-external-format* 
@@ -125,12 +131,13 @@
   (load conffile)
   (publish-feed atom:*tm-feed*)
   (set-up-json-interface)
-  (setf *acceptor* (make-instance 'hunchentoot:acceptor :address host-name :port port))
+  (setf *server-acceptor* (make-instance 'hunchentoot:acceptor :address host-name :port port))
   (setf hunchentoot:*lisp-errors-log-level* :info)
   (setf hunchentoot:*message-log-pathname* "./hunchentoot-errors.log")
-  (hunchentoot:start *acceptor*))
+  (hunchentoot:start *server-acceptor*))
 
 (defun shutdown-tm-engine ()
   "Shut down the Topic Map Engine"
-  (hunchentoot:stop *acceptor*)
+  (hunchentoot:stop *server-acceptor*)
+  (setf *server-acceptor* nil)
   (elephant:close-store))
\ No newline at end of file

Modified: trunk/src/rest_interface/set-up-json-interface.lisp
==============================================================================
--- trunk/src/rest_interface/set-up-json-interface.lisp	(original)
+++ trunk/src/rest_interface/set-up-json-interface.lisp	Mon May  4 11:02:44 2009
@@ -13,6 +13,10 @@
 (defparameter *json-commit-url* "/json/commit/?$") ;the url to commit a json fragment by "put" or "post"
 (defparameter *json-get-all-psis* "/json/psis/?$") ;the url to get all topic psis of isidorus -> localhost:8000/json/psis
 (defparameter *json-get-summary-url* "/json/summary/?$") ;the url to get a summary od all topic stored in isidorus; you have to set the GET-parameter "start" for the start index of all topics within elephant and the GET-paramter "end" for the last index of the topic sequence -> http://localhost:8000/json/summary/?start=12&end=13
+(defparameter *json-get-all-type-psis* "/json/tmcl/types/?$") ;returns a list of all psis that can be a type
+(defparameter *json-get-topic-stub-prefix* "/json/tmcl/topicstubs/(.+)$") ;the json prefix for getting some topic stub information of a topic and its "derived" topics
+(defparameter *json-get-type-tmcl-prefix* "/json/tmcl/type/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as a type
+(defparameter *json-get-instance-tmcl-prefix* "/json/tmcl/instance/(.+)$") ;the json prefix for getting some tmcl information of a topic treated as an instance
 (defparameter *ajax-user-interface-url* "/isidorus/?$") ;the url to the user interface; if you want to get all topics set start=0&end=nil -> localhost:8000/isidorus
 (defparameter *ajax-user-interface-css-prefix* "/css") ;the url to the css files of the user interface
 (defparameter *ajax-user-interface-css-directory-path* "ajax/css") ;the directory contains the css files
@@ -20,11 +24,14 @@
 (defparameter *ajax-javascript-directory-path* "ajax/javascripts") ;the directory which contains all necessary javascript files
 (defparameter *ajax-javascript-url-prefix* "/javascripts") ; the url prefix of all javascript files
 
-
 (defun set-up-json-interface (&key (json-get-prefix *json-get-prefix*)
 			      (json-get-all-psis *json-get-all-psis*)
 			      (json-commit-url *json-commit-url*)
 			      (json-get-summary-url *json-get-summary-url*)
+			      (json-get-all-type-psis *json-get-all-type-psis*)
+			      (json-get-topic-stub-prefix *json-get-topic-stub-prefix*)
+			      (json-get-type-tmcl-prefix *json-get-type-tmcl-prefix*)
+			      (json-get-instance-tmcl-prefix *json-get-instance-tmcl-prefix*)
 			      (ajax-user-interface-url *ajax-user-interface-url*)
 			      (ajax-user-interface-file-path *ajax-user-interface-file-path*)
 			      (ajax-user-interface-css-prefix *ajax-user-interface-css-prefix*)
@@ -71,16 +78,103 @@
    (create-regex-dispatcher json-get-prefix #'return-json-fragment)
    hunchentoot:*dispatch-table*)
   (push
+   (create-regex-dispatcher json-get-topic-stub-prefix #'return-topic-stub-of-psi)
+   hunchentoot:*dispatch-table*)
+  (push
+   (create-regex-dispatcher json-get-all-type-psis #'return-all-tmcl-types)
+   hunchentoot:*dispatch-table*)
+  (push
+   (create-regex-dispatcher json-get-type-tmcl-prefix #'(lambda(&optional psi)
+							  (return-tmcl-info-of-psi 'json-tmcl::type psi)))
+   hunchentoot:*dispatch-table*)
+  (push
+   (create-regex-dispatcher json-get-instance-tmcl-prefix #'(lambda(&optional psi)
+							      (return-tmcl-info-of-psi 'json-tmcl::instance psi)))
+   hunchentoot:*dispatch-table*)
+  (push
    (create-regex-dispatcher json-commit-url #'json-commit)
    hunchentoot:*dispatch-table*)
   (push
    (create-regex-dispatcher json-get-summary-url #'return-topic-summaries)
    hunchentoot:*dispatch-table*))
 
-
 ;; =============================================================================
 ;; --- some handlers for the json-rest-interface -------------------------------
 ;; =============================================================================
+(defun return-all-tmcl-types(&optional param)
+  (declare (ignorable param))
+  (handler-case (let ((all-topics
+		       (elephant:get-instances-by-class 'd:TopicC))
+		      (topictype (get-item-by-psi json-tmcl-constants::*topictype-psi*))
+		      (topictype-constraint (get-item-by-psi json-tmcl-constants::*topictype-constraint-psi*)))
+		  (let ((all-types
+			 (remove-if #'null
+				    (map 'list #'(lambda(x)
+						   (handler-case (progn
+								   (json-tmcl::topictype-p x topictype topictype-constraint)
+								   x)
+						     (condition () nil))) all-topics))))
+		    (let ((not-abstract-types
+			   (remove-if #'null
+				      (map 'list #'(lambda(x)
+						     (unless (json-tmcl:abstract-p x)
+						       x))
+					   all-types))))
+		      (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+		      (json:encode-json-to-string
+		       (map 'list #'(lambda(y)
+				      (map 'list #'uri y))
+			    (map 'list #'psis not-abstract-types))))))
+    (condition (err) (progn
+		       (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+		       (setf (hunchentoot:content-type*) "text")
+		       (format nil "Condition: \"~a\"" err)))))
+
+(defun return-topic-stub-of-psi(&optional psi)
+  "Returns a json string of a topic depending on the
+   passed psi as a topic-stub-construct."
+  (assert psi)
+  (let ((topic (d:get-item-by-psi psi)))
+    (if topic
+	(let ((topic-json
+	       (handler-case (json-exporter::to-json-topicStub-string topic)
+		 (condition (err) (progn
+				    (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+				    (setf (hunchentoot:content-type*) "text")
+				    (format nil "Condition: \"~a\"" err))))))
+	  (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+	  topic-json)
+	(progn
+	  (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+)
+	  (setf (hunchentoot:content-type*) "text")
+	  (format nil "Condition: Topic \"~a\" not found" psi)))))
+
+
+(defun return-tmcl-info-of-psi(treat-as &optional psi)
+  "Returns a json string which represents the defined tmcl-constraints of the
+   topic and the associations where this topic can be a player."
+    (assert psi)
+    (let ((http-method (hunchentoot:request-method*)))
+      (if (eq http-method :GET)
+	  (let ((identifier (string-replace psi "%23" "#")))
+	    (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+	    (handler-case (let ((tmcl
+				 (json-tmcl:get-constraints-of-fragment identifier :treat-as treat-as)))
+			    (if tmcl
+				(progn
+				  (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
+				  tmcl)
+				(progn
+				  (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+)
+				  (setf (hunchentoot:content-type*) "text")
+				  (format nil "Topic \"~a\" not found." psi))))
+	      (condition (err) (progn
+				 (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+				 (setf (hunchentoot:content-type*) "text")
+				 (format nil "Condition: \"~a\"" err)))))
+	  (setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))))
+
+
 (defun return-all-topic-psis (&optional param)
   "return all psis currently existing in isidorus as a list of list. every topic is a list
    of psis and the entire list contains a list of topics"
@@ -102,14 +196,7 @@
   (assert psi)
   (let ((http-method (hunchentoot:request-method*)))
     (if (eq http-method :GET)
-	(let ((identifier (let ((pos (search "%23" psi)))
-			    (if pos
-				(let ((str-1 (subseq psi 0 pos))
-				      (str-2 (if (> (length psi) (+ pos 3))
-						 (subseq psi (+ pos 3))
-						 "")))
-				  (concatenate 'string str-1 "#" str-2))
-				psi))))
+	(let ((identifier (string-replace psi "%23" "#")))
 	  (setf (hunchentoot:content-type*) "application/json") ;RFC 4627
 	  (let ((fragment
 		 (get-latest-fragment-of-topic identifier)))
@@ -120,7 +207,10 @@
 		      (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
 		      (setf (hunchentoot:content-type*) "text")
 		      (format nil "Condition: \"~a\"" err))))
-		"{}")))
+		(progn
+		  (setf (hunchentoot:return-code*) hunchentoot:+http-not-found+)
+		  (setf (hunchentoot:content-type*) "text")
+		  (format nil "Topic \"~a\" not found" psi)))))
 	(setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))))
 
 
@@ -201,4 +291,27 @@
 							       (concatenate 'string url-prefix
 									    (subseq current-path-string start-position-of-relative-path last-position-of-current-path))))
 							  (push (list :path current-path :url current-url) files-and-urls))))))
-      files-and-urls)))
\ No newline at end of file
+      files-and-urls)))
+
+
+(defun string-replace (str search-str replace-str)
+  "replaces all sub-strings in str of the form search-str with
+   the string replace-str and returns the new generated string"
+  (if (= (length search-str) 0)
+      str
+      (progn
+	(let ((ret-str "")
+	      (idx 0))
+	  (loop
+	     (if (string= str search-str
+			  :start1 idx
+			  :end1 (min (length str)
+				     (+ idx (length search-str))))
+		 (progn
+		   (setf ret-str (concatenate 'string ret-str replace-str))
+		   (incf idx (length search-str)))
+		 (progn
+		   (setf ret-str (concatenate 'string ret-str (subseq str idx (1+ idx))))
+		   (incf idx)))
+	     (unless (< idx (length str))
+	       (return ret-str)))))))
\ No newline at end of file

Added: trunk/src/unit_tests/poems.xtm
==============================================================================
--- (empty file)
+++ trunk/src/unit_tests/poems.xtm	Mon May  4 11:02:44 2009
@@ -0,0 +1,1857 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tm:topicMap version="2.0" xmlns:tm="http://www.topicmaps.org/xtm/">
+
+  <!-- === association-test ================================================ -->
+  <tm:topic id="test-scope-1">
+    <tm:subjectIdentifier href="test-scope-1"/>
+    <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="test-scope-2">
+    <tm:subjectIdentifier href="test-scope-2"/>
+    <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="written-by-test-scope-constraint">
+    <tm:subjectIdentifier href="written-by-test-scope-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#associationtypescope-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-min"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-max"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type>
+      <tm:topicRef href="#applies-to"/>
+    </tm:type>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#constraint-role"/>
+      </tm:type>
+      <tm:topicRef href="#written-by-test-scope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#associationtype-role"/>
+      </tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type>
+      <tm:topicRef href="#applies-to"/>
+    </tm:type>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#constraint-role"/>
+      </tm:type>
+      <tm:topicRef href="#written-by-test-scope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#scopetype-role"/>
+      </tm:type>
+      <tm:topicRef href="#test-scope-1"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type>
+      <tm:topicRef href="#applies-to"/>
+    </tm:type>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#constraint-role"/>
+      </tm:type>
+      <tm:topicRef href="#written-by-test-scope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type>
+	<tm:topicRef href="#scopetype-role"/>
+      </tm:type>
+      <tm:topicRef href="#test-scope-2"/>
+    </tm:role>
+  </tm:association>
+  <!-- === end association-test ============================================ -->
+
+
+  <!-- ===================================================================== -->
+  <!-- === TMCL meta-model topics ========================================== -->
+  <!-- ===================================================================== -->
+  <tm:topic id="topictype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type"/> <!-- naming of psis: Prague, March 25-27, 2008, page 12 -->
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="occurrencetype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="associationtype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="roletype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="nametype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="scopetype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- role types used to include the topictype metatypes in associations -->
+  <tm:topic id="topictype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="occurrencetype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="associationtype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="roletype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="otherroletype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="othertopictype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-topic-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="nametype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="scopetype-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type-role"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the constraint roletype -->
+  <tm:topic id="constraint-role">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint-role"/>
+    <tm:instanceOf><tm:topicref href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- ===================================================================== -->
+  <!-- === TMCL model topics =============================================== -->
+  <!-- ===================================================================== -->
+
+  <!-- the constraint topic is the common supertype of all constraint types
+       defined by TMCL. -->
+  <tm:topic id="constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+ 
+  <!-- this occurrence type is used to type a single occurrence on each
+       constraint type. This occurrence holds the TMQL value used to 
+       evaluate constraint instances for validity. -->
+  <tm:topic id="validation-expression">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/validation-expression"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the association type used to bind different components into a
+       constraint -->
+  <tm:topic id="applies-to">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/applies-to"/>
+    <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the card min facet is used on many constraint types -->
+  <tm:topic id="card-min">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-min"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the card max facet is used on many constraint types -->
+  <tm:topic id="card-max">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-max"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the reg exp facet is used on many constraint types -->
+  <tm:topic id="regexp">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/reg-exp"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- the datatype facet is used on many constraint types -->
+  <tm:topic id="datatype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/datatype"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- ===================================================================== -->
+  <!-- === topics for super-subtype-associations (ako) ===================== -->
+  <!-- ===================================================================== -->
+
+  <tm:topic id="supertype-subtype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype-subtype"/>
+  </tm:topic>
+
+  <tm:topic id="supertype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype"/>
+  </tm:topic>
+
+  <tm:topic id="subtype">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/subtype"/>
+  </tm:topic>
+
+
+  <!-- ===================================================================== -->
+  <!-- === schema type and ?schema definitions ============================= -->
+  <!-- ===================================================================== -->
+
+  <!-- constraints can be bound to a schema -->
+  <tm:topic id="schema">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/schema"/>
+    <tm:instanceOf><tm:topicref href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+
+  <!-- ===================================================================== -->
+  <!-- === TMCL constraint types =========================================== -->
+  <!-- ===================================================================== -->
+
+  <!-- topictype-constraint -->
+  <tm:topic id="topictype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-constraint"/>
+  </tm:topic> <!-- standard constraints doesn't own a valiadtion-expression-occurrence: Prague, March 25-27, 2008, page 34-36 -->
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#topictype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- associationtype-constraint -->
+  <tm:topic id="associationtype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#associationtype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- roletype-constraint -->
+  <tm:topic id="roletype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#roletype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- occurrencetype-constraint -->
+  <tm:topic id="occurrencetype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#occurrencetype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- nametype-constraint -->
+  <tm:topic id="nametype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#nametype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- abstract-topictype-constraint -->
+  <tm:topic id="abstract-topictype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#abstract-topictype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+    </tm:association>
+
+
+  <!-- exclusive-instance -->
+  <tm:topic id="exclusive-instance">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/exclusive-instance"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#exclusive-instance"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- ===================================================================== -->
+  <!-- === subjectidentifier/locator constraints =========================== -->
+  <!-- ===================================================================== -->
+  
+  <!-- subjectlocator-constraint -->
+  <tm:topic id="subjectlocator-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-locator-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#subjectlocator-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- subjectidentifier-constraint -->
+  <tm:topic id="subjectidentifier-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-identifier-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#subjectidentifier-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- ===================================================================== -->
+  <!-- === names/occurrences/associations/association roles ================ -->
+  <!-- ===================================================================== -->
+
+  <!-- topicname-constraint -->
+  <tm:topic id="topicname-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-name-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#topicname-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- topicoccurrence-constraint -->
+  <tm:topic id="topicoccurrence-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-occurrence-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#topicoccurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- occurrencedatatype-constraint -->
+  <tm:topic id="occurrencedatatype-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#occurrencedatatype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- uniqueoccurrence-constraint -->
+  <tm:topic id="uniqueoccurrence-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/unique-occurrence-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#uniqueoccurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- associationrole-constraint -->
+  <tm:topic id="associationrole-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-role-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#associationrole-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- roleplayer-constraint -->
+  <tm:topic id="roleplayer-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-player-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#roleplayer-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- otherrole-constraint -->
+  <tm:topic id="otherrole-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#otherrole-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- ===================================================================== -->
+  <!-- === scopes ========================================================== -->
+  <!-- ===================================================================== -->
+
+  <!-- nametypescope-constraint -->
+  <tm:topic id="nametypescope-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-scope-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#nametypescope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- occurrencetypescope-constraint -->
+  <tm:topic id="occurrencetypescope-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#occurrencetypescope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- associationtypescope-constraint -->
+  <tm:topic id="associationtypescope-constraint">
+    <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-scope-constraint"/>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#subtype"/></tm:type>
+      <tm:topicRef href="#associationtypescope-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#supertype"/></tm:type>
+      <tm:topicRef href="#constraint"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: type handling ==================================== -->
+  <!-- ===================================================================== -->
+
+  <!-- only topics that are instances of topictype are allowed as topic
+       types -->
+  <tm:topic id="ttc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/ttc"/>
+    <tm:instanceOf><tm:topicRef href="#topictype-constraint"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- only topics that are instances of associationtype are allowed as
+       association types -->
+  <tm:topic id="atc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/atc"/>
+    <tm:instanceOf><tm:topicRef href="#associationtype-constraint"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- only topics that are instances of roletype are allowed as
+       association role types -->
+  <tm:topic id="rtc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/rtc"/>
+    <tm:instanceOf><tm:topicRef href="#roletype-constraint"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- only topics that are instances of occurrencetype are allowed as
+       occurrence types -->
+  <tm:topic id="otc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/otc"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype-constraint"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- only topics that are instances of nametype are allowed as
+       name types -->
+  <tm:topic id="ntc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/ntc"/>
+    <tm:instanceOf><tm:topicRef href="#nametype-constraint"/></tm:instanceOf>
+  </tm:topic>
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: base types ======================================= -->
+  <!-- ===================================================================== -->
+
+  <!-- author -->
+  <tm:topic id="author">
+    <tm:subjectIdentifier href="http://some.where/base-psis/author"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="first-name">
+    <tm:subjectIdentifier href="http://some.where/base-psis/first-name"/>
+    <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="last-name">
+    <tm:subjectIdentifier href="http://some.where/base-psis/last-name"/>
+    <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="author-info">
+    <tm:subjectIdentifier href="http://some.where/base-psis/author-info"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- poem -->
+  <tm:topic id="poem">
+    <tm:subjectIdentifier href="http://some.where/base-psis/poem"/>
+    <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="title">
+    <tm:subjectIdentifier href="http://some.where/base-psis/title"/>
+    <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="poem-content">
+    <tm:subjectIdentifier href="http://some.where/base-psis/poem-content"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- poem scopes -->
+  <tm:topic id="de">
+    <tm:subjectIdentifier href="http://some.where/base-psis/de"/>
+    <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="en">
+    <tm:subjectIdentifier href="http://some.where/base-psis/en"/>
+    <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf>
+  </tm:topic>
+
+  <!-- association author-poem -->
+  <tm:topic id="written-by">
+    <tm:subjectIdentifier href="http://some.where/base-psis/written-by"/>
+    <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="writer">
+    <tm:subjectIdentifier href="http://some.where/base-psis/writer"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:topic id="written">
+    <tm:subjectIdentifier href="http://some.where/base-psis/written"/>
+    <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+  </tm:topic>
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: exclusive type constraint ======================== -->
+  <!-- ===================================================================== -->
+  <!-- same instances of the type author and title are not allowed -->
+  <tm:topic id="exc">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/exc"/>
+    <tm:instanceOf><tm:topicRef href="#exclusive-instance"/></tm:instanceOf>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#exc"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#exc"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+  <!-- ===================================================================== -->
+  <!-- a topic of the type author has to have a psi of the form
+       "^http://some.where/psis/author/.+$"
+       and a topic of the type poem has to have a psi of the form
+       "^http://some.where/psis/poem/.+$".
+       further all topics can have mor psis of the form "^.+$" -->
+
+  <!-- subjectidentifier of author -->
+  <tm:topic id="sic-author">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-author"/>
+    <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/author/.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#sic-author"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- subjectidentifier of poem -->
+  <tm:topic id="sic-poem">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-poem"/>
+    <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://some.where/psis/poem/.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#sic-poem"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- further subjectidentifiers of author and poem -->
+  <tm:topic id="sic-author-poem">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/sic-author-poem"/>
+    <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">MAX_INT</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#sic-author-poem"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#sic-author-poem"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+  <!-- ===================================================================== -->
+  <!-- all instances of author and poem are not allowed to own a
+       subjectLocator -->
+
+  <tm:topic id="slc-author-poem">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/slc-author-poem"/>
+    <tm:instanceOf><tm:topicRef href="#subjectlocator-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#slc-author-poem"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#slc-author-poem"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: names constraints ================================ -->
+  <!-- ===================================================================== -->
+  <!-- instances of the type author has to own a name of the type first-name
+       and one of the type last-name. both must be valid to the regular
+       expression "^.+$".
+       instances of the type poem has exactly one name of the type title
+       with the regular expression "^.+$" -->
+
+  <!-- author first name -->
+  <tm:topic id="author-first-name-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/author-first-name-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+        <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-first-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-first-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+      <tm:topicRef href="#first-name"/>
+    </tm:role>
+  </tm:association>
+  
+  <!-- author last name -->
+  <tm:topic id="author-last-name-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/author-last-name-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+        <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-last-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-last-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+      <tm:topicRef href="#last-name"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- poem title name -->
+  <tm:topic id="poem-title-name-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-title-name-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#poem-title-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#poem-title-name-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+      <tm:topicRef href="#title"/>
+    </tm:role>
+  </tm:association>  
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: occurences constraints =========================== -->
+  <!-- ===================================================================== -->
+  <!-- every instance of the topic author can have one occurrence of the type
+       author-info which contains a resourceRef (= datatype #anyURI) -->
+
+  <!-- author info occurrence -->
+  <tm:topic id="author-occurrence-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/author-occurrence-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#author-info"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- author info occurrence datatype -->
+  <tm:topic id="author-info-occurrence-datatype-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/author-poem-occurrence-datatype-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#datatype"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#anyURI</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#author-info-occurrence-datatype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#author-info"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- all instances of the type poem has to have exactly one occurrence
+       of the type poem-content with the datatype string and the either
+       the scope en or de-->
+  <tm:topic id="poem-occurrence-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-occurrence-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#poem-content"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- poem content-occurrence datatype -->
+  <tm:topic id="poem-content-occurrence-datatype-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/poem-content-occurrence-datatype-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#datatype"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#poem-content-occurrence-datatype-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#poem-content"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- the poem-content-occurrence can only appear once per topictype,
+       so all topic with this occurrence type must have different
+       occurrence-values -->
+  <tm:topic id="unique-poem-occurrence-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/unique-poem-occurrence-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#uniqueoccurrence-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#regexp"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#unique-poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#poem-content"/>
+    </tm:role>
+  </tm:association>
+  
+  <!-- add a scope to the occurrence "poem-content" -->
+  <tm:topic id="scoped-poem-occurrence-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/scoped-poem-occurrence-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#occurrencetypescope-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">2</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+      <tm:topicRef href="#poem-content"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+      <tm:topicRef href="#en"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#scoped-poem-occurrence-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#scopetype-role"/></tm:type>
+      <tm:topicRef href="#de"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- ===================================================================== -->
+  <!-- === own datamodel: association (-role) constraints ================== -->
+  <!-- ===================================================================== -->
+  <!-- there exists one asoociation of the type written-by between the types
+       author and poem. where one role is of type writer which has a player
+       of type author and another role of type written which owns a player of
+       type poem -->
+
+  <!-- the writer role has to appear exactly once in an association of type
+       written-by -->
+  <tm:topic id="writer-role-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#writer-role-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#writer-role-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#writer"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- the writer role owns a player of the type author -->
+  <tm:topic id="writer-role-player-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/writer-role-player-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#writer-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#writer-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#writer-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#writer"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- the written role has to appear exactly once in an association of type
+       written-by -->
+  <tm:topic id="written-role-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-role-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-role-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#written"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- the written role owns a player of the type poem -->
+  <tm:topic id="written-role-player-constraint">
+    <tm:subjectIdentifier href="http://some.where/constraint-psis/written-role-player-constraint"/>
+    <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-min"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#card-max"/></tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-role-player-constraint"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#written"/>
+    </tm:role>
+  </tm:association>
+
+
+  <!-- otherrole-constraint:
+       If there is a role of the type written with a player of the type poem
+       there must be another role of the type writer with a player of the
+       type author.
+       In contrast if there is a role of the type writer with a player of the
+       type author there must be a role of the type written with a player of
+       the type poem.
+       So for this case there are two otherrole-constraints which handle this
+       both cases. -->
+
+  <tm:topic id="written-by-otherrole-constraint-for-writer">
+    <tm:subjectIdentifier href="written-by-otherrole-constraint-for-writer"/>
+    <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-min"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-max"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#writer"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+      <tm:topicRef href="#written"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-writer"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:topic id="written-by-otherrole-constraint-for-written">
+    <tm:subjectIdentifier href="written-by-otherrole-constraint-for-written"/>
+    <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-min"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+    <tm:occurrence>
+      <tm:type>
+	<tm:topicRef href="#card-max"/>
+      </tm:type>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+      <tm:topicRef href="#written-by"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+      <tm:topicRef href="#written"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+      <tm:topicRef href="#poem"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+      <tm:topicRef href="#writer"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+      <tm:topicRef href="#written-by-otherrole-constraint-for-written"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+      <tm:topicRef href="#author"/>
+    </tm:role>
+  </tm:association>
+
+  <!-- ===================================================================== -->
+  <!-- === the "user's" topic map ========================================== -->
+  <!-- ===================================================================== -->
+  <tm:topic id="goethe">
+    <tm:subjectIdentifier href="http://some.where/psis/author/goethe"/> <!-- must have a psi of this form -->
+    <tm:subjectIdentifier href="http://some.where/psis/persons/goethe"/> <!-- can own psis of any form -->
+    <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> <!-- must be an instanceOf author -->
+    <tm:name>
+      <tm:type><tm:topicRef href="#first-name"/></tm:type> <!-- must contain a name of the type first-name -->
+      <tm:value>Johann Wolfgang</tm:value>
+    </tm:name>
+    <tm:name>
+      <tm:type><tm:topicRef href="#last-name"/></tm:type> <!-- must contain a name of the type last-name -->
+      <tm:value>von Goethe</tm:value>
+    </tm:name>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#author-info"/></tm:type> <!-- can own an occurrence of the type autor-info with the datatype anyURI -->
+      <tm:resourceRef href="http://de.wikipedia.org/wiki/Johann_Wolfgang_von_Goethe"/>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:topic id="schiller">
+    <tm:subjectIdentifier href="http://some.where/psis/author/schiller"/> <!-- must have a psi of this form -->
+    <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> <!-- must be an instanceOf author -->
+    <tm:name>
+      <tm:type><tm:topicRef href="#first-name"/></tm:type> <!-- must contain a name of the type first-name -->
+      <tm:value>Johann Christoph Friedrich</tm:value>
+    </tm:name>
+    <tm:name>
+      <tm:type><tm:topicRef href="#last-name"/></tm:type> <!-- must contain a name of the type last-name -->
+      <tm:value>von Schiller</tm:value>
+    </tm:name>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#author-info"/></tm:type> <!-- can own an occurrence of the type autor-info with the datatype anyURI -->
+      <tm:resourceRef href="http://de.wikipedia.org/wiki/Schiller"/>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:topic id="zauberlehrling">
+    <tm:subjectIdentifier href="http://some.where/psis/poem/zauberlehrling"/> <!-- must have a psi of this form -->
+    <tm:subjectIdentifier href="http://some.where/psis/der_zauberlehrling"/> <!-- can own psis of any form -->
+    <tm:instanceOf>
+      <tm:topicRef href="#poem"/><!--
+      <tm:topicRef href="#author"/>
+      <tm:topicRef href="#zauberlehrling"/>
+      <tm:topicRef href="#topictype-constraint"/>-->
+    </tm:instanceOf> <!-- must be an instanceOf poem -->
+    <tm:name>
+      <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+      <tm:value>Der Zauberlehrling</tm:value>
+    </tm:name>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+      <tm:scope><tm:topicRef href="#de"/></tm:scope>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Hat der alte Hexenmeister
+sich doch einmal wegbegeben!
+Und nun sollen seine Geister
+auch nach meinem Willen leben.
+Seine Wort und Werke
+merkt ich und den Brauch,
+und mit Geistesstärke
+tu ich Wunder auch.
+
+Walle! walle
+Manche Strecke,
+daß, zum Zwecke,
+Wasser fließe
+und mit reichem, vollem Schwalle
+zu dem Bade sich ergieße.
+
+Und nun komm, du alter Besen!
+Nimm die schlechten Lumpenhüllen;
+bist schon lange Knecht gewesen:
+nun erfülle meinen Willen!
+Auf zwei Beinen stehe,
+oben sei ein Kopf,
+eile nun und gehe
+mit dem Wassertopf!
+
+Walle! walle
+manche Strecke,
+daß, zum Zwecke,
+Wasser fließe
+und mit reichem, vollem Schwalle
+zu dem Bade sich ergieße.
+
+Seht, er läuft zum Ufer nieder,
+Wahrlich! ist schon an dem Flusse,
+und mit Blitzesschnelle wieder
+ist er hier mit raschem Gusse.
+Schon zum zweiten Male!
+Wie das Becken schwillt!
+Wie sich jede Schale
+voll mit Wasser füllt!
+
+Stehe! stehe!
+denn wir haben
+deiner Gaben
+vollgemessen! -
+Ach, ich merk es! Wehe! wehe!
+Hab ich doch das Wort vergessen!
+
+Ach, das Wort, worauf am Ende
+er das wird, was er gewesen.
+Ach, er läuft und bringt behende!
+Wärst du doch der alte Besen!
+Immer neue Güsse
+bringt er schnell herein,
+Ach! und hundert Flüsse
+stürzen auf mich ein.
+
+Nein, nicht länger
+kann ichs lassen;
+will ihn fassen.
+Das ist Tücke!
+Ach! nun wird mir immer bänger!
+Welche Mine! welche Blicke!
+
+O du Ausgeburt der Hölle!
+Soll das ganze Haus ersaufen?
+Seh ich über jede Schwelle
+doch schon Wasserströme laufen.
+Ein verruchter Besen,
+der nicht hören will!
+Stock, der du gewesen,
+steh doch wieder still!
+
+Willst am Ende
+gar nicht lassen?
+Will dich fassen,
+will dich halten
+und das alte Holz behende
+mit dem scharfen Beile spalten.
+
+Seht da kommt er schleppend wieder!
+Wie ich mich nur auf dich werfe,
+gleich, o Kobold, liegst du nieder;
+krachend trifft die glatte Schärfe.
+Wahrlich, brav getroffen!
+Seht, er ist entzwei!
+Und nun kann ich hoffen,
+und ich atme frei!
+
+Wehe! wehe!
+Beide Teile
+stehn in Eile
+schon als Knechte
+völlig fertig in die Höhe!
+Helft mir, ach! ihr hohen Mächte!
+
+Und sie laufen! Naß und nässer
+wirds im Saal und auf den Stufen.
+Welch entsetzliches Gewässer!
+Herr und Meister! hör mich rufen! -
+Ach, da kommt der Meister!
+Herr, die Not ist groß!
+Die ich rief, die Geister
+werd ich nun nicht los.
+
+"In die Ecke,
+Besen, Besen!
+Seids gewesen.
+Denn als Geister
+ruft euch nur zu diesem Zwecke,
+erst hervor der alte Meister."</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <tm:topic id="erlkoenig">
+    <tm:subjectIdentifier href="http://some.where/psis/poem/erlkoenig"/> <!-- must have a psi of this form -->
+    <tm:instanceOf><tm:topicRef href="#poem"/></tm:instanceOf> <!-- must be an instanceOf poem -->
+    <tm:name>
+      <tm:type><tm:topicRef href="#title"/></tm:type> <!-- must have a name of the type title -->
+      <tm:value>Der Erlkönig</tm:value>
+    </tm:name>
+    <tm:occurrence>
+      <tm:type><tm:topicRef href="#poem-content"/></tm:type> <!-- must have an occurrence of the type poem-content with the scope de or en -->
+      <tm:scope><tm:topicRef href="#en"/></tm:scope>
+      <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">Who rides there so late through the night dark and drear?
+The father it is, with his infant so dear;
+He holdeth the boy tightly clasp'd in his arm,
+He holdeth him safely, he keepeth him warm.
+
+"My son, wherefore seek'st thou thy face thus to hide?"
+"Look, father, the Erl-King is close by our side!
+Dost see not the Erl-King, with crown and with train?"
+"My son, 'tis the mist rising over the plain."
+
+"Oh, come, thou dear infant! oh come thou with me!
+For many a game I will play there with thee;
+On my strand, lovely flowers their blossoms unfold,
+My mother shall grace thee with garments of gold."
+
+"My father, my father, and dost thou not hear
+The words that the Erl-King now breathes in mine ear?"
+"Be calm, dearest child, 'tis thy fancy deceives;
+'Tis the sad wind that sighs through the withering leaves."
+
+"Wilt go, then, dear infant, wilt go with me there?
+My daughters shall tend thee with sisterly care
+My daughters by night their glad festival keep,
+They'll dance thee, and rock thee, and sing thee to sleep."
+
+"My father, my father, and dost thou not see,
+How the Erl-King his daughters has brought here for me?"
+"My darling, my darling, I see it aright,
+'Tis the aged grey willows deceiving thy sight."
+
+"I love thee, I'm charm'd by thy beauty, dear boy!
+And if thou'rt unwilling, then force I'll employ."
+"My father, my father, he seizes me fast,
+For sorely the Erl-King has hurt me at last."
+
+The father now gallops, with terror half wild,
+He grasps in his arms the poor shuddering child;
+He reaches his courtyard with toil and with dread,--
+The child in his arms finds he motionless, dead.</tm:resourceData>
+    </tm:occurrence>
+  </tm:topic>
+
+  <!-- some assocaitions between goethe and some of his poems,
+       currently there are no associations between the topic schiller
+       and any other topic, because there are no topic representing
+       a poem of schiller -->
+  <tm:association>
+    <tm:type><tm:topicRef href="#written-by"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#writer"/></tm:type>
+      <tm:topicRef href="#goethe"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#written"/></tm:type>
+      <tm:topicRef href="#zauberlehrling"/>
+    </tm:role>
+  </tm:association>
+
+  <tm:association>
+    <tm:type><tm:topicRef href="#written-by"/></tm:type>
+    <tm:role>
+      <tm:type><tm:topicRef href="#writer"/></tm:type>
+      <tm:topicRef href="#goethe"/>
+    </tm:role>
+    <tm:role>
+      <tm:type><tm:topicRef href="#written"/></tm:type>
+      <tm:topicRef href="#erlkoenig"/>
+    </tm:role>
+  </tm:association>
+
+</tm:topicMap>




More information about the Isidorus-cvs mailing list