Move processing of scalars to the beginning in Expansion and Compaction
authorMarkus Lanthaler <mark_lanthaler@gmx.net>
Sun, 17 Feb 2013 16:19:11 +0100
changeset 1292 66ab689a396e
parent 1291 1f847b3ef74a
child 1293 7a339dfa8490
Move processing of scalars to the beginning in Expansion and Compaction

This addresses #218.
spec/latest/json-ld-api/index.html
--- a/spec/latest/json-ld-api/index.html	Sun Feb 17 16:01:46 2013 +0100
+++ b/spec/latest/json-ld-api/index.html	Sun Feb 17 16:19:11 2013 +0100
@@ -1298,30 +1298,24 @@
 <section>
 <h3>General Solution</h3>
 
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="expansion">expanded</tref> <em>result</em>. When
-<tref title="expansion">expanding</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
+<p>Starting with its root <em>element</em>, we can process the
+  JSON-LD document recursively, until we have a fully
+  <tref title="expansion">expanded</tref> <em>result</em>. When
+  <tref title="expansion">expanding</tref> an <em>element</em>, we can treat
+  each one differently according to its type, in order to break down the
+  problem:</p>
 
 <ol>
-  <li>
-    If the <em>element</em> is <tref>null</tref>, there is nothing
-    to expand.
-  </li>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we expand
+  <li>If the <em>element</em> is <tref>null</tref>, there is nothing
+    to expand.</li>
+  <li>Otherwise, if <em>element</em> is a <tref>scalar</tref>, we expand it
+    according to the <a href="#value-expansion">Value Expansion</a> subalgorithm.</li>
+  <li>Otherwise, if the <em>element</em> is an <tref>array</tref>, then we expand
     each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we expand each of its keys, adding them to our <em>result</em>,
-    and then we expand each value for each key recursively. Some of the keys
-    will be
+    <tref>array</tref>.</li>
+  <li>Otherwise, <em>element</em> is a <tref>JSON object</tref>. We expand
+    each of its keys, adding them to our <em>result</em>, and then we expand
+    each value for each key recursively. Some of the keys will be
     <tref title="term">terms</tref> or
     <tref title="compact IRI">compact IRIs</tref> and others will be
     <tref title="keyword">keywords</tref> or simply ignored because
@@ -1329,43 +1323,43 @@
     <tref title="IRI">IRIs</tref> will be expanded using the
     <a href="#iri-expansion">IRI Expansion</a> algorithm.
   </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, which
-    we expand according to the <a href="#value-expansion">Value Expansion</a>
-    subalgorithm.
-  </li>
 </ol>
 
-<p>
-Finally, after ensuring <em>result</em> is in an <tref>array</tref>,
-we return <em>result</em>.
-</p>
+<p>Finally, after ensuring <em>result</em> is in an <tref>array</tref>,
+  we return <em>result</em>.</p>
 
 </section>
 
 <section>
 <h3>Algorithm</h3>
 
-<p>
-The algorithm takes four input variables: an <tref>active context</tref>,
-an <tref>active property</tref>, an <em>element</em> to be expanded, and
-an <em>insideList</em> flag. To begin, the <tref>active context</tref> is set
-to the result of performing, <a
-href="#context-processing">Context Processing</a> on the passed
-<code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
-or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
-is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>,
-<em>element</em> is set to the <tref>JSON-LD input</tref>, and <em>insideList</em>
-is set to <tref>false</tref>. This algorithm expects the
-<tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in
-[[!JSON-LD]].
-
-The algorithm outputs the result of expanding <em>element</em>.
-</p>
+<p>The algorithm takes four input variables: an <tref>active context</tref>,
+  an <tref>active property</tref>, an <em>element</em> to be expanded, and
+  an <em>insideList</em> flag. To begin, the <tref>active context</tref> is set
+  to the result of performing, <a
+  href="#context-processing">Context Processing</a> on the passed
+  <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>,
+  or empty if <code class="idlMemberName"><a href="#widl-JsonLdOptions-expandContext">expandContext</a></code>
+  is <tref>null</tref>, <tref>active property</tref> is set to <tref>null</tref>,
+  <em>element</em> is set to the <tref>JSON-LD input</tref>, and <em>insideList</em>
+  is set to <tref>false</tref>. This algorithm expects the
+  <tref>JSON-LD input</tref> to be a well-formed JSON-LD document as defined in [[!JSON-LD]].</p>
 
 <ol class="algorithm">
-  <li>
-    If <em>element</em> is <tref>null</tref>, return <tref>null</tref>.
+  <li>If <em>element</em> is <tref>null</tref>, return <tref>null</tref>.</li>
+  <li>If <em>element</em> is a <tref>scalar</tref>,
+    <ol class="algorithm">
+      <li>If <em>insideList</em> equals <tref>false</tref> and
+        either <tref>active property</tref> equals <tref>null</tref> or
+        the result of expanding <tref>active property</tref> using the
+        <a href="#iri-expansion">IRI Expansion</a> algorithm is
+        <code>@graph</code>, then drop the top-level
+        <tref>scalar</tref> by returning <tref>null</tref>.</li>
+      <li>Return the result of the
+        <a href="#value-expansion">Value Expansion</a> algorithm, passing the
+        <tref>active context</tref>, <tref>active property</tref>, and
+        <em>element</em> as <em>value</em>.</li>
+    </ol>
   </li>
   <li>If <em>element</em> is an <tref>array</tref>,
     <ol class="algorithm">
@@ -1398,338 +1392,314 @@
       </li>
     </ol>
   </li>
-  <li>If <em>element</em> is a <tref>JSON object</tref>,
+  <li>Otherwise <em>element</em> is a <tref>JSON object</tref>.</li>
+  <li>
+    If <em>element</em> contains the key <code>@context</code>, set
+    <tref>active context</tref> equal to the result of the
+    <a href="#context-processing">Context Processing</a> algorithm,
+    passing <tref>active context</tref> and the value of the
+    <code>@context</code> key as <tref>local context</tref>.
+  </li>
+  <li>
+    Initialize <em>expanded active property</em> to the result of the
+    <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
+    <tref>active context</tref>, <tref>active property</tref> for
+    <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
+  <li>
+    Initialize an empty <tref>JSON object</tref>, <em>result</em>.
+  </li>
+  <li>
+    For each <em>key</em> and <em>value</em> in <em>element</em>,
+    ordered lexicographically by <em>key</em>:
     <ol class="algorithm">
       <li>
-        If <em>element</em> contains the key <code>@context</code>, set
-        <tref>active context</tref> equal to the result of the
-        <a href="#context-processing">Context Processing</a> algorithm,
-        passing <tref>active context</tref> and the value of the
-        <code>@context</code> key as <tref>local context</tref>.
+        If <em>key</em> equals <code>@context</code>, continue to
+        the next <em>key</em>.
       </li>
       <li>
-        Initialize <em>expanded active property</em> to the result of the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm, passing
-        <tref>active context</tref>, <tref>active property</tref> for
+        If <em>key</em> is mapped to a <tref>property generator</tref>
+        in <tref>active context</tref>, set <em>expanded property</em>
+        to an array containing its <tref title="IRI">IRIs</tref>.
+        Otherwise, set <em>expanded property</em> to the result of
+        using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
+        passing <tref>active context</tref>, <em>key</em> for
         <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
