<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../xsl/unit.xsl"?>
<KIVSPEC name="VerifyThis2"><SPECBODY>enrich
   <a href="../../../specs/natlist/export/unit.xml">natlist</a>, 
   <a href="../../../../../lib/basic/specs/olist/export/unit.xml">olist</a>
with
   

   
   
   functions  leftneighbors : list → natlist;
              first-lower : natlist × list × elem → nat;
   predicates  bounded : natlist × nat × nat;
               ordered&gt; : natlist;
               valid-stack : natlist × list;
   procedures LEFTNEIGHBORS list :  : natlist  ;
   variables  x : list;
              y : list;
              left : natlist;
              lneighbors : natlist;
              stack : natlist;
              xpos : nat;
              a : elem;
   partial functions  leftneighbor : list × nat → nat with λ x, n. n &lt; &#35; x;
                      leftneighbor : list × nat × elem → nat with λ x, n, a. n &lt; &#35; x;
                      leftneighbors : list × nat → natlist with λ x, n. n ≤ &#35; x;
                      . [ . ]! : list × nat → elem with λ x, n. 0 &lt; n ∧ n ≤ &#35; x;
                     comment: 1-based lookup;
   

   

   axioms one-based-lookup :  ⊦ x[n]! = x[n -1];
          used for: ls;
          first-lower-base :  ⊦ first-lower([], x, a) = 0;
          used for: s, ls;
          first-lower-rec :  ⊦ first-lower(xpos ' + stack, x, a) = (x[xpos]! &lt; a ⊃ xpos;first-lower(stack, x, a));
          used for: s, ls;
          leftneighbors :  ⊦ leftneighbors(x) = leftneighbors(x, &#35; x);
          used for: s, ls;
          leftneighbors-base :  ⊦ leftneighbors(x, 0) = [];
          used for: s, ls;
          leftneighbors-rec :  ⊦ leftneighbors(x, n + 1) = leftneighbors(x, n) + leftneighbor(x, n);
          used for: s, ls;
          leftneighbor :  ⊦ leftneighbor(x, n) = leftneighbor(x, n, x[n]);
          leftneighbor-base :  ⊦ leftneighbor(x, 0, a) = 0;
          used for: s, ls;
          leftneighbor-rec :  ⊦ leftneighbor(x, n + 1, a) = (x[n] &lt; a ⊃ n + 1;leftneighbor(x, n, a));
          used for: s, ls;
          bounded-base :  ⊦ bounded([], n0, n1);
          used for: s, ls;
          bounded-rec :  ⊦ bounded(m ' + stack, n0, n1) ↔ n0 ≤ m ∧ m &lt; n1 ∧ bounded(stack, n0, n1);
          used for: s, ls;
          ordered-base :  ⊦ ordered&gt;([]);
          used for: s, ls;
          ordered-one :  ⊦ ordered&gt;(n ');
          used for: s, ls;
          ordered-rec :  ⊦ ordered&gt;(n0 ' + n1 ' + stack) ↔ n1 &lt; n0 ∧ ordered&gt;(n1 ' + stack);
          used for: s, ls;
          valid-stack-base :  ⊦ valid-stack([], x);
          used for: s, ls;
          valid-stack-one :  ⊦ valid-stack(xpos ', x) ↔ 0 &lt; xpos ∧ xpos ≤ &#35; x ∧ leftneighbor(x, xpos - 1) = 0;
          used for: s, ls;
          valid-stack-rec
          : ⊦   valid-stack(xpos1 ' + xpos0 ' + stack, x)
              ↔ 0 &lt; xpos1 ∧ xpos1 ≤ &#35; x ∧ leftneighbor(x, xpos1 - 1) = xpos0 ∧ valid-stack(xpos0 ' + stack, x);
          used for: s, ls;

   theorems LEFTNEIGHBORS-correct :  ⊦ ⟨LEFTNEIGHBORS(x; ; lneighbors)⟩ (lneighbors = leftneighbors(x));

   declarations LEFTNEIGHBORS-decl
                : LEFTNEIGHBORS(x; ; lneighbors)
                  {lneighbors := []; 
                   let xpos = 1, stack = []
                   in while xpos ≤ &#35; x
                      do {/* _:
                             invariant   xpos ≠ 0 ∧ xpos ≤ &#35; x + 1 ∧ (stack = [] ↔ xpos = 1) ∧ ordered&gt;(stack) ∧ bounded(stack, 1, xpos)
                                       ∧ lneighbors = leftneighbors(x, xpos - 1) ∧ valid-stack(stack, x) ∧ (stack ≠ [] → stack.head = xpos - 1)
                             wfbound &#35; x + 1 - xpos; 
                          */; 
                          while stack ≠ [] ∧ ¬ x[stack.head]! &lt; x[xpos]!
                          do {/* _:
                                 invariant   xpos ≠ 0 ∧ xpos ≤ &#35; x ∧ ordered&gt;(stack) ∧ bounded(stack, 1, xpos) ∧ valid-stack(stack, x)
                                           ∧ leftneighbor(x, xpos - 1) = first-lower(stack, x, x[xpos]!)
                                 wfbound &#35; stack; 
                              */; 
                              stack := stack.tail}; 
                          if stack = [] then lneighbors := lneighbors + 0 else lneighbors := lneighbors + stack.head; stack := xpos + stack; 
                          xpos := xpos + 1}
                  }
                ;
end enrich</SPECBODY></KIVSPEC>