Merge Compare Flattened Values algorithm into Node Map Generation
authorMarkus Lanthaler <mark_lanthaler@gmx.net>
Fri, 05 Apr 2013 12:52:54 +0200
changeset 1548 0a520c8e1f48
parent 1547 81563d0565de
child 1549 ea2f054185ba
Merge Compare Flattened Values algorithm into Node Map Generation

The algorithm can be reduced two a single sentence because it will only ever compare value objects or node references, i.e., node objects with only an @id member. Lists, and thus also arrays, are handled separately (step 5 in the Node Map generation algorithm).

Lists are never merged because they are implicit unlabeled blank nodes. If we would merge them, RDF round-tripping would break.

This addresses #212.
spec/latest/json-ld-api/index.html
test-suite/tests/flatten-0042-in.jsonld
test-suite/tests/flatten-0042-out.jsonld
test-suite/tests/flatten-manifest.jsonld
--- a/spec/latest/json-ld-api/index.html	Fri Apr 05 12:10:11 2013 +0200
+++ b/spec/latest/json-ld-api/index.html	Fri Apr 05 12:52:54 2013 +0200
@@ -2892,18 +2892,15 @@
           <ol class="algorithm">
             <li>If <i>list</i> is <tref>null</tref>:
               <ol class="algorithm">
-                <li>If <tref>active property</tref> is not a key in <i>node</i>,
-                  then add a key-value pair to <i>node</i> where the key is
-                  <tref>active property</tref> and the value is an <tref>array</tref>
-                  containing <i>element</i>.
-                </li>
-                <li>
-                  Otherwise, compare <i>element</i> against every item in the
-                  <tref>array</tref> associated with the key <tref>active property</tref> in
-                  <i>node</i> using the
-                  <a href="#compare-flattened-values">Compare Flattened Values</a>
-                  algorithm. If there is no item equivalent to <i>element</i>
-                  in the <tref>array</tref>, append <i>element</i> to it.</li>
+                <li>If <i>node</i> does not have an <tref>active property</tref> member,
+                  create one and initialize its value to an <tref>array</tref>
+                  containing <i>element</i>.</li>
+                <li>Otherwise, compare <i>element</i> against every item in the
+                  <tref>array</tref> associated with the <tref>active property</tref>
+                  member of <i>node</i>. If there is no item equivalent to <i>element</i>,
+                  append <i>element</i> to the <tref>array</tref>. Two
+                  <tref title="JSON object">JSON objects</tref> are considered
+                  equal if they have equivalent key-value pairs.</li>
                 </li>
               </ol>
             </li>
@@ -2943,19 +2940,15 @@
                   <code>@id</code> whose value is <i>id</i>.</li>
                 <li>If <i>list</i> is <tref>null</tref>:
                   <ol class="algorithm">
-                    <li>If <tref>active property</tref> is not a key in <i>node</i>,
-                      then add a key-value pair to <i>node</i> where the key is
-                      <tref>active property</tref> and the value is an <tref>array</tref>
-                      containing <i>element</i>.
-                    </li>
-                    <li>
-                      Otherwise, compare <i>element</i> against every item in the
-                      <tref>array</tref> associated with the key <tref>active property</tref> in
-                      <i>node</i> using the
-                      <a href="#compare-flattened-values">Compare Flattened Values</a>
-                      algorithm. If there is no item equivalent to <i>element</i>
-                      in the <tref>array</tref>, append <i>element</i> to it.</li>
-                    </li>
+                    <li>If <i>node</i> does not have an <tref>active property</tref> member,
+                      create one and initialize its value to an <tref>array</tref>
+                      containing <i>reference</i>.</li>
+                    <li>Otherwise, compare <i>reference</i> against every item in the
+                      <tref>array</tref> associated with the <tref>active property</tref>
+                      member of <i>node</i>. If there is no item equivalent to <i>reference</i>,
+                      append <i>reference</i> to the <tref>array</tref>. Two
+                      <tref title="JSON object">JSON objects</tref> are considered
+                      equal if they have equivalent key-value pairs.</li>
                   </ol>
                 </li>
                 <li>Otherwise, append <i>element</i> to the <code>@list</code> member of <i>list</i>.</li>
@@ -3020,76 +3013,6 @@
   </section> <!-- end of Node Map Generation -->
 
   <section>