-      <li>
-        Initialize an empty <tref>JSON object</tref>, <em>result</em>.
       </li>
       <li>
-        For each <em>key</em> and <em>value</em> in <em>element</em>,
-        ordered lexicographically by <em>key</em>:
+        If <em>expanded property</em> is either <tref>null</tref> or
+        is: not an <tref>array</tref>, an <tref>absolute IRI</tref> or
+        a <tref>keyword</tref>, then drop <em>key</em> by
+        continuing to the next <em>key</em>.
+      </li>
+      <li>
+        Validate <em>expanded property</em> against <em>value</em>
+        as follows:
         <ol class="algorithm">
           <li>
-            If <em>key</em> equals <code>@context</code>, continue to
-            the next <em>key</em>.
-          </li>
-          <li>
-            If <em>key</em> is mapped to a <tref>property generator</tref>
-            in <tref>active context</tref>, set <em>expanded property</em>
-            to an array containing its <tref title="IRI">IRIs</tref>.
-            Otherwise, set <em>expanded property</em> to the result of
-            using the <a href="#iri-expansion">IRI Expansion</a> algorithm,
-            passing <tref>active context</tref>, <em>key</em> for
-            <em>value</em>, and <tref>true</tref> for <em>vocabRelative</em>.
+            If <em>expanded property</em> is <code>@id</code> then
+            <em>value</em> MUST be a <tref>string</tref>, otherwise
+            an invalid value has been detected, which is an error.
           </li>
           <li>
-            If <em>expanded property</em> is either <tref>null</tref> or
-            is: not an <tref>array</tref>, an <tref>absolute IRI</tref> or
-            a <tref>keyword</tref>, then drop <em>key</em> by
-            continuing to the next <em>key</em>.
+            If <em>expanded property</em> is <code>@type</code> then
+            <em>value</em> MUST be a <tref>string</tref> or an <tref>array</tref>
+            of strings, otherwise an invalid value has been detected, which
+            is an error.
           </li>
           <li>
-            Validate <em>expanded property</em> against <em>value</em>
-            as follows:
+            If <em>expanded property</em> is <code>@graph</code> then
+            <em>value</em> MUST be a <tref>JSON object</tref> or an
+            <tref>array</tref>, otherwise an invalid value has been
+            detected, which is an error.
+          </li>
+          <li>
+            If <em>expanded property</em> is <code>@value</code> then
+            <em>value</em> MUST NOT be a <tref>JSON object</tref> or
+            an <tref>array</tref>, otherwise an invalid value has been
+            detected, which is an error.
+          </li>
+          <li>
+            If <em>expanded property</em> is <code>@language</code> then
+            <em>value</em> MUST be a <tref>string</tref>, otherwise an
+            invalid value has been detected, which is an error. Set
+            <em>expanded value</em> to lowercased <em>value</em>.
+          </li>
+          <li>
+            If <em>expanded property</em> is <code>@index</code>
+            then <em>value</em> MUST be a <tref>string</tref>, otherwise an
+            invalid value has been detected, which is an error.
+          </li>
+        </ol>
+      </li>
+      <li>
+        If <em>key</em>'s <tref>container mapping</tref> in
+        <tref>active context</tref> is <code>@language</code> and
+        <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
+        is expanded from a <tref>language map</tref> as follows:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>expanded value</em> to an empty
+            <tref>array</tref>.
+          </li>
+          <li>
+            For each key <em>language</em> and value <em>language value</em>
+            in <em>value</em>, ordered lexicographically by
+            <em>language</em>:
             <ol class="algorithm">
               <li>
-                If <em>expanded property</em> is <code>@id</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise
-                an invalid value has been detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@type</code> then
-                <em>value</em> MUST be a <tref>string</tref> or an <tref>array</tref>
-                of strings, otherwise an invalid value has been detected, which
-                is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@graph</code> then
-                <em>value</em> MUST be a <tref>JSON object</tref> or an
-                <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@value</code> then
-                <em>value</em> MUST NOT be a <tref>JSON object</tref> or
-                an <tref>array</tref>, otherwise an invalid value has been
-                detected, which is an error.
-              </li>
-              <li>
-                If <em>expanded property</em> is <code>@language</code> then
-                <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error. Set
-                <em>expanded value</em> to lowercased <em>value</em>.
+                If <em>language value</em> is not an <tref>array</tref>
+                set it to an <tref>array</tref> containing only
+                <em>language value</em>.
               </li>
               <li>
-                If <em>expanded property</em> is <code>@index</code>
-                then <em>value</em> MUST be a <tref>string</tref>, otherwise an
-                invalid value has been detected, which is an error.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@language</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from a <tref>language map</tref> as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>language</em> and value <em>language value</em>
-                in <em>value</em>, ordered lexicographically by
-                <em>language</em>:
+                For each <em>item</em> in <em>language value</em>:
                 <ol class="algorithm">
                   <li>
-                    If <em>language value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>language value</em>.
+                    <em>item</em> MUST be a <tref>string</tref>,
+                    otherwise an invalid value has been detected,
+                    which is an error.
                   </li>
                   <li>
-                    For each <em>item</em> in <em>language value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        <em>item</em> MUST be a <tref>string</tref>,
-                        otherwise an invalid value has been detected,
-                        which is an error.
-                      </li>
-                      <li>
-                        Append a <tref>JSON object</tref> to
-                        <em>expanded value</em> that consists of two
-                        key-value pairs: (<code>@value</code>-<em>item</em>)
-                        and (<code>@language</code>-lowercased
-                        <em>language</em>).
-                      </li>
-                    </ol>
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@index</code> and
-            <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
-            is expanded from an index map as follows:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>expanded value</em> to an empty
-                <tref>array</tref>.
-              </li>
-              <li>
-                For each key <em>index</em> and value
-                <em>index value</em> in <em>value</em>, ordered
-                lexicographically by <em>index</em>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>index value</em> is not an <tref>array</tref>
-                    set it to an <tref>array</tref> containing only
-                    <em>index value</em>.
-                  </li>
-                  <li>
-                    Initialize <em>index value</em> to the result of
-                    using this algorithm recursively, passing
-                    <tref>active context</tref>, <tref>active property</tref>,
-                    <em>index value</em> as <em>element</em>, and
-                    <tref>false</tref> for <em>insideList</em>.
-                  <li>
-                    For each <em>item</em> in <em>index value</em>:
-                    <ol class="algorithm">
-                      <li>
-                        If <em>item</em> does not have the key
-                        <code>@index</code>, add the key-value pair
-                        (<code>@index</code>-<em>index</em>) to
-                        <em>item</em>.
-                      </li>
-                      <li>
-                        Append <em>item</em> to <em>expanded value</em>.
-                      </li>
-                    </ol>
+                    Append a <tref>JSON object</tref> to
+                    <em>expanded value</em> that consists of two
+                    key-value pairs: (<code>@value</code>-<em>item</em>)
+                    and (<code>@language</code>-lowercased
+                    <em>language</em>).
                   </li>
                 </ol>
               </li>
             </ol>
           </li>
