mailman3.common-lisp.net
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
List overview
Download
isidorus-cvs
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
isidorus-cvs@common-lisp.net
1037 discussions
Start a n
N
ew thread
[isidorus-cvs] r404 - in trunk/src: TM-SPARQL unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 09:57:58 2011 New Revision: 404 Log: TM-SPARQL: finsihed the unit-tests for the special-uri tms:value => fixed a bug when '<date>'^^xml-date is given Modified: trunk/src/TM-SPARQL/sparql.lisp trunk/src/TM-SPARQL/sparql_special_uris.lisp trunk/src/unit_tests/sparql_test.lisp trunk/src/unit_tests/sparql_test.xtm Modified: trunk/src/TM-SPARQL/sparql.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql.lisp (original) +++ trunk/src/TM-SPARQL/sparql.lisp Fri Apr 1 09:57:58 2011 @@ -505,7 +505,8 @@ Note the type xsd:date is not supported and so handled as a string." (declare (String literal-datatype)) (let ((chars - (cond ((string= literal-datatype *xml-string*) + (cond ((or (string= literal-datatype *xml-string*) + (string= literal-datatype *xml-date*)) (remove-if #'(lambda(elem) (string/= (charvalue elem) literal-value)) (append Modified: trunk/src/TM-SPARQL/sparql_special_uris.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_special_uris.lisp (original) +++ trunk/src/TM-SPARQL/sparql_special_uris.lisp Fri Apr 1 09:57:58 2011 @@ -255,7 +255,7 @@ (not (variable-p obj))) (when (or (and (typep subj 'NameC) (string= literal-datatype *xml-string*) - (string= (charvalue subj) (value obj))) + (string= (charvalue (value subj)) (value obj))) (filter-datatypable-by-value subj obj literal-datatype)) (list (list :subject subj-uri :predicate pred-uri @@ -264,10 +264,10 @@ ((not (variable-p subj)) (list (list :subject subj-uri :predicate pred-uri - :object (charvalue subj) - :literal-datatype (if (typep subj 'd:NameC) + :object (charvalue (value subj)) + :literal-datatype (if (typep (value subj) 'd:NameC) *xml-string* - (datatype subj))))) + (datatype (value subj)))))) ((not (variable-p obj)) (loop for char in (return-characteristics (value obj) literal-datatype) collect (list :subject (sparql-node char :revision revision) Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 09:57:58 2011 @@ -1882,12 +1882,55 @@ r-1)))) +(test test-all-8 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/ii/goethe-untyped-name
> tms:value ?obj1. + <
http://some.where/ii/goethe-occ
> tms:value ?obj2. + <
http://some.where/ii/goethe-variant
> tms:value ?obj3. + ?subj1 tms:value 'Goethe'. + ?subj2 tms:value '28.08.1749'^^http://www.w3.org/2001/XMLSchema#date. + ?subj3 tms:value 'Johann Wolfgang von Goethe'. + ?subj4 tms:value 82" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 7)) + (map 'list #'(lambda(item) + (cond ((string= (getf item :variable) "obj1") + (is (string= (first (getf item :result)) + "Johann Wolfgang von Goethe"))) + ((string= (getf item :variable) "obj2") + (is (string= (first (getf item :result)) + "28.08.1749"))) + ((string= (getf item :variable) "obj3") + (is (string= (first (getf item :result)) + "Goethe"))) + ((string= (getf item :variable) "subj1") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/goethe-variant
>"))) + ((string= (getf item :variable) "subj2") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/goethe-occ
>"))) + ((string= (getf item :variable) "subj3") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/goethe-untyped-name
>"))) + ((string= (getf item :variable) "subj4") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/goethe-years-occ
>"))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + -;TODO: tms:scope, tms:value, complex filter -; <obj> <pred> <subj> -; ?obj <pred> ?subj -; <subj> ?pred ?obj +;TODO: tms:value, complex filter, +; <obj> <pred> <subj>, +; ?obj <pred> ?subj, +; <subj> ?pred ?obj, ; ?subj ?pred <obj> ;TODO: PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> ; SELECT * WHERE { Modified: trunk/src/unit_tests/sparql_test.xtm ============================================================================== --- trunk/src/unit_tests/sparql_test.xtm (original) +++ trunk/src/unit_tests/sparql_test.xtm Fri Apr 1 09:57:58 2011 @@ -141,6 +141,7 @@ <tm:type><tm:topicRef href="#last-name"/></tm:type> <tm:value>von Goethe</tm:value> <tm:variant> + <tm:itemIdentity href="
http://some.where/ii/goethe-variant
"/> <tm:scope><tm:topicRef href="#display-name"/></tm:scope> <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#string
">Goethe</tm:resourceData> </tm:variant> @@ -159,6 +160,7 @@ <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#date
">22.03.1832</tm:resourceData> </tm:occurrence> <tm:occurrence> + <tm:itemIdentity href="
http://some.where/ii/goethe-years-occ
"/> <tm:type><tm:topicRef href="#years"/></tm:type> <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#integer
">82</tm:resourceData> </tm:occurrence>
1
0
0
0
[isidorus-cvs] r403 - trunk/src/unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 09:30:30 2011 New Revision: 403 Log: TM-SPARQL: finsihed the unit-tests for the special-uri tms:scope Modified: trunk/src/unit_tests/sparql_test.lisp trunk/src/unit_tests/sparql_test.xtm Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 09:30:30 2011 @@ -1858,6 +1858,30 @@ r-1)))) +(test test-all-7 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/ii/zb/occurrence
> tms:scope ?scope. + ?owner tms:scope <
http://some.where/tmsparql/de
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 2)) + (map 'list #'(lambda(item) + (cond ((string= (getf item :variable) "scope") + (is (string= (first (getf item :result)) + "<
http://some.where/tmsparql/de
>"))) + ((string= (getf item :variable) "owner") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/zb/occurrence
>"))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + + ;TODO: tms:scope, tms:value, complex filter Modified: trunk/src/unit_tests/sparql_test.xtm ============================================================================== --- trunk/src/unit_tests/sparql_test.xtm (original) +++ trunk/src/unit_tests/sparql_test.xtm Fri Apr 1 09:30:30 2011 @@ -191,6 +191,7 @@ <tm:value>Der Zauberlehrling</tm:value> </tm:name> <tm:occurrence> + <tm:itemIdentity href="
http://some.where/ii/zb/occurrence
"/> <tm:type><tm:topicRef href="#poem-content"/></tm:type> <tm:scope><tm:topicRef href="#de"/></tm:scope> <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#string
">Hat der alte Hexenmeister
1
0
0
0
[isidorus-cvs] r402 - trunk/src/unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 09:23:24 2011 New Revision: 402 Log: TM-SPARQL: finsihed the unit-tests for the special-uri tms:topicProperty Modified: trunk/src/unit_tests/sparql_test.lisp Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 09:23:24 2011 @@ -1787,7 +1787,6 @@ r-1)))) - (test test-all-5 "Tests the entire module with the file sparql_test.xtm" (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) @@ -1817,9 +1816,51 @@ r-1)))) +(test test-all-6 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/tmsparql/author/goethe
> tms:topicProperty ?props. + ?subj1 tms:topicProperty <
http://some.where/ii/goethe-untyped-name
>. + ?subj2 tms:topicProperty <
http://some.where/ii/goethe-occ
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1))) + (prop-ids + (map 'list + #'(lambda(prop) + (if (item-identifiers prop :revision 0) + (concat "<" (d:uri (first (item-identifiers + prop :revision 0))) ">") + (if (typep prop 'OccurrenceC) + (concat "_:o" (write-to-string (elephant::oid prop))) + (concat "_:n" (write-to-string (elephant::oid prop)))))) + (append (names (get-item-by-psi + "
http://some.where/tmsparql/author/goethe
" + :revision 0)) + (occurrences (get-item-by-psi + "
http://some.where/tmsparql/author/goethe
" + :revision 0)))))) + (is-true (= (length r-1) 3)) + (map 'list #'(lambda(item) + (cond ((or (string= (getf item :variable) "subj1") + (string= (getf item :variable) "subj2")) + (is (string= + (first (getf item :result)) + "<
http://some.where/tmsparql/author/goethe
>"))) + ((string= (getf item :variable) "props") + (is (= (length (getf item :result)) 8)) + (is-false (intersection prop-ids (getf item :result)))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + + -;TODO: tms:topicProperty, tms:scope, tms:value, complex filter +;TODO: tms:scope, tms:value, complex filter ; <obj> <pred> <subj> ; ?obj <pred> ?subj ; <subj> ?pred ?obj
1
0
0
0
[isidorus-cvs] r401 - trunk/src/unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 09:05:56 2011 New Revision: 401 Log: TM-SPARQL: finsihed the unit-tests for the special-uri tms:player Modified: trunk/src/unit_tests/sparql_test.lisp Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 09:05:56 2011 @@ -1788,11 +1788,44 @@ +(test test-all-5 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/ii/role-2
> tms:player ?player. + ?role tms:player <
http://some.where/psis/poem/zauberlehrling
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 2)) + (map 'list #'(lambda(item) + (cond ((string= (getf item :variable) "player") + (is (string= + (first (getf item :result)) + "<
http://some.where/psis/poem/zauberlehrling
>"))) + ((string= (getf item :variable) "role") + (is (= (length (getf item :result)) 2)) + ;one role is the type-instance role + (is (or (string= (first (getf item :result)) + "<
http://some.where/ii/role-2
>") + (string= (second (getf item :result)) + "<
http://some.where/ii/role-2
>")))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) -;TODO: tms:player, tms:topicProperty, tms:scope, tms:value, complex filter -;TODO: "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> -; SELECT * WHERE { + + +;TODO: tms:topicProperty, tms:scope, tms:value, complex filter +; <obj> <pred> <subj> +; ?obj <pred> ?subj +; <subj> ?pred ?obj +; ?subj ?pred <obj> +;TODO: PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> +; SELECT * WHERE { ; ?assoc tms:reifier <
http://some.where/ii/association-reifier
>. ; ?assoc tms:role ?roles} ; => ?assoc =
http://some.where/ii/association
1
0
0
0
[isidorus-cvs] r400 - in trunk/src: TM-SPARQL unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 08:50:49 2011 New Revision: 400 Log: TM-SPARQL: finsihed the unit-tests for the special-uri tms:role => fixed a bug when the object is a resource and not a variable Modified: trunk/src/TM-SPARQL/sparql.lisp trunk/src/TM-SPARQL/sparql_special_uris.lisp trunk/src/unit_tests/sparql_test.lisp trunk/src/unit_tests/sparql_test.xtm Modified: trunk/src/TM-SPARQL/sparql.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql.lisp (original) +++ trunk/src/TM-SPARQL/sparql.lisp Fri Apr 1 08:50:49 2011 @@ -16,10 +16,9 @@ :init-tm-sparql)) - (in-package :TM-SPARQL) -(defvar *empty-label* "_empty_label_symbol" "A label symobl for empyt prefix labels") +(defvar *empty-label* "_empty_label_symbol" "A label symbol for empyt prefix labels") (defvar *equal-operators* nil "A Table taht contains tuples of classes and equality operators.") @@ -779,7 +778,8 @@ (filter-characteristics subj pred (value (object construct)) (literal-datatype (object construct)) :revision revision))) - ((iri-p (object construct)) + ((and (iri-p (object construct)) + (typep subj 'TopicC)) (filter-associations subj pred (value (object construct)) :revision revision))))))) Modified: trunk/src/TM-SPARQL/sparql_special_uris.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_special_uris.lisp (original) +++ trunk/src/TM-SPARQL/sparql_special_uris.lisp Fri Apr 1 08:50:49 2011 @@ -151,7 +151,7 @@ (when (and (or (variable-p subj) (typep (value subj) 'd:AssociationC)) (or (variable-p obj) - (typep (value subj) 'd:RoleC))) + (typep (value obj) 'd:RoleC))) (cond ((and (not (variable-p subj)) (not (variable-p obj))) (when (find obj (roles (value subj) :revision revision)) Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 08:50:49 2011 @@ -1744,12 +1744,59 @@ (let* ((q-1 (concat "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> SELECT * WHERE { - <
http://some.where/ii/goethe-occ
> tms:reifier ?obj1. - ?subj1 tms:reifier <
http://some.where/ii/goethe-name-reifier
>" + ?assoc tms:reifier <
http://some.where/ii/association-reifier
>. + <
http://some.where/ii/association
> tms:role ?roles. + ?assoc2 tms:role <
http://some.where/ii/role-2
>" "}")) - (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) - (is-true (= (length r-1) 2)) - ))) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1))) + (role-1 (concat "_:r" (write-to-string + (elephant::oid + (first (roles + (get-item-by-item-identifier + "
http://some.where/ii/association
" + :revision 0))))))) + (role-2 (concat "_:r" (write-to-string + (elephant::oid + (second (roles + (get-item-by-item-identifier + "
http://some.where/ii/association
" + :revision 0)))))))) + (is-true (= (length r-1) 3)) + (map 'list #'(lambda(item) + (cond ((string= (getf item :variable) "assoc") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/association
>"))) + ((string= (getf item :variable) "roles") + (is (or (string= (first (getf item :result)) + role-1) + (string= (first (getf item :result)) + role-2) + (string= (first (getf item :result)) + "<
http://some.where/ii/role-2
>"))) + (is (or (string= (second (getf item :result)) + role-1) + (string= (second (getf item :result)) + role-2) + (string= (second (getf item :result)) + "<
http://some.where/ii/role-2
>")))) + ((string= (getf item :variable) "assoc2") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/association
>"))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + + + + + +;TODO: tms:player, tms:topicProperty, tms:scope, tms:value, complex filter +;TODO: "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> +; SELECT * WHERE { +; ?assoc tms:reifier <
http://some.where/ii/association-reifier
>. +; ?assoc tms:role ?roles} +; => ?assoc =
http://some.where/ii/association
+; => ?roles = (
http://some.where/ii/role-2
, _:r????) (defun run-sparql-tests () Modified: trunk/src/unit_tests/sparql_test.xtm ============================================================================== --- trunk/src/unit_tests/sparql_test.xtm (original) +++ trunk/src/unit_tests/sparql_test.xtm Fri Apr 1 08:50:49 2011 @@ -201,13 +201,14 @@ </tm:topic> <tm:association reifier="
http://some.where/ii/association-reifier
"> - <tm:itemIdentity href="
http://somw.where/ii/association
"/> + <tm:itemIdentity href="
http://some.where/ii/association
"/> <tm:type><tm:topicRef href="#written-by"/></tm:type> <tm:role reifier="
http://some.where/ii/role-reifier
"> <tm:type><tm:topicRef href="#writer"/></tm:type> <tm:topicRef href="#goethe"/> </tm:role> <tm:role> + <tm:itemIdentity href="
http://some.where/ii/role-2
"/> <tm:type><tm:topicRef href="#written"/></tm:type> <tm:topicRef href="#zauberlehrling"/> </tm:role>
1
0
0
0
[isidorus-cvs] r399 - in trunk/src: TM-SPARQL model unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 07:22:42 2011 New Revision: 399 Log: TM-SPARQL: finished the unit-tests for the special predicate tms:reifier; fixed a problem with 2-dim. lists; fixed a bug in get-item-by-content; added get-most-recent-version to CharacteristicC, PointerC, and RoleC Modified: trunk/src/TM-SPARQL/sparql.lisp trunk/src/TM-SPARQL/sparql_special_uris.lisp trunk/src/model/datamodel.lisp trunk/src/unit_tests/sparql_test.lisp Modified: trunk/src/TM-SPARQL/sparql.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql.lisp (original) +++ trunk/src/TM-SPARQL/sparql.lisp Fri Apr 1 07:22:42 2011 @@ -769,14 +769,16 @@ (pred (when (iri-p (predicate construct)) (value (predicate construct))))) (cond ((variable-p (object construct)) - (append (filter-characteristics - subj pred nil nil :revision revision) - (filter-associations - subj pred nil :revision revision))) + (when (typep subj 'TopicC) + (append (filter-characteristics + subj pred nil nil :revision revision) + (filter-associations + subj pred nil :revision revision)))) ((literal-p (object construct)) - (filter-characteristics - subj pred (value (object construct)) - (literal-datatype (object construct)) :revision revision)) + (when (typep subj 'TopicC) + (filter-characteristics + subj pred (value (object construct)) + (literal-datatype (object construct)) :revision revision))) ((iri-p (object construct)) (filter-associations subj pred (value (object construct)) :revision revision))))))) Modified: trunk/src/TM-SPARQL/sparql_special_uris.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_special_uris.lisp (original) +++ trunk/src/TM-SPARQL/sparql_special_uris.lisp Fri Apr 1 07:22:42 2011 @@ -114,16 +114,19 @@ (let ((player-top (player (value subj) :revision revision))) (when player-top - (list :subject subj-uri - :predicate pred-uri - :object (sparql-node player-top :revision revision))))) + (list + (list + :subject subj-uri + :predicate pred-uri + :object (sparql-node player-top :revision revision)))))) ((not (variable-p obj)) (let ((parent-roles (player-in-roles (value obj) :revision revision))) (loop for role in parent-roles - collect (list :subject (sparql-node role :revision revision) - :predicate pred-uri - :object (sparql-node (player role :revision revision) + collect (list + :subject (sparql-node role :revision revision) + :predicate pred-uri + :object (sparql-node (player role :revision revision) :revision revision))))) (t ; only pred is given (let ((all-roles @@ -163,9 +166,10 @@ ((not (variable-p obj)) (let ((parent-assoc (parent (value obj) :revision revision))) (when revision - (list :subject (sparql-node parent-assoc :revision revision) - :predicate pred-uri - :object obj-uri)))) + (list + (list :subject (sparql-node parent-assoc :revision revision) + :predicate pred-uri + :object obj-uri))))) (t ; only pred is given (let ((assocs (remove-null @@ -211,9 +215,10 @@ ((not (variable-p obj)) (let ((parent-top (parent (value obj) :revision revision))) (when revision - (list :subject (sparql-node parent-top :revision revision) - :predicate pred-uri - :object obj-uri)))) + (list + (list :subject (sparql-node parent-top :revision revision) + :predicate pred-uri + :object obj-uri))))) (t ; only pred is given (let ((topics (remove-null @@ -353,9 +358,10 @@ (let ((reifier-top (reifier (value subj) :revision revision))) (when reifier-top - (list :subject subj-uri - :predicate pred-uri - :object (sparql-node reifier-top :revision revision))))) + (list + (list :subject subj-uri + :predicate pred-uri + :object (sparql-node reifier-top :revision revision)))))) ((not (variable-p obj)) (let ((reified-cons (reified-construct (value obj) :revision revision))) Modified: trunk/src/model/datamodel.lisp ============================================================================== --- trunk/src/model/datamodel.lisp (original) +++ trunk/src/model/datamodel.lisp Fri Apr 1 07:22:42 2011 @@ -749,10 +749,13 @@ (typep inst class-symbol)) db-instances))) (if revision - (remove-if #'null - (map 'list #'(lambda(inst) - (find-item-by-revision inst revision)) - filtered-instances)) + (remove-null + (map 'list #'(lambda(inst) + (if (typep inst 'CHaracteristicC) + (find-item-by-revision inst revision + (parent inst :revision revision)) + (find-item-by-revision inst revision))) + filtered-instances)) filtered-instances)))) @@ -809,15 +812,17 @@ (defun get-item-by-content (content &key (revision *TM-REVISION*)) "Finds characteristics by their (atomic) content." - (flet - ((get-existing-instances (class-symbol) - (delete-if-not - #'(lambda (constr) - (find-item-by-revision constr revision)) - (elephant:get-instances-by-value class-symbol 'charvalue content)))) - (nconc (get-existing-instances 'OccurenceC) - (get-existing-instances 'NameC) - (get-existing-instances 'VariantC)))) + (let ((constructs + (nconc (elephant:get-instances-by-value 'NameC 'Charvalue content) + (elephant:get-instances-by-value 'OccurrenceC 'Charvalue content) + (elephant:get-instances-by-value 'VariantC 'Charvalue content)))) + (first + (remove-if + #'(lambda(construct) + (or (string/= (charvalue construct) content) + (not (find-item-by-revision construct revision + (parent construct :revision revision))))) + constructs)))) (defmacro with-revision (revision &rest body) @@ -1154,6 +1159,24 @@ construct))) +(defmethod find-most-recent-revision ((construct CharacteristicC)) + (loop for c-assoc in (slot-p construct 'parent) + when (find-most-recent-revision c-assoc) + return construct)) + + +(defmethod find-most-recent-revision ((construct PointerC)) + (loop for p-assoc in (slot-p construct 'identified-construct) + when (find-most-recent-revision p-assoc) + return construct)) + + +(defmethod find-most-recent-revision ((construct RoleC)) + (loop for r-assoc in (slot-p construct 'parent) + when (find-most-recent-revision r-assoc) + return construct)) + + (defun add-version-info(construct start-revision) "Adds 'construct' to the given version. If the construct is a VersionedConstructC add-to-version-history Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 07:22:42 2011 @@ -1709,5 +1709,48 @@ r-1)))) +(test test-all-3 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/ii/goethe-occ
> tms:reifier ?obj1. + ?subj1 tms:reifier <
http://some.where/ii/goethe-name-reifier
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 2)) + (map 'list #'(lambda(item) + (cond ((string= (getf item :variable) "subj1") + (is (string= + (first (getf item :result)) + (concat "_:n" + (write-to-string + (elephant::oid + (d:get-item-by-content "von Goethe"))))))) + ((string= (getf item :variable) "obj1") + (is (string= (first (getf item :result)) + "<
http://some.where/ii/goethe-occ-reifier
>"))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + + +(test test-all-4 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX tms:<
http://www.networkedplanet.com/tmsparql/
> + SELECT * WHERE { + <
http://some.where/ii/goethe-occ
> tms:reifier ?obj1. + ?subj1 tms:reifier <
http://some.where/ii/goethe-name-reifier
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 2)) + ))) + + (defun run-sparql-tests () (it.bese.fiveam:run! 'sparql-test:sparql-tests))
1
0
0
0
[isidorus-cvs] r398 - in trunk/src: TM-SPARQL unit_tests
by Lukas Giessmann
01 Apr '11
01 Apr '11
Author: lgiessmann Date: Fri Apr 1 06:04:00 2011 New Revision: 398 Log: TM-SPARQL: finished unit-tests for the special predicates rdf:type, a, and tmdm:type => fixed a problem with rdf:type Modified: trunk/src/TM-SPARQL/sparql_parser.lisp trunk/src/unit_tests/sparql_test.lisp Modified: trunk/src/TM-SPARQL/sparql_parser.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_parser.lisp (original) +++ trunk/src/TM-SPARQL/sparql_parser.lisp Fri Apr 1 06:04:00 2011 @@ -144,7 +144,14 @@ :elem-type 'IRI :value *type-psi*))) ((string-starts-with trimmed-str "<") - (parse-base-suffix-pair construct trimmed-str)) + (let ((result (parse-base-suffix-pair construct trimmed-str))) + (if (and (not (variable-p (getf result :value))) + (string= (value (getf result :value)) *rdf-type*)) + (list :next-query (getf result :next-query) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'IRI + :value *type-psi*)) + result))) ((or (string-starts-with trimmed-str "?") (string-starts-with trimmed-str "$")) (let ((result @@ -166,8 +173,14 @@ trimmed-str (original-query construct) "an IRI of the form prefix:suffix or <iri> but found a literal."))) (parse-literal-elem construct trimmed-str)) - (parse-prefix-suffix-pair construct trimmed-str))))))) - + (let ((result (parse-prefix-suffix-pair construct trimmed-str))) + (if (and (not (variable-p (getf result :value))) + (string= (value (getf result :value)) *rdf-type*)) + (list :next-query (getf result :next-query) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'IRI + :value *type-psi*)) + result)))))))) (defgeneric parse-literal-elem (construct query-string) (:documentation "A helper-function that returns a literal vaue of the form @@ -338,7 +351,7 @@ (:method ((construct SPARQL-Query) (query-string String)) (let* ((trimmed-str (cut-comment query-string)) (delimiters (list "." ";" "}" "<" " " (string #\newline) - (string #\tab) "#")) + (string #\tab))) ; "#")) (end-pos (search-first delimiters trimmed-str)) (elem-str (when end-pos (subseq trimmed-str 0 end-pos))) Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Fri Apr 1 06:04:00 2011 @@ -1635,7 +1635,7 @@ "SELECT * WHERE { ?subj1 <
http://some.where/tmsparql/first-name
> \"Johann Wolfgang\". ?subj2 <
http://some.where/tmsparql/last-name
> 'von Goethe'^^" - *xml-string* ". + *xml-string* ". ?subj3 <
http://some.where/tmsparql/date-of-birth
> '28.08.1749'^^" *xml-date* ". ?subj4 <
http://some.where/tmsparql/date-of-death
> '22.03.1832'^^" @@ -1683,5 +1683,31 @@ (is-true (d:get-item-by-psi *rdf-type* :revision 0)))) +(test test-all-2 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "PREFIX pref:<
http://www.w3.org/1999/02/
> + SELECT * WHERE { + ?subj1 a <
http://some.where/tmsparql/author
> . + ?subj2 <
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
> <
http://some.where/tmsparql/author
> . + ?subj3 <
http://psi.topicmaps.org/iso13250/model/type
> <
http://some.where/tmsparql/author
> . + ?subj4 pref:22-rdf-syntax-ns#type <
http://some.where/tmsparql/author
>" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 4)) + (map 'list #'(lambda(item) + (cond ((or (string= (getf item :variable) "subj1") + (string= (getf item :variable) "subj2") + (string= (getf item :variable) "subj3") + (string= (getf item :variable) "subj4")) + (is (string= (first (getf item :result)) + "<
http://some.where/tmsparql/author/goethe
>"))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)))) + + (defun run-sparql-tests () (it.bese.fiveam:run! 'sparql-test:sparql-tests))
1
0
0
0
[isidorus-cvs] r397 - in trunk/src: . TM-SPARQL base-tools unit_tests
by Lukas Giessmann
31 Mar '11
31 Mar '11
Author: lgiessmann Date: Thu Mar 31 07:34:18 2011 New Revision: 397 Log: tm-sparql: finished all unittests that checks the api's behaviour with different literal datatypes => fixed several bugs that handles xml-boolean, xml-integer, xml-decimal, xml-double, and xml-date values; fixed a bug in the xtm test file; extended the function "literal=" so any objects can be compared to other objects in the string^^datatype format. Modified: trunk/src/TM-SPARQL/sparql.lisp trunk/src/TM-SPARQL/sparql_parser.lisp trunk/src/TM-SPARQL/tmsparql_core_psis.xtm trunk/src/base-tools/base-tools.lisp trunk/src/constants.lisp trunk/src/isidorus.asd trunk/src/unit_tests/sparql_test.lisp trunk/src/unit_tests/sparql_test.xtm trunk/src/unit_tests/unittests-constants.lisp Modified: trunk/src/TM-SPARQL/sparql.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql.lisp (original) +++ trunk/src/TM-SPARQL/sparql.lisp Thu Mar 31 07:34:18 2011 @@ -502,7 +502,8 @@ (defun return-characteristics (literal-value literal-datatype) - "Returns all characteristica that own the specified value." + "Returns all characteristica that own the specified value. + Note the type xsd:date is not supported and so handled as a string." (declare (String literal-datatype)) (let ((chars (cond ((string= literal-datatype *xml-string*) @@ -516,7 +517,8 @@ (elephant:get-instances-by-value 'NameC 'charvalue literal-value)))) ((and (string= literal-datatype *xml-boolean*) - literal-value) + (or (and (stringp literal-value) (string= literal-value "true")) + (and (typep literal-value 'Boolean) literal-value))) (remove-if #'(lambda(elem) (string/= (charvalue elem) "true")) (append (elephant:get-instances-by-value @@ -524,7 +526,8 @@ (elephant:get-instances-by-value 'OccurrenceC 'charvalue "true")))) ((and (string= literal-datatype *xml-boolean*) - (not literal-value)) + (or (and (stringp literal-value) (string= literal-value "false")) + (and (typep literal-value 'Boolean) (not literal-value)))) (remove-if #'(lambda(elem) (string/= (charvalue elem) "false")) (append (elephant:get-instances-by-value @@ -541,9 +544,15 @@ (elephant:get-instances-by-value 'VariantC 'datatype literal-datatype) (elephant:get-instances-by-value - 'OccurrenceC 'datatype literal-datatype))))) + 'OccurrenceC 'datatype literal-datatype)))) + (user-val (if (stringp literal-value) + (concat "\"\"\"" literal-value "\"\"\"^^" + literal-datatype) + literal-value))) (remove-if #'(lambda(con) - (not (literal= (charvalue con) literal-value))) + (not (literal= (concat "\"\"\"" (charvalue con) + "\"\"\"^^" (datatype con)) + user-val))) constructs)))))) ;;elephant returns names, occurences, and variants if any string ;;value matches, so all duplicates have to be removed @@ -830,24 +839,53 @@ (get-item-by-any-id (value construct) :revision revision))))) +(defun split-literal-string (literal-string) + "Returns a list of the form (:value literal-value :datatype literal-type) + of a string literal-value^^literal-type." + (when (stringp literal-string) + (let ((str (cut-comment literal-string))) + (when (string-starts-with-one-of literal-string (list "\"" "'")) + (let* ((delimiter (cond ((string-starts-with str "'") "'") + ((string-starts-with str "\"\"\"") "\"\"\"") + (t "\""))) + (l-end (find-literal-end (subseq str (length delimiter)) delimiter)) + (l-value (subseq str (length delimiter) l-end)) + (l-rest (subseq str (+ (length delimiter) l-end))) + (l-type (if (string-starts-with l-rest "^^") + (subseq l-rest 2) + *xml-string*))) + (list :value l-value :datatype l-type)))))) + + (defun literal= (value-1 value-2) "Returns t if both arguments are equal. The equality function is searched in the table *equal-operators*." - (when (or (and (numberp value-1) (numberp value-2)) - (typep value-1 (type-of value-2)) - (typep value-2 (type-of value-1))) - (let ((operator (get-equal-operator value-1))) - (funcall operator value-1 value-2)))) + (let ((real-value-1 (let ((result (split-literal-string value-1))) + (if result + (cast-literal (getf result :value) + (getf result :datatype)) + value-1))) + (real-value-2 (let ((result (split-literal-string value-2))) + (if result + (cast-literal (getf result :value) + (getf result :datatype)) + value-2)))) + (when (or (and (numberp real-value-1) (numberp real-value-2)) + (typep value-1 (type-of real-value-2)) + (typep value-2 (type-of real-value-1))) + (let ((operator (get-equal-operator real-value-1))) + (funcall operator real-value-1 real-value-2))))) (defun filter-datatypable-by-value (construct literal-value literal-datatype) "A helper that compares the datatypable's charvalue with the passed literal value." (declare (d::DatatypableC construct) - (type (or Null String) literal-value literal-datatype)) + (type (or Null String) literal-datatype)) (when (or (not literal-datatype) (string= (datatype construct) literal-datatype)) - (if (not literal-value) + (if (and (not literal-value) + (string/= literal-datatype *xml-boolean*)) construct (handler-case (let ((occ-value (cast-literal (charvalue construct) @@ -869,7 +907,7 @@ "A helper that compares the occurrence's charvalue with the passed literal value." (declare (OccurrenceC occurrence) - (type (or Null String) literal-value literal-datatype)) + (type (or Null String) literal-datatype)) (filter-datatypable-by-value occurrence literal-value literal-datatype)) @@ -919,7 +957,8 @@ (by-literal (if literal-value (names-by-value construct #'(lambda(name) - (string= name literal-value)) + (literal= name literal-value)) + ;(string= name literal-value)) :revision revision) (names construct :revision revision))) (all-names (intersection by-type by-literal)) Modified: trunk/src/TM-SPARQL/sparql_parser.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_parser.lisp (original) +++ trunk/src/TM-SPARQL/sparql_parser.lisp Thu Mar 31 07:34:18 2011 @@ -288,17 +288,21 @@ (triple-delimiters (list ". " ";" " " (string #\tab) (string #\newline) "}")) - (end-pos (search-first triple-delimiters - trimmed-str))) + (end-pos (search-first triple-delimiters trimmed-str))) (unless end-pos (error (make-sparql-parser-condition trimmed-str (original-query construct) "'. ', , ';' ' ', '\\t', '\\n' or '}'"))) (let* ((literal-number - (read-from-string (subseq trimmed-str 0 end-pos))) + (read-from-string + (let ((str-value (subseq trimmed-str 0 end-pos))) + (if (string-ends-with str-value ".") + (progn (decf end-pos) + (subseq str-value 0 (1- (length str-value)))) + str-value)))) (number-type (if (search "." (subseq trimmed-str 0 end-pos)) - *xml-double* ;could also be an xml:decimal, since the doucble has + *xml-double* ;could also be an xml:decimal, since the double has ;a bigger range it shouldn't matter *xml-integer*))) (unless (numberp literal-number) Modified: trunk/src/TM-SPARQL/tmsparql_core_psis.xtm ============================================================================== --- trunk/src/TM-SPARQL/tmsparql_core_psis.xtm (original) +++ trunk/src/TM-SPARQL/tmsparql_core_psis.xtm Thu Mar 31 07:34:18 2011 @@ -42,4 +42,7 @@ <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/value
"/> </topic> + <topic id="rdf-type"> + <subjectIdentifier href="
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"/> + </topic> </topicMap> Modified: trunk/src/base-tools/base-tools.lisp ============================================================================== --- trunk/src/base-tools/base-tools.lisp (original) +++ trunk/src/base-tools/base-tools.lisp Thu Mar 31 07:34:18 2011 @@ -113,20 +113,23 @@ (defun trim-whitespace-left (value) "Uses string-left-trim with a predefined character-list." - (declare (String value)) - (string-left-trim *white-space* value)) + (declare (type (or Null String) value)) + (when value + (string-left-trim *white-space* value))) (defun trim-whitespace-right (value) "Uses string-right-trim with a predefined character-list." - (declare (String value)) - (string-right-trim *white-space* value)) + (declare (type (or Null String) value)) + (when value + (string-right-trim *white-space* value))) (defun trim-whitespace (value) "Uses string-trim with a predefined character-list." - (declare (String value)) - (string-trim *white-space* value)) + (declare (type (or Null String) value)) + (when value + (string-trim *white-space* value))) (defun string-starts-with (str prefix &key (ignore-case nil)) Modified: trunk/src/constants.lisp ============================================================================== --- trunk/src/constants.lisp (original) +++ trunk/src/constants.lisp Thu Mar 31 07:34:18 2011 @@ -30,6 +30,7 @@ :*xml-decimal* :*xml-double* :*xml-integer* + :*xml-date* :*xml-uri* :*rdf2tm-ns* :*rdf-statement* @@ -109,6 +110,8 @@ (defparameter *xml-integer* "
http://www.w3.org/2001/XMLSchema#integer
") +(defparameter *xml-date* "
http://www.w3.org/2001/XMLSchema#date
") + (defparameter *xml-decimal* "
http://www.w3.org/2001/XMLSchema#decimal
") (defparameter *xml-double* "
http://www.w3.org/2001/XMLSchema#double
") Modified: trunk/src/isidorus.asd ============================================================================== --- trunk/src/isidorus.asd (original) +++ trunk/src/isidorus.asd Thu Mar 31 07:34:18 2011 @@ -149,6 +149,7 @@ (:static-file "reification_xtm1.0.xtm") (:static-file "reification_xtm2.0.xtm") (:static-file "reification.rdf") + (:static-file "sparql_test.xtm") (:file "atom-conf") (:file "unittests-constants" :depends-on ("dangling_topicref.xtm" Modified: trunk/src/unit_tests/sparql_test.lisp ============================================================================== --- trunk/src/unit_tests/sparql_test.lisp (original) +++ trunk/src/unit_tests/sparql_test.lisp Thu Mar 31 07:34:18 2011 @@ -1625,7 +1625,63 @@ "<
http://some.where/psis/poem/erlkoenig
>" "<
http://some.where/psis/poem/zauberlehrling
>") :test #'string=)))))) - + + +(test test-all-1 + "Tests the entire module with the file sparql_test.xtm" + (with-fixture with-tm-filled-db ("data_base" *sparql_test.xtm*) + (tm-sparql:init-tm-sparql) + (let* ((q-1 (concat + "SELECT * WHERE { + ?subj1 <
http://some.where/tmsparql/first-name
> \"Johann Wolfgang\". + ?subj2 <
http://some.where/tmsparql/last-name
> 'von Goethe'^^" + *xml-string* ". + ?subj3 <
http://some.where/tmsparql/date-of-birth
> '28.08.1749'^^" + *xml-date* ". + ?subj4 <
http://some.where/tmsparql/date-of-death
> '22.03.1832'^^" + *xml-date* ". + ?subj5 <
http://some.where/tmsparql/years
> 82.0. + ?subj6 <
http://some.where/tmsparql/years
> 82. + ?subj7 <
http://some.where/tmsparql/years
> '82'^^" *xml-integer* ". + ?subj8 <
http://some.where/tmsparql/isDead
> true. + ?subj9 <
http://some.where/tmsparql/isDead
> 'true'^^" *xml-boolean* ". + ?subj10 <
http://some.where/tmsparql/isDead
> 'false'^^" *xml-boolean* ". + ?subj11 <
http://some.where/tmsparql/isDead
> false" + "}")) + (r-1 (tm-sparql:result (make-instance 'TM-SPARQL:SPARQL-Query :query q-1)))) + (is-true (= (length r-1) 11)) + (map 'list #'(lambda(item) + (cond ((or (string= (getf item :variable) "subj1") + (string= (getf item :variable) "subj2") + (string= (getf item :variable) "subj3") + (string= (getf item :variable) "subj4") + (string= (getf item :variable) "subj6") + (string= (getf item :variable) "subj7") + (string= (getf item :variable) "subj8") + (string= (getf item :variable) "subj9")) + (is (string= (first (getf item :result)) + "<
http://some.where/tmsparql/author/goethe
>"))) + ((or (string= (getf item :variable) "subj5") + (string= (getf item :variable) "subj10") + (string= (getf item :variable) "subj11")) + (is-false (getf item :result))) + (t + (is-true (format t "bad variable-name found"))))) + r-1)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/topicProperty
" + :revision 0)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/reifier
" + :revision 0)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/role
" + :revision 0)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/player
" + :revision 0)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/scope
" + :revision 0)) + (is-true (d:get-item-by-psi "
http://www.networkedplanet.com/tmsparql/value
" + :revision 0)) + (is-true (d:get-item-by-psi *rdf-type* :revision 0)))) + (defun run-sparql-tests () (it.bese.fiveam:run! 'sparql-test:sparql-tests)) Modified: trunk/src/unit_tests/sparql_test.xtm ============================================================================== --- trunk/src/unit_tests/sparql_test.xtm (original) +++ trunk/src/unit_tests/sparql_test.xtm Thu Mar 31 07:34:18 2011 @@ -73,7 +73,7 @@ </tm:topic> <tm:topic id="last-name"> - <tm:subjectIdentifier href="
http://some.where/tmsparql/first-name
"/> + <tm:subjectIdentifier href="
http://some.where/tmsparql/last-name
"/> <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf> </tm:topic> @@ -117,6 +117,11 @@ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> </tm:topic> + <tm:topic id="isAlive"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/isAlive
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + <tm:topic id="reifier-type"> <tm:subjectIdentifier href="
http://some.where/tmsparql/reifier-type
"/> <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf> @@ -147,19 +152,23 @@ <tm:occurrence reifier="
http://some.where/ii/goethe-occ-reifier
"> <tm:itemIdentity href="
http://some.where/ii/goethe-occ
"/> <tm:type><tm:topicRef href="#date-of-birth"/></tm:type> - <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#date
">28.08.1749</tm:resourceData> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#date
">28.08.1749</tm:resourceData> </tm:occurrence> <tm:occurrence> <tm:type><tm:topicRef href="#date-of-death"/></tm:type> - <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#integer
">22.03.1832</tm:resourceData> <!-- bad data type --> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#date
">22.03.1832</tm:resourceData> </tm:occurrence> <tm:occurrence> <tm:type><tm:topicRef href="#years"/></tm:type> - <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#integer
">82</tm:resourceData> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#integer
">82</tm:resourceData> </tm:occurrence> <tm:occurrence> <tm:type><tm:topicRef href="#isDead"/></tm:type> - <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#boolean
">true</tm:resourceData> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#boolean
">true</tm:resourceData> + </tm:occurrence> + <tm:occurrence> + <tm:type><tm:topicRef href="#isAlive"/></tm:type> <!-- redundancy: needed for checking booleans --> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#boolean
">false</tm:resourceData> </tm:occurrence> </tm:topic> Modified: trunk/src/unit_tests/unittests-constants.lisp ============================================================================== --- trunk/src/unit_tests/unittests-constants.lisp (original) +++ trunk/src/unit_tests/unittests-constants.lisp Thu Mar 31 07:34:18 2011 @@ -30,6 +30,7 @@ :*atom_test.xtm* :*atom-conf.lisp* :*poems.xtm* + :*sparql_test.xtm* :*poems_light.rdf* :*poems_light.xtm* :*poems_light.xtm.txt* @@ -105,6 +106,10 @@ (asdf:component-pathname (asdf:find-component *unit-tests-component* "poems.xtm"))) +(defparameter *sparql_test.xtm* + (asdf:component-pathname + (asdf:find-component *unit-tests-component* "sparql_test.xtm"))) + (defparameter *poems_light.rdf* (asdf:component-pathname (asdf:find-component *unit-tests-component* "poems_light.rdf")))
1
0
0
0
[isidorus-cvs] r396 - trunk/src/unit_tests
by Lukas Giessmann
03 Mar '11
03 Mar '11
Author: lgiessmann Date: Thu Mar 3 12:00:13 2011 New Revision: 396 Log: tmsparql: added a new test file for the sparql-api Added: trunk/src/unit_tests/sparql_test.xtm Added: trunk/src/unit_tests/sparql_test.xtm ============================================================================== --- (empty file) +++ trunk/src/unit_tests/sparql_test.xtm Thu Mar 3 12:00:13 2011 @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ======================================================================= --> +<!-- Isidorus --> +<!-- (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff --> +<!-- --> +<!-- Isidorus is freely distributable under the LLGPL license. --> +<!-- This ajax module uses the frameworks PrototypeJs and Scriptaculous, --> +<!-- both are distributed under the MIT license. --> +<!-- You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt, --> +<!-- trunk/docs/LGPL-LICENSE.txt and in --> +<!-- trunk/src/ajax/javascripts/external/MIT-LICENSE.txt. --> +<!-- ======================================================================= --> + +<tm:topicMap version="2.0" xmlns:tm="
http://www.topicmaps.org/xtm/
"> + <tm:topic id="topictype"> + <tm:subjectIdentifier href="
http://psi.topicmaps.org/tmcl/topic-type
"/> + <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="written-by"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/written-by
"/> + <tm:instanceOf><tm:topicRef href="#associationtype"/></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="written"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/written
"/> + <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="writer"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/writer
"/> + <tm:instanceOf><tm:topicRef href="#roletype"/></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> + + <tm:topic id="author"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/author
"/> + <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="poem"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/poem
"/> + <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="first-name"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/first-name
"/> + <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="last-name"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/first-name
"/> + <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="title"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/title
"/> + <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="display-name"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/display-name
"/> + <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="de"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/de
"/> + <tm:instanceOf><tm:topicRef href="#scopetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="date-of-birth"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/date-of-birth
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="date-of-death"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/date-of-death
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="poem-content"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/poem-content
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="years"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/years
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="isDead"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/isDead
"/> + <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="reifier-type"> + <tm:subjectIdentifier href="
http://some.where/tmsparql/reifier-type
"/> + <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf> + </tm:topic> + + + + <tm:topic id="goethe"> + <tm:instanceOf><tm:topicRef href="#author"/></tm:instanceOf> + <tm:subjectIdentifier href="
http://some.where/tmsparql/author/goethe
"/> + <tm:itemIdentity href="
http://some.where/ii/goethe
"/> + <tm:name> + <tm:type><tm:topicRef href="#first-name"/></tm:type> + <tm:value>Johann Wolfgang</tm:value> + </tm:name> + <tm:name reifier="
http://some.where/ii/goethe-name-reifier
"> + <tm:type><tm:topicRef href="#last-name"/></tm:type> + <tm:value>von Goethe</tm:value> + <tm:variant> + <tm:scope><tm:topicRef href="#display-name"/></tm:scope> + <tm:resourceData datatype="
http://www.w3.org/2001/XMLSchema#string
">Goethe</tm:resourceData> + </tm:variant> + </tm:name> + <tm:name> + <tm:itemIdentity href="
http://some.where/ii/goethe-untyped-name
"/> + <tm:value>Johann Wolfgang von Goethe</tm:value> <!-- untyped name --> + </tm:name> + <tm:occurrence reifier="
http://some.where/ii/goethe-occ-reifier
"> + <tm:itemIdentity href="
http://some.where/ii/goethe-occ
"/> + <tm:type><tm:topicRef href="#date-of-birth"/></tm:type> + <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#date
">28.08.1749</tm:resourceData> + </tm:occurrence> + <tm:occurrence> + <tm:type><tm:topicRef href="#date-of-death"/></tm:type> + <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#integer
">22.03.1832</tm:resourceData> <!-- bad data type --> + </tm:occurrence> + <tm:occurrence> + <tm:type><tm:topicRef href="#years"/></tm:type> + <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#integer
">82</tm:resourceData> + </tm:occurrence> + <tm:occurrence> + <tm:type><tm:topicRef href="#isDead"/></tm:type> + <tm:resourceData href="
http://www.w3.org/2001/XMLSchema#boolean
">true</tm:resourceData> + </tm:occurrence> + </tm:topic> + + <tm:topic id="occ-reifier"> + <tm:itemIdentity href="
http://some.where/ii/goethe-occ-reifier
"/> + <tm:instanceOf><tm:topicRef href="#reifier-type"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="goethe-name-reifier"> + <tm:itemIdentity href="
http://some.where/ii/goethe-name-reifier
"/> + <tm:instanceOf><tm:topicRef href="#reifier-type"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="zauberlehrling"> + <tm:subjectIdentifier href="
http://some.where/psis/poem/zauberlehrling
"/> + <tm:instanceOf> + <tm:topicRef href="#poem"/></tm:instanceOf> + <tm:name> + <tm:type><tm:topicRef href="#title"/></tm:type> + <tm:value>Der Zauberlehrling</tm:value> + </tm:name> + <tm:occurrence> + <tm:type><tm:topicRef href="#poem-content"/></tm:type> + <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! + ... + </tm:resourceData> + </tm:occurrence> + </tm:topic> + + <tm:association reifier="
http://some.where/ii/association-reifier
"> + <tm:itemIdentity href="
http://somw.where/ii/association
"/> + <tm:type><tm:topicRef href="#written-by"/></tm:type> + <tm:role reifier="
http://some.where/ii/role-reifier
"> + <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:topic id="association-reifier"> + <tm:itemIdentity href="
http://some.where/ii/association-reifier
"/> + <tm:instanceOf><tm:topicRef href="#reifier-type"/></tm:instanceOf> + </tm:topic> + + <tm:topic id="role-reifier"> + <tm:itemIdentity href="
http://some.where/ii/role-reifier
"/> + <tm:instanceOf><tm:topicRef href="#reifier-type"/></tm:instanceOf> + </tm:topic> + +</tm:topicMap>
1
0
0
0
[isidorus-cvs] r395 - in trunk: playground/abcl-test playground/abcl-test/.settings playground/abcl-test/lib playground/abcl-test/lisp-code playground/abcl-test/lisp-code/TM-SPARQL playground/abcl-test/lisp-code/base-tools playground/abcl-test/lisp-code/test-code playground/abcl-test/src playground/abcl-test/src/program src/TM-SPARQL
by Lukas Giessmann
16 Feb '11
16 Feb '11
Author: lgiessmann Date: Wed Feb 16 04:51:06 2011 New Revision: 395 Log: playground: added a project that uses some test cases with ABCL Added: trunk/playground/abcl-test/ trunk/playground/abcl-test/.classpath trunk/playground/abcl-test/.project trunk/playground/abcl-test/.settings/ trunk/playground/abcl-test/.settings/org.eclipse.jdt.core.prefs trunk/playground/abcl-test/lib/ trunk/playground/abcl-test/lib/abcl.jar (contents, props changed) trunk/playground/abcl-test/lisp-code/ trunk/playground/abcl-test/lisp-code/TM-SPARQL/ trunk/playground/abcl-test/lisp-code/TM-SPARQL/filter_wrappers.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_constants.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_filter.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_parser.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_special_uris.lisp trunk/playground/abcl-test/lisp-code/TM-SPARQL/tmsparql_core_psis.xtm trunk/playground/abcl-test/lisp-code/base-tools/ trunk/playground/abcl-test/lisp-code/base-tools/base-tools.lisp trunk/playground/abcl-test/lisp-code/test-code/ trunk/playground/abcl-test/lisp-code/test-code/functions.lisp trunk/playground/abcl-test/src/ trunk/playground/abcl-test/src/program/ trunk/playground/abcl-test/src/program/Main.java Modified: trunk/src/TM-SPARQL/sparql_special_uris.lisp Added: trunk/playground/abcl-test/.classpath ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/.classpath Wed Feb 16 04:51:06 2011 @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="lib" path="lib/abcl.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> Added: trunk/playground/abcl-test/.project ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/.project Wed Feb 16 04:51:06 2011 @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>abcl-test</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> Added: trunk/playground/abcl-test/.settings/org.eclipse.jdt.core.prefs ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/.settings/org.eclipse.jdt.core.prefs Wed Feb 16 04:51:06 2011 @@ -0,0 +1,12 @@ +#Wed Feb 16 08:34:56 CET 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 Added: trunk/playground/abcl-test/lib/abcl.jar ============================================================================== Binary file. No diff available. Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/filter_wrappers.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/filter_wrappers.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,192 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + + +(defpackage :filter-functions + (:use :base-tools :constants :tm-sparql) + (:import-from :cl progn handler-case let)) + + +(defun filter-functions::normalize-value (value) + "Returns the normalized value, i.e. if a literal + is passed as '12'^^xsd:integer 12 is returned." + (cond ((not (stringp value)) + value) + ((or (base-tools:string-starts-with value "'") + (base-tools:string-starts-with value "\"")) + (let* ((literal-result (tm-sparql::get-literal value)) + (literal-value + (cond ((or (base-tools:string-starts-with + (getf literal-result :literal) "\"\"\"") + (base-tools:string-starts-with + (getf literal-result :literal) "'''")) + (subseq (getf literal-result :literal) 3 + (- (length (getf literal-result :literal)) 3))) + (t + (subseq (getf literal-result :literal) 1 + (- (length (getf literal-result :literal)) 1))))) + (given-datatype + (when (base-tools:string-starts-with + (getf literal-result :next-string) "^^") + (subseq (getf literal-result :next-string) 2)))) + (tm-sparql::cast-literal literal-value given-datatype))) + (t + value))) + + +(defun filter-functions::not(x) + (not (filter-functions::normalize-value x))) + + +(defun filter-functions::one+(x) + (1+ (filter-functions::normalize-value x))) + + +(defun filter-functions::one-(x) + (1- (filter-functions::normalize-value x))) + + +(defun filter-functions::+(x y) + (+ (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::-(x y) + (- (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::*(x y) + (* (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::/(x y) + (/ (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::or(x y) + (or (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::and(x y) + (and (filter-functions::normalize-value x) + (filter-functions::normalize-value y))) + + +(defun filter-functions::=(x y) + (let ((local-x (filter-functions::normalize-value x)) + (local-y (filter-functions::normalize-value y))) + (cond ((and (stringp local-x) (stringp local-y)) + (string= local-x local-y)) + ((and (numberp local-x)( numberp local-y)) + (= local-x local-y)) + (t + (eql local-x local-y))))) + + +(defun filter-functions::!=(x y) + (filter-functions::not + (filter-functions::= x y))) + + +(defun filter-functions::<(x y) + (let ((local-x (filter-functions::normalize-value x)) + (local-y (filter-functions::normalize-value y))) + (cond ((and (numberp local-x) (numberp local-y)) + (< local-x local-y)) + ((and (stringp local-x) (stringp local-y)) + (string< local-x local-y)) + ((and (typep local-x 'Boolean) (typep local-y 'Boolean)) + (and (not local-x) local-y)) + (t + nil)))) + + +(defun filter-functions::>(x y) + (filter-functions::not + (filter-functions::< x y))) + + +(defun filter-functions::<=(x y) + (filter-functions::or + (filter-functions::< x y) + (filter-functions::= x y))) + + +(defun filter-functions::>=(x y) + (filter-functions::or + (filter-functions::> x y) + (filter-functions::= x y))) + + +(defun filter-functions::regex(str pattern &optional flags) + (let* ((local-str (filter-functions::normalize-value str)) + (local-flags (filter-functions::normalize-value flags)) + (case-insensitive (when (find #\i local-flags) t)) + (multi-line (when (find #\m local-flags) t)) + (single-line (when (find #\s local-flags) t)) + (local-pattern + (if (find #\x local-flags) + (base-tools:string-replace + (base-tools:string-replace + (base-tools:string-replace + (base-tools:string-replace + (filter-functions::normalize-value pattern) + (string #\newline) "") + (string #\tab) "") (string #\cr) "") " " "") + (filter-functions::normalize-value pattern))) + (scanner + (ppcre:create-scanner local-pattern + :case-insensitive-mode case-insensitive + :multi-line-mode multi-line + :single-line-mode single-line))) + (ppcre:scan scanner local-str))) + + +(defun filter-functions::bound(x) + (boundp x)) + + +(defun filter-functions::isLITERAL(x) + (or (numberp x) + (not (and (base-tools:string-starts-with x "<") + (base-tools:string-ends-with x ">") + (base-tools:absolute-uri-p x))))) + + +(defun filter-functions::datatype(x) + (let ((type-suffix + (when (and (stringp x) + (or (base-tools:string-starts-with x "'") + (base-tools:string-starts-with x "\""))) + (let* ((result (base-tools:get-literal x)) + (literal-datatype + (when (base-tools:string-starts-with + (getf result :next-string) "^^") + (subseq (getf result :next-string) 2)))) + literal-datatype)))) + (cond (type-suffix type-suffix) + ((integerp x) constants::*xml-integer*) + ((floatp x) constants::*xml-decimal*) + ((numberp x) constants::*xml-double*) + ((stringp x) constants::*xml-string*) + (t (type-of x))))) + + +(defun filter-functions::str(x) + (if (stringp x) + (if (and (base-tools:string-starts-with x "<") + (base-tools:string-ends-with x ">") + (base-tools:absolute-uri-p (subseq x 1 (1- (length x))))) + (subseq x 1 (1- (length x))) + x) + (write-to-string x))) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,1221 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + +(defpackage :TM-SPARQL + (:use :cl :datamodel :base-tools :exceptions :constants + :TM-SPARQL-Constants :xml-importer :xml-constants + :isidorus-threading :xml-tools) + (:export :SPARQL-Query + :result + :init-tm-sparql)) + + + +(in-package :TM-SPARQL) + +(defvar *empty-label* "_empty_label_symbol" "A label symobl for empyt prefix labels") + +(defvar *equal-operators* nil "A Table taht contains tuples of + classes and equality operators.") + + + +(defgeneric sparql-node (construct &key revision) + (:documentation "Returns a string of the form <uri> or _t123 that represents + a resource node or a blank node.") + (:method ((construct TopicMapConstructC) &key (revision d:*TM-REVISION*)) + (declare (Integer revision)) + (let ((uri-string (any-id construct :revision revision))) + (if uri-string + (concat "<" uri-string ">") + (let ((oid-string (write-to-string (elephant::oid construct))) + (pref (subseq (symbol-name (type-of construct)) 0 1))) + (concat "_:" (string-downcase pref) oid-string)))))) + + +(defun init-tm-sparql (&optional (revision (get-revision))) + "Imports the file tmsparql_core_psis.xtm. core_psis.xtm has to be imported + before." + (with-writer-lock + (with-tm (revision "tmsparql.xtm" (concat *tms* "topic-map")) + (let ((core-dom (cxml:parse-file *tmsparql_core_psis.xtm* + (cxml-dom:make-dom-builder))) + (xtm-id (reverse + (base-tools:string-until + (reverse + (pathname-name + xml-constants:*tmsparql_core_psis.xtm*)) "/")))) + (elephant:ensure-transaction (:txn-nosync t) + (loop for top-elem across + (xpath-child-elems-by-qname (dom:document-element core-dom) + *xtm2.0-ns* "topic") + do (let ((top + (from-topic-elem-to-stub top-elem revision + :xtm-id xtm-id))) + (add-to-tm xml-importer::tm top)))))))) + + + +(defun init-*equal-operators* () + (setf *equal-operators* + (list (list :class 'Boolean :operator #'eql) + (list :class 'String :operator #'string=) + (list :class 'Number :operator #'=)))) + + +(init-*equal-operators*) + + +(defun get-equal-operator (value) + (let ((entry + (find-if #'(lambda(entry) + (typep value (getf entry :class))) + *equal-operators*))) + (when entry + (getf entry :operator)))) + + +(defclass SPARQL-Triple-Elem() + ((elem-type :initarg :elem-type + :reader elem-type + :type Symbol + :initform (error + (make-condition + 'missing-argument-error + :message "From SPARQL-Triple-Elem(): elem-type must be set")) + :documentation "Contains information about the type of this element + possible values are 'IRI, 'VARIABLE, or 'LITERAL") + (value :initarg :value + :accessor value + :type T + :initform nil + :documentation "Contains the actual value of any type.") + (literal-lang :initarg :literal-lang + :accessor literal-lang + :initform nil + :type String + :documentation "Contains the @lang attribute of a literal") + (literal-datatype :initarg :literal-datatype + :accessor literal-datatype + :type String + :initform nil + :documentation "Contains the datatype of the literal, + e.g. xml:string")) + (:documentation "Represents one element of an RDF-triple.")) + + +(defclass SPARQL-Triple() + ((subject :initarg :subject + :accessor subject + :type SPARQL-Triple-Elem + :initform (error + (make-condition + 'missing-argument-error + :message "From SPARQL-Triple(): subject must be set")) + :documentation "Represents the subject of an RDF-triple.") + (subject-result :initarg :subject-result + :accessor subject-result + :type T + :initform nil + :documentation "Contains the result of the subject triple elem.") + (predicate :initarg :predicate + :accessor predicate + :type SPARQL-Triple-Elem + :initform (error + (make-condition + 'missing-argument-error + :message "From SPARQL-Triple(): predicate must be set")) + :documentation "Represents the predicate of an RDF-triple.") + (predicate-result :initarg :predicate-result + :accessor predicate-result + :type T + :initform nil + :documentation "Contains the result of the predicate + triple elem.") + (object :initarg :object + :accessor object + :type SPARQL-Triple-Elem + :initform (error + (make-condition + 'missing-argument-error + :message "From SPARQL-Triple-(): object must be set")) + :documentation "Represents the subject of an RDF-triple.") + (object-result :initarg :object-result + :accessor object-result + :type T + :initform nil + :documentation "Contains the result of the object triple elem.")) + (:documentation "Represents an entire RDF-triple.")) + + +(defclass SPARQL-Query () + ((revision :initarg :revision + :accessor revision + :type Integer + :initform 0 + :documentation "Represents the revision in which all the queries + are processed in the DB.") + (original-query :initarg :query + :accessor original-query ;this value is only for internal + ;purposes and mustn't be reset + :type String + :initform (error + (make-condition + 'missing-argument-error + :message "From TM-Query(): original-query must be set")) + :documentation "Containst the original received querry as string") + (variables :initarg :variables + :accessor variables ;this value is only for internal purposes + ;purposes and mustn't be reset + :type List + :initform nil + :documentation "A list of that contains the variable + names as strings.") + (prefixes :initarg :prefixes + :accessor prefixes ;this value is only for internal purposes + ;purposes and mustn't be reset + :type List + :initform nil + :documentation "A list of the form + ((:label 'id' :value 'prefix'))") + (base-value :initarg :base ;initialy the requester's address + :accessor base-value ;this value is only for internal purposes + ;purposes and mustn't be reset + :type String + :initform nil + :documentation "Contains the last set base-value.") + (select-group :initarg :select-group + :accessor select-group ;this value is only for + ;internal purposes purposes + ;and mustn't be reset + :type List + :initform nil + :documentation "Contains a SPARQL-Group that represents + the entire inner select-where statement.") + (filters :initarg filters + :accessor filters ;this value is only for internal purposes + ;purposes and mustn't be reset + :type List ;a list of strings + :initform nil + :documentation "Contains strings, each string represents a filter + that was transformed to lisp code and can be evoked + on each triple in the list select-group.")) + (:documentation "This class represents the entire request.")) + + +(defgeneric *-p (construct) + (:documentation "Returns t if the user selected all variables with *.") + (:method ((construct SPARQL-Query)) + (loop for var in (variables construct) + when (string= var "*") + return t))) + + +(defgeneric add-filter (construct filter) + (:documentation "Pushes the filter string to the corresponding list in + the construct.") + (:method ((construct SPARQL-Query) (filter String)) + (push filter (filters construct)))) + + +(defmethod variables ((construct SPARQL-Triple)) + "Returns all variable names that are contained in the passed element." + (remove-duplicates + (remove-null + (list (when (variable-p (subject construct)) + (value (subject construct))) + (when (variable-p (predicate construct)) + (value (predicate construct))) + (when (variable-p (object construct)) + (value (object construct))))) + :test #'string=)) + + +(defgeneric add-triple (construct triple) + (:documentation "Adds a triple object to the select-group list.") + (:method ((construct SPARQL-Query) (triple SPARQL-Triple)) + (push triple (slot-value construct 'select-group)))) + + +(defgeneric (setf elem-type) (construct elem-type) + (:documentation "Sets the passed elem-type on the passed cosntruct.") + (:method ((construct SPARQL-Triple-Elem) (elem-type Symbol)) + (when (and (not (eql elem-type 'IRI)) + (not (eql elem-type 'VARIABLE)) + (not (eql elem-type 'LITERAL))) + (error (make-condition + 'bad-argument-error + :message (format nil "Expected a one of the symbols ~a, but get ~a~%" + '('IRI 'VARIABLE 'LITERAL) elem-type)))) + (setf (slot-value construct 'elem-type) elem-type))) + + +(defgeneric add-prefix (construct prefix-label prefix-value) + (:documentation "Adds the new prefix tuple to the list of all existing. + If there already exists a tuple with the same label + the label's value will be overwritten by the new value.") + (:method ((construct SPARQL-Query) (prefix-label String) (prefix-value String)) + (let ((existing-tuple + (find-if #'(lambda(x) + (string= (getf x :label) prefix-label)) + (prefixes construct)))) + (if existing-tuple + (setf (getf existing-tuple :value) prefix-value) + (push (list :label prefix-label :value prefix-value) + (prefixes construct)))))) + + +(defgeneric get-prefix (construct string-with-prefix) + (:documentation "Returns the URL corresponding to the found prefix-label + followed by : and the variable. Otherwise the return + value is nil.") + (:method ((construct SPARQL-query) (string-with-prefix String)) + (loop for entry in (prefixes construct) + when (string-starts-with string-with-prefix (concat (getf entry :label) ":")) + return (concatenate-uri + (getf entry :value) + (string-after string-with-prefix (concat (getf entry :label) ":")))))) + + +(defgeneric add-variable (construct variable-name) + (:documentation "Adds a new variable-name with its value to the aexisting list. + If a variable-already exists the existing entry will be + overwritten. An entry is of the form + (:variable string :value any-type).") + (:method ((construct SPARQL-Query) (variable-name String)) + (unless (find variable-name (variables construct) :test #'string=) + (push variable-name (variables construct))))) + + +(defgeneric make-variable-values(construct variable-name existing-results) + (:documentation "Returns a list of values that are bound to the passed + variable. The first occurrence of the given variable + is evaluated, since all occurrences have the same values, + because reduce-results is called before and makes an + intersection over all triples.") + (:method ((construct SPARQL-Query) (variable-name String) (existing-results List)) + (let* ((found-p nil) + (results + (loop for triple in (select-group construct) + when (and (variable-p (subject triple)) + (string= (value (subject triple)) variable-name)) + return (progn (setf found-p t) + (subject-result triple)) + when (and (variable-p (predicate triple)) + (string= (value (predicate triple)) variable-name)) + return (progn (setf found-p t) + (predicate-result triple)) + when (and (variable-p (object triple)) + (string= (value (object triple)) + variable-name)) + return (progn (setf found-p t) + (object-result triple)))) + (new-results nil)) + (if (not found-p) + existing-results + (if existing-results + (dolist (result results new-results) + (dolist (old-result existing-results) + (push (append old-result (list (list :variable-name variable-name + :variable-value result))) + new-results))) + (map 'list #'(lambda(result) + (list (list :variable-name variable-name + :variable-value result))) + results)))))) + + +(defun to-lisp-code (variable-values filter) + "Concatenates all variable names and elements with the filter expression + in a let statement and returns a string representing the corresponding + lisp code." + (declare (List variable-values)) + (let ((result "(let* ((true t)(false nil)")) + (dolist (var-elem variable-values) + (push-string (concat "(?" (getf var-elem :variable-name) " " + (write-to-string (getf var-elem :variable-value)) ")") + result) + (push-string (concat "($" (getf var-elem :variable-name) " " + (write-to-string (getf var-elem :variable-value)) ")") + result)) + (push-string (concat "(result " filter "))") result) + (push-string "(declare (Ignorable true false " result) + (when variable-values + (dolist (var-elem variable-values) + (push-string (concat "?" (getf var-elem :variable-name) " ") result) + (push-string (concat "$" (getf var-elem :variable-name) " ") result))) + (push-string ")) result)" result) + (concat "(handler-case " result " (condition () nil))"))) + + +(defun return-false-values (all-values true-values) + "Returns a list that contains all values from all-values that + are not contained in true-values." + (let ((local-all-values + (remove-duplicates (reduce #'(lambda(x y) (append x y)) all-values) + :test #'variable-list=)) + (results nil)) + (dolist (value local-all-values) + (when (not (find value true-values :test #'variable-list=)) + (push value results))) + results)) + + +(defun variable-list= (x y) + (and (string= (getf x :variable-name) + (getf y :variable-name)) + (literal= (getf x :variable-value) + (getf y :variable-value)))) + + +(defgeneric process-filters (construct) + (:documentation "Processes all filters by calling invoke-filter.") + (:method ((construct SPARQL-Query)) + (dolist (filter (filters construct)) + (let* ((filter-variable-names + (get-variables-from-filter-string filter)) + (filter-variable-values nil) + (true-values nil)) + (dolist (var-name filter-variable-names) + (setf filter-variable-values + (make-variable-values construct var-name filter-variable-values))) + (dolist (filter (filters construct)) + (dolist (var-elem filter-variable-values) + (when (eval (read-from-string (to-lisp-code var-elem filter))) + (map 'list #'(lambda(list-elem) + (push list-elem true-values)) + var-elem)))) + (let ((values-to-remove + (return-false-values filter-variable-values + (remove-duplicates true-values + :test #'variable-list=)))) + (dolist (to-del values-to-remove) + (delete-rows-by-value construct (getf to-del :variable-name) + (getf to-del :variable-value)))))) + construct)) + + +(defgeneric idx-of (construct variable-name variable-value &key what) + (:documentation "Returns the idx of the variable with the name + variable-name and the value variable-value.") + (:method ((construct SPARQL-Triple) (variable-name String) + variable-value &key (what :subject)) + (declare (Keyword what)) + (let ((result nil) + (local-results + (cond ((eql what :subject) (subject-result construct)) + ((eql what :predicate) (predicate-result construct)) + ((eql what :object) (object-result construct)))) + (is-variable + (cond ((eql what :subject) + (and (variable-p (subject construct)) + (value (subject construct)))) + ((eql what :predicate) + (and (variable-p (predicate construct)) + (value (predicate construct)))) + ((eql what :object) + (and (variable-p (object construct)) + (value (object construct))))))) + (when is-variable + (remove-null + (dotimes (idx (length local-results)) + (when (literal= variable-value (elt local-results idx)) + (push idx result))))) + result))) + + +(defgeneric delete-rows-by-value (construct variable-name value-to-delete) + (:documentation "Deletes all rows that owns a variable with the + given value.") + (:method ((construct SPARQL-Query) (variable-name String) value-to-delete) + (dolist (triple (select-group construct)) + (let* ((subj-delete-idx-lst + (idx-of triple variable-name value-to-delete)) + (pred-delete-idx-lst + (idx-of triple variable-name value-to-delete :what :predicate)) + (obj-delete-idx-lst + (idx-of triple variable-name value-to-delete :what :object)) + (all-idxs (union (union subj-delete-idx-lst + pred-delete-idx-lst) + obj-delete-idx-lst))) + (when all-idxs + (let ((new-values nil)) + (dotimes (idx (length (subject-result triple))) + (when (not (find idx all-idxs)) + (push + (list :subject (elt (subject-result triple) idx) + :predicate (elt (predicate-result triple) idx) + :object (elt (object-result triple) idx)) + new-values))) + (setf (subject-result triple) + (map 'list #'(lambda(elem) (getf elem :subject)) new-values)) + (setf (predicate-result triple) + (map 'list #'(lambda(elem) (getf elem :predicate)) new-values)) + (setf (object-result triple) + (map 'list #'(lambda(elem) (getf elem :object)) new-values)))))) + construct)) + + +(defgeneric set-results (construct &key revision) + (:documentation "Calculates the result of a triple and set all the values in + the passed object.") + (:method ((construct SPARQL-Triple) &key (revision d:*TM-REVISION*)) + (declare (Integer revision)) + (set-tm-constructs construct :revision revision) + (when (not (iri-not-found-p construct)) ;there is only a result if all IRIs were found + (let ((results (append + (or (filter-by-given-subject construct :revision revision) + (filter-by-given-predicate construct :revision revision) + (filter-by-given-object construct :revision revision)) + (filter-by-special-uris construct :revision revision)))) + (map 'list #'(lambda(result) + (push (getf result :subject) (subject-result construct)) + (push (getf result :predicate) (predicate-result construct)) + (push (getf result :object) (object-result construct))) + ;;literal-datatype is not used and is not returned, since + ;;the values are returned as object of their specific type, e.g. + ;;integer, boolean, string, ... + results))))) + + +(defgeneric filter-by-given-object (construct &key revision) + (:documentation "Returns a list representing a triple that is the result + of a given object.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (and (not (variable-p (object construct))) + (variable-p (predicate construct)) + (variable-p (subject construct))) + (cond ((literal-p (object construct)) + (filter-by-characteristic-value (value (object construct)) + (literal-datatype (object construct)) + :revision revision)) + ((iri-p (object construct)) + (filter-by-otherplayer (value (object construct)) + :revision revision)))))) + + +(defun return-characteristics (literal-value literal-datatype) + "Returns all characteristica that own the specified value." + (declare (String literal-datatype)) + (let ((chars + (cond ((string= literal-datatype *xml-string*) + (remove-if #'(lambda(elem) + (string/= (charvalue elem) literal-value)) + (append + (elephant:get-instances-by-value + 'OccurrenceC 'charvalue literal-value) + (elephant:get-instances-by-value + 'VariantC 'charvalue literal-value) + (elephant:get-instances-by-value + 'NameC 'charvalue literal-value)))) + ((and (string= literal-datatype *xml-boolean*) + literal-value) + (remove-if #'(lambda(elem) + (string/= (charvalue elem) "true")) + (append (elephant:get-instances-by-value + 'VariantC 'charvalue "true") + (elephant:get-instances-by-value + 'OccurrenceC 'charvalue "true")))) + ((and (string= literal-datatype *xml-boolean*) + (not literal-value)) + (remove-if #'(lambda(elem) + (string/= (charvalue elem) "false")) + (append (elephant:get-instances-by-value + 'VariantC 'charvalue "true") + (elephant:get-instances-by-value + 'OccurrenceC 'charvalue "false")))) + ((or (string= literal-datatype *xml-double*) + (string= literal-datatype *xml-decimal*) + (string= literal-datatype *xml-integer*)) + (let ((constructs + (remove-if #'(lambda(con) + (string/= (datatype con) literal-datatype)) + (append + (elephant:get-instances-by-value + 'VariantC 'datatype literal-datatype) + (elephant:get-instances-by-value + 'OccurrenceC 'datatype literal-datatype))))) + (remove-if #'(lambda(con) + (not (literal= (charvalue con) literal-value))) + constructs)))))) + ;;elephant returns names, occurences, and variants if any string + ;;value matches, so all duplicates have to be removed + (remove-duplicates chars))) + + +(defun filter-by-characteristic-value (literal-value literal-datatype + &key (revision *TM-REVISION*)) + "Returns a triple where the passed value is a charvalue in a occurrence + or name. The subject is the owner topic and the predicate is the + characteristic's type. + (Variants are not considered because they are not typed, so they cannot + be referenced via a predicate)." + (declare (Integer revision) + (String literal-datatype)) + (remove-null + (map 'list #'(lambda(char) + (let ((subj-uri + (when-do top (parent char :revision revision) + (sparql-node top :revision revision))) + (pred-uri + (when-do top (instance-of char :revision revision) + (sparql-node top :revision revision)))) + (list :subject subj-uri + :predicate pred-uri + :object (charvalue char) + :literal-datatype literal-datatype))) + (remove-if #'(lambda(char) + (typep char 'VariantC)) + (return-characteristics literal-value literal-datatype))))) + + +(defgeneric filter-by-otherplayer (construct &key revision) + (:documentation "Returns triples where the passed player is the object, + the other player is the subject and the type of the passed + player's role is the predicate.") + (:method ((construct TopicC) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (let ((roles-by-oplayer (player-in-roles construct :revision revision)) + (obj-uri (sparql-node construct :revision revision))) + (remove-null + (map 'list + #'(lambda(role) + (let ((orole + (when-do assoc (parent role :revision revision) + (when (= (length (roles assoc :revision revision)) + 2) + (find-if #'(lambda(r) (not (eql r role))) + (roles assoc :revision revision)))))) + (list :subject + (when-do plr (player orole :revision revision) + (sparql-node plr :revision revision)) + :predicate + (when-do type (instance-of role :revision revision) + (sparql-node type :revision revision)) + :object obj-uri))) + roles-by-oplayer))))) + + +(defgeneric filter-by-given-predicate (construct &key revision) + (:documentation "Returns all topics that owns a characteristic of the + given type or an associaiton with an otherrole of the + given type. The result is a plist representing a triple.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (and (variable-p (subject construct)) + (iri-p (predicate construct))) + (cond ((variable-p (object construct)) + (append (filter-by-otherroletype construct :revision revision) + (filter-by-characteristictype construct :revision revision))) + ((literal-p (object construct)) + (filter-by-characteristictype construct :revision revision)) + ((iri-p (object construct)) + (filter-by-otherroletype construct :revision revision)))))) + + +(defgeneric filter-by-otherroletype (construct &key revision) + (:documentation "Returns triple where the passed predicate is a + type of a role. The returned subject is the otherplayer, + the predicate is the passed predicate, the object is + the player of the role of the passed type.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (or (variable-p (object construct)) + (iri-p (object construct))) + (let* ((roles-by-type + (remove-null + (map 'list #'(lambda(typed-construct) + (when (typep typed-construct 'RoleC) + typed-construct)) + (used-as-type (value (predicate construct)) :revision revision)))) + (roles-by-player + (if (iri-p (object construct)) + (remove-null + (map 'list #'(lambda(role) + (when (eql (player role :revision revision) + (value (object construct))) + role)) + roles-by-type)) + roles-by-type))) + (remove-null + (map 'list + #'(lambda(role) + (let* ((assoc (parent role :revision revision)) + (orole (when (and assoc + (= (length + (roles assoc :revision revision)) + 2)) + (find-if #'(lambda(r) + (not (eql r role))) + (roles assoc :revision revision))))) + (list :subject + (when-do plr (player orole :revision revision) + (sparql-node plr :revision revision)) + :predicate + (sparql-node (value (predicate construct)) + :revision revision) + :object + (when-do plr-top (player role :revision revision) + (sparql-node plr-top :revision revision))))) + roles-by-player)))))) + + +(defgeneric filter-by-characteristictype (construct &key revision) + (:documentation "Returns the results of filter-by-nametype and + filter-by-occurrencetype.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (append (filter-by-nametype construct :revision revision) + (filter-by-occurrencetype construct :revision revision)))) + + +(defgeneric filter-by-nametype (construct &key revision) + (:documentation "Returns all names that corresponds to the given parameters.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (and (not (iri-p (object construct))) + (or (not (literal-datatype (object construct))) + (string= (literal-datatype (object construct)) *xml-string*))) + (let* ((names-by-type + (remove-null + (map 'list #'(lambda(typed-construct) + (when (typep typed-construct 'NameC) + typed-construct)) + (used-as-type (value (predicate construct)) + :revision revision)))) + (names-by-literal + (if (variable-p (object construct)) + names-by-type + (remove-null + (map 'list #'(lambda(name) + (when (string= (charvalue name) + (value (object construct))) + name)) + names-by-type))))) + (remove-null + (map 'list + #'(lambda(name) + (list :subject + (when-do top (parent name :revision revision) + (sparql-node top :revision revision)) + :predicate + (when-do top (instance-of name :revision revision) + (sparql-node top :revision revision)) + :object (charvalue name) + :literal-datatype *xml-string*)) + names-by-literal)))))) + + +(defgeneric filter-by-occurrencetype (construct &key revision) + (:documentation "Returns all occurrence that corresponds to the + given parameters.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (unless (iri-p (object construct)) + (let* ((occs-by-type + (remove-null + (map 'list #'(lambda(typed-construct) + (when (typep typed-construct 'OccurrenceC) + typed-construct)) + (used-as-type (value (predicate construct)) + :revision revision)))) + (all-occs + (let ((literal-value (if (variable-p (object construct)) + nil + (value (object construct)))) + (literal-datatype (literal-datatype (object construct)))) + (remove-null + (map 'list #'(lambda(occ) + (filter-occ-by-value occ literal-value + literal-datatype)) + occs-by-type))))) + (remove-null + (map 'list + #'(lambda(occ) + (list :subject + (when-do top (parent occ :revision revision) + (sparql-node top :revision revision)) + :predicate + (when-do top (instance-of occ :revision revision) + (sparql-node top :revision revision)) + :object (charvalue occ) + :literal-datatype (datatype occ))) + all-occs)))))) + + +(defgeneric filter-by-given-subject (construct &key revision) + (:documentation "Calls filter-characteristics and filter associations + for the topic that is set as a subject of the passed triple.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (iri-p (subject construct)) + (let* ((subj (value (subject construct))) + (pred (when (iri-p (predicate construct)) + (value (predicate construct))))) + (cond ((variable-p (object construct)) + (append (filter-characteristics + subj pred nil nil :revision revision) + (filter-associations + subj pred nil :revision revision))) + ((literal-p (object construct)) + (filter-characteristics + subj pred (value (object construct)) + (literal-datatype (object construct)) :revision revision)) + ((iri-p (object construct)) + (filter-associations subj pred (value (object construct)) + :revision revision))))))) + + +(defgeneric literal-p (construct) + (:documentation "Returns t if the passed construct has an elem-type + set to 'LITERAL.") + (:method ((construct SPARQL-Triple-Elem)) + (eql (elem-type construct) 'LITERAL))) + + +(defgeneric iri-p (construct) + (:documentation "Returns t if the passed construct has an elem-type + set to 'IRI.") + (:method ((construct SPARQL-Triple-Elem)) + (eql (elem-type construct) 'IRI))) + + +(defgeneric variable-p (construct) + (:documentation "Returns t if the passed construct has an elem-type + set to 'VARIABLE.") + (:method ((construct SPARQL-Triple-Elem)) + (eql (elem-type construct) 'VARIABLE))) + + +(defgeneric iri-not-found-p (construct) + (:documentation "Must be called after a call of set-tm-constructs. + It returns t if a TM-construct was not found for a + given IRI, so the result value of a query is nil.") + (:method ((construct SPARQL-Triple)) + (or (iri-not-found-p (subject construct)) + (iri-not-found-p (predicate construct)) + (iri-not-found-p (object construct))))) + + +(defmethod iri-not-found-p ((construct SPARQL-Triple-Elem)) + (and (eql (elem-type construct) 'IRI) + (not (value construct)))) + + +(defgeneric set-tm-constructs (construct &key revision) + (:documentation "Calls the method set-tm-construct for every element + in a SPARQL-Triple object.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (when-do subj (subject construct) + (set-tm-construct subj :revision revision)) + (when-do pred (predicate construct) + (set-tm-construct pred :revision revision)) + (when-do obj (object construct) (set-tm-construct obj :revision revision)))) + + +(defgeneric set-tm-construct (construct &key revision) + (:documentation "Replaces the IRI in the given object by the corresponding + TM-construct.") + (:method ((construct SPARQL-Triple-Elem) &key (revision *TM-REVISION*)) + (declare (Integer revision)) + (when (eql (elem-type construct) 'IRI) + (setf (value construct) + (get-item-by-any-id (value construct) :revision revision))))) + + +(defun literal= (value-1 value-2) + "Returns t if both arguments are equal. The equality function is searched in + the table *equal-operators*." + (when (or (and (numberp value-1) (numberp value-2)) + (typep value-1 (type-of value-2)) + (typep value-2 (type-of value-1))) + (let ((operator (get-equal-operator value-1))) + (funcall operator value-1 value-2)))) + + +(defun filter-datatypable-by-value (construct literal-value literal-datatype) + "A helper that compares the datatypable's charvalue with the passed + literal value." + (declare (d::DatatypableC construct) + (type (or Null String) literal-value literal-datatype)) + (when (or (not literal-datatype) + (string= (datatype construct) literal-datatype)) + (if (not literal-value) + construct + (handler-case + (let ((occ-value (cast-literal (charvalue construct) + (datatype construct)))) + (when (literal= occ-value literal-value) + construct)) + (condition () nil))))) + + +(defun filter-variant-by-value (variant literal-value literal-datatype) + "A helper that compares the occurrence's variant's with the passed + literal value." + (declare (VariantC variant) + (type (or Null String) literal-value literal-datatype)) + (filter-datatypable-by-value variant literal-value literal-datatype)) + + +(defun filter-occ-by-value (occurrence literal-value literal-datatype) + "A helper that compares the occurrence's charvalue with the passed + literal value." + (declare (OccurrenceC occurrence) + (type (or Null String) literal-value literal-datatype)) + (filter-datatypable-by-value occurrence literal-value literal-datatype)) + + +(defgeneric filter-occurrences(construct type-top literal-value + literal-datatype &key revision) + (:documentation "Returns a list representing a triple.") + (:method ((construct TopicC) type-top literal-value literal-datatype + &key (revision *TM-REVISION*)) + (declare (Integer revision) + (type (or Null String) literal-value literal-datatype) + (type (or Null TopicC) type-top)) + (let* ((occs-by-type + (if type-top + (occurrences-by-type construct type-top :revision revision) + (occurrences construct :revision revision))) + (all-occs + (remove-null + (map 'list + #'(lambda(occ) + (filter-occ-by-value occ literal-value literal-datatype)) + occs-by-type))) + (subj-uri (sparql-node construct :revision revision))) + (remove-null + (map 'list #'(lambda(occ) + (list :subject subj-uri + :predicate + (when-do type-top + (instance-of occ :revision revision) + (sparql-node type-top :revision revision)) + :object (charvalue occ) + :literal-datatype (datatype occ))) + all-occs))))) + + +(defgeneric filter-names(construct type-top literal-value + &key revision) + (:documentation "Returns a list representing a triple.") + (:method ((construct TopicC) type-top literal-value + &key (revision *TM-REVISION*)) + (declare (Integer revision) + (type (or Null String) literal-value) + (type (or Null TopicC) type-top)) + (let* ((by-type + (if type-top + (names-by-type construct type-top :revision revision) + (names construct :revision revision))) + (by-literal (if literal-value + (names-by-value + construct #'(lambda(name) + (string= name literal-value)) + :revision revision) + (names construct :revision revision))) + (all-names (intersection by-type by-literal)) + (subj-uri (sparql-node construct :revision revision))) + (remove-null + (map 'list #'(lambda(name) + (list :subject subj-uri + :predicate + (when-do type-top (instance-of name :revision revision) + (sparql-node type-top :revision revision)) + :object (charvalue name) + :literal-datatype *xml-string*)) + all-names))))) + + +(defgeneric filter-characteristics (construct type-top literal-value + literal-datatype &key revision) + (:documentation "Returns a list representing a triple.") + (:method ((construct TopicC) type-top literal-value literal-datatype + &key (revision *TM-REVISION*)) + (declare (Integer revision) + (type (or Null String) literal-value literal-datatype) + (type (or Null TopicC) type-top)) + (let ((occs (filter-occurrences construct type-top literal-value + literal-datatype :revision revision)) + (names (if (or (not literal-datatype) + (string= literal-datatype *xml-string*)) + (filter-names construct type-top literal-value + :revision revision) + nil))) + (append occs names)))) + + +(defgeneric filter-associations(construct type-top player-top + &key revision) + (:documentation "Returns a list of the form (:predicate <uri> + :object <uri> :subject <uri>). + predicate is the type of the otherrole and + object is the uri of the otherplayer.") + (:method ((construct TopicC) type-top player-top + &key (revision *TM-REVISION*)) + (declare (Integer revision) + (type (or Null TopicC) type-top player-top)) + (let ((assocs + (associations-of construct nil nil type-top player-top + :revision revision)) + (subj-uri (sparql-node construct :revision revision))) + (remove-null ;only assocs with two roles can match! + (map 'list + #'(lambda(assoc) + (when (= (length (roles assoc :revision revision)) 2) + (let* ((other-role + (find-if #'(lambda(role) + (and + (not (eql construct + (player role :revision revision))) + (or (not type-top) + (eql type-top + (instance-of + role :revision revision))))) + (roles assoc :revision revision))) + (pred-uri + (when other-role + (when-do + type-top (instance-of other-role + :revision revision) + (sparql-node type-top :revision revision)))) + + (obj-uri + (when other-role + (when-do player-top (player other-role + :revision revision) + (sparql-node player-top :revision revision))))) + (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + assocs))))) + + +(defgeneric result (construct) + (:documentation "Returns the result of the entire query.") + (:method ((construct SPARQL-Query)) + (let* ((response-variables + (reverse (if (*-p construct) + (all-variables construct) + (variables construct)))) + (cleaned-results (make-result-lists construct))) + (map 'list #'(lambda(response-variable) + (list :variable response-variable + :result (variable-intersection response-variable + cleaned-results))) + response-variables)))) + + +(defgeneric make-result-lists (construct) + (:documentation "Returns a list of the form ((:variable 'var-name' + :result (<any-object>)).") + (:method ((construct SPARQL-Query)) + (remove-null + (loop for triple in (select-group construct) + append (remove-null + (list + (when (variable-p (subject triple)) + (list :variable (value (subject triple)) + :result (subject-result triple))) + (when (variable-p (predicate triple)) + (list :variable (value (predicate triple)) + :result (predicate-result triple))) + (when (variable-p (object triple)) + (list :variable (value (object triple)) + :result (object-result triple))))))))) + + +(defgeneric all-variables (result-lists) + (:documentation "Returns a list of all variables that are contained in + the passed result-lists.")) + + +(defmethod all-variables ((result-lists List)) + (remove-duplicates + (map 'list #'(lambda(entry) + (getf entry :variable)) + result-lists) + :test #'string=)) + + +(defmethod all-variables ((construct SPARQL-Query)) + "Returns all variables that are contained in the select group memebers." + (remove-duplicates + (remove-null + (loop for triple in (select-group construct) + append (variables triple))) + :test #'string=)) + + +(defgeneric variable-intersection (variable-name result-lists) + (:documentation "Returns a list with all results of the passed variable + that are contained in the result-lists. All results is + an intersection of all paratial results.") + (:method ((variable-name String) (result-lists List)) + (let* ((all-values (results-for-variable variable-name result-lists)) + (list-1 (when (>= (length all-values) 1) + (first all-values))) + (list-2 (if (> (length all-values) 2) + (second all-values) + list-1)) + (more-lists (rest (rest all-values)))) + (recursive-intersection list-1 list-2 more-lists)))) + + +(defun recursive-intersection (list-1 list-2 more-lists) + "Returns an intersection of al the passed lists." + (declare (List list-1 list-2)) + (let ((current-result + (intersection list-1 list-2 + :test #'(lambda(val-1 val-2) + (if (and (stringp val-1) (stringp val-2)) + (string= val-1 val-2) + (eql val-1 val-2)))))) + (if (not more-lists) + current-result + (recursive-intersection current-result (first more-lists) + (rest more-lists))))) + + +(defgeneric reduce-results(construct result-lists) + (:documentation "Reduces the select-group of the passed construct by processing + all triples with the intersection-results.") + (:method ((construct SPARQL-Query) (result-lists List)) + (map 'list #'(lambda(triple) + (reduce-triple triple result-lists)) + (select-group construct)))) + + +(defgeneric reduce-triple(construct result-lists) + (:documentation "Reduces the results of a triple by using only the + intersection values.") + (:method ((construct SPARQL-Triple) (result-lists List)) + (let* ((triple-variables (variables construct)) + (intersections + (map 'list #'(lambda(var) + (list :variable var + :result (variable-intersection + var result-lists))) + triple-variables))) + (map 'list #'(lambda(entry) + (delete-rows construct (getf entry :variable) + (getf entry :result))) + intersections)))) + + +(defgeneric delete-rows (construct variable-name dont-touch-values) + (:documentation "Checks all results of the passed variable of the given + construct and deletes every result with the corresponding + row that is not contained in the dont-touch-values.") + (:method ((construct SPARQL-Triple) (variable-name String) + (dont-touch-values List)) + (let ((var-elem + (cond ((and (variable-p (subject construct)) + (string= (value (subject construct)) variable-name)) + (subject-result construct)) + ((and (variable-p (predicate construct)) + (string= (value (predicate construct)) variable-name)) + (predicate-result construct)) + ((and (variable-p (object construct)) + (string= (value (object construct)) variable-name)) + (object-result construct))))) + (when var-elem + (let* ((rows-to-hold + (remove-null + (map 'list #'(lambda(res) + (when (cond + ((stringp res) + (find res dont-touch-values :test #'string=)) + ((numberp res) + (find res dont-touch-values :test #'=)) + (t + (find res dont-touch-values))) + (position res var-elem))) + var-elem))) + (new-result-list + (map 'list + #'(lambda(row-idx) + (list :subject (elt (subject-result construct) row-idx) + :predicate (elt (predicate-result construct) row-idx) + :object (elt (object-result construct) row-idx))) + rows-to-hold))) + (setf (subject-result construct) + (map 'list #'(lambda(entry) + (getf entry :subject)) new-result-list)) + (setf (predicate-result construct) + (map 'list #'(lambda(entry) + (getf entry :predicate)) new-result-list)) + (setf (object-result construct) + (map 'list #'(lambda(entry) + (getf entry :object)) new-result-list))))))) + + +(defgeneric results-for-variable (variable-name result-lists) + (:documentation "Returns a list with result-lists for the passed variable.") + (:method ((variable-name String) (result-lists List)) + (let* ((cleaned-result-lists + (remove-if-not #'(lambda(entry) + (string= (getf entry :variable) + variable-name)) + result-lists)) + (values + (map 'list #'(lambda(entry) + (getf entry :result)) + cleaned-result-lists))) + values))) + + +(defun cast-literal (literal-value literal-type) + "A helper function that casts the passed string value of the literal + corresponding to the passed literal-type." + (declare (String literal-value literal-type)) + (cond ((string= literal-type *xml-string*) + literal-value) + ((string= literal-type *xml-boolean*) + (when (and (string/= literal-value "false") + (string/= literal-value "true")) + (error (make-condition + 'sparql-parser-error + :message (format nil "Could not cast from ~a to ~a" + literal-value literal-type)))) + (if (string= literal-value "false") + nil + t)) + ((string= literal-type *xml-integer*) + (handler-case (parse-integer literal-value) + (condition () + (error (make-condition + 'sparql-parser-error + :message (format nil "Could not cast from ~a to ~a" + literal-value literal-type)))))) + ((or (string= literal-type *xml-decimal*) ;;both types are + (string= literal-type *xml-double*)) ;;handled the same way + (let ((value (read-from-string literal-value))) + (unless (numberp value) + (error (make-condition + 'sparql-parser-error + :message (format nil "Could not cast from ~a to ~a" + literal-value literal-type)))) + value)) + (t ; return the value as a string + literal-value))) + + +(defmethod initialize-instance :after ((construct SPARQL-Query) &rest args) + (declare (ignorable args)) + (parser-start construct (original-query construct)) + (dolist (triple (select-group construct)) + (set-results triple :revision (revision construct))) + ;; filters all entries that are not important for the result + ;; => an intersection is invoked + (reduce-results construct (make-result-lists construct)) + (process-filters construct) + construct) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_constants.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_constants.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,35 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + +(defpackage :TM-SPARQL-Constants + (:use :cl :base-tools) + (:nicknames tms) + (:export :*tms* + :*tms-reifier* + :*tms-role* + :*tms-player* + :*tms-topicProperty* + :*tms-scope* + :*tms-value*)) + +(in-package :TM-SPARQL-Constants) + +(defvar *tms* "
http://www.networkedplanet.com/tmsparql/
") + +(defvar *tms-reifier* (concat *tms* "reifier")) + +(defvar *tms-role* (concat *tms* "role")) + +(defvar *tms-player* (concat *tms* "player")) + +(defvar *tms-topicProperty* (concat *tms* "topicProperty")) + +(defvar *tms-scope* (concat *tms* "scope")) + +(defvar *tms-value* (concat *tms* "value")) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_filter.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_filter.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,975 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + +(in-package :TM-SPARQL) + + +(defparameter *supported-functions* + (list "BOUND" "isLITERAL" "STR" "DATATYPE" "REGEX") + "Contains all supported SPARQL-functions") + + +(defparameter *supported-primary-arithmetic-operators* + (list "*" "/") "Contains all supported arithmetic operators.") + + +(defparameter *supported-secundary-arithmetic-operators* + (list "+" "-") "Contains all supported arithmetic operators.") + + +(defparameter *supported-compare-operators* + (list "!=" "<=" ">=" "=" "<" ">") ;note the order is important! + ;the operators with length = 2 + ;must be listed first + "Contains all supported binary operators.") + + +(defparameter *supported-join-operators* + (list "||" "&&") "Contains all supported join operators.") + + +(defparameter *supported-unary-operators* + (list "!" "+" "-") "Contains all supported unary operators") + + +(defparameter *allowed-filter-calls* + (append (list "one+" "one-" "progn" "or" "and" "not" "/=" "=" + ">" ">=" "<" "<=" "+" "-" "*" "/") + *supported-functions*)) + + +(defun *2-compare-operators* () + (remove-null + (map 'list #'(lambda(op) + (when (= (length op) 2) + op)) + *supported-compare-operators*))) + + +(defun *1-compare-operators* () + (remove-null + (map 'list #'(lambda(op) + (when (= (length op) 1) + op)) + *supported-compare-operators*))) + + +(defun *supported-arithmetic-operators* () + (append *supported-primary-arithmetic-operators* + *supported-secundary-arithmetic-operators*)) + + +(defun *supported-binary-operators* () + (append (*supported-arithmetic-operators*) + *supported-compare-operators* + *supported-join-operators*)) + + +(defun *supported-operators* () + (union (*supported-binary-operators*) *supported-unary-operators* + :test #'string=)) + + +(defparameter *supported-brackets* + (list "(" ")") + "Contains all supported brackets in a list of strings.") + + +(defun make-sparql-parser-condition(rest-of-query entire-query expected) + "Creates a spqrql-parser-error object." + (declare (String rest-of-query entire-query expected)) + (let ((message + (format nil "The query:~%\"~a\"~%~%has a bad token at position ~a => ~a.~%Expected: ~a" + entire-query (- (length entire-query) + (length rest-of-query)) + (subseq entire-query (- (length entire-query) + (length rest-of-query))) + expected))) + (make-condition 'sparql-parser-error :message message))) + + +(defgeneric parse-filter (construct query-string) + (:documentation "A helper functions that returns a filter and the next-query + string in the form (:next-query string + :filter-string object).") + (:method ((construct SPARQL-Query) (query-string String)) + ;note the order of the invacations is important! + (let* ((result-set-boundings (set-boundings construct query-string)) + (filter-string (getf result-set-boundings :filter-string)) + (next-query (getf result-set-boundings :next-query)) + (original-filter-string + (subseq query-string 0 (- (length query-string) + (length next-query)))) + (filter-string-unary-ops + (set-unary-operators construct filter-string)) + (filter-string-or-and-ops + (set-or-and-operators construct filter-string-unary-ops + original-filter-string)) + (filter-string-arithmetic-ops + (set-arithmetic-operators construct filter-string-or-and-ops)) + (filter-string-compare-ops + (set-compare-operators construct filter-string-arithmetic-ops)) + (filter-string-functions + (set-functions construct filter-string-compare-ops))) + (add-filter construct + (scan-filter-for-deprecated-calls + construct filter-string-functions original-filter-string)) + (parse-group construct next-query)))) + + +(defgeneric scan-filter-for-deprecated-calls (construct filter-string + original-filter) + (:documentation "Returns the passed filter-string where all functions + are explicit wrapped in the filter-functions package + or throws a sparql-parser-error of there is an + unallowed function call.") + (:method ((construct SPARQL-Query) (filter-string String) + (original-filter String)) + (let ((result "")) + (dotimes (idx (length filter-string) result) + (let ((fun-name (return-function-name (subseq filter-string idx)))) + (cond ((not fun-name) + (push-string (subseq filter-string idx (1+ idx)) result)) + ((string-starts-with-one-of fun-name *allowed-filter-calls*) + (push-string "(filter-functions::" result) + (push-string fun-name result) + (incf idx (length fun-name))) + (t + (error + (make-condition + 'exceptions:sparql-parser-error + :message (format nil "Invalid filter: the filter \"~a\" evaluated to \"~a\" which contains the deprecated function ~a!" + filter-string original-filter fun-name)))))))))) + + +(defun return-function-name (filter-string) + "If the string starts with ( there is returned the function name + that is placed directly after the (." + (declare (String filter-string)) + (when (string-starts-with filter-string "(") + (let ((local-str (trim-whitespace-left (subseq filter-string 1))) + (whitespaces (map 'list #'string (white-space))) + (result "")) + (dotimes (idx (length local-str) result) + (let ((current-char (subseq local-str idx (1+ idx)))) + (if (string-starts-with-one-of + current-char (append whitespaces *supported-brackets*)) + (setf idx (length local-str)) + (push-string current-char result))))))) + + +(defgeneric set-functions (construct filter-string) + (:documentation "Transforms all supported functions of the form + function(x, y) to (function x y).") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((op-pos (find-functions filter-string))) + (if (not op-pos) + filter-string + (let* ((fun-name + (return-if-starts-with (subseq filter-string op-pos) + *supported-functions*)) + (left-str (subseq filter-string 0 op-pos)) + (right-str (subseq filter-string + (+ op-pos (length fun-name)))) + (cleaned-right-str (trim-whitespace-left right-str)) + (arg-list (bracket-scope cleaned-right-str)) + (cleaned-arg-list (clean-function-arguments arg-list)) + (modified-str + (concat + left-str "(" fun-name " " cleaned-arg-list ")" + (subseq right-str (+ (- (length right-str) + (length cleaned-right-str)) + (length arg-list)))))) + (set-functions construct modified-str)))))) + + +(defun clean-function-arguments (argument-string) + "Transforms all arguments within an argument list of the form + (x, y, z, ...) to x y z." + (declare (String argument-string)) + (when (and (string-starts-with argument-string "(") + (string-ends-with argument-string ")")) + (let ((local-str (subseq argument-string 1 (1- (length argument-string)))) + (result "")) + (dotimes (idx (length local-str) result) + (let ((current-char (subseq local-str idx (1+ idx)))) + (if (and (string= current-char ",") + (not (in-literal-string-p local-str idx))) + (push-string " " result) + (push-string current-char result))))))) + + +(defun find-functions (filter-string) + "Returns the idx of the first found 'BOUND', 'isLITERAL', 'STR', + 'DATATYPE', or 'REGEX'. + It must not be in a literal string or directly after a (." + (declare (String filter-string)) + (let* ((first-pos + (search-first-ignore-literals *supported-functions* + filter-string))) + (when first-pos + (let ((left-part (trim-whitespace-right (subseq filter-string 0 first-pos)))) + (if (not (string-ends-with left-part "(")) + first-pos + (let ((next-pos + (find-functions (subseq filter-string (1+ first-pos))))) + (when next-pos + (+ 1 first-pos next-pos)))))))) + + +(defgeneric set-compare-operators (construct filter-string) + (:documentation "Transforms the =, !=, <, >, <= and >= operators in the + filter string to the the corresponding lisp functions.") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((op-pos (find-compare-operators filter-string))) + (if (not op-pos) + filter-string + (let* ((op-str (if (string-starts-with-one-of + (subseq filter-string op-pos) + (*2-compare-operators*)) + (subseq filter-string op-pos (+ 2 op-pos)) + (subseq filter-string op-pos (1+ op-pos)))) + (left-str (subseq filter-string 0 op-pos)) + (right-str (subseq filter-string (+ (length op-str) op-pos))) + (left-scope (find-compare-left-scope left-str)) + (right-scope (find-compare-right-scope right-str)) + (modified-str + (concat (subseq left-str 0 (- (length left-str) + (length left-scope))) + "(" op-str " " left-scope " " right-scope ")" + (subseq right-str (length right-scope))))) + (set-compare-operators construct modified-str)))))) + + +(defun find-compare-operators (filter-string) + "Returns the idx of the first found =, !=, <, >, <= or >= operator. + It must not be in a literal string or directly after a (." + (declare (String filter-string)) + (let* ((first-pos + (search-first-ignore-literals *supported-compare-operators* + filter-string)) + (delta (if first-pos + (if (string-starts-with-one-of + (subseq filter-string first-pos) + (*2-compare-operators*)) + 2 + 1) + 1))) + (when first-pos + (let ((left-part (trim-whitespace-right (subseq filter-string 0 first-pos)))) + (if (not (string-ends-with-one-of + left-part (append (*1-compare-operators*) (list "(")))) + first-pos + (let ((next-pos + (find-compare-operators (subseq filter-string (+ delta first-pos))))) + (when next-pos + (+ delta first-pos next-pos)))))))) + + +(defun find-compare-left-scope (left-string) + "Returns the string that is the left part of the binary scope." + (declare (String left-string)) + (let* ((first-bracket + (let ((inner-value (search-first-unclosed-paranthesis left-string))) + (when inner-value + (+ inner-value (1+ (length (name-after-paranthesis + (subseq left-string inner-value)))))))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-right left-string)) + (bracket-scope (reverse-bracket-scope cleaned-str))) + (when bracket-scope + (- (- (length left-string) + (- (length left-string) (length cleaned-str))) + (length bracket-scope))))) + (start-idx (or first-bracket paranthesis-pair-idx 0))) + (subseq left-string start-idx))) + + +(defun find-compare-right-scope (right-string) + "Returns the string that is the right part of the binary scope." + (declare (String right-string)) + (let* ((first-pos + (search-first-ignore-literals *supported-compare-operators* + right-string)) + (first-bracket + (let ((inner-value (search-first-unopened-paranthesis right-string))) + (when inner-value (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-left right-string)) + (bracket-scope (bracket-scope cleaned-str))) + (when bracket-scope + (+ (- (length right-string) (length cleaned-str)) + (length bracket-scope))))) + (end-idx (cond (paranthesis-pair-idx + paranthesis-pair-idx) + ((and first-pos first-bracket) + (min first-pos first-bracket)) + (first-pos first-pos) + (first-bracket first-bracket) + (t (if (= (length right-string) 0) + 0 + (length right-string)))))) + (subseq right-string 0 end-idx))) + + +(defgeneric set-arithmetic-operators (construct filter-string) + (:documentation "Transforms the +, -, *, / operators in the filter + string to the the corresponding lisp functions.") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((filter-string-*/ (set-*-and-/-operators construct filter-string))) + (set-+-and---operators construct filter-string-*/)))) + + +(defun find-*/-operators (filter-string) + "Returns the idx of the first found * or / operator. + It must not be in a literal string or directly after a (." + (declare (String filter-string)) + (let ((first-pos + (search-first-ignore-literals *supported-primary-arithmetic-operators* + filter-string))) + (when first-pos + (let ((left-part (trim-whitespace-right (subseq filter-string 0 first-pos)))) + (if (not (string-ends-with left-part "(")) + first-pos + (let ((next-pos + (find-*/-operators (subseq filter-string (1+ first-pos))))) + (when next-pos + (+ 1 first-pos next-pos)))))))) + + +(defgeneric set-*-and-/-operators (construct filter-string) + (:documentation "Transforms the *, / operators in the filter + string to the the corresponding lisp functions.") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((op-pos (find-*/-operators filter-string))) + (if (not op-pos) + filter-string + (let* ((op-str (subseq filter-string op-pos (1+ op-pos))) + (left-str (subseq filter-string 0 op-pos)) + (right-str (subseq filter-string (1+ op-pos))) + (left-scope (find-*/-left-scope left-str)) + (right-scope (find-*/-right-scope right-str)) + (modified-str + (concat + (subseq left-str 0 (- (length left-str) + (length left-scope))) + "(" op-str " " left-scope " " right-scope ")" + (subseq right-str (length right-scope))))) + (set-*-and-/-operators construct modified-str)))))) + + +(defun find-*/-left-scope (left-string) + "Returns the string that is the left part of the binary scope." + (declare (String left-string)) + (let* ((first-bracket + (let ((inner-value (search-first-unclosed-paranthesis left-string))) + (when inner-value + (+ inner-value (1+ (length (name-after-paranthesis + (subseq left-string inner-value)))))))) + (other-anchor + (let ((inner-value + (search-first-ignore-literals + (append *supported-secundary-arithmetic-operators* + *supported-compare-operators*) + left-string :from-end t))) + (when inner-value + (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-right left-string)) + (bracket-scope (reverse-bracket-scope cleaned-str))) + (when bracket-scope + (- (- (length left-string) + (- (length left-string) (length cleaned-str))) + (length bracket-scope))))) + (start-idx (cond (paranthesis-pair-idx + paranthesis-pair-idx) + ((and first-bracket other-anchor) + (max first-bracket other-anchor)) + ((or first-bracket other-anchor) + (or first-bracket other-anchor)) + (t 0)))) + (subseq left-string start-idx))) + + +(defun find-*/-right-scope (right-string) + "Returns the string that is the right part of the binary scope." + (declare (String right-string)) + (let* ((first-pos (search-first-ignore-literals + (append (*supported-arithmetic-operators*) + *supported-compare-operators*) + right-string)) + (first-bracket + (let ((inner-value (search-first-unopened-paranthesis right-string))) + (when inner-value (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-left right-string)) + (bracket-scope (bracket-scope cleaned-str))) + (when bracket-scope + (+ (- (length right-string) (length cleaned-str)) + (length bracket-scope))))) + (end-idx (cond (paranthesis-pair-idx + paranthesis-pair-idx) + ((and first-pos first-bracket) + (min first-pos first-bracket)) + (first-pos first-pos) + (first-bracket first-bracket) + (t (if (= (length right-string) 0) + (1- (length right-string))))))) + (subseq right-string 0 end-idx))) + + +(defgeneric set-+-and---operators (construct filter-string) + (:documentation "Transforms the +, - operators in the filter + string to the the corresponding lisp functions.") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((op-pos (find-+--operators filter-string))) + (if (not op-pos) + filter-string + (let* ((op-str (subseq filter-string op-pos (1+ op-pos))) + (left-str (subseq filter-string 0 op-pos)) + (right-str (subseq filter-string (1+ op-pos))) + (left-scope (find-+--left-scope left-str)) + (right-scope (find-+--right-scope right-str)) + (modified-str + (concat (subseq left-str 0 (- (length left-str) + (length left-scope))) + "(" op-str " " left-scope " " right-scope ")" + (subseq right-str (length right-scope))))) + (set-+-and---operators construct modified-str)))))) + + +(defun find-+--left-scope (left-string) + "Returns the string that is the left part of the binary scope." + (declare (String left-string)) + (let* ((first-bracket + (let ((inner-value (search-first-unclosed-paranthesis left-string))) + (when inner-value + (+ inner-value (1+ (length (name-after-paranthesis + (subseq left-string inner-value)))))))) + (other-anchor + (let ((inner-value + (search-first-ignore-literals *supported-compare-operators* + left-string :from-end t))) + (when inner-value + (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-right left-string)) + (bracket-scope (reverse-bracket-scope cleaned-str))) + (when bracket-scope + (- (- (length left-string) + (- (length left-string) (length cleaned-str))) + (length bracket-scope))))) + (start-idx (cond (paranthesis-pair-idx + paranthesis-pair-idx) + ((and first-bracket other-anchor) + (max first-bracket other-anchor)) + ((or first-bracket other-anchor) + (or first-bracket other-anchor)) + (t 0)))) + (subseq left-string start-idx))) + + +(defun find-+--right-scope (right-string) + "Returns the string that is the right part of the binary scope." + (declare (String right-string)) + (let* ((first-pos (search-first-ignore-literals + (append (*supported-arithmetic-operators*) + *supported-compare-operators*) + right-string)) + (first-bracket + (let ((inner-value (search-first-unopened-paranthesis right-string))) + (when inner-value (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-left right-string)) + (bracket-scope (bracket-scope cleaned-str))) + (when bracket-scope + (+ (- (length right-string) (length cleaned-str)) + (length bracket-scope))))) + (end-idx (cond (paranthesis-pair-idx + paranthesis-pair-idx) + ((and first-pos first-bracket) + (min first-pos first-bracket)) + (first-pos first-pos) + (first-bracket first-bracket) + (t (if (= (length right-string) 0) + (1- (length right-string))))))) + (subseq right-string 0 end-idx))) + + +(defun find-+--operators (filter-string) + "Returns the idx of the first found + or - operator. + It must not be in a literal string or directly after a (." + (declare (String filter-string)) + (let ((first-pos + (search-first-ignore-literals *supported-secundary-arithmetic-operators* + filter-string))) + (when first-pos + (let ((left-part (trim-whitespace-right (subseq filter-string 0 first-pos)))) + (if (and (not (string-ends-with left-part "(one")) + (not (string-ends-with left-part "("))) + first-pos + (let ((next-pos + (find-+--operators (subseq filter-string (1+ first-pos))))) + (when next-pos + (+ 1 first-pos next-pos)))))))) + + +(defgeneric set-or-and-operators (construct filter-string original-filter-string) + (:documentation "Transforms the || and && operators in the filter string to + the the lisp or and and functions.") + (:method ((construct SPARQL-Query) (filter-string String) + (original-filter-string String)) + (let ((op-pos (search-first-ignore-literals + *supported-join-operators* filter-string))) + (if (not op-pos) + filter-string + (let* ((op-str (subseq filter-string op-pos (+ 2 op-pos))) + (left-str (subseq filter-string 0 op-pos)) + (right-str (subseq filter-string (+ (length op-str) op-pos))) + (left-scope (find-or-and-left-scope left-str)) + (right-scope (find-or-and-right-scope right-str)) + (modified-str + (concat (subseq left-str 0 (- (length left-str) + (length left-scope))) + "(" (if (string= op-str "||") "or" "and") " " + "(progn " left-scope ")" "(progn " right-scope ")) " + (subseq right-str (length right-scope))))) + (when (or (= (length (trim-whitespace left-scope)) 0) + (= (length (trim-whitespace right-scope)) 0)) + (error (make-condition + 'sparql-parser-error + :message (format nil "Invalid filter: \"~a\", expect an RDF term after and before: \"~a\"" original-filter-string op-str)))) + (set-or-and-operators construct modified-str original-filter-string)))))) + + +(defun find-binary-op-string (filter-string idx) + "Returns the operator as string that is placed on the position idx." + (let* ((2-ops + (remove-null (map 'list #'(lambda(op-string) + (when (= (length op-string) 2) + op-string)) + (*supported-binary-operators*)))) + (operator-str (subseq filter-string idx))) + (if (string-starts-with-one-of operator-str 2-ops) + (subseq operator-str 0 2) + (subseq operator-str 0 1)))) + + +(defun find-or-and-left-scope (left-string) + "Returns the string that is the left part of the binary scope." + (declare (String left-string)) + (let* ((first-bracket + (let ((inner-value (search-first-unclosed-paranthesis left-string))) + (when inner-value + (+ inner-value (1+ (length (name-after-paranthesis + (subseq left-string inner-value)))))))) + + (start-idx (if first-bracket + first-bracket + 0))) + (subseq left-string start-idx))) + + +(defun name-after-paranthesis (str) + "Returns the substring that is contained after the paranthesis. + str must start with a ( otherwise the returnvalue is nil." + (declare (String str)) + (let ((result "") + (non-whitespace-found nil)) + (when (string-starts-with str "(") + (let ((cleaned-str (subseq str 1))) + (dotimes (idx (length cleaned-str)) + (let ((current-char (subseq cleaned-str idx (1+ idx)))) + (cond ((string-starts-with-one-of current-char (list "(" ")")) + (setf idx (length cleaned-str))) + ((and non-whitespace-found + (white-space-p current-char)) + (setf idx (length cleaned-str))) + ((white-space-p current-char) + (push-string current-char result)) + (t + (push-string current-char result) + (setf non-whitespace-found t))))) + result)))) + + +(defun find-or-and-right-scope (right-string) + "Returns the string that is the right part of the binary scope." + (declare (String right-string)) + (let* ((first-pos (search-first-ignore-literals + *supported-join-operators* right-string)) + (first-bracket + (let ((inner-value (search-first-unopened-paranthesis right-string))) + (when inner-value (1+ inner-value)))) + (paranthesis-pair-idx + (let* ((cleaned-str (trim-whitespace-left right-string)) + (bracket-scope (bracket-scope cleaned-str))) + (when bracket-scope + (+ (- (length right-string) (length cleaned-str)) + (length bracket-scope))))) + (end-idx + (cond ((and first-pos first-bracket) + (if (< first-pos first-bracket) + (if paranthesis-pair-idx + (if (< first-pos paranthesis-pair-idx) + paranthesis-pair-idx + first-pos) + first-pos) + first-bracket)) + (first-bracket first-bracket) + (first-pos + (if paranthesis-pair-idx + (if (< first-pos paranthesis-pair-idx) + paranthesis-pair-idx + first-pos) + first-pos)) + (t + (if (= (length right-string) 0) + 0 + (length right-string)))))) + (subseq right-string 0 end-idx))) + + +(defgeneric set-unary-operators (construct filter-string) + (:documentation "Transforms the unary operators !, +, - to (not ), + (one+ ) and (one- ). The return value is a modified filter + string.") + (:method ((construct SPARQL-Query) (filter-string String)) + (let ((result-string "")) + (dotimes (idx (length filter-string)) + (let ((current-char (subseq filter-string idx (1+ idx)))) + (cond ((string= current-char "!") + (if (and (< idx (1- (length filter-string))) + (string= (subseq filter-string (1+ idx) (+ 2 idx)) "=")) + (push-string current-char result-string) + (let ((result (unary-operator-scope filter-string idx))) + (push-string "(not " result-string) + (push-string (set-unary-operators construct (getf result :scope)) + result-string) + (push-string ")" result-string) + (setf idx (- (1- (length filter-string)) + (length (getf result :next-query))))))) + ((or (string= current-char "-") + (string= current-char "+")) + (let ((string-before + (trim-whitespace-right (subseq filter-string 0 idx)))) + (if (or (string= string-before "") + (string-ends-with string-before "(progn") + (string-ends-with-one-of + string-before (append (*supported-operators*) (list "(")))) + (let ((result (unary-operator-scope filter-string idx))) + (push-string (concat "(one" current-char " ") + result-string) + (push-string (set-unary-operators construct + (getf result :scope)) + result-string) + (push-string ")" result-string) + (setf idx (- (1- (length filter-string)) + (length (getf result :next-query))))) + (push-string current-char result-string)))) + ((or (string= current-char "'") + (string= current-char "\"")) + (let ((literal + (get-literal (subseq filter-string idx)))) + (if literal + (progn + (setf idx (- (1- (length filter-string)) + (length (getf literal :next-string)))) + (push-string (getf literal :literal) result-string)) + (push-string current-char result-string)))) + (t + (push-string current-char result-string))))) + result-string))) + + +(defun unary-operator-scope (filter-string idx) + "Returns a list of the form (:next-query <string> :scope <string>). + scope contains the statement that is in the scope of one of the following + operators !, +, -." + (declare (String filter-string) + (Integer idx)) + (let* ((string-after (subseq filter-string (1+ idx))) + (cleaned-str (cut-comment string-after))) + (cond ((string-starts-with cleaned-str "(") + (let ((result (bracket-scope cleaned-str))) + (list :next-query (string-after cleaned-str result) + :scope result))) + ((or (string-starts-with cleaned-str "?") + (string-starts-with cleaned-str "$")) + (let ((result (get-filter-variable cleaned-str))) + (list :next-query (string-after cleaned-str result) + :scope result))) + ((string-starts-with cleaned-str "\"") + (let ((result (get-literal cleaned-str :quotation "\""))) + (list :next-query (getf result :next-string) + :scope (getf result :literal)))) + ((string-starts-with-digit cleaned-str) + (let ((result (separate-leading-digits cleaned-str))) + (list :next-query (string-after cleaned-str result) + :scope result))) + ((string-starts-with cleaned-str "true") + (list :next-query (string-after cleaned-str "true") + :scope "true")) + ((string-starts-with cleaned-str "false") + (list :next-query (string-after cleaned-str "false") + :scope "false")) + ((let ((pos (search-first *supported-functions* cleaned-str))) + (when pos + (= pos 0))) + (let ((result (function-scope cleaned-str))) + (list :next-query (string-after cleaned-str result) + :scope result))) + (t + (error + (make-condition + 'sparql-parser-error + :message + (format + nil "Invalid filter: \"~a\". An unary operator must be followed by ~a" + filter-string + "a number, boolean, string, function or a variable"))))))) + + +(defun function-scope (str) + "If str starts with a supported function there is given the entire substr + that is the scope of the function, i.e. the function name and all its + variable including the closing )." + (declare (String str)) + (let* ((cleaned-str (cut-comment str)) + (after-fun + (remove-null (map 'list #'(lambda(fun) + (when (string-starts-with cleaned-str fun) + (string-after str fun))) + *supported-functions*))) + (fun-suffix (when after-fun + (cut-comment (first after-fun))))) + (when fun-suffix + (let* ((args (bracket-scope fun-suffix)) + (fun-name (string-until cleaned-str args))) + (concat fun-name args))))) + + +(defun get-filter-variable (str) + "Returns the substring of str if str starts with ? or $ until the variable ends, + otherwise the return value is nil." + (declare (String str)) + (when (or (string-starts-with str "?") + (string-starts-with str "$")) + (let ((found-end (search-first (append (white-space) (*supported-operators*) + *supported-brackets* (list "?" "$")) + (subseq str 1)))) + (if found-end + (subseq str 0 (1+ found-end)) + str)))) + + +(defun reverse-bracket-scope (str &key (open-bracket "(") (close-bracket ")")) + "If str ends with close-bracket there will be returned the substring until + the matching open-bracket is found. Otherwise the return value is nil." + (declare (String str open-bracket close-bracket)) + (when (string-ends-with str close-bracket) + (let ((local-str (subseq str 0 (1- (length str)))) + (result ")") + (close-brackets 1)) + (do ((idx (1- (length local-str)))) ((< idx 0)) + (let ((current-char (subseq local-str idx (1+ idx)))) + (push-string current-char result) + (cond ((string= current-char open-bracket) + (when (not (in-literal-string-p local-str idx)) + (decf close-brackets)) + (when (= close-brackets 0) + (setf idx 0))) + ((string= current-char close-bracket) + (when (not (in-literal-string-p local-str idx)) + (incf close-brackets))))) + (decf idx)) + (reverse result)))) + + +(defun bracket-scope (str &key (open-bracket "(") (close-bracket ")")) + "If str starts with open-bracket there will be returned the substring until + the matching close-bracket is found. Otherwise the return value is nil." + (declare (String str open-bracket close-bracket)) + (when (string-starts-with str open-bracket) + (let ((open-brackets 0) + (result "")) + (dotimes (idx (length str)) + (let ((current-char (subseq str idx (1+ idx)))) + (cond ((or (string= "'" current-char) + (string= "\"" current-char)) + (let ((literal (get-literal (subseq str idx)))) + (if literal + (progn + (setf idx (- (1- (length str)) + (length (getf literal :next-string)))) + (push-string (getf literal :literal) result)) + (progn + (setf result nil) + (setf idx (length str)))))) + ((string= current-char close-bracket) + (decf open-brackets) + (push-string current-char result) + (when (= open-brackets 0) + (setf idx (length str)))) + ((string= current-char open-bracket) + (incf open-brackets) + (push-string current-char result)) + (t + (push-string current-char result))))) + result))) + + +(defgeneric set-boundings (construct query-string) + (:documentation "Returns a list of the form (:next-query <string> + :filter-string <string>). next-query is a string containing + the query after the filter and filter is a string + containing the actual filter. Additionally all free + '(' are transformed into '(progn' and all ', ''', \"\"\" + are transformed into \".") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((filter-string "") + (open-brackets 0) + (result nil)) + (dotimes (idx (length query-string)) + (let ((current-char (subseq query-string idx (1+ idx)))) + (cond ((string= "(" current-char) + (setf open-brackets (1+ open-brackets)) + (if (progn-p query-string idx) + (push-string "(progn " filter-string) + (push-string current-char filter-string))) + ((string= ")" current-char) + (setf open-brackets (1- open-brackets)) + (when (< open-brackets 0) + (error + (make-sparql-parser-condition + (subseq query-string idx) + (original-query construct) + "an opening bracket \"(\" is missing for the current closing one"))) + (push-string current-char filter-string)) + ((or (string= "'" current-char) + (string= "\"" current-char)) + (let ((result + (get-literal (subseq query-string idx) :quotation "\""))) + (unless result + (error (make-sparql-parser-condition + (subseq query-string idx) + (original-query construct) + "a closing character for the given literal"))) + (setf idx (- (1- (length query-string)) + (length (getf result :next-string)))) + (push-string (getf result :literal) filter-string))) + ((string= "#" current-char) + (let ((comment-string + (string-until (subseq query-string idx) + (string #\newline)))) + (setf idx (+ idx (length comment-string))))) + ((and (string= current-char (string #\newline)) + (= 0 open-brackets)) + (setf result + (list :next-query (subseq query-string idx) + :filter-string filter-string)) + (setf idx (1- (length query-string)))) + ((string= current-char "}") + (when (/= open-brackets 0) + (error (make-sparql-parser-condition + (subseq query-string idx) + (original-query construct) + (format nil + "a valid filter, but the filter is not complete, ~a" + (if (> open-brackets 0) + (format nil "~a ')' is missing" + open-brackets) + (format nil "~a '(' is missing" + open-brackets)))))) + (setf result + (list :next-query (subseq query-string idx) + :filter-string filter-string))) + (t + (push-string current-char filter-string))))) + result))) + + +(defun progn-p(query-string idx) + "Returns t if the ( at position idx in the filter string + represents a (progn) block." + (declare (String query-string) + (Integer idx)) + (let* ((delimiters (append (list " " "," (string #\Space) (string #\Tab) + (string #\Newline) (string #\cr) "(" ")") + (*supported-operators*))) + (string-before (trim-whitespace-right (subseq query-string 0 idx))) + (fragment-before-idx + (search-first delimiters string-before :from-end t)) + (fragment-before + (if (and (not fragment-before-idx) + (and (> (length string-before) 0) + (not (string-ends-with-one-of + (trim-whitespace-right string-before) + *supported-functions*)))) + (error (make-condition + 'SPARQL-PARSER-ERROR + :message (format nil "Invalid filter: \"~a\"~%" + query-string))) + (if fragment-before-idx + (subseq string-before fragment-before-idx) + nil)))) + (when fragment-before + (mapcan #'(lambda(operator) + (when (and (string-starts-with fragment-before operator) + (> (length fragment-before) (length operator))) + (setf fragment-before + (string-after fragment-before operator)))) + (append (*supported-operators*) *supported-brackets*))) + (if fragment-before + (progn + (when (or (string-starts-with fragment-before "?") + (string-starts-with fragment-before "$")) + (error + (make-condition + 'SPARQL-PARSER-ERROR + :message (format nil "Invalid filter: found \"~a\" but expected ~a" + fragment-before *supported-functions*)))) + (when (not (string-starts-with-one-of + fragment-before (append *supported-functions* delimiters))) + (error + (make-condition + 'SPARQL-PARSER-ERROR + :message + (format nil "Invalid character: \"~a\", expected characters: ~a" + fragment-before (append *supported-functions* delimiters))))) + (if (string-ends-with-one-of fragment-before *supported-functions*) + nil + t)) + (if (find string-before *supported-functions* :test #'string=) + nil + t)))) + + +(defun get-variables-from-filter-string(filter-string) + "Returns a list of string with all variables that are used in this filter." + (let ((variables nil)) + (dotimes (idx (length filter-string)) + (let ((current-string (subseq filter-string idx))) + (when (and (or (string-starts-with current-string "?") + (string-starts-with current-string "$")) + (not (in-literal-string-p filter-string idx))) + (let ((end-pos + (let ((inner-value + (search-first + (append (list " " "?" "$" "." ",") + (*supported-operators*) + *supported-brackets* + (map 'list #'string (white-space))) + (subseq current-string 1)))) + (if inner-value + (1+ inner-value) + (length current-string))))) + (push (subseq current-string 1 end-pos) variables) + (incf idx end-pos))))) + (remove-duplicates variables :test #'string=))) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_parser.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_parser.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,476 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + +(in-package :TM-SPARQL) + +(defun parse-closed-value(query-string query-object &key (open "<") (close ">")) + "A helper function that checks the value of a statement within + two brackets, i.e. <prefix-value>. A list of the + form (:next-query string :value string) is returned." + (declare (String query-string open close) + (SPARQL-Query query-object)) + (let ((trimmed-string (cut-comment query-string))) + (if (string-starts-with trimmed-string open) + (let* ((pref-url (string-until (string-after trimmed-string open) close)) + (next-query-str (string-after trimmed-string close))) + (unless next-query-str + (error (make-sparql-parser-condition + trimmed-string (original-query query-object) + close))) + (list :next-query next-query-str + :value pref-url)) + (error (make-sparql-parser-condition + trimmed-string (original-query query-object) + close))))) + + +(defun cut-comment (query-string) + "Returns the given string back. If the query starts with a # or + space # the characters until the nextline are removed." + (declare (String query-string)) + (let ((trimmed-str (trim-whitespace-left query-string))) + (if (string-starts-with trimmed-str "#") + (let ((next-query (string-after trimmed-str (string #\newline)))) + (if next-query + next-query + "")) + trimmed-str))) + + +(defgeneric parser-start(construct query-string) + (:documentation "The entry point of the SPARQL-parser.") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((trimmed-query-string (cut-comment query-string))) + (cond ((string-starts-with trimmed-query-string "SELECT") + (parse-select + construct (string-after trimmed-query-string "SELECT"))) + ((string-starts-with trimmed-query-string "PREFIX") + (parse-prefixes + construct (string-after trimmed-query-string "PREFIX"))) + ((string-starts-with trimmed-query-string "BASE") + (parse-base construct (string-after trimmed-query-string "BASE") + #'parser-start)) + ((= (length trimmed-query-string) 0) + ;; If there is only a BASE and/or PREFIX statement return a + ;; query-object with the result nil + construct) + (t + (error (make-sparql-parser-condition + trimmed-query-string (original-query construct) + (format nil "SELECT, PREFIX or BASE, but found: ~a..." + (subseq trimmed-query-string 0 10))))))))) + + +(defgeneric parse-select (construct query-string) + (:documentation "The entry-point of the parsing of the select - where + statement.") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (next-query (if (string-starts-with trimmed-str "WHERE") + trimmed-str + (parse-variables construct trimmed-str)))) + (unless (string-starts-with next-query "WHERE") + (error (make-sparql-parser-condition + next-query (original-query construct) "WHERE"))) + (let* ((triples (string-after next-query "WHERE")) + (query-tail (parse-where construct triples))) + (when (> (length query-tail) 0) + (error (make-sparql-parser-condition + query-tail (original-query construct) + "The end of the query. Solution sequence modifiers are not supported yet."))) + construct)))) + + +(defgeneric parse-where (construct query-string) + (:documentation "The entry-point for the parsing of the WHERE statement.") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((trimmed-str (cut-comment query-string))) + (unless (string-starts-with trimmed-str "{") + (error (make-sparql-parser-condition trimmed-str + (original-query construct) "{"))) + (let ((query-tail (parse-group construct (subseq trimmed-str 1)))) + (when (> (length (trim-whitespace query-tail)) 0) + (make-sparql-parser-condition + query-tail (original-query construct) "end of query, solution sequences and modifiers are not supported")) + query-tail)))) + + +(defgeneric parse-group (construct query-string &key last-subject) + (:documentation "The entry-point for the parsing of a {} statement.") + (:method ((construct SPARQL-Query) (query-string String) + &key (last-subject nil)) + (declare (type (or Null SPARQL-Triple-Elem) last-subject)) + (let ((trimmed-str (cut-comment query-string))) + (cond ((string-starts-with trimmed-str "BASE") + (parse-base construct (string-after trimmed-str "BASE") + #'(lambda(constr query-str) + (parse-group constr query-str + :last-subject last-subject)))) + ((string-starts-with trimmed-str "{") + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) + ((string-starts-with trimmed-str "FILTER") + (parse-filter construct (string-after trimmed-str "FILTER"))) + ((string-starts-with trimmed-str "OPTIONAL") + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) + ((string-starts-with trimmed-str "UNION") + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "FILTER, BASE, or triple. Grouping is currently no implemented."))) + ((string-starts-with trimmed-str "}") ;ending of this group + (subseq trimmed-str 1)) + (t + (parse-triple construct trimmed-str :last-subject last-subject)))))) + + +(defgeneric parse-triple-elem (construct query-string &key literal-allowed) + (:documentation "A helper function to parse a subject or predicate of an RDF triple.") + (:method ((construct SPARQL-Query) (query-string String) + &key (literal-allowed nil)) + (declare (Boolean literal-allowed)) + (let ((trimmed-str (cut-comment query-string))) + (cond ((string-starts-with trimmed-str "a ") ;;rdf:type + (list :next-query (cut-comment (subseq trimmed-str 1)) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'IRI + :value *type-psi*))) + ((string-starts-with trimmed-str "<") + (parse-base-suffix-pair construct trimmed-str)) + ((or (string-starts-with trimmed-str "?") + (string-starts-with trimmed-str "$")) + (let ((result + (parse-variable-name construct trimmed-str + :additional-delimiters (list "}")))) + (list :next-query (cut-comment (getf result :next-query)) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'VARIABLE + :value (getf result :value))))) + (t + (if (or (string-starts-with-digit trimmed-str) + (string-starts-with trimmed-str "\"") + (string-starts-with trimmed-str "true") + (string-starts-with trimmed-str "false") + (string-starts-with trimmed-str "'")) + (progn + (unless literal-allowed + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "an IRI of the form prefix:suffix or <iri> but found a literal."))) + (parse-literal-elem construct trimmed-str)) + (parse-prefix-suffix-pair construct trimmed-str))))))) + + +(defgeneric parse-literal-elem (construct query-string) + (:documentation "A helper-function that returns a literal vaue of the form + (:value (:value object :literal-type string :literal-lang + string :type <'LITERAL>) :next-query string).") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (value-type-lang-query + (cond ((or (string-starts-with trimmed-str "\"") + (string-starts-with trimmed-str "'")) + (parse-literal-string-value construct trimmed-str)) + ((string-starts-with trimmed-str "true") + (list :value t :type *xml-boolean* + :next-query (subseq trimmed-str (length "true")))) + ((string-starts-with trimmed-str "false") + (list :value nil :type *xml-boolean* + :next-query (subseq trimmed-str (length "false")))) + ((string-starts-with-digit trimmed-str) + (parse-literal-number-value construct trimmed-str))))) + (list :next-query (getf value-type-lang-query :next-query) + :value (make-instance + 'SPARQL-Triple-Elem + :elem-type 'LITERAL + :value (getf value-type-lang-query :value) + :literal-lang (getf value-type-lang-query :lang) + :literal-datatype (getf value-type-lang-query :type)))))) + + +(defgeneric parse-literal-string-value (construct query-string) + (:documentation "A helper function that parses a string that is a literal. + The return value is of the form + (list :value object :type string :lang string + :next-query string).") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (result-1 (separate-literal-value construct trimmed-str)) + (after-literal-value (getf result-1 :next-query)) + (l-value (getf result-1 :literal)) + (result-2 (separate-literal-lang-or-type + construct after-literal-value)) + (l-type (if (getf result-2 :type) + (getf result-2 :type) + *xml-string*)) + (l-lang (getf result-2 :lang)) + (next-query (getf result-2 :next-query))) + (list :next-query next-query :lang l-lang :type l-type + :value (cast-literal l-value l-type))))) + + +(defgeneric separate-literal-lang-or-type (construct query-string) + (:documentation "A helper function that returns (:next-query string + :lang string :type string). Only one of :lang and + :type can be set, the other element is set to nil. + The query string must be the string direct after + the closing literal bounding.") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((delimiters-1 (list "." ";" "}" " " (string #\tab) + (string #\newline))) + (delimiters-2 (list " ." ". " ";" "}" " " (string #\tab) + (string #\newline) + (concat "." (string #\newline)) + (concat "." (string #\tab))))) + (cond ((string-starts-with query-string "@") + (let ((end-pos (search-first delimiters-1 + (subseq query-string 1)))) + (unless end-pos + (error (make-sparql-parser-condition + query-string (original-query construct) + "'.', ';', '}', ' ', '\t', or '\n'"))) + (list :next-query (subseq (subseq query-string 1) end-pos) + :lang (subseq (subseq query-string 1) 0 end-pos) + :type nil))) + ((string-starts-with query-string "^^") + (let ((end-pos (search-first delimiters-2 (subseq query-string 2)))) + (unless end-pos + (error (make-sparql-parser-condition + query-string (original-query construct) + "'. ', ,' .', ';', '}', ' ', '\t', or '\n'"))) + (let* ((type-str (subseq (subseq query-string 2) 0 end-pos)) + (next-query (subseq (subseq query-string 2) end-pos)) + (final-type (if (get-prefix construct type-str) + (get-prefix construct type-str) + type-str))) + (list :next-query (cut-comment next-query) + :type final-type :lang nil)))) + (t + (list :next-query (cut-comment query-string) :type nil :lang nil)))))) + + +(defgeneric separate-literal-value (construct query-string) + (:documentation "A helper function that returns (:next-query string + :literal string). The literal string contains the + pure literal value.") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (delimiter (cond ((string-starts-with trimmed-str "\"") + "\"") + ((string-starts-with trimmed-str "'''") + "'''") + ((string-starts-with trimmed-str "'") + "'") + (t + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "a literal starting with ', ''', or \""))))) + (literal-end (find-literal-end (subseq trimmed-str (length delimiter)) + delimiter 0))) + (list :next-query (subseq trimmed-str (+ literal-end (length delimiter))) + :literal (subseq trimmed-str (length delimiter) literal-end))))) + + +(defgeneric parse-literal-number-value (construct query-string) + (:documentation "A helper function that parses any number that is a literal. + The return value is of the form + (list :value nil :type string :next-query string.") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (triple-delimiters + (list ". " ";" " " (string #\tab) + (string #\newline) "}")) + (end-pos (search-first triple-delimiters + trimmed-str))) + (unless end-pos + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "'. ', , ';' ' ', '\\t', '\\n' or '}'"))) + (let* ((literal-number + (read-from-string (subseq trimmed-str 0 end-pos))) + (number-type + (if (search "." (subseq trimmed-str 0 end-pos)) + *xml-double* ;could also be an xml:decimal, since the doucble has + ;a bigger range it shouldn't matter + *xml-integer*))) + (unless (numberp literal-number) + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "a valid number of the form '1', '1.3', 1.0e6'"))) + (list :value literal-number :type number-type + :next-query (subseq trimmed-str end-pos)))))) + + +(defgeneric parse-base-suffix-pair (construct query-string) + (:documentation "A helper function that returns a list of the form + (list :next-query string :value (:value uri :type 'IRI)).") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (result (parse-closed-value trimmed-str construct)) + (result-uri + (if (or (absolute-uri-p (getf result :value)) + (not (base-value construct))) + (getf result :value) + (concatenate-uri (base-value construct) + (getf result :value)))) + (next-query (getf result :next-query))) + (list :next-query (cut-comment next-query) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'IRI + :value result-uri))))) + + +(defgeneric parse-prefix-suffix-pair(construct query-string) + (:documentation "A helper function that returns a list of the form + (list :next-query string :value (:value uri :type 'IRI)).") + (:method ((construct SPARQL-Query) (query-string String)) + (let* ((trimmed-str (cut-comment query-string)) + (delimiters (list "." ";" "}" "<" " " (string #\newline) + (string #\tab) "#")) + (end-pos (search-first delimiters trimmed-str)) + (elem-str (when end-pos + (subseq trimmed-str 0 end-pos))) + (prefix (when elem-str + (string-until elem-str ":"))) + (suffix (when prefix + (string-after elem-str ":"))) + (full-url + (when (and suffix prefix) + (get-prefix construct (concat prefix ":" suffix))))) + (unless (and end-pos prefix suffix) + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "An IRI of the form prefix:suffix"))) + (unless full-url + (error (make-condition + 'sparql-parser-error + :message (format nil "The prefix in \"~a:~a\" is not registered" + prefix suffix)))) + (list :next-query (cut-comment + (string-after trimmed-str + (concat prefix ":" suffix))) + :value (make-instance 'SPARQL-Triple-Elem + :elem-type 'IRI + :value full-url))))) + + +(defgeneric parse-triple (construct query-string &key last-subject) + (:documentation "Parses a triple within a trippel group.") + (:method ((construct SPARQL-Query) (query-string String) &key (last-subject nil)) + (declare (type (or Null SPARQL-Triple-Elem) last-subject)) + (let* ((trimmed-str (cut-comment query-string)) + (subject-result (if last-subject ;;is used after a ";" + last-subject + (parse-triple-elem construct trimmed-str))) + (predicate-result (parse-triple-elem + construct + (if last-subject + trimmed-str + (getf subject-result :next-query)))) + (object-result (parse-triple-elem construct + (getf predicate-result :next-query) + :literal-allowed t))) + (add-triple construct + (make-instance 'SPARQL-Triple + :subject (if last-subject + last-subject + (getf subject-result :value)) + :predicate (getf predicate-result :value) + :object (getf object-result :value))) + (let ((tr-str (cut-comment (getf object-result :next-query)))) + (cond ((string-starts-with tr-str ";") + (parse-group construct (subseq tr-str 1) + :last-subject (getf subject-result :value))) + ((string-starts-with tr-str ".") + (parse-group construct (subseq tr-str 1))) + ((string-starts-with tr-str "}") + (parse-group construct tr-str))))))) + + +(defgeneric parse-variables (construct query-string) + (:documentation "Parses the variables of the SELECT statement + and adds them to the passed construct.") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((trimmed-str (cut-comment query-string))) + (if (string-starts-with trimmed-str "WHERE") + trimmed-str + (if (string-starts-with trimmed-str "*") + (progn (add-variable construct "*") + (parse-variables construct (string-after trimmed-str "*"))) + (let ((result (parse-variable-name construct trimmed-str))) + (add-variable construct (getf result :value)) + (parse-variables construct (getf result :next-query)))))))) + + +(defgeneric parse-variable-name (construct query-string &key additional-delimiters) + (:documentation "A helper function that parses the first non-whitespace character + in the query. since it must be a variable, it must be prefixed + by a ? or $. The return value is of the form + (:next-query string :value string).") + (:method ((construct SPARQL-Query) (query-string String) + &key (additional-delimiters)) + (declare (List additional-delimiters)) + (let ((trimmed-str (cut-comment query-string)) + (delimiters (append + (list " " "?" "$" "." (string #\newline) (string #\tab)) + additional-delimiters))) + (unless (or (string-starts-with trimmed-str "?") + (string-starts-with trimmed-str "$")) + (error (make-sparql-parser-condition + trimmed-str (original-query construct) "? or $"))) + (let* ((var-name-end (search-first delimiters (subseq trimmed-str 1))) + (var-name + (if var-name-end + (subseq trimmed-str 0 (+ 1 var-name-end)) + (error (make-sparql-parser-condition + trimmed-str (original-query construct) + "space, newline, tab, ?, ., $ or WHERE")))) + (next-query (string-after trimmed-str var-name)) + (normalized-var-name + (if (<= (length var-name) 1) + (error (make-sparql-parser-condition + next-query (original-query construct) + "a variable name")) + (subseq var-name 1)))) + (list :next-query next-query :value normalized-var-name))))) + + +(defgeneric parse-base (construct query-string next-fun) + (:documentation "Parses the Base statment and sets the corresponding + attribute in the query-construct. Since the BASE statement + may appear in different states the next-fun defines the next + call function that calls the next transitions and states.") + (:method ((construct SPARQL-Query) (query-string String) (next-fun Function)) + (let* ((trimmed-str (cut-comment query-string)) + (result (parse-closed-value trimmed-str construct))) + (setf (base-value construct) (getf result :value)) + (funcall next-fun construct (getf result :next-query))))) + + +(defgeneric parse-prefixes (construct query-string) + (:documentation "Sets the correponding prefix-tuples in the passed object.") + (:method ((construct SPARQL-Query) (query-string String)) + (let ((trimmed-string (cut-comment query-string))) + (if (string-starts-with trimmed-string ":") + (let ((results + (parse-closed-value (subseq trimmed-string 1) construct))) + (add-prefix construct *empty-label* (getf results :value)) + (parser-start construct (getf results :next-query))) + (let* ((label-name + (trim-whitespace-right (string-until trimmed-string ":"))) + (next-query-str + (trim-whitespace-left (string-after trimmed-string ":"))) + (results (parse-closed-value next-query-str construct))) + (when (string= label-name trimmed-string) + (error (make-sparql-parser-condition + trimmed-string (original-query construct) ":"))) + (add-prefix construct label-name (getf results :value)) + (parser-start construct (getf results :next-query))))))) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_special_uris.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/sparql_special_uris.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,379 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + + +(in-package :TM-SPARQL) + + +(defmacro with-triple-nodes (triple-construct &body body) + "Generates the variables subj, pred, obj that references the triple's + nodes. Additionaly the variables subj-uri, pred-uri and obj-uri are + generated when the corresponding node is a resource-nodes." + `(let* ((subj (subject ,triple-construct)) + (pred (predicate ,triple-construct)) + (obj (object ,triple-construct)) + (subj-uri (unless (variable-p subj) + (sparql-node (value subj) :revision revision))) + (pred-uri (unless (variable-p pred) + (sparql-node (value pred) :revision revision))) + (obj-uri (when (and (not (variable-p obj)) + (not (literal-p obj))) + (sparql-node (value obj) :revision revision))) + (literal-datatype (when (literal-p obj) + (literal-datatype obj)))) + (declare (Ignorable subj-uri pred-uri obj-uri literal-datatype)) + ,@body)) + + +(defgeneric filter-by-special-uris (construct &key revision) + (:documentation "Returns lists representing triples that handles special + predicate uris defined in tmsparql.") + (:method ((construct SPARQL-Triple) &key (revision d:*TM-REVISION*)) + (let ((pred (predicate construct)) + (pred-val (value (predicate construct)))) + (if (variable-p pred) + (filter-for-special-uris construct :revision revision) + (cond ((has-identifier pred-val *tms-reifier*) + (filter-for-reifier construct :revision revision)) + ((has-identifier pred-val *tms-scope*) + (filter-for-scopes construct :revision revision)) + ((has-identifier pred-val *tms-value*) + (filter-for-values construct :revision revision)) + ((has-identifier pred-val *tms-topicProperty*) + (filter-for-topicProperties construct :revision revision)) + ((has-identifier pred-val *tms-role*) + (filter-for-roles construct :revision revision)) + ((has-identifier pred-val *tms-player*) + (filter-for-player construct :revision revision))))))) + + +(defgeneric filter-for-special-uris (construct &key revision) + (:documentation "Returns a list of triples representing the subject + and its objects corresponding to the defined + special-uris, e.g. <subj> var <obj>.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (let* ((pred (predicate construct)) + (old-pred-value (value pred)) + (res-1 + (progn + (setf (value pred) (get-item-by-psi *tms-reifier* :revision revision)) + (let ((val (filter-for-reifier construct :revision revision))) + (setf (value pred) old-pred-value) + val))) + (res-2 + (progn + (setf (value pred) (get-item-by-psi *tms-scope* :revision revision)) + (let ((val (filter-for-scopes construct :revision revision))) + (setf (value pred) old-pred-value) + val))) + (res-3 + (progn + (setf (value pred) (get-item-by-psi *tms-value* :revision revision)) + (let ((val (filter-for-values construct :revision revision))) + (setf (value pred) old-pred-value) + val))) + (res-4 + (progn + (setf (value pred) (get-item-by-psi *tms-role* :revision revision)) + (let ((val (filter-for-roles construct :revision revision))) + (setf (value pred) old-pred-value) + val))) + (res-5 + (progn + (setf (value pred) (get-item-by-psi *tms-player* :revision revision)) + (let ((val (filter-for-player construct :revision revision))) + (setf (value pred) old-pred-value) + val)))) + (append res-1 res-2 res-3 res-4 res-5)))) + + +(defgeneric filter-for-player (construct &key revision) + (:documentation "Returns a list with triples where the subject + represents a role and the object represents a player.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (unless (literal-p (object construct)) + (with-triple-nodes construct + (when (and (or (typep (value subj) 'RoleC) + (variable-p subj)) + (or (typep (value obj) 'TopicC) + (variable-p obj))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (eql (player (value subj) :revision revision) + (value obj)) + (list (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + ((not (variable-p subj)) + (let ((player-top + (player (value subj) :revision revision))) + (when player-top + (list :subject subj-uri + :predicate pred-uri + :object (sparql-node player-top :revision revision))))) + ((not (variable-p obj)) + (let ((parent-roles + (player-in-roles (value obj) :revision revision))) + (loop for role in parent-roles + collect (list :subject (sparql-node role :revision revision) + :predicate pred-uri + :object (sparql-node (player role :revision revision) + :revision revision))))) + (t ; only pred is given + (let ((all-roles + (remove-null + (map 'list #'(lambda(role) + (when (player role :revision revision) + role)) + (get-all-roles revision))))) + (loop for role in all-roles + collect (list :subject (sparql-node role :revision revision) + :predicate pred-uri + :object (sparql-node (player role :revision revision) + :revision revision))))))))))) + + +(defgeneric filter-for-roles (construct &key revision) + (:documentation "Returns a list of triples where the subject represents + an Association and the object represents a role.") + (:method((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (unless (literal-p (object construct)) + (with-triple-nodes construct + (when (and (or (variable-p subj) + (typep (value subj) 'd:AssociationC)) + (or (variable-p obj) + (typep (value subj) 'd:RoleC))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (find obj (roles (value subj) :revision revision)) + (list (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + ((not (variable-p subj)) + (loop for role in (roles (value subj) :revision revision) + collect (list :subject subj-uri + :predicate pred-uri + :object (sparql-node role :revision revision)))) + ((not (variable-p obj)) + (let ((parent-assoc (parent (value obj) :revision revision))) + (when revision + (list :subject (sparql-node parent-assoc :revision revision) + :predicate pred-uri + :object obj-uri)))) + (t ; only pred is given + (let ((assocs + (remove-null + (map 'list #'(lambda(assoc) + (when (roles assoc :revision revision) + assoc)) + (get-all-associations revision))))) + (loop for assoc in assocs + append (loop for role in (roles assoc :revision revision) + collect (list :subject (sparql-node + assoc :revision revision) + :predicate pred-uri + :object (sparql-node + role :revision revision)))))))))))) + + +(defgeneric filter-for-topicProperties (construct &key revision) + (:documentation "Returns a list of triples where the subject represents + a topic and the object represents a name or occurrence.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (unless (literal-p (object construct)) + (with-triple-nodes construct + (when (and (or (variable-p subj) + (typep (value subj) 'd:TopicC)) + (or (variable-p obj) + (typep (value obj) 'd:OccurrenceC) + (typep (value obj) 'd:NameC))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (find obj (append (names (value subj) :revision revision) + (occurrences (value subj) :revision revision))) + (list (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + ((not (variable-p subj)) + (loop for property in (append + (names (value subj) :revision revision) + (occurrences (value subj) :revision revision)) + collect (list :subject subj-uri + :predicate pred-uri + :object + (sparql-node property :revision revision)))) + ((not (variable-p obj)) + (let ((parent-top (parent (value obj) :revision revision))) + (when revision + (list :subject (sparql-node parent-top :revision revision) + :predicate pred-uri + :object obj-uri)))) + (t ; only pred is given + (let ((topics + (remove-null + (map 'list #'(lambda(top) + (when (append + (names top :revision revision) + (occurrences top :revision revision)) + top)) + (get-all-topics revision))))) + (loop for top in topics + append (loop for prop in (append + (names top :revision revision) + (occurrences top :revision revision)) + collect (list :subject (sparql-node + top :revision revision) + :predicate pred-uri + :object (sparql-node + prop :revision revision)))))))))))) + + +(defgeneric filter-for-values (construct &key revision) + (:documentation "Returns a list of triples that represent a + subject and its literal value as object.") + (:method ((construct SPARQL-Triple) &key revision) + (declare (ignorable revision)) + (with-triple-nodes construct + (when (and (or (variable-p subj) + (typep (value subj) 'd:OccurrenceC) + (typep (value subj) 'd:NameC) + (typep (value subj) 'd:VariantC)) + (or (variable-p obj) + (literal-p obj))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (or (and (typep subj 'NameC) + (string= literal-datatype *xml-string*) + (string= (charvalue subj) (value obj))) + (filter-datatypable-by-value subj obj literal-datatype)) + (list (list :subject subj-uri + :predicate pred-uri + :object (value obj) + :literal-datatype literal-datatype)))) + ((not (variable-p subj)) + (list (list :subject subj-uri + :predicate pred-uri + :object (charvalue subj) + :literal-datatype (if (typep subj 'd:NameC) + *xml-string* + (datatype subj))))) + ((not (variable-p obj)) + (loop for char in (return-characteristics (value obj) literal-datatype) + collect (list :subject (sparql-node char :revision revision) + :predicate pred-uri + :object (charvalue char) + :literal-datatype (if (typep char 'd:NameC) + *xml-string* + (datatype char))))) + (t ;only pred is given + (let ((chars (append (get-all-names revision) + (get-all-occurrences revision) + (get-all-variants revision)))) + (loop for char in chars + collect (list :subject (sparql-node char :revision revision) + :predicate pred-uri + :object (charvalue char) + :literal-datatype (if (typep char 'd:NameC) + *xml-string* + (datatype char))))))))))) + + + (defgeneric filter-for-scopes (construct &key revision) + (:documentation "Returns a list of triples that represent a subject as the + scoped item and the object as the scope-topic.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (unless (literal-p (object construct)) + (with-triple-nodes construct + (when (and (or (variable-p subj) + (typep (value subj) 'd:ScopableC)) + (or (variable-p obj) + (typep (value obj) 'd:TopicC))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (find obj (themes (value subj) :revision revision)) + (list (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + ((not (variable-p subj)) + (loop for scope in (themes (value subj) :revision revision) + collect (list :subject subj-uri + :predicate pred-uri + :object (sparql-node scope :revision revision)))) + ((not (variable-p obj)) + (let ((scoped-constructs + (used-as-theme (value obj) :revision revision))) + (loop for construct in scoped-constructs + collect (list :subject (sparql-node construct :revision revision) + :predicate pred-uri + :object obj-uri)))) + (t ;only pred is given + (let ((scoped-constructs + (remove-null + (map 'list #'(lambda(construct) + (when (themes construct :revision revision) + construct)) + (append (get-all-associations revision) + (get-all-occurrences revision) + (get-all-names revision) + (get-all-variants)))))) + (loop for construct in scoped-constructs + append (loop for scope in (themes construct :revision revision) + collect + (list :subject (sparql-node + construct :revision revision) + :predicate pred-uri + :object (sparql-node + construct :revision revision)))))))))))) + + +(defgeneric filter-for-reifier (construct &key revision) + (:documentation "Returns a list with triples representing a reifier + and the corresponding reified construct.") + (:method ((construct SPARQL-Triple) &key (revision *TM-REVISION*)) + (unless (literal-p (object construct)) + (with-triple-nodes construct + (when (and (or (variable-p subj) + (typep (value subj) 'd:ReifiableConstructC)) + (or (variable-p obj) + (typep (value obj) 'd:TopicC))) + (cond ((and (not (variable-p subj)) + (not (variable-p obj))) + (when (eql (reifier (value subj) :revision revision) + (value obj)) + (list (list :subject subj-uri + :predicate pred-uri + :object obj-uri)))) + ((not (variable-p subj)) + (let ((reifier-top + (reifier (value subj) :revision revision))) + (when reifier-top + (list :subject subj-uri + :predicate pred-uri + :object (sparql-node reifier-top :revision revision))))) + ((not (variable-p obj)) + (let ((reified-cons + (reified-construct (value obj) :revision revision))) + (when reified-cons + (list (list :subject + (sparql-node reified-cons :revision revision) + :predicate pred-uri + :object obj-uri))))) + (t ; only pred is given + (let ((topics + (remove-null + (map 'list #'(lambda(top) + (when (reified-construct top :revision revision) + top)) + (get-all-topics revision))))) + (loop for top in topics + collect (list :subject + (sparql-node (reified-construct top :revision revision) + :revision revision) + :predicate pred-uri + :object (sparql-node top :revision revision))))))))))) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/TM-SPARQL/tmsparql_core_psis.xtm ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/TM-SPARQL/tmsparql_core_psis.xtm Wed Feb 16 04:51:06 2011 @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!-- ======================================================================= --> +<!-- Isidorus --> +<!-- (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff --> +<!-- --> +<!-- Isidorus is freely distributable under the LLGPL license. --> +<!-- This ajax module uses the frameworks PrototypeJs and Scriptaculous, --> +<!-- both are distributed under the MIT license. --> +<!-- You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt, --> +<!-- trunk/docs/LGPL-LICENSE.txt and in --> +<!-- trunk/src/ajax/javascripts/external/MIT-LICENSE.txt. --> +<!-- ======================================================================= --> + + +<!-- this file contains the special uri defined in tmsparql + (
http://www.networkedplanet.com/ontopic/2009/11/making_topic_maps_sparql.html
) + as topic with only a psi as element corresponding to those defined in + tmsparql --> + +<topicMap xmlns="
http://www.topicmaps.org/xtm/
" version="2.0"> + <topic id="reifier"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/reifier
"/> + </topic> + + <topic id="role"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/role
"/> + </topic> + + <topic id="player"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/player
"/> + </topic> + + <topic id="topicProperty"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/topicProperty
"/> + </topic> + + <topic id="scope"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/scope
"/> + </topic> + + <topic id="value"> + <subjectIdentifier href="
http://www.networkedplanet.com/tmsparql/value
"/> + </topic> + +</topicMap> Added: trunk/playground/abcl-test/lisp-code/base-tools/base-tools.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/base-tools/base-tools.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,520 @@ +;;+----------------------------------------------------------------------------- +;;+ Isidorus +;;+ (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff +;;+ +;;+ Isidorus is freely distributable under the LLGPL license. +;;+ You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and +;;+ trunk/docs/LGPL-LICENSE.txt. +;;+----------------------------------------------------------------------------- + +(defpackage :base-tools + (:use :cl) + (:nicknames :tools) + (:export :push-string + :concat + :when-do + :string-replace + :remove-null + :full-path + :trim-whitespace-left + :trim-whitespace-right + :trim-whitespace + :string-starts-with + :string-ends-with + :string-ends-with-one-of + :string-starts-with-char + :string-starts-with-one-of + :string-until + :string-after + :search-first + :search-first-ignore-literals + :concatenate-uri + :absolute-uri-p + :string-starts-with-digit + :string-after-number + :separate-leading-digits + :white-space + :white-space-p + :escape-string + :search-first-unclosed-paranthesis + :search-first-unopened-paranthesis + :in-literal-string-p + :find-literal-end + :get-literal-quotation + :get-literal + :return-if-starts-with)) + +(in-package :base-tools) + + +(defparameter *white-space* + (list #\Space #\Tab #\Newline (code-char 13)) + "Contains all characters that are treated as white space.") + + +(defun white-space() + "Returns a lit os string that represents a white space." + (map 'list #'(lambda(char) + (string char)) + *white-space*)) + + +(defmacro concat (&rest strings) + `(concatenate 'string ,@strings)) + + +(defmacro push-string (obj place) + "Imitates the push macro but instead of pushing object in a list, + there will be appended the given string to the main string object." + `(setf ,place (concat ,place ,obj))) + + +(defmacro when-do (result-bounding condition-statement do-with-result) + "Executes the first statement and stores its result in the variable result. + If result isn't nil the second statement is called. + The second statement can use the variable tools:result as a parameter." + `(let ((,result-bounding ,condition-statement)) + (if ,result-bounding + ,do-with-result + nil))) + + +(defun white-space-p (str) + "Returns t if the passed str contains only white space characters." + (cond ((and (= (length str) 1) + (string-starts-with-one-of str (white-space))) + t) + ((string-starts-with-one-of str (white-space)) + (white-space-p (subseq str 1))) + (t + nil))) + + +(defun remove-null (lst) + "Removes all null values from the passed list." + (remove-if #'null lst)) + + +(defun full-path (pathname) + "Returns a string that represents the full path of the passed + CL:Pathname construct." + (declare (CL:Pathname pathname)) + (let ((segments + (remove-if #'null + (map 'list #'(lambda(item) + (when (stringp item) + (concat "/" item))) + (pathname-directory pathname)))) + (full-path-string "")) + (dolist (segment segments) + (push-string segment full-path-string)) + (concat full-path-string "/" (pathname-name pathname)))) + + +(defun trim-whitespace-left (value) + "Uses string-left-trim with a predefined character-list." + (declare (String value)) + (string-left-trim *white-space* value)) + + +(defun trim-whitespace-right (value) + "Uses string-right-trim with a predefined character-list." + (declare (String value)) + (string-right-trim *white-space* value)) + + +(defun trim-whitespace (value) + "Uses string-trim with a predefined character-list." + (declare (String value)) + (string-trim *white-space* value)) + + +(defun string-starts-with (str prefix &key (ignore-case nil)) + "Checks if string str starts with a given prefix." + (declare (String str prefix) + (Boolean ignore-case)) + (let ((str-i (if ignore-case + (string-downcase str :start 0 :end (min (length str) + (length prefix))) + str)) + (prefix-i (if ignore-case + (string-downcase prefix) + prefix))) + (string= str-i prefix-i :start1 0 :end1 + (min (length prefix-i) + (length str-i))))) + + +(defun string-starts-with-one-of (str prefixes &key (ignore-case nil)) + "Returns t if str ends with one of the string contained in suffixes." + (declare (String str) + (List prefixes) + (Boolean ignore-case)) + (loop for prefix in prefixes + when (string-starts-with str prefix :ignore-case ignore-case) + return t)) + + +(defun string-ends-with (str suffix &key (ignore-case nil)) + "Checks if string str ends with a given suffix." + (declare (String str suffix) + (Boolean ignore-case)) + (let ((str-i (if ignore-case + (string-downcase str :start (max (- (length str) + (length suffix)) + 0) + :end (length str)) + str)) + (suffix-i (if ignore-case + (string-downcase suffix) + suffix))) + (string= str-i suffix-i :start1 (max (- (length str) + (length suffix)) + 0)))) + + +(defun string-ends-with-one-of (str suffixes &key (ignore-case nil)) + "Returns t if str ends with one of the string contained in suffixes." + (declare (String str) + (List suffixes) + (Boolean ignore-case)) + (loop for suffix in suffixes + when (string-ends-with str suffix :ignore-case ignore-case) + return t)) + + +(defun string-replace (main-string string-to-replace new-string) + "Replaces every occurrence of string-to-replace by new-string + in main-string." + (declare (String main-string string-to-replace new-string)) + (if (string= string-to-replace new-string) + main-string + (let ((search-idx (search-first (list string-to-replace) main-string))) + (if (not search-idx) + main-string + (let ((modified-string + (concat (subseq main-string 0 search-idx) + new-string + (subseq main-string + (+ search-idx (length string-to-replace)))))) + (string-replace modified-string string-to-replace new-string)))))) + + + +(defun string-starts-with-digit (str) + "Checks whether the passed string starts with a digit." + (declare (String str)) + (loop for item in (list 0 1 2 3 4 5 6 7 8 9) + when (string-starts-with str (write-to-string item)) + return t)) + + +(defun string-after-number (str) + "If str starts with a digit, there is returned the first + substring after a character that is a non-digit. + If str does not start with a digit str is returned." + (declare (String str)) + (if (and (string-starts-with-digit str) + (> (length str) 0)) + (string-after-number (subseq str 1)) + str)) + + +(defun separate-leading-digits (str &optional digits) + "If str starts with a number the number is returned." + (declare (String str) + (type (or Null String) digits)) + (if (string-starts-with-digit str) + (separate-leading-digits + (subseq str 1) (concat digits (subseq str 0 1))) + digits)) + + +(defun string-starts-with-char (begin str) + (equal (char str 0) begin)) + + +(defun string-until (str anchor) + "Returns a substring until the position of the passed anchor." + (declare (String str anchor)) + (let ((pos (search anchor str))) + (if pos + (subseq str 0 pos) + str))) + + +(defun string-after (str prefix) + "Returns the substring after the found prefix. + If there is no substring equal to prefix nil is returned." + (declare (String str prefix)) + (let ((pos (search prefix str))) + (if pos + (subseq str (+ pos (length prefix))) + nil))) + + +(defun search-first (search-strings main-string &key from-end) + "Returns the position of one of the search-strings. The returned position + is the one closest to 0. If no search-string is found, nil is returned." + (declare (String main-string) + (List search-strings)) + (let ((positions + (remove-null + (map 'list #'(lambda(search-str) + (search search-str main-string :from-end from-end)) + search-strings)))) + (let ((sorted-positions (if from-end + (sort positions #'>) + (sort positions #'<)))) + (when sorted-positions + (first sorted-positions))))) + + +(defun find-literal-end (query-string delimiter &optional (overall-pos 0)) + "Returns the end of the literal corresponding to the passed delimiter + string. The query-string must start after the opening literal delimiter. + The return value is an int that represents the start index of closing + delimiter. delimiter must be either \", ', or '''. + If the returns value is nil, there is no closing delimiter." + (declare (String query-string delimiter) + (Integer overall-pos)) + (let ((current-pos (search delimiter query-string))) + (if current-pos + (if (string-ends-with (subseq query-string 0 current-pos) "\\") + (find-literal-end (subseq query-string (+ current-pos + (length delimiter))) + delimiter (+ overall-pos current-pos 1)) + (+ overall-pos current-pos (length delimiter))) + nil))) + + +(defun get-literal-quotation (str) + "Returns ', ''', \" or \"\"\" when the string starts with a literal delimiter." + (cond ((string-starts-with str "'''") + "'") + ((string-starts-with str "\"\"\"") + "\"\"\"") + ((string-starts-with str "'") + "'") + ((string-starts-with str "\"") + "\""))) + + +(defun get-literal (query-string &key (quotation nil)) + "Returns a list of the form (:next-string <string> :literal <string> + where next-query is the query after the found literal and literal + is the literal string." + (declare (String query-string) + (type (or Null String) quotation)) + (let ((local-quotation quotation)) + (cond ((or (string-starts-with query-string "\"\"\"") + (string-starts-with query-string "'''")) + (unless local-quotation + (setf local-quotation (subseq query-string 0 3))) + (let ((literal-end + (find-literal-end (subseq query-string 3) (subseq query-string 0 3)))) + (when literal-end + (list :next-string (subseq query-string (+ 3 literal-end)) + :literal (concat quotation + (subseq query-string 3 literal-end) + quotation))))) + ((or (string-starts-with query-string "\"") + (string-starts-with query-string "'")) + (unless local-quotation + (setf local-quotation (subseq query-string 0 1))) + (let ((literal-end + (find-literal-end (subseq query-string 1) + (subseq query-string 0 1)))) + (when literal-end + (let ((literal + (escape-string (subseq query-string 1 literal-end) "\""))) + (list :next-string (subseq query-string (+ 1 literal-end)) + :literal (concat local-quotation literal + local-quotation))))))))) + + +(defun search-first-ignore-literals (search-strings main-string &key from-end) + (declare (String main-string) + (List search-strings) + (Boolean from-end)) + (let ((first-pos + (search-first search-strings main-string :from-end from-end))) + (when first-pos + (if (not (in-literal-string-p main-string first-pos)) + first-pos + (let* ((literal-start + (search-first (list "\"" "'") (subseq main-string 0 first-pos) + :from-end from-end)) + (next-str + (if from-end + + + (subseq main-string 0 literal-start) + + + (let* ((sub-str (subseq main-string literal-start)) + (literal-result (get-literal sub-str))) + (getf literal-result :next-string))))) + (let ((next-pos + (search-first-ignore-literals search-strings next-str + :from-end from-end))) + (when next-pos + (+ (- (length main-string) (length next-str)) next-pos)))))))) + + +(defun concatenate-uri (absolute-ns value) + "Returns a string conctenated of the absolut namespace an the given value + separated by either '#' or '/'." + (declare (string absolute-ns value)) + (unless (and (> (length absolute-ns) 0) + (> (length value) 0)) + (error "From concatenate-uri(): absolute-ns and value must be of length > 0")) + (unless (absolute-uri-p absolute-ns) + (error "From concatenate-uri(): absolute-ns has to be an absolute URI: ~a" absolute-ns)) + (let ((last-char + (elt absolute-ns (- (length absolute-ns) 1))) + (first-char + (elt value 0))) + (let ((separator + (cond + ((or (eql first-char #\#) + (eql first-char #\/)) + "") + ((or (eql last-char #\#) + (eql last-char #\/)) + "") + (t + "/")))) + (let ((prep-ns + (if (and (eql last-char first-char) + (or (eql last-char #\#) + (eql last-char #\/))) + (subseq absolute-ns 0 (- (length absolute-ns) 1)) + (if (and (eql last-char #\#) + (find #\/ value)) + (progn + (when (not (eql first-char #\/)) + (setf separator "/")) + (subseq absolute-ns 0 (- (length absolute-ns) 1))) + absolute-ns)))) + (concat prep-ns separator value))))) + + +(defun absolute-uri-p (uri) + "Returns t if the passed uri is an absolute one. This + is indicated by a ':' with no leadgin '/'." + (when uri + (let ((position-of-colon + (position #\: uri))) + (declare (string uri)) + (and position-of-colon (> position-of-colon 0) + (not (find #\/ (subseq uri 0 position-of-colon))))))) + + +(defun escape-string (str char-to-escape) + "Escapes every occurrence of char-to-escape in str, if it is + not escaped." + (declare (String str char-to-escape)) + (let ((result "")) + (dotimes (idx (length str)) + (let ((current-char (subseq str idx (1+ idx))) + (previous-char (if (= idx 0) "" (subseq str (1- idx) idx)))) + (cond ((and (string= current-char char-to-escape) + (string/= previous-char "\\")) + (push-string "\\" result) + (push-string current-char result)) + (t + (push-string current-char result))))) + result)) + + +(defun in-literal-string-p(filter-string pos) + "Returns t if the passed pos is within a literal string value." + (declare (String filter-string) + (Integer pos)) + (let ((result nil)) + (dotimes (idx (length filter-string) result) + (let ((current-char (subseq filter-string idx (1+ idx)))) + (cond ((or (string= current-char "'") + (string= current-char "\"")) + (let* ((l-result (get-literal (subseq filter-string idx))) + (next-idx + (when l-result + (- (length filter-string) + (length (getf l-result :next-string)))))) + (when (and next-idx (< pos next-idx)) + (setf result t) + (setf idx (length filter-string))) + (when (<= pos idx) + (setf idx (length filter-string))))) + (t + (when (<= pos idx) + (setf idx (length filter-string))))))))) + + +(defun search-first-unclosed-paranthesis (str &key ignore-literals) + "Returns the idx of the first ( that is not closed, the search is + started from the end of the string. + If ignore-literals is set to t all paranthesis that are within + \", \"\"\", ' and ''' are ignored." + (declare (String str) + (Boolean ignore-literals)) + (let ((open-brackets 0) + (result-idx nil)) + (do ((idx (1- (length str)))) ((< idx 0)) + (let ((current-char (subseq str idx (1+ idx)))) + (cond ((string= current-char ")") + (when (or ignore-literals + (not (in-literal-string-p str idx))) + (decf open-brackets))) + ((string= current-char "(") + (when (or ignore-literals + (not (in-literal-string-p str idx))) + (incf open-brackets) + (when (> open-brackets 0) + (setf result-idx idx) + (setf idx 0))))) + (decf idx))) + result-idx)) + + +(defun search-first-unopened-paranthesis (str &key ignore-literals) + "Returns the idx of the first paranthesis that is not opened in str. + If ignore-literals is set to t all mparanthesis that are within + \", \"\"\", ' and ''' are ignored." + (declare (String str) + (Boolean ignore-literals)) + (let ((closed-brackets 0) + (result-idx nil)) + (dotimes (idx (length str)) + (let ((current-char (subseq str idx (1+ idx)))) + (cond ((string= current-char "(") + (when (or ignore-literals + (not (in-literal-string-p str idx))) + (decf closed-brackets) + (setf result-idx nil))) + ((string= current-char ")") + (when (or ignore-literals + (not (in-literal-string-p str idx))) + (incf closed-brackets) + (when (> closed-brackets 0) + (setf result-idx idx) + (setf idx (length str)))))))) + result-idx)) + + +(defun return-if-starts-with (str to-be-matched &key from-end ignore-case + ignore-leading-whitespace) + "Returns the string that is contained in to-be-matched and that is the + start of the string str." + (declare (String str) + (List to-be-matched) + (Boolean from-end ignore-case ignore-leading-whitespace)) + (let ((cleaned-str (if ignore-leading-whitespace + (trim-whitespace-left str) + str))) + (loop for try in to-be-matched + when (if from-end + (string-ends-with cleaned-str try :ignore-case ignore-case) + (string-starts-with cleaned-str try :ignore-case ignore-case)) + return try))) \ No newline at end of file Added: trunk/playground/abcl-test/lisp-code/test-code/functions.lisp ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/lisp-code/test-code/functions.lisp Wed Feb 16 04:51:06 2011 @@ -0,0 +1,11 @@ +(defun print-line(param) + (format t "~a~%" param)) + + +(defun add(a b) + (+ a b)) + + + +(let ((line-str (concatenate 'string "the result of 6 + 2 is " (write-to-string (add 6 2))))) + (print-line line-str)) \ No newline at end of file Added: trunk/playground/abcl-test/src/program/Main.java ============================================================================== --- (empty file) +++ trunk/playground/abcl-test/src/program/Main.java Wed Feb 16 04:51:06 2011 @@ -0,0 +1,75 @@ +package program; + +import org.armedbear.lisp.Cons; +import org.armedbear.lisp.Fixnum; +import org.armedbear.lisp.Function; +import org.armedbear.lisp.Interpreter; +import org.armedbear.lisp.JavaObject; +import org.armedbear.lisp.LispObject; +import org.armedbear.lisp.MacroObject; +import org.armedbear.lisp.Packages; +import org.armedbear.lisp.Package; +import org.armedbear.lisp.Symbol; + + + +public class Main { + public static void main(String[] args){ + //testABCL(); + loadTmSparql(); + } + + + public static void testABCL(){ + // load the file functions.lisp which also evaluates a let as last command + Interpreter interpreter = Interpreter.createInstance(); + interpreter.eval("(load \"lisp-code/test-code/functions.lisp\")"); + + + // use the lisp function print-line + Package defaultPackage = Packages.findPackage("CL-USER"); + Symbol myFunctionSym = defaultPackage.findAccessibleSymbol("PRINT-LINE"); + Function printLineFun = (Function)myFunctionSym.getSymbolFunction(); + LispObject lispString = JavaObject.getInstance("This is a java string", true); + printLineFun.execute(lispString); + + + // use the lisp function add + myFunctionSym = defaultPackage.findAccessibleSymbol("ADD"); + Function addFun = (Function)myFunctionSym.getSymbolFunction(); + LispObject lispInt1 = JavaObject.getInstance(6, true); + LispObject lispInt2 = JavaObject.getInstance(2, true); + LispObject result = addFun.execute(lispInt1, lispInt2); + System.out.println(result.intValue()); + + + // use the build-i function cons + myFunctionSym = defaultPackage.findAccessibleSymbol("CONS"); + Function consFun = (Function)myFunctionSym.getSymbolFunction(); + Cons list = (Cons) consFun.execute(Fixnum.getInstance(64), Fixnum.getInstance(65)); + System.out.println(list.car.intValue() + ", " + list.cdr.intValue()); + } + + + public static void loadTmSparql(){ + // === load base-tools.lisp =========================================== + Interpreter interpreter = Interpreter.createInstance(); + interpreter.eval("(load \"lisp-code/base-tools/base-tools.lisp\")"); + + + // === load sparql.lisp =============================================== + //interpreter.eval("(load \"lisp-code/TM-SPARQL/sparql.lisp\")"); + //TODO: import datamodel => implement an abstract datamodel + + + // === test the loaded files ========================================== + Package defaultPackage = Packages.findPackage("BASE-TOOLS"); + Symbol myFunSym = defaultPackage.findAccessibleSymbol("separate-leading-digits".toUpperCase()); + Function strFun = (Function)myFunSym.getSymbolFunction(); + + LispObject str1 = JavaObject.getInstance("no leading digits in this string", true); + LispObject str2 = JavaObject.getInstance("123 string started with 3 digits", true); + System.out.println(strFun.execute(str1)); + System.out.println(strFun.execute(str2)); + } +} Modified: trunk/src/TM-SPARQL/sparql_special_uris.lisp ============================================================================== --- trunk/src/TM-SPARQL/sparql_special_uris.lisp (original) +++ trunk/src/TM-SPARQL/sparql_special_uris.lisp Wed Feb 16 04:51:06 2011 @@ -11,13 +11,13 @@ (in-package :TM-SPARQL) -;TODO: create a macro for "filter-for-scopes", "filter-for-reifier", ... - - -(defmacro with-triple-nodes (construct &body body) - `(let* ((subj (subject ,construct)) - (pred (predicate ,construct)) - (obj (object ,construct)) +(defmacro with-triple-nodes (triple-construct &body body) + "Generates the variables subj, pred, obj that references the triple's + nodes. Additionaly the variables subj-uri, pred-uri and obj-uri are + generated when the corresponding node is a resource-nodes." + `(let* ((subj (subject ,triple-construct)) + (pred (predicate ,triple-construct)) + (obj (object ,triple-construct)) (subj-uri (unless (variable-p subj) (sparql-node (value subj) :revision revision))) (pred-uri (unless (variable-p pred)
1
0
0
0
← Newer
1
...
62
63
64
65
66
67
68
...
104
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Results per page:
10
25
50
100
200