#name: reentrance
#evalFull
-- in.cue --
// This indirection is needed to avoid binding references to fib
// within fib to the instantiated version.
fibRec: {nn: int, out: (fib & {n: nn}).out}
fib: {
	n: int

	if n >= 2 {
		out: (fibRec & {nn: n - 2}).out + (fibRec & {nn: n - 1}).out
	}
	if n < 2 {
		out: n
	}
}
fib1:  (fib & {n: 1}).out  // MAY NOT be an error
fib2:  (fib & {n: 2}).out  // MAY be an error
fib3:  (fib & {n: 3}).out  // SHOULD be an error
fib7:  (fib & {n: 7}).out  // Error
fib12: (fib & {n: 12}).out // Error

-- out/legacy-debug --
<0>{fibRec: <1>{nn: int, out: (<2>.fib & <3>{n: <4>.nn}).out}, fib: <5>{n: int if (<6>.n >= 2) yield <7>{out: ((<2>.fibRec & <8>{nn: (<6>.n - 2)}).out + (<2>.fibRec & <9>{nn: (<6>.n - 1)}).out)},  if (<6>.n < 2) yield <10>{out: <6>.n}}, fib2: 1, fib7: 13, fib12: 144}
-- out/compile --
--- in.cue
{
  fibRec: {
    nn: int
    out: (〈1;fib〉 & {
      n: 〈1;nn〉
    }).out
  }
  fib: {
    n: int
    if (〈0;n〉 >= 2) {
      out: ((〈2;fibRec〉 & {
        nn: (〈2;n〉 - 2)
      }).out + (〈2;fibRec〉 & {
        nn: (〈2;n〉 - 1)
      }).out)
    }
    if (〈0;n〉 < 2) {
      out: 〈1;n〉
    }
  }
  fib1: (〈0;fib〉 & {
    n: 1
  }).out
  fib2: (〈0;fib〉 & {
    n: 2
  }).out
  fib3: (〈0;fib〉 & {
    n: 3
  }).out
  fib7: (〈0;fib〉 & {
    n: 7
  }).out
  fib12: (〈0;fib〉 & {
    n: 12
  }).out
}
-- out/evalalpha/stats --
Leaks:  78
Freed:  0
Reused: 0
Allocs: 78
Retain: 0

Unifications: 62
Conjuncts:    140
Disjuncts:    0

CloseIDElems: 0
NumCloseIDs: 41
-- out/evalalpha --
Errors:
structural cycle:
    ./in.cue:8:9
structural cycle:
    ./in.cue:8:38

Result:
(_|_){
  // [structural cycle]
  fibRec: (struct){
    nn: (int){ int }
    out: (_|_){
      // [incomplete] non-concrete value int in operand to >=:
      //     ./in.cue:7:5
      //     ./in.cue:3:35
      //     ./in.cue:5:5
      // non-concrete value int in operand to <:
      //     ./in.cue:10:5
      //     ./in.cue:3:35
      //     ./in.cue:5:5
    }
  }
  fib: (_|_){
    // [incomplete] fib: non-concrete value int in operand to >=:
    //     ./in.cue:7:5
    //     ./in.cue:5:5
    // fib: non-concrete value int in operand to <:
    //     ./in.cue:10:5
    //     ./in.cue:5:5
    n: (int){ int }
  }
  fib1: (int){ 1 }
  fib2: (int){ 1 }
  fib3: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:8:9
    // structural cycle:
    //     ./in.cue:8:38
  }
  fib7: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:8:9
    // structural cycle:
    //     ./in.cue:8:38
  }
  fib12: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:8:9
    // structural cycle:
    //     ./in.cue:8:38
  }
}
-- diff/-out/evalalpha/stats<==>+out/eval/stats --
diff old new
--- old
+++ new
@@ -1,9 +1,12 @@
-Leaks:  16
-Freed:  180
-Reused: 170
-Allocs: 26
-Retain: 148
-
-Unifications: 196
-Conjuncts:    464
-Disjuncts:    268
+Leaks:  78
+Freed:  0
+Reused: 0
+Allocs: 78
+Retain: 0
+
+Unifications: 62
+Conjuncts:    140
+Disjuncts:    0
+
+CloseIDElems: 0
+NumCloseIDs: 41
-- diff/-out/evalalpha<==>+out/eval --
diff old new
--- old
+++ new
@@ -1,7 +1,5 @@
 Errors:
 structural cycle:
-    ./in.cue:3:25
-structural cycle:
     ./in.cue:8:9
 structural cycle:
     ./in.cue:8:38
@@ -35,14 +33,12 @@
   fib2: (int){ 1 }
   fib3: (_|_){
     // [structural cycle] structural cycle:
-    //     ./in.cue:3:25
+    //     ./in.cue:8:9
     // structural cycle:
     //     ./in.cue:8:38
   }
   fib7: (_|_){
     // [structural cycle] structural cycle:
-    //     ./in.cue:3:25
-    // structural cycle:
     //     ./in.cue:8:9
     // structural cycle:
     //     ./in.cue:8:38
@@ -49,8 +45,6 @@
   }
   fib12: (_|_){
     // [structural cycle] structural cycle:
-    //     ./in.cue:3:25
-    // structural cycle:
     //     ./in.cue:8:9
     // structural cycle:
     //     ./in.cue:8:38
-- diff/todo/p3 --
Note that it is okay for fib2 to fail.
-- out/eval/stats --
Leaks:  16
Freed:  180
Reused: 170
Allocs: 26
Retain: 148

Unifications: 196
Conjuncts:    464
Disjuncts:    268
-- out/eval --
Errors:
structural cycle:
    ./in.cue:3:25
structural cycle:
    ./in.cue:8:9
structural cycle:
    ./in.cue:8:38

Result:
(_|_){
  // [structural cycle]
  fibRec: (struct){
    nn: (int){ int }
    out: (_|_){
      // [incomplete] non-concrete value int in operand to >=:
      //     ./in.cue:7:5
      //     ./in.cue:3:35
      //     ./in.cue:5:5
      // non-concrete value int in operand to <:
      //     ./in.cue:10:5
      //     ./in.cue:3:35
      //     ./in.cue:5:5
    }
  }
  fib: (_|_){
    // [incomplete] fib: non-concrete value int in operand to >=:
    //     ./in.cue:7:5
    //     ./in.cue:5:5
    // fib: non-concrete value int in operand to <:
    //     ./in.cue:10:5
    //     ./in.cue:5:5
    n: (int){ int }
  }
  fib1: (int){ 1 }
  fib2: (int){ 1 }
  fib3: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:3:25
    // structural cycle:
    //     ./in.cue:8:38
  }
  fib7: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:3:25
    // structural cycle:
    //     ./in.cue:8:9
    // structural cycle:
    //     ./in.cue:8:38
  }
  fib12: (_|_){
    // [structural cycle] structural cycle:
    //     ./in.cue:3:25
    // structural cycle:
    //     ./in.cue:8:9
    // structural cycle:
    //     ./in.cue:8:38
  }
}
-- diff/todo/p2 --
Elimination of unnecessary, but potentially useful, errors.