+        </ol>
+      </li>
+      <li>
+        If <em>key</em>'s <tref>container mapping</tref> in
+        <tref>active context</tref> is <code>@index</code> and
+        <em>value</em> is a <tref>JSON object</tref> then <em>value</em>
+        is expanded from an index map as follows:
+        <ol class="algorithm">
           <li>
-            Otherwise, if <em>expanded property</em> equals <code>@list</code>
-            or <code>@set</code>, initialize <em>expanded value</em> to the
-            result of using this algorithm recursively passing
-            <tref>active context</tref>, <tref>null</tref> for
-            <tref>active property</tref> if <em>expanded property</em> equals
-            <code>@list</code> and <em>expanded active property</em> equals
-            <code>@graph</code> otherwise <tref>active property</tref>,
-            <em>value</em> for <em>element</em>, and <tref>true</tref>
-            for <em>insideList</em> if <em>expanded property</em> equals
-            <code>@list</code> otherwise <tref>false</tref>.
-            If <em>expanded property</em> equals <code>@list</code>
-            then <em>expanded value</em> MUST NOT be a
-            <tref>list object</tref>, otherwise a list of lists has been
-            detected, which is an error.
-          </li>
-          <li>
-            Otherwise, initialize <em>expanded value</em> to the result of
-            using this algorithm recursively, passing
-            <tref>active context</tref>, <em>key</em> for
-            <tref>active property</tref>, <em>value</em>
-            for <em>element</em>, and <tref>false</tref> for
-            <em>insideList</em>.
+            Initialize <em>expanded value</em> to an empty
+            <tref>array</tref>.
           </li>
           <li>
-            If <em>expanded value</em> equals <tref>null</tref> and
-            <em>expanded property</em> is not <code>@value</code> then
-            drop <em>key</em> by continuing to the next key.
-          </li>
-          <li>
-            If <em>expanded property</em> is not <code>@list</code> and
-            <em>expanded value</em> is not a <tref>list object</tref> and
-            <em>key</em>'s <tref>container mapping</tref> in
-            <tref>active context</tref> is <code>@list</code> then convert
-            <em>expanded value</em> to a <tref>list object</tref> by first
-            setting it to an <tref>array</tref> containing only
-            <em>expanded value</em> if it is not already an
-            <tref>array</tref>, and then by setting it to a
-            <tref>JSON object</tref> containing the key-value pair
-            (<code>@list</code>-<em>expanded value</em>).
-          </li>
-          <li>
-            If <em>expanded property</em> is an <tref>array</tref>:
+            For each key <em>index</em> and value
+            <em>index value</em> in <em>value</em>, ordered
+            lexicographically by <em>index</em>:
             <ol class="algorithm">
               <li>
-                Set <em>expanded value</em> to the result of the
-                <a href="#label-blank-nodes-subalgorithm">Label Blank Nodes</a>
-                subalgorithm, passing <tref>active context</tref> and
-                <em>expanded value</em> as <em>element</em>.
+                If <em>index value</em> is not an <tref>array</tref>
+                set it to an <tref>array</tref> containing only
+                <em>index value</em>.
               </li>
               <li>
-                For each item <em>iri</em> in <em>expanded property</em>:
+                Initialize <em>index value</em> to the result of
+                using this algorithm recursively, passing
+                <tref>active context</tref>, <tref>active property</tref>,
+                <em>index value</em> as <em>element</em>, and
+                <tref>false</tref> for <em>insideList</em>.
+              <li>
+                For each <em>item</em> in <em>index value</em>:
                 <ol class="algorithm">
                   <li>
-                    If <em>result</em> does not have the key <em>iri</em>,
-                    set this key's value in <em>result</em> to an empty
-                    <tref>array</tref>. Append a copy of
-                    <em>expanded value</em> to the <tref>array</tref> value
-                    associated with <em>result</em>'s <em>iri</em> key.
+                    If <em>item</em> does not have the key
+                    <code>@index</code>, add the key-value pair
+                    (<code>@index</code>-<em>index</em>) to
+                    <em>item</em>.
+                  </li>
+                  <li>
+                    Append <em>item</em> to <em>expanded value</em>.
                   </li>
                 </ol>
               </li>
             </ol>
           </li>
-          <li>
-            Otherwise, if <em>expanded property</em> is
-            <code>@index</code>, <code>@id</code>, <code>@type</code>,
-            <code>@value</code>, or <code>@language</code>, then
-            set key <em>expanded property</em>'s value to
-            <em>expanded value</em> in <em>result</em>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> does not have the key
-            <em>expanded property</em>, set this key's value in <em>result</em>
-            to an empty <tref>array</tref>. Append <em>expanded value</em>
-            to the <tref>array</tref> value associated with <em>result</em>'s
-            <em>expanded property</em> key.
-          </li>
         </ol>
       </li>
       <li>
-        If <em>result</em> contains the key <code>@value</code>:
+        Otherwise, if <em>expanded property</em> equals <code>@list</code>
+        or <code>@set</code>, initialize <em>expanded value</em> to the
+        result of using this algorithm recursively passing
+        <tref>active context</tref>, <tref>null</tref> for
+        <tref>active property</tref> if <em>expanded property</em> equals
+        <code>@list</code> and <em>expanded active property</em> equals
+        <code>@graph</code> otherwise <tref>active property</tref>,
+        <em>value</em> for <em>element</em>, and <tref>true</tref>
+        for <em>insideList</em> if <em>expanded property</em> equals
+        <code>@list</code> otherwise <tref>false</tref>.
+        If <em>expanded property</em> equals <code>@list</code>
+        then <em>expanded value</em> MUST NOT be a
+        <tref>list object</tref>, otherwise a list of lists has been
+        detected, which is an error.
+      </li>
+      <li>
+        Otherwise, initialize <em>expanded value</em> to the result of
+        using this algorithm recursively, passing
+        <tref>active context</tref>, <em>key</em> for
+        <tref>active property</tref>, <em>value</em>
+        for <em>element</em>, and <tref>false</tref> for
+        <em>insideList</em>.
+      </li>
+      <li>
+        If <em>expanded value</em> equals <tref>null</tref> and
+        <em>expanded property</em> is not <code>@value</code> then
+        drop <em>key</em> by continuing to the next key.
+      </li>
+      <li>
+        If <em>expanded property</em> is not <code>@list</code> and
+        <em>expanded value</em> is not a <tref>list object</tref> and
+        <em>key</em>'s <tref>container mapping</tref> in
+        <tref>active context</tref> is <code>@list</code> then convert
+        <em>expanded value</em> to a <tref>list object</tref> by first
+        setting it to an <tref>array</tref> containing only
+        <em>expanded value</em> if it is not already an
+        <tref>array</tref>, and then by setting it to a
+        <tref>JSON object</tref> containing the key-value pair
+        (<code>@list</code>-<em>expanded value</em>).
+      </li>
+      <li>
+        If <em>expanded property</em> is an <tref>array</tref>:
         <ol class="algorithm">
           <li>
