{"id":1078,"date":"2018-09-30T07:37:29","date_gmt":"2018-09-30T02:07:29","guid":{"rendered":"https:\/\/www.rangakrish.com\/?p=1078"},"modified":"2018-09-30T07:39:57","modified_gmt":"2018-09-30T02:09:57","slug":"dependency-graph-to-rdf-part-2","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/30\/dependency-graph-to-rdf-part-2\/","title":{"rendered":"Dependency Graph to RDF &#8211; Part 2"},"content":{"rendered":"<p>In the <a href=\"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/16\/dependency-graph-to-rdf\/\" target=\"_blank\" rel=\"noopener\">last post<\/a>, I outlined an approach to convert a dependency graph (the result of dependency parsing) to RDF. The particular RDF format I used is <em><strong>Turtle<\/strong><\/em>, which is widely supported. Today, I would like to show how to load this RDF data in a Semantic<span class=\"Apple-converted-space\">\u00a0 <\/span>Graph database and make queries on it.<\/p>\n<p>There are several Semantic Web Frameworks and Graph databases that we could use, but my choice today is <a href=\"https:\/\/allegrograph.com\/products\/allegrograph\/\" target=\"_blank\" rel=\"noopener\"><em><strong>AllegroGraph<\/strong><\/em><\/a>\u00a0free Server Edition from Franz Inc. It supports <em><strong>SPARQL<\/strong><\/em> as well as multiple <em><strong>Reasoners<\/strong><\/em>. Besides, it has excellent integration with <a href=\"https:\/\/franz.com\/products\/allegro-common-lisp\/\" target=\"_blank\" rel=\"noopener\"><em><strong>Allegro Common Lisp<\/strong><\/em><\/a> and I am an avid user of that Lisp (in addition to <a href=\"http:\/\/www.lispworks.com\" target=\"_blank\" rel=\"noopener\"><em><strong>LispWorks Lisp<\/strong><\/em><\/a>). It also supports clients written in <em><strong>Java<\/strong><\/em>, <em><strong>Python<\/strong><\/em>, <em><strong>Clojure<\/strong><\/em>, and many more via its <em><strong>REST<\/strong><\/em> API.<\/p>\n<p>I downloaded the <em><strong>Virtual Machine<\/strong><\/em> package (Ubuntu 64-bit) and since my development machine is Windows 64-bit, installed the VM in my <em><strong>VMware Workstation 12 Player<\/strong><\/em> running on my Windows 10.<\/p>\n<figure id=\"attachment_1079\" aria-describedby=\"caption-attachment-1079\" style=\"width: 563px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png?ssl=1\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" data-attachment-id=\"1079\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/30\/dependency-graph-to-rdf-part-2\/allegrograph-vm\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png\" data-orig-size=\"563,588\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"AllegroGraph VM\" data-image-description=\"&lt;p&gt;AllegroGraph VM&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;AllegroGraph VM&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png\" class=\"size-full wp-image-1079\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png?resize=563%2C588&#038;ssl=1\" alt=\"AllegroGraph VM\" width=\"563\" height=\"588\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png?w=563&amp;ssl=1 563w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/AllegroGraph-VM.png?resize=287%2C300&amp;ssl=1 287w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><figcaption id=\"caption-attachment-1079\" class=\"wp-caption-text\">AllegroGraph VM<\/figcaption><\/figure>\n<p>Please note that your version of the <em><strong>AllegroGraph<\/strong><\/em> server might differ from the one I am using. But that should not matter for our discussion.<\/p>\n<p>There are convenient icons to <em><strong>Start<\/strong><\/em> and <em><strong>Stop<\/strong><\/em> the server.<\/p>\n<p>Let us double click on <em><strong>Start AG<\/strong><\/em> and wait for a few seconds before the server is ready. Since the server is running inside a VM box, I need the <em><strong>IP<\/strong><\/em> of the server to connect to it from my <em><strong>Windows<\/strong><\/em> machine.<\/p>\n<p>To find the IP address, let us open the <em><strong>Terminal<\/strong><\/em> and enter<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<blockquote><p><span style=\"color: #0000ff;\">~\/franz\/ipaddr.sh<\/span><span class=\"Apple-converted-space\">\u00a0<\/span><\/p><\/blockquote>\n<p>This shows the IP address. The port to use is 10035.<\/p>\n<figure id=\"attachment_1080\" aria-describedby=\"caption-attachment-1080\" style=\"width: 563px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"1080\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/30\/dependency-graph-to-rdf-part-2\/ip-address\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png\" data-orig-size=\"563,588\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Finding the IP Address\" data-image-description=\"&lt;p&gt;Finding the IP Address&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Finding the IP Address&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png\" class=\"size-full wp-image-1080\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png?resize=563%2C588&#038;ssl=1\" alt=\"Finding the IP Address\" width=\"563\" height=\"588\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png?w=563&amp;ssl=1 563w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/IP-Address.png?resize=287%2C300&amp;ssl=1 287w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/a><figcaption id=\"caption-attachment-1080\" class=\"wp-caption-text\">Finding the IP Address<\/figcaption><\/figure>\n<p>To make sure the server is running fine, let us open a <em><strong>Browser<\/strong><\/em> and point to the server:<\/p>\n<figure id=\"attachment_1081\" aria-describedby=\"caption-attachment-1081\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" data-attachment-id=\"1081\" data-permalink=\"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/30\/dependency-graph-to-rdf-part-2\/checking-the-server\/\" data-orig-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png\" data-orig-size=\"814,626\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Browser View\" data-image-description=\"&lt;p&gt;Browser View&lt;\/p&gt;\n\" data-image-caption=\"&lt;p&gt;Browser View&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png\" class=\"wp-image-1081\" src=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png?resize=650%2C500&#038;ssl=1\" alt=\"Browser View\" width=\"650\" height=\"500\" srcset=\"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png?w=814&amp;ssl=1 814w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png?resize=300%2C231&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/Checking-the-server.png?resize=768%2C591&amp;ssl=1 768w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/a><figcaption id=\"caption-attachment-1081\" class=\"wp-caption-text\">Browser View<\/figcaption><\/figure>\n<p>You can see that this shows the <em><strong>Web View<\/strong><\/em> of the server. This means the server is working fine. Although we can work with the database using this interface, we will instead access the services programmatically using <em><strong>Allegro Common Lisp<\/strong><\/em>.<\/p>\n<h2>Using Lisp Client<\/h2>\n<p>After launching <em><strong>AllegroCL<\/strong><\/em>, we have to first load the client library and set up the basic package environment:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">(load &#8220;G:\/acl-projects\/Allegrograph\/agraph.fasl&#8221;)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(eval-when (:compile-toplevel :load-toplevel :execute)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0\u00a0<\/span>(require :agraph)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 <\/span>(db.agraph:enable-readtable :allegrograph)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 <\/span>)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(in-package :db.agraph.user)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(use-package :cl)<\/span><\/p><\/blockquote>\n<p>We then define some convenient functions:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">(defun create-or-open (name server-ip function)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (funcall function name<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 :triple-store-class &#8216;remote-triple-store<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 :server server-ip<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 :port 10035<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 :user &#8220;test&#8221; :password &#8220;xyzzy&#8221;))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun create-store (name server-ip) <\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (create-or-open name server-ip #&#8217;create-triple-store))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun open-store (name server-ip)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (create-or-open name server-ip #&#8217;open-triple-store))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun close-store ()<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (close-triple-store))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">;;; Open the Dependency Graph DB<\/span><\/p>\n<p><span style=\"color: #0000ff;\">;;; Returns the number of triples in the DB<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun open-dep-graph-store (dbname serverip)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (open-store dbname serverip)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (enable-!-reader) <\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (enable-print-decoded t)<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (triple-count))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">;; Close the currently open DB after committing the data.<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun close-dep-graph-store ()<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 \u00a0(commit-triple-store) <\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 \u00a0(close-store))<\/span><\/p>\n<p><span style=\"color: #0000ff;\">;;; Delete all the tuples. Not Committed!<\/span><\/p>\n<p><span style=\"color: #0000ff;\">(defun delete-all-tuples ()<\/span><\/p>\n<p><span style=\"color: #0000ff;\">\u00a0 \u00a0 (delete-triples :s nil))<\/span><\/p><\/blockquote>\n<p>Since the server is now running, let us create a new triple store (listener transcript is shown &#8211; result is in green text):<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(15): (create-store &#8220;rdf-test&#8221; &#8220;192.168.240.133&#8221;)<\/span><\/p>\n<p><span style=\"color: #339966;\">#&lt;remote-triple-store<\/span><\/p>\n<p><span style=\"color: #339966;\"><span class=\"Apple-converted-space\">\u00a0 <\/span>rdf-test <a style=\"color: #339966;\" href=\"http:\/\/192.168.240.133:37792\/sessions\/8e0ed752-549e-b354-2e98-000c29d66220\">http:\/\/192.168.240.133:37792\/sessions\/8e0ed752-549e-b354-2e98-000c29d66220<\/a>, open @ #x204a7a1a2&gt;<\/span><\/p><\/blockquote>\n<p>Let us verify that there is no data in the triple store yet.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(16): (triple-count)<\/span><\/p>\n<p><span style=\"color: #339966;\">0<\/span><\/p><\/blockquote>\n<p>Let us also confirm the <em><strong>DB<\/strong><\/em> name:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(17): (db-name *db*)<\/span><\/p>\n<p><span style=\"color: #339966;\">&#8220;rdf-test&#8221;<\/span><\/p><\/blockquote>\n<p>OK. Now let us load our <em><strong>Turtle<\/strong><\/em> file, created in the last post.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(18): (load-turtle &#8220;G:\/Python Projects\/Dependency parser\/Sample.ttl&#8221;)<\/span><\/p>\n<p><span style=\"color: #339966;\">300<\/span><\/p>\n<p><span style=\"color: #339966;\">{G}<\/span><\/p><\/blockquote>\n<p>Let us check the count of triples.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(19): (triple-count)<\/span><\/p>\n<p><span style=\"color: #339966;\">300<\/span><\/p><\/blockquote>\n<p>Although this step is not needed, for safety, let us commit the transaction, close the triple store and re-open it.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(20): (commit-triple-store)<\/span><\/p>\n<p><span style=\"color: #339966;\">t<\/span><\/p>\n<p><span style=\"color: #0000ff;\">triple-store-user(21): (close-store)<\/span><\/p>\n<p><span style=\"color: #339966;\">nil<\/span><\/p><\/blockquote>\n<p>Let us now open the triple store instead of creating a new one.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(22): (open-dep-graph-store &#8220;rdf-test&#8221; &#8220;192.168.240.133&#8221;)<\/span><\/p>\n<p><span style=\"color: #339966;\">300<\/span><\/p>\n<p><span style=\"color: #0000ff;\">triple-store-user(23): (db-name *db*)<\/span><\/p>\n<p><span style=\"color: #339966;\">&#8220;rdf-test&#8221;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">triple-store-user(24): (triple-count)<\/span><\/p>\n<p><span style=\"color: #339966;\">300<\/span><\/p><\/blockquote>\n<p>If you recall, we had used a namespace called <em><strong>m<\/strong><\/em> in our triples. We have to register that name space as part of the current DB.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(25): (register-namespace &#8220;m&#8221; &#8220;<a style=\"color: #0000ff;\" href=\"http:\/\/mmsindia\/depgraph\/example\/\">http:\/\/mmsindia\/depgraph\/example\/<\/a>&#8220;)<\/span><\/p>\n<p><span style=\"color: #339966;\">&#8220;<a style=\"color: #339966;\" href=\"http:\/\/mmsindia\/depgraph\/example\/\">http:\/\/mmsindia\/depgraph\/example\/<\/a>&#8220;<\/span><\/p><\/blockquote>\n<h2><b>Querying Using Prolog<\/b><\/h2>\n<p>One of the benefits of using Lisp client is that <em><strong>AllegroCL<\/strong><\/em> lets you query the triple store using its implementation of <em><strong>Prolog<\/strong><\/em> (this syntax is lispy compared to the standard Prolog). A good tutorial is here:<\/p>\n<p><a href=\"https:\/\/franz.com\/agraph\/support\/documentation\/current\/prolog-tutorial.html\">https:\/\/franz.com\/agraph\/support\/documentation\/current\/prolog-tutorial.html<\/a><\/p>\n<p>Let us start with a simple query:\u00a0<em><strong>Find the lemmas of all the words appearing in the text<\/strong><\/em>:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(26): (remove-duplicates (apply #&#8217;append (select (?x) <span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(q- ? !m:lemma ?x))) :test #&#8217;string=)<\/span><\/p>\n<p><span style=\"color: #339966;\">(&#8220;jack&#8221; &#8220;happily&#8221; &#8220;walk&#8221; &#8220;down&#8221; &#8220;street&#8221; &#8220;icecream&#8221; &#8220;in&#8221; &#8220;hand&#8221; &#8220;suddenly&#8221; &#8220;a&#8221; &#8230;)<\/span><\/p><\/blockquote>\n<p>The above shows a partial list; there are many more words in the result.<\/p>\n<p>You can see that the query pattern is pretty straightforward. We are looking for that <em><strong>?x<\/strong><\/em> which appears as the third element of the triple:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">&lt;word-id&gt; m:lemma &lt;the-lemma&gt;<\/span><\/p><\/blockquote>\n<p>Thus it matches <em><strong>jack<\/strong><\/em> in the triple<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">m:word-250 m:lemma &#8220;jack&#8221;<\/span><\/p><\/blockquote>\n<p>and so on.<\/p>\n<p>Next, let us <em><strong>find the root words of all the sentences<\/strong><\/em>:<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(27): (remove-duplicates (apply #&#8217;append (select (?z) <span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(q- ?x !m:ROOT ?)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(q- ?x !m:label ?z))) :test #&#8217;string=)<\/span><\/p>\n<p><span style=\"color: #339966;\">(&#8220;walking&#8221; &#8220;started&#8221; &#8220;saw&#8221; &#8220;kicked&#8221; &#8220;ran&#8221;)<\/span><\/p><\/blockquote>\n<p>Here we have a query that involves two triples.<span class=\"Apple-converted-space\">\u00a0<\/span><\/p>\n<p>The variable <em><strong>?x in t<\/strong><\/em>he first pattern matches the first element of every triple that has <em><strong>m:ROOT<\/strong><\/em> as the second element.<\/p>\n<p>The second pattern matches the triple that has <em><strong>m:label<\/strong><\/em> as the second element, but whose first element is the same as the just matched <em><strong>?x<\/strong><\/em>. The variable <em><strong>?z<\/strong><\/em> then binds to the third element of that triple.<\/p>\n<p>As you would have noticed, the pattern structure is quite similar to what we use in <em><strong>SPARQL<\/strong><\/em>.<\/p>\n<p>Here are two more queries:<\/p>\n<p><em><strong>How many times does the word Jack appear in the text?<\/strong><\/em><\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(28): (length (select (?x) <span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(q- ?x !m:label ?root)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(lispp (string= (upi-&gt;value ?root) &#8220;Jack&#8221;))<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>))<\/span><\/p>\n<p><span style=\"color: #339966;\">1<\/span><\/p><\/blockquote>\n<p>It occurs in the first sentence and not later.<\/p>\n<p><em><strong>How many sentences are there in the whole text?<\/strong><\/em><\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(29): (length (remove-duplicates (apply #&#8217;append (select (?x) <span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>(q- ?x !m:word ?)<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 <\/span>)) :test #&#8217;string=))<\/span><\/p>\n<p><span style=\"color: #339966;\">5<\/span><\/p><\/blockquote>\n<p>OK, a total of 5 sentences.<\/p>\n<p>Many complex queries can be conveniently expressed in the <em><strong>Prolog<\/strong><\/em> format. The Lisp client also supports <em><strong>SPARQL<\/strong><\/em> queries. Here is an example.<\/p>\n<p><em><strong>Which sentences contain the work Jack?<\/strong><\/em><\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(30): (run-sparql<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0<\/span>&#8220;prefix m: &lt;<a style=\"color: #0000ff;\" href=\"http:\/\/mmsindia\/depgraph\/example\/\">http:\/\/mmsindia\/depgraph\/example\/<\/a>&gt;<span class=\"Apple-converted-space\">\u00a0<\/span><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0<\/span>select ?x {<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 <\/span>?x m:word ?w .<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0 \u00a0 <\/span>?w m:label \\&#8221;Jack\\&#8221; .<\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span class=\"Apple-converted-space\">\u00a0<\/span>}&#8221; :results-format :lists)<\/span><\/p>\n<p><span style=\"color: #339966;\">(({sent-1}))<\/span><\/p><\/blockquote>\n<p>OK, only\u00a0<em><strong>sent-1<\/strong><\/em> has it.<\/p>\n<p>Notice how the patterns of triples are quite similar in <em><strong>SPARQL<\/strong><\/em> and <em><strong>Prolog<\/strong><\/em> queries.<\/p>\n<p>Let us close the DB.<\/p>\n<blockquote><p><span style=\"color: #0000ff;\">triple-store-user(31): (close-store)<\/span><\/p>\n<p><span style=\"color: #339966;\">nil<\/span><\/p><\/blockquote>\n<p>I suppose you get the big picture. By converting the dependency graph of parsed sentences to <em><strong>RDF<\/strong><\/em>, we are able to load the triples into a Semantic Web DB (a graph database) and apply interesting queries on the data.<span class=\"Apple-converted-space\">\u00a0With additional information stored, it may even be possible to make inferences over the data.<\/span><\/p>\n<p>Although I have shown the use case of <em><strong>AllegroGraph<\/strong><\/em>, the RDF data can be loaded into any Semantic Web DB (and almost all of them support <em><strong>Turtle<\/strong><\/em> format) and similarly queried using <em><strong>SPARQL<\/strong><\/em>.<\/p>\n<p>Hope you found this discussion useful.<\/p>\n<p>Have a nice weekend!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last post, I outlined an approach to convert a dependency graph (the result of dependency parsing) to RDF. The particular RDF format I used is Turtle, which is widely supported. Today, I would like to show how to load this RDF data in a Semantic\u00a0 Graph database and make queries on it. There [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[18,107,17],"tags":[158,156,74,148,153,154,159,157,155],"class_list":["post-1078","post","type-post","status-publish","format-standard","hentry","category-lisp","category-natural-language-processing","category-programming","tag-allegrograph","tag-dependency-graph","tag-nlp","tag-prolog","tag-rdf","tag-semantic-web","tag-sparql","tag-triple-store","tag-turtle"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-ho","jetpack-related-posts":[{"id":1068,"url":"https:\/\/www.rangakrish.com\/index.php\/2018\/09\/16\/dependency-graph-to-rdf\/","url_meta":{"origin":1078,"position":0},"title":"Dependency Graph to RDF","author":"admin","date":"September 16, 2018","format":false,"excerpt":"Dependency parsing is widely used these days, and many NLP tools give a dependency graph as the parsed representation of the input text. See for example, SpacY and TextRazor.\u00a0 The following is the dependency tree corresponding to the sentence Mary is drinking cold water: The above tree was generated using\u2026","rel":"","context":"In &quot;Natural Language Processing&quot;","block_context":{"text":"Natural Language Processing","link":"https:\/\/www.rangakrish.com\/index.php\/category\/natural-language-processing\/"},"img":{"alt_text":"Dependency Graph","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/DepGraph.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/DepGraph.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/09\/DepGraph.png?resize=525%2C300 1.5x"},"classes":[]},{"id":3660,"url":"https:\/\/www.rangakrish.com\/index.php\/2025\/04\/11\/using-claude-to-generate-rdf-triples\/","url_meta":{"origin":1078,"position":1},"title":"Using Claude to Generate RDF Triples","author":"admin","date":"April 11, 2025","format":false,"excerpt":"We all know that LLMs are now capable of generating structured data. I have used OpenAI models earlier to generate Tables and JSON data, but this time I wanted to try a more complex example.\u00a0 As someone interested in Homeopathy, I wanted to generate remedy descriptions as RDF triples, in\u2026","rel":"","context":"In &quot;Homeopathy&quot;","block_context":{"text":"Homeopathy","link":"https:\/\/www.rangakrish.com\/index.php\/category\/homeopathy\/"},"img":{"alt_text":"Lycopodium TTL Format","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/Lyco-300x232.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/Lyco-300x232.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2025\/04\/Lyco-300x232.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":328,"url":"https:\/\/www.rangakrish.com\/index.php\/2016\/09\/11\/natural-language-processing-in-mathematica\/","url_meta":{"origin":1078,"position":2},"title":"Natural Language Processing in Mathematica","author":"admin","date":"September 11, 2016","format":false,"excerpt":"Welcome back. Today I am going to share with you some of the nice capabilities of Mathematica in the area of Natural Language Processing (NLP). Let us start with words. What if we wish to know\u00a0the various definitions of the word image?\u00a0Here is the answer. Mathematica gives the various senses\u2026","rel":"","context":"In &quot;Mathematica&quot;","block_context":{"text":"Mathematica","link":"https:\/\/www.rangakrish.com\/index.php\/category\/mathematica\/"},"img":{"alt_text":"Word Definition","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/09\/word-data1-1024x238.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/09\/word-data1-1024x238.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/09\/word-data1-1024x238.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/09\/word-data1-1024x238.png?resize=700%2C400 2x"},"classes":[]},{"id":912,"url":"https:\/\/www.rangakrish.com\/index.php\/2018\/04\/22\/question-answering-using-dependency-trees\/","url_meta":{"origin":1078,"position":3},"title":"Question Answering\u00a0Using Dependency Trees","author":"admin","date":"April 22, 2018","format":false,"excerpt":"A few weeks ago I had written about my brief experiment with Mathematica's new feature, which provides answers to questions based on given text. After that post, I spent some time thinking about how to implement something similar. In today's post, I want to show you what I have been\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Dependency Tree","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2018\/04\/Deptree-example.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":575,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/08\/06\/text-generation-using-ilanggen-framework\/","url_meta":{"origin":1078,"position":4},"title":"Text Generation Using iLangGen Framework","author":"admin","date":"August 6, 2017","format":false,"excerpt":"The two primary areas in Natural Language processing are Natural Language Understanding and Natural Language Generation. The former is concerned with processing and making sense of natural language text, whereas the latter is concerned with synthesizing text, possibly from some deep representation. Both are fascinating and at the same time,\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"iLangGen Grammar","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2017\/08\/Blog1.png?resize=525%2C300 1.5x"},"classes":[]},{"id":41,"url":"https:\/\/www.rangakrish.com\/index.php\/2015\/10\/08\/learning-lisp-resources\/","url_meta":{"origin":1078,"position":5},"title":"Learning LISP &#8211; Resources","author":"admin","date":"October 8, 2015","format":false,"excerpt":"During my talks on Lisp Programming, I am invariably asked to suggest good books to start learning the language. Here is a (partial) list that I readily recommend. Beginner Level: ANSI Common Lisp, Paul Graham, Prentice Hall, 1996. Common LISP: A Tutorial, Wendy L.Milner, Prentice Hall, 1988. Land of LISP:\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/1078","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=1078"}],"version-history":[{"count":0,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/1078\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=1078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=1078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=1078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}