-    <h2>Compare Flattened Values</h2>
-
-    <p>This algorithm is used to compare two flattened values for equivalence.
-      It is used by the
-      <a href="#node-map-generation">Node Map Generation algorithm</a> in
-      order to detect duplicate values.</p>
-
-    <section class="informative">
-      <h3>Overview</h3>
-
-      <p>Two flattened values are considered equivalent if they are
-        equal <tref title="scalar">scalars</tref>, equivalent
-        <tref title="value object">value objects</tref>,
-        they are both <tref title="JSON object">JSON objects</tref> with
-        equivalent key-pairs for the key <code>@id</code>, or they are both
-        <tref title="list object">list objects</tref> with equivalent
-        key-pairs for the key <code>@index</code> (or neither have
-        <code>@index</code> keys) and have equivalent values, per this
-        algorithm, in each position.</p>
-    </section>
-
-    <section>
-      <h3>Algorithm</h3>
-
-      <p>The algorithm takes two input variables: <i>v1</i> and <i>v2</i>,
-        the two flattened values to compare. It returns <tref>true</tref>
-        if the values are equivalent and <tref>false</tref> if not.</p>
-
-      <ol class="algorithm">
-        <li>If <i>v1</i> and <i>v2</i> are equal
-          <tref title="scalar">scalars</tref>, then return
-          <tref>true</tref>.</li>
-        <li>If <i>v1</i> and <i>v2</i> are both
-          <tref title="value object">value objects</tref>:
-          <ol class="algorithm">
-            <li>If <i>v1</i> and <i>v2</i> have equivalent
-              key-value pairs for the keys <code>@value</code>,
-              <code>@type</code>, <code>@language</code>, and
-              <code>@index</code>, then return <tref>true</tref>, otherwise
-              return <tref>false</tref>.</li>
-            </li>
-          </ol>
-        </li>
-        <li>If <i>v1</i> and <i>v2</i> are both
-          <tref title="list object">list objects</tref>:
-          <ol class="algorithm">
-            <li>If <i>v1</i> and <i>v2</i> have equivalent
-              key-value pairs for the key <code>@index</code>, or if neither
-              have the key <code>@index</code>, and the
-              <tref title="array">arrays</tref> associated with their
-              <code>@list</code> keys have the same length and their
-              corresponding items, by index, are equivalent as determined by
-              recursively calling this algorithm, then return
-              <tref>true</tref>, otherwise return <tref>false</tref>.
-            </li>
-          </ol>
-        </li>
-        <li>If <i>v1</i> and <i>v2</i> are both
-          <tref title="JSON object">JSON objects</tref> that contain
-          the key <code>@id</code> and the values associated with their
-          keys are equal, return <tref>true</tref>.
-        </li>
-        <li>
-          Return <tref>false</tref>.
-        </li>
-      </ol>
-    </section>
-  </section> <!-- end of Compare Flattened Values -->
-
-  <section>
     <h2>Generate Blank Node Identifier</h2>
 
     <p>This algorithm is used to determine if two generate new
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-suite/tests/flatten-0042-in.jsonld	Fri Apr 05 12:52:54 2013 +0200
@@ -0,0 +1,10 @@
+{
+  "@context": {
+    "test": "http://example.com/list"
+  },
+  "@id": "list-equivalence-test",
+  "test": [
+    { "@list": [ "1", "2" ] },
+    { "@list": [ "1", "2" ] }
+  ]
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-suite/tests/flatten-0042-out.jsonld	Fri Apr 05 12:52:54 2013 +0200
@@ -0,0 +1,13 @@
+[
+  {
+    "@id": "http://json-ld.org/test-suite/tests/list-equivalence-test",
+    "http://example.com/list": [
+      {
+        "@list": [ { "@value": "1" }, { "@value": "2" } ]
+      },
+      {
+        "@list": [ { "@value": "1" }, { "@value": "2" } ]
+      }
+    ]
+  }
+]
--- a/test-suite/tests/flatten-manifest.jsonld	Fri Apr 05 12:10:11 2013 +0200
+++ b/test-suite/tests/flatten-manifest.jsonld	Fri Apr 05 12:52:54 2013 +0200
@@ -211,6 +211,11 @@
       "name": "Free-floating sets and lists",
       "input": "flatten-0041-in.jsonld",
       "expect": "flatten-0041-out.jsonld"
+    }, {
+      "@type": ["test:TestCase", "jld:ExpandTest"],
+      "name": "Lists objects are implicit unlabeled blank nodes and thus never equivalent",
+      "input": "flatten-0042-in.jsonld",
+      "expect": "flatten-0042-out.jsonld"
     }
   ]
 }