-            The <em>result</em> MUST NOT contain any keys other than
-            <code>@value</code>, <code>@language</code>, <code>@type</code>,
-            and <code>@index</code>. It MUST NOT contain both the
-            <code>@language</code> key and the <code>@type</code> key.
-            Otherwise, an invalid value has been detected, which is an error.
+            Set <em>expanded value</em> to the result of the
+            <a href="#label-blank-nodes-subalgorithm">Label Blank Nodes</a>
+            subalgorithm, passing <tref>active context</tref> and
+            <em>expanded value</em> as <em>element</em>.
           </li>
           <li>
-            If the value of <em>result</em>'s <code>@value</code> key is
-            <tref>null</tref>, then set <em>result</em> to <tref>null</tref>.
-          </li>
-          <li>
-            Otherwise, if <em>result</em> contains the key
-            <code>@language</code> and the value of <em>result</em>'s
-            <code>@value</code> key is not a <tref>string</tref>, then remove
-            the <code>@language</code> key from <em>result</em>.
+            For each item <em>iri</em> in <em>expanded property</em>:
+            <ol class="algorithm">
+              <li>
+                If <em>result</em> does not have the key <em>iri</em>,
+                set this key's value in <em>result</em> to an empty
+                <tref>array</tref>. Append a copy of
+                <em>expanded value</em> to the <tref>array</tref> value
+                associated with <em>result</em>'s <em>iri</em> key.
+              </li>
+            </ol>
           </li>
         </ol>
       </li>
       <li>
-        Otherwise, if <em>result</em> contains the key <code>@type</code>
-        and its associated value is not an <tref>array</tref>, set it to
-        an <tref>array</tref> containing only the associated value.
-      </li>
-      <li>
-        Otherwise, if <em>result</em> contains the key <code>@set</code>
-        or <code>@list</code>:
-        <ol class="algorithm">
-          <li>
-            The <em>result</em> MUST contain at most one other key and that
-            key MUST be <code>@index</code>. Otherwise, an invalid
-            value has been detected, which is an error.
-          </li>
-          <li>
-            If <em>result</em> contains the key <code>@set</code>, then
-            set <em>result</em> to the key's associated value.
-          </li>
-        </ol>
+        Otherwise, if <em>expanded property</em> is
+        <code>@index</code>, <code>@id</code>, <code>@type</code>,
+        <code>@value</code>, or <code>@language</code>, then
+        set key <em>expanded property</em>'s value to
+        <em>expanded value</em> in <em>result</em>.
       </li>
       <li>
-        Otherwise, if <em>result</em> contains only the key
-        <code>@language</code>, set <em>result</em> to <tref>null</tref>.
-      </li>
-      <li>
-        If <em>insideList</em> equals false and either
-        <tref>active property</tref> equals <tref>null</tref> or
-        <em>expanded active property</em> equals <code>@graph</code>, then
-        drop free-floating values as follows:
-        <ol class="algorithm">
-          <li>
-            If <em>result</em> contains no keys or contains the key
-            <code>@value</code>, setting <em>result</em> to
-            <tref>null</tref>.
-          <li>
-            Otherwise, if <em>result</em>'s keys are only keywords and none
-            of the keys are <code>@graph</code> or <code>@type</code> then
-            set <em>result</em> to <tref>null</tref>.
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
+        Otherwise, if <em>result</em> does not have the key
+        <em>expanded property</em>, set this key's value in <em>result</em>
+        to an empty <tref>array</tref>. Append <em>expanded value</em>
+        to the <tref>array</tref> value associated with <em>result</em>'s
+        <em>expanded property</em> key.
       </li>
     </ol>
   </li>
   <li>
-    Otherwise, <em>element</em> must be a <tref>scalar</tref>,
+    If <em>result</em> contains the key <code>@value</code>:
     <ol class="algorithm">
       <li>
-        If <em>insideList</em> equals <tref>false</tref> and
-        either <tref>active property</tref> equals <tref>null</tref> or
-        the result of expanding <tref>active property</tref> using the
-        <a href="#iri-expansion">IRI Expansion</a> algorithm is
-        <code>@graph</code>, then drop the top-level
-        <tref>scalar</tref> by returning <tref>null</tref>.
+        The <em>result</em> MUST NOT contain any keys other than
+        <code>@value</code>, <code>@language</code>, <code>@type</code>,
+        and <code>@index</code>. It MUST NOT contain both the
+        <code>@language</code> key and the <code>@type</code> key.
+        Otherwise, an invalid value has been detected, which is an error.
       </li>
       <li>
-        Return the result of the
-        <a href="#value-expansion">Value Expansion</a> algorithm, passing the
-        <tref>active context</tref>, <tref>active property</tref>, and
-        <em>element</em> as <em>value</em>.
+        If the value of <em>result</em>'s <code>@value</code> key is
+        <tref>null</tref>, then set <em>result</em> to <tref>null</tref>.
+      </li>
+      <li>
+        Otherwise, if <em>result</em> contains the key
+        <code>@language</code> and the value of <em>result</em>'s
+        <code>@value</code> key is not a <tref>string</tref>, then remove
+        the <code>@language</code> key from <em>result</em>.
       </li>
     </ol>
   </li>
+  <li>
+    Otherwise, if <em>result</em> contains the key <code>@type</code>
+    and its associated value is not an <tref>array</tref>, set it to
+    an <tref>array</tref> containing only the associated value.
+  </li>
+  <li>
+    Otherwise, if <em>result</em> contains the key <code>@set</code>
+    or <code>@list</code>:
+    <ol class="algorithm">
+      <li>
+        The <em>result</em> MUST contain at most one other key and that
+        key MUST be <code>@index</code>. Otherwise, an invalid
+        value has been detected, which is an error.
+      </li>
+      <li>
+        If <em>result</em> contains the key <code>@set</code>, then
+        set <em>result</em> to the key's associated value.
+      </li>
+    </ol>
+  </li>
+  <li>
+    Otherwise, if <em>result</em> contains only the key
+    <code>@language</code>, set <em>result</em> to <tref>null</tref>.
+  </li>
+  <li>
+    If <em>insideList</em> equals false and either
+    <tref>active property</tref> equals <tref>null</tref> or
+    <em>expanded active property</em> equals <code>@graph</code>, then
+    drop free-floating values as follows:
+    <ol class="algorithm">
+      <li>
+        If <em>result</em> contains no keys or contains the key
+        <code>@value</code>, setting <em>result</em> to
+        <tref>null</tref>.
+      <li>
+        Otherwise, if <em>result</em>'s keys are only keywords and none
+        of the keys are <code>@graph</code> or <code>@type</code> then
+        set <em>result</em> to <tref>null</tref>.
+      </li>
+    </ol>
+  </li>
+  <li>Return <em>result</em>.</li>
 </ol>
 
 <p>
@@ -2201,41 +2171,36 @@
 <section>
 <h3>Purpose</h3>
 
-<p>
-A JSON-LD document needs to be compacted, such that the given
-<tref>context</tref> is applied. This must result in shortening
-any applicable <tref title="IRI">IRIs</tref> to
-<tref title="term">terms</tref> or
-<tref title="compact IRI">compact IRIs</tref> and
-any applicable <tref title="JSON-LD value">JSON-LD values</tref>
-expressed in <tref>expanded form</tref> to simple values such as
-<tref title="string">strings</tref> or
-<tref title="number">numbers</tref>.
-</p>
+<p>A JSON-LD document needs to be compacted, such that the given
+  <tref>context</tref> is applied. This must result in shortening
+  any applicable <tref title="IRI">IRIs</tref> to
+  <tref title="term">terms</tref> or
+  <tref title="compact IRI">compact IRIs</tref> and
+  any applicable <tref title="JSON-LD value">JSON-LD values</tref>
+  expressed in <tref>expanded form</tref> to simple values such as
+  <tref title="string">strings</tref> or
+  <tref title="number">numbers</tref>.</p>
 
 </section>
 
 <section>
 <h3>General Solution</h3>
 
-<p>
-Starting with its root <em>element</em>, we can process the
-JSON-LD document recursively, until we have a fully
-<tref title="compaction">compacted</tref> <em>result</em>. When
-<tref title="compaction">compacting</tref> an <em>element</em>, we can treat
-each one differently according to its type, in order to break down the
-problem:
-</p>
+<p>Starting with its root <em>element</em>, we can process the
+  JSON-LD document recursively, until we have a fully
+  <tref title="compaction">compacted</tref> <em>result</em>. When
+  <tref title="compaction">compacting</tref> an <em>element</em>, we can treat
+  each one differently according to its type, in order to break down the
+  problem:</p>
 
 <ol>
-  <li>
-    If the <em>element</em> is an <tref>array</tref>, then we compact
+  <li>If the <em>element</em> is a <tref>scalar</tref>, it is
+    already in <tref>compacted form</tref>, so we simply return it.</li>
+  <li>If the <em>element</em> is an <tref>array</tref>, we compact
     each of its items recursively and return them in a new
-    <tref>array</tref>.
-  </li>
-  <li>
-    If the <em>element</em> is a <tref>JSON object</tref>,
-    then we start by creating a shallow copy of it and each of its
+    <tref>array</tref>.</li>
+  <li>Otherwise <em>element</em> is a <tref>JSON object</tref>.
+    We start by creating a shallow copy of it and each of its
     key's <tref>array</tref> values. This is done so that if any key
     is compacted to a <tref>property generator</tref> <tref>term</tref>,
     we can remove duplicate values without modifying the original
@@ -2253,43 +2218,36 @@
     will be reshaped based on
     <tref title="container mapping">container mappings</tref> specified
     in the context such as <code>@index</code> or <code>@language</code>
-    maps.
-  </li>
-  <li>
-    Otherwise, the <em>element</em> is a <tref>scalar</tref>, it is
-    already in <tref>compacted form</tref>, so we simply return.
-  </li>
+    maps.</li>
 </ol>
 
-<p>
-The final output is a <tref>JSON object</tref> with a <code>@context</code>
-key, if a <tref>context</tref> was given, where the <tref>JSON object</tref>
-is either <em>result</em> or a wrapper for it where <em>result</em> appears
-as the value of an aliased <code>@graph</code> key because <em>result</em>
-contained two or more items in an <tref>array</tref>. If no
-<tref>context</tref> was given, the <em>result</em> is only simplified
-from an <tref>array</tref> to a <tref>JSON object</tref> if it has one or
-fewer items.
-</p>
+<p>The final output is a <tref>JSON object</tref> with a <code>@context</code>
+  key, if a <tref>context</tref> was given, where the <tref>JSON object</tref>
+  is either <em>result</em> or a wrapper for it where <em>result</em> appears
+  as the value of an aliased <code>@graph</code> key because <em>result</em>
+  contained two or more items in an <tref>array</tref>. If no
+  <tref>context</tref> was given, the <em>result</em> is only simplified
+  from an <tref>array</tref> to a <tref>JSON object</tref> if it has one or
+  fewer items.</p>
 
 </section>
 
 <section>
 <h3>Algorithm</h3>
 
-<p>
-The algorithm takes four required input variables: an
-<tref>active context</tref>, an <tref>active property</tref>, and an
-<em>element</em> to be compacted. To begin, the <tref>active context</tref>
-is set to the result of performing
-<a href="#context-processing">Context Processing</a> on the passed
-<em>context</em>, the <tref>active property</tref> is set to
-<tref>null</tref>, and <em>element</em> is set to the result of performing
-the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
-<tref>JSON-LD input</tref>.
-</p>
+<p>The algorithm takes four required input variables: an
+  <tref>active context</tref>, an <tref>active property</tref>, and an
+  <em>element</em> to be compacted. To begin, the <tref>active context</tref>
+  is set to the result of performing
+  <a href="#context-processing">Context Processing</a> on the passed
+  <em>context</em>, the <tref>active property</tref> is set to
+  <tref>null</tref>, and <em>element</em> is set to the result of performing
+  the <a href="#expansion-algorithm">Expansion Algorithm</a> on the
+  <tref>JSON-LD input</tref>.</p>
 
 <ol class="algorithm">
+  <li>If <em>element</em> is a <tref>scalar</tref>, it is already in its most
+    compact form, so simply return <em>element</em>.</li>
   <li>
     If <em>element</em> is an <tref>array</tref>:
     <ol class="algorithm">
@@ -2322,329 +2280,319 @@
       </li>
     </ol>
   </li>
+  <li>Otherwise <em>element</em> is a <tref>JSON object</tref>.</li>
   <li>
-    If <em>element</em> is an <tref>JSON object</tref>:
+    If <em>element</em> contains the key <code>@value</code> or
+    if it contains only one key and that key is <code>@id</code>,
+    then return the result of using the
+    <a href="#value-compaction">Value Compaction</a> algorithm,
+    passing <tref>active context</tref>, <tref>active property</tref>,
+    and <em>element</em> as <em>value</em>.
+  </li>
+  <li>
+    Create a shallow copy of <em>element</em> and each <tref>array</tref>
+    associated with its keys so that duplicate values can be removed
+    during <tref>property generator</tref> <tref>compaction</tref>:
     <ol class="algorithm">
       <li>
-        If <em>element</em> contains the key <code>@value</code> or
-        if it contains only one key and that key is <code>@id</code>,
-        then return the result of using the
-        <a href="#value-compaction">Value Compaction</a> algorithm,
-        passing <tref>active context</tref>, <tref>active property</tref>,
-        and <em>element</em> as <em>value</em>.
+        Initialize <em>shallow</em> to an empty <tref>JSON object</tref>.
       </li>
       <li>
-        Create a shallow copy of <em>element</em> and each <tref>array</tref>
-        associated with its keys so that duplicate values can be removed
-        during <tref>property generator</tref> <tref>compaction</tref>:
+        For each <em>key</em>-<em>value</em> pair in <em>element</em>:
         <ol class="algorithm">
           <li>
-            Initialize <em>shallow</em> to an empty <tref>JSON object</tref>.
+            If <em>value</em> is an <tref>array</tref>, then add
+            a key-value pair to <em>shallow</em> where the key
+            is <em>key</em> and the value is a shallow copy of
+            <em>value</em>.
           </li>
           <li>
-            For each <em>key</em>-<em>value</em> pair in <em>element</em>:
+            Otherwise, add the key-value pair, <em>key</em>-<em>value</em>
+            to <em>shallow</em>.
+          </li>
+        </ol>
+      </li>
+    </ol>
+  </li>
+  <li>
+    Initialize <em>result</em> to an empty <tref>JSON object</tref>.
+  </li>
+  <li>
+    Initialize <em>keys</em> to an <tref>array</tref> containing
+    all of the keys in <em>shallow</em>, ordered lexicographically.
+  </li>
+  <li>
+    For each key <em>expanded property</em> in <em>keys</em>:
+    <ol class="algorithm">
+      <li>
+        If <em>shallow</em> does not contain a key that equals
+        <em>expanded property</em>, then continue to the next
+        <em>expanded property</em>.
+      </li>
+      <li>
+        Initialize <em>expanded value</em> to the value associated
+        with the key that equals <em>expanded property</em> in
+        <em>shallow</em>.
+      </li>
+      <li>
+        If <em>expanded property</em> equals <code>@id</code> or
+        <code>@type</code>:
+          <ol class="algorithm">
+            <li>
+              If <em>expanded value</em> is a <tref>string</tref>,
+              then initialize <em>compacted value</em> to the result
+              of using the
+              <a href="#iri-compaction-algorithm">IRI Compaction</a>
+              algorithm, passing <tref>active context</tref>,
+              <em>expanded value</em> for <em>iri</em>,
+              and <tref>true</tref> for <em>vocabRelative</em> if
+              <em>expanded property</em> equals <code>@type</code>,
+              <tref>false</tref> otherwise.
+            </li>
+            <li>
+              Otherwise, <em>expanded value</em> must be a
+              <code>@type</code> <tref>array</tref>:
+              <ol class="algorithm">
+                <li>
+                  Initialize <em>compacted value</em> to an empty
+                  <tref>array</tref>.
+                </li>
+                <li>
+                  For each item <em>expanded type</em> in
+                  <em>expanded value</em>, append the result of
+                  of using the
+                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                  algorithm, passing <tref>active context</tref>,
+                  <em>expanded type</em> for <em>iri</em>, and
+                  <tref>true</tref> for <em>vocabRelative</em>,
+                  to <em>compacted value</em>.
+                </li>
+                <li>
+                  If <em>compacted value</em> contains only one
+                  item (it has a length of <code>1</code>), then
+                  set <em>compacted value</em> to its only item.
+                </li>
+              </ol>
+            </li>
+            <li>
+              Initialize <em>alias</em> to the result of using the
+              <a href="#iri-compaction-algorithm">IRI Compaction</a>
+              algorithm, passing <tref>active context</tref> and
+              <em>expanded property</em> for <em>iri</em>.
+            </li>
+            <li>
+              Add the key-value pair,
+              (<em>alias</em>-<em>compacted value</em>) to
+              <em>result</em> and continue to the next
+              <em>expanded property</em>.
+            </li>
+          </ol>
+        </li>
+      <li>
+        If <em>expanded property</em> equals <code>@index</code>:
+        <ol class="algorithm">
+          <li>
+            If <tref>active property</tref> has a
+            <tref>container mapping</tref> in <tref>active context</tref>
+            that equals <code>@index</code>, then the compacted
+            result will be inside of an <code>@index</code>
+            container, so simply drop the <code>@index</code>
+            property by continuing to the next
+            <em>expanded property</em>.
+          </li>
+          <li>
+            Otherwise, initialize <em>alias</em> to the result of using
+            the <a href="#iri-compaction-algorithm">IRI Compaction</a>
+            algorithm, passing <tref>active context</tref> and
+            <em>expanded property</em> for <em>iri</em>.
+          </li>
+          <li>
+            Add the key-value pair,
+            (<em>alias</em>-<em>expanded value</em>) to
+            <em>result</em> and continue to the next
+            <em>expanded property</em>.
+          </li>
+        </ol>
+      </li>
+      <li>
+        If <em>expanded value</em> is an empty <tref>array</tref>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>item active property</em> to the result of
+            using the
+            <a href="#iri-compaction-algorithm">IRI Compaction</a>
+            algorithm, passing <tref>active context</tref>,
+            <em>expanded property</em> for <em>iri</em>,
+            <em>expanded value</em> for <em>value</em>,
+            <tref>true</tref> for <em>vocabRelative</em>, and
+            <em>shallow</em> for <em>parent</em>.
+          </li>
+          <li>
+            If <em>result</em> does not have the key that equals
+            <em>item active property</em>, set this key's value in
+            <em>result</em> to an empty <tref>array</tref>. Otherwise, if
+            the key's value is not an <tref>array</tref>, then set it
+            equal to one containing only the value.
+          </li>
+        </ol>
+      </li>
+      <li>
+        At this point, <em>expanded value</em> must be an
+        <tref>array</tref> due to the
+        <a href="#expansion-algorithm">Expansion algorithm</a>.
+        For each item <em>expanded item</em> in <em>expanded value</em>:
+        <ol class="algorithm">
+          <li>
+            Initialize <em>item active property</em> to the result of using
+            the <a href="#iri-compaction-algorithm">IRI Compaction</a>
+            algorithm, passing <tref>active context</tref>,
+            <em>expanded property</em> for <em>iri</em>,
+            <em>expanded item</em> for <em>value</em>,
+            <tref>true</tref> for <em>vocabRelative</em>, and
+            <em>shallow</em> for <em>parent</em>.
+          </li>
+          <li>
+            Initialize <em>container</em> to <tref>null</tref>. If there
+            is a <tref>container mapping</tref> for
+            <em>item active property</em> in <tref>active context</tref>,
+            set <em>container</em> to its value.
+          </li>
+          <li>
+            If there is a <tref>term definition</tref> for
+            <em>item active property</em> in <tref>active context</tref>
+            that is a <tref>property generator</tref>, then invoke the
+            <a href="#find-property-generator-duplicates-subalgorithm">Find Property Generator Duplicates</a>
+            algorithm, passing <tref>active context</tref>,
+            <em>shallow</em> for <em>element</em>,
+            <em>expanded property</em>, <em>expanded item</em> for
+            <em>value</em>, <em>item active property</em> for
+            <tref>active property</tref>, and
+            <tref>true</tref> for <em>remove</em>.
+          </li>
+          <li>
+            Initialize <em>compacted item</em> to the result of using
+            this algorithm recursively, passing
+            <tref>active context</tref>, <em>item active property</em>
+            for </tref>active property</tref>,
+            <em>expanded item</em> for <em>element</em> if it does
+            not contain the key <code>@list</code>, otherwise pass
+            the key's associated value for <em>element</em>.
+          </li>
+          <li>
+            If <em>expanded item</em> is a <tref>list object</tref>:
             <ol class="algorithm">
               <li>
-                If <em>value</em> is an <tref>array</tref>, then add
-                a key-value pair to <em>shallow</em> where the key
-                is <em>key</em> and the value is a shallow copy of
-                <em>value</em>.
+                If <em>compacted item</em> is not an <tref>array</tref>,
+                then set it to an <tref>array</tref> containing only
+                <em>compacted item</em>.
               </li>
               <li>
-                Otherwise, add the key-value pair, <em>key</em>-<em>value</em>
-                to <em>shallow</em>.
+                If <em>container</em> does not equal <code>@list</code>:
+                <ol class="algorithm">
+                  <li>
+                    Convert <em>compacted item</em> to a
+                    <tref>list object</tref> by setting it to a
+                    <tref>JSON object</tref> containing key-value pair
+                    where the key is the result of the
+                    <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                    algorithm, passing <tref>active context</tref> and
+                    <code>@list</code> for <em>iri</em>, and the
+                    value is <em>compacted item</em>.
+                  </li>
+                  <li>
+                    If <em>expanded item</em> contains the key
+                    <code>@index</code>, then add a key-value pair
+                    to <em>compacted item</em> where the key is the
+                    result of the
+                    <a href="#iri-compaction-algorithm">IRI Compaction</a>
+                    algorithm, passing <tref>active context</tref> and
+                    <code>@index</code> for <em>iri</em>, and the
+                    value is the value associated with the
+                    <code>@index</code> key in
+                    <em>expanded item</em>.
+                  </li>
+                </ol>
+              </li>
+              <li>
+                Otherwise, <em>item active property</em> MUST NOT be a key
+                in <em>result</em> because there cannot be two
+                <tref title="list object">list objects</tref> associated
+                with an <tref>active property</tref> that has a
+                <tref>container mapping</tref>; this is an error.
+              </li>
+            </ol>
+          </li>
+          <li>
+            If <em>container</em> equals <code>@language</code> or
+            <code>@index</code>:
+            <ol class="algorithm">
+              <li>
+                If <em>item active property</em> is a key in
+                <em>result</em>, then initialize <em>map object</em> to
+                its associated value, otherwise initialize it to an empty
+                <tref>JSON object</tref>.
+              </li>
+              <li>
+                If <em>container</em> is <code>@language</code> and
+                <em>compacted item</em> contains the key
+                <code>@value</code>, then set <em>compacted item</em>
+                to the value associated with its <code>@value</code> key.
+              </li>
+              <li>
+                Initialize <em>map key</em> to the value associated with
+                with the key that equals <em>container</em> in
+                <em>expanded item</em>.
+              </li>
+              <li>
+                If <em>map key</em> is not a key in <em>map object</em>,
+                then set this key's value in <em>map object</em>
+                to <em>compacted item</em>. Otherwise, if the value
+                is not an <tref>array</tref>, then set it equal to one
+                containing only the value and then append
+                <em>compacted item</em> to it.
+              </li>
+            </ol>
+          </li>
+          <li>
+            Otherwise,
+            <ol class="algorithm">
+              <li>
+                Initialize <em>useArray</em> to <tref>false</tref>. If
+                <em>container</em> equals <code>@set</code> or
+                <code>@list</code>, or <em>compacted item</em> is
+                an empty <tref>array</tref>, or
+                <em>expanded property</em> equals <code>@list</code> or
+                <code>@graph</code>, then set <em>useArray</em>
+                to <tref>true</tref>.
+              </li>
+              <li>
+                If <em>useArray</em> is <tref>true</tref> and
+                <em>compacted item</em> is not an <tref>array</tref>,
+                then set it equal to a new <tref>array</tref>
+                containing only <em>compacted item</em>.
+              </li>
+              <li>
+                If <em>item active property</em> is not a key in
+                <em>result</em> then add the key-value pair,
+                (<em>item active property</em>-<em>compacted item</em>),
+                to <em>result</em>.
+              </li>
+              <li>
+                Otherwise, if the value associated with the key that
+                equals <em>item active property</em> in <em>result</em>
+                is not an <tref>array</tref>, set it equal to a new
+                <tref>array</tref> containing only the value. Then
+                append <em>compacted item</em> to the value if
+                <em>compacted item</em> is not an <tref>array</tref>,
+                otherwise, concatenate it.
               </li>
             </ol>
           </li>
         </ol>
       </li>
-      <li>
-        Initialize <em>result</em> to an empty <tref>JSON object</tref>.
-      </li>
-      <li>
-        Initialize <em>keys</em> to an <tref>array</tref> containing
-        all of the keys in <em>shallow</em>, ordered lexicographically.
-      </li>
-      <li>
-        For each key <em>expanded property</em> in <em>keys</em>:
-        <ol class="algorithm">
-          <li>
-            If <em>shallow</em> does not contain a key that equals
-            <em>expanded property</em>, then continue to the next
-            <em>expanded property</em>.
-          </li>
-          <li>
-            Initialize <em>expanded value</em> to the value associated
-            with the key that equals <em>expanded property</em> in
-            <em>shallow</em>.
-          </li>
-          <li>
-            If <em>expanded property</em> equals <code>@id</code> or
-            <code>@type</code>:
-              <ol class="algorithm">
-                <li>
-                  If <em>expanded value</em> is a <tref>string</tref>,
-                  then initialize <em>compacted value</em> to the result
-                  of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref>,
-                  <em>expanded value</em> for <em>iri</em>,
-                  and <tref>true</tref> for <em>vocabRelative</em> if
-                  <em>expanded property</em> equals <code>@type</code>,
-                  <tref>false</tref> otherwise.
-                </li>
-                <li>
-                  Otherwise, <em>expanded value</em> must be a
-                  <code>@type</code> <tref>array</tref>:
-                  <ol class="algorithm">
-                    <li>
-                      Initialize <em>compacted value</em> to an empty
-                      <tref>array</tref>.
-                    </li>
-                    <li>
-                      For each item <em>expanded type</em> in
-                      <em>expanded value</em>, append the result of
-                      of using the
-                      <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                      algorithm, passing <tref>active context</tref>,
-                      <em>expanded type</em> for <em>iri</em>, and
-                      <tref>true</tref> for <em>vocabRelative</em>,
-                      to <em>compacted value</em>.
-                    </li>
-                    <li>
-                      If <em>compacted value</em> contains only one
-                      item (it has a length of <code>1</code>), then
-                      set <em>compacted value</em> to its only item.
-                    </li>
-                  </ol>
-                </li>
-                <li>
-                  Initialize <em>alias</em> to the result of using the
-                  <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                  algorithm, passing <tref>active context</tref> and
-                  <em>expanded property</em> for <em>iri</em>.
-                </li>
-                <li>
-                  Add the key-value pair,
-                  (<em>alias</em>-<em>compacted value</em>) to
-                  <em>result</em> and continue to the next
-                  <em>expanded property</em>.
-                </li>
-              </ol>
-            </li>
-          <li>
-            If <em>expanded property</em> equals <code>@index</code>:
-            <ol class="algorithm">
-              <li>
-                If <tref>active property</tref> has a
-                <tref>container mapping</tref> in <tref>active context</tref>
-                that equals <code>@index</code>, then the compacted
-                result will be inside of an <code>@index</code>
-                container, so simply drop the <code>@index</code>
-                property by continuing to the next
-                <em>expanded property</em>.
-              </li>
-              <li>
-                Otherwise, initialize <em>alias</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref> and
-                <em>expanded property</em> for <em>iri</em>.
-              </li>
-              <li>
-                Add the key-value pair,
-                (<em>alias</em>-<em>expanded value</em>) to
-                <em>result</em> and continue to the next
-                <em>expanded property</em>.
-              </li>
-            </ol>
-          </li>
-          <li>
-            If <em>expanded value</em> is an empty <tref>array</tref>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>item active property</em> to the result of
-                using the
-                <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <em>expanded value</em> for <em>value</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                If <em>result</em> does not have the key that equals
-                <em>item active property</em>, set this key's value in
-                <em>result</em> to an empty <tref>array</tref>. Otherwise, if
-                the key's value is not an <tref>array</tref>, then set it
-                equal to one containing only the value.
-              </li>
-            </ol>
-          </li>
-          <li>
-            At this point, <em>expanded value</em> must be an
-            <tref>array</tref> due to the
-            <a href="#expansion-algorithm">Expansion algorithm</a>.
-            For each item <em>expanded item</em> in <em>expanded value</em>:
-            <ol class="algorithm">
-              <li>
-                Initialize <em>item active property</em> to the result of using
-                the <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>expanded property</em> for <em>iri</em>,
-                <em>expanded item</em> for <em>value</em>,
-                <tref>true</tref> for <em>vocabRelative</em>, and
-                <em>shallow</em> for <em>parent</em>.
-              </li>
-              <li>
-                Initialize <em>container</em> to <tref>null</tref>. If there
-                is a <tref>container mapping</tref> for
-                <em>item active property</em> in <tref>active context</tref>,
-                set <em>container</em> to its value.
-              </li>
-              <li>
-                If there is a <tref>term definition</tref> for
-                <em>item active property</em> in <tref>active context</tref>
-                that is a <tref>property generator</tref>, then invoke the
-                <a href="#find-property-generator-duplicates-subalgorithm">Find Property Generator Duplicates</a>
-                algorithm, passing <tref>active context</tref>,
-                <em>shallow</em> for <em>element</em>,
-                <em>expanded property</em>, <em>expanded item</em> for
-                <em>value</em>, <em>item active property</em> for
-                <tref>active property</tref>, and
-                <tref>true</tref> for <em>remove</em>.
-              </li>
-              <li>
-                Initialize <em>compacted item</em> to the result of using
-                this algorithm recursively, passing
-                <tref>active context</tref>, <em>item active property</em>
-                for </tref>active property</tref>,
-                <em>expanded item</em> for <em>element</em> if it does
-                not contain the key <code>@list</code>, otherwise pass
-                the key's associated value for <em>element</em>.
-              </li>
-              <li>
-                If <em>expanded item</em> is a <tref>list object</tref>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it to an <tref>array</tref> containing only
-                    <em>compacted item</em>.
-                  </li>
-                  <li>
-                    If <em>container</em> does not equal <code>@list</code>:
-                    <ol class="algorithm">
-                      <li>
-                        Convert <em>compacted item</em> to a
-                        <tref>list object</tref> by setting it to a
-                        <tref>JSON object</tref> containing key-value pair
-                        where the key is the result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@list</code> for <em>iri</em>, and the
-                        value is <em>compacted item</em>.
-                      </li>
-                      <li>
-                        If <em>expanded item</em> contains the key
-                        <code>@index</code>, then add a key-value pair
-                        to <em>compacted item</em> where the key is the
-                        result of the
-                        <a href="#iri-compaction-algorithm">IRI Compaction</a>
-                        algorithm, passing <tref>active context</tref> and
-                        <code>@index</code> for <em>iri</em>, and the
-                        value is the value associated with the
-                        <code>@index</code> key in
-                        <em>expanded item</em>.
-                      </li>
-                    </ol>
-                  </li>
-                  <li>
-                    Otherwise, <em>item active property</em> MUST NOT be a key
-                    in <em>result</em> because there cannot be two
-                    <tref title="list object">list objects</tref> associated
-                    with an <tref>active property</tref> that has a
-                    <tref>container mapping</tref>; this is an error.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                If <em>container</em> equals <code>@language</code> or
-                <code>@index</code>:
-                <ol class="algorithm">
-                  <li>
-                    If <em>item active property</em> is a key in
-                    <em>result</em>, then initialize <em>map object</em> to
-                    its associated value, otherwise initialize it to an empty
-                    <tref>JSON object</tref>.
-                  </li>
-                  <li>
-                    If <em>container</em> is <code>@language</code> and
-                    <em>compacted item</em> contains the key
-                    <code>@value</code>, then set <em>compacted item</em>
-                    to the value associated with its <code>@value</code> key.
-                  </li>
-                  <li>
-                    Initialize <em>map key</em> to the value associated with
-                    with the key that equals <em>container</em> in
-                    <em>expanded item</em>.
-                  </li>
-                  <li>
-                    If <em>map key</em> is not a key in <em>map object</em>,
-                    then set this key's value in <em>map object</em>
-                    to <em>compacted item</em>. Otherwise, if the value
-                    is not an <tref>array</tref>, then set it equal to one
-                    containing only the value and then append
-                    <em>compacted item</em> to it.
-                  </li>
-                </ol>
-              </li>
-              <li>
-                Otherwise,
-                <ol class="algorithm">
-                  <li>
-                    Initialize <em>useArray</em> to <tref>false</tref>. If
-                    <em>container</em> equals <code>@set</code> or
-                    <code>@list</code>, or <em>compacted item</em> is
-                    an empty <tref>array</tref>, or
-                    <em>expanded property</em> equals <code>@list</code> or
-                    <code>@graph</code>, then set <em>useArray</em>
-                    to <tref>true</tref>.
-                  </li>
-                  <li>
-                    If <em>useArray</em> is <tref>true</tref> and
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    then set it equal to a new <tref>array</tref>
-                    containing only <em>compacted item</em>.
-                  </li>
-                  <li>
-                    If <em>item active property</em> is not a key in
-                    <em>result</em> then add the key-value pair,
-                    (<em>item active property</em>-<em>compacted item</em>),
-                    to <em>result</em>.
-                  </li>
-                  <li>
-                    Otherwise, if the value associated with the key that
-                    equals <em>item active property</em> in <em>result</em>
-                    is not an <tref>array</tref>, set it equal to a new
-                    <tref>array</tref> containing only the value. Then
-                    append <em>compacted item</em> to the value if
-                    <em>compacted item</em> is not an <tref>array</tref>,
-                    otherwise, concatenate it.
-                  </li>
-                </ol>
-              </li>
-            </ol>
-          </li>
-        </ol>
-      </li>
-      <li>
-        Return <em>result</em>.
-      </li>
     </ol>
   </li>
-  <li>
-    At this point, <em>element</em> must a be <tref>scalar</tref>, which
-    is already compact, so simply return <em>element</em>.
-  </li>
+  <li>Return <em>result</em>.</li>
 </ol>
 
 <p>