-- x.cue --
// variants of fib

inline: small: {
	f: {
		n: int
		out: (f & {"n": n - 1}).out
	}
}

inline: medium: {
	f2: (f & {n: 2}).out
	fRec: {nn: int, out: (f & {n: nn}).out}
	f: {
		n: int
		out: (fRec & {nn: n - 1}).out
	}
}

inline: patterns: {
	f: n: (f & {n: {}}).n
	f: n: {}
	[string]: {n: {}}
	f: [string]: {}
	f: {}
}

inline: acrossFields: fail1: {
	f: {
		in:  number
		out: in + 1
	}
	k00: 0
	k10: (f & {in: k00}).out
	k20: (f & {in: k10}).out
	k30: (f & {in: k20}).out

	// invalid recursion is here.
	k10: (f & {in: k30}).out
}

// Issue #2163
inline: acrossFields: ok1: {
	f: {
		in:  number
		out: in
	}
	k00: 0
	k10: (f & {in: k00}).out
	k20: (f & {in: k10}).out
	k30: (f & {in: k20}).out

	// TODO: what is correct behavior here.
	// This is borderline okay.
	k10: (f & {in: k30}).out
}
-- inlineexpand.cue --
inlined: {
	X: {
		input: a: _
		output: input.a
	}
	root: a: (X & {input: root}).output
}
expanded1: hasCycle: {
	X: {
		input: a: _
		output: input.a
	}
	root: {
		a: _a.output
		_a: X & {input: root}
	}
}
expanded2: noCycle: {
	X: {
		input: a: _
		output: input.a
	}
	root: a: _a.output
	_a: X & {input: root}
}
issue3731: reduced: {
	#lookup: {
		input: {...}
		output: [
			for _, v in input if v.show != _|_ {v},
		]
	}

	root: {
		self: show: true
		others: (#lookup & {input: root}).output
	}
}
issue3731: expanded: {
	#lookup: {
		input: {...}
		output: [
			for _, v in input if v.show != _|_ {v},
		]
	}

	root: {
		self: show: true
		others: _others.output
		_others: #lookup & {input: root}
	}
}
issue3731: full: {
	#Workspace: {
		workspaceA?: {}
		workspaceB?: {}
	}

	#AccountConfig: {
		workspaces: #Workspace
		siblings?: [...string]
	}

	#AccountConfigSub1: {
		#AccountConfig
		workspaces: "workspaceA": {}
	}

	#AccountConfigSub2: {
		#AccountConfig
		workspaces: "workspaceB": {}
	}

	tree: env1: {
		"region1": {
			"env1-r1-account-sub1":   #AccountConfigSub1
			"env1-r1-account-sub2-1": #AccountConfigSub2
		}
	}

	#lookupSiblings: {
		envtree: {...}
		out: [
			for region, v in envtree
			for account, config in v
			if config.workspaces."workspaceB" != _|_ {account},
		]
	}

	tree: ENVTREE=env1: [_]: [_]: #AccountConfig & {
		siblings: (#lookupSiblings & {envtree: ENVTREE}).out
	}
}
-- out/compile --
--- inlineexpand.cue
{
  inlined: {
    X: {
      input: {
        a: _
      }
      output: 〈0;input〉.a
    }
    root: {
      a: (〈1;X〉 & {
        input: 〈2;root〉
      }).output
    }
  }
  expanded1: {
    hasCycle: {
      X: {
        input: {
          a: _
        }
        output: 〈0;input〉.a
      }
      root: {
        a: 〈0;_a〉.output
        _a: (〈1;X〉 & {
          input: 〈2;root〉
        })
      }
    }
  }
  expanded2: {
    noCycle: {
      X: {
        input: {
          a: _
        }
        output: 〈0;input〉.a
      }
      root: {
        a: 〈1;_a〉.output
      }
      _a: (〈0;X〉 & {
        input: 〈1;root〉
      })
    }
  }
  issue3731: {
    reduced: {
      #lookup: {
        input: {
          ...
        }
        output: [
          for _, v in 〈1;input〉 if (〈0;v〉.show != _|_(explicit error (_|_ literal) in source)) {
            〈1;v〉
          },
        ]
      }
      root: {
        self: {
          show: true
        }
        others: (〈1;#lookup〉 & {
          input: 〈2;root〉
        }).output
      }
    }
  }
  issue3731: {
    expanded: {
      #lookup: {
        input: {
          ...
        }
        output: [
          for _, v in 〈1;input〉 if (〈0;v〉.show != _|_(explicit error (_|_ literal) in source)) {
            〈1;v〉
          },
        ]
      }
      root: {
        self: {
          show: true
        }
        others: 〈0;_others〉.output
        _others: (〈1;#lookup〉 & {
          input: 〈2;root〉
        })
      }
    }
  }
  issue3731: {
    full: {
      #Workspace: {
        workspaceA?: {}
        workspaceB?: {}
      }
      #AccountConfig: {
        workspaces: 〈1;#Workspace〉
        siblings?: [
          ...string,
        ]
      }
      #AccountConfigSub1: {
        〈1;#AccountConfig〉
        workspaces: {
          workspaceA: {}
        }
      }
      #AccountConfigSub2: {
        〈1;#AccountConfig〉
        workspaces: {
          workspaceB: {}
        }
      }
      tree: {
        env1: {
          region1: {
            "env1-r1-account-sub1": 〈3;#AccountConfigSub1〉
            "env1-r1-account-sub2-1": 〈3;#AccountConfigSub2〉
          }
        }
      }
      #lookupSiblings: {
        envtree: {
          ...
        }
        out: [
          for region, v in 〈1;envtree〉 for account, config in 〈0;v〉 if (〈0;config〉.workspaces.workspaceB != _|_(explicit error (_|_ literal) in source)) {
            〈1;account〉
          },
        ]
      }
      tree: {
        env1: {
          [_]: {
            [_]: (〈3;#AccountConfig〉 & {
              siblings: (〈4;#lookupSiblings〉 & {
                envtree: 〈4;env1〉
              }).out
            })
          }
        }
      }
    }
  }
}
--- x.cue
{
  inline: {
    small: {
      f: {
        n: int
        out: (〈1;f〉 & {
          n: (〈1;n〉 - 1)
        }).out
      }
    }
  }
  inline: {
    medium: {
      f2: (〈0;f〉 & {
        n: 2
      }).out
      fRec: {
        nn: int
        out: (〈1;f〉 & {
          n: 〈1;nn〉
        }).out
      }
      f: {
        n: int
        out: (〈1;fRec〉 & {
          nn: (〈1;n〉 - 1)
        }).out
      }
    }
  }
  inline: {
    patterns: {
      f: {
        n: (〈1;f〉 & {
          n: {}
        }).n
      }
      f: {
        n: {}
      }
      [string]: {
        n: {}
      }
      f: {
        [string]: {}
      }
      f: {}
    }
  }
  inline: {
    acrossFields: {
      fail1: {
        f: {
          in: number
          out: (〈0;in〉 + 1)
        }
        k00: 0
        k10: (〈0;f〉 & {
          in: 〈1;k00〉
        }).out
        k20: (〈0;f〉 & {
          in: 〈1;k10〉
        }).out
        k30: (〈0;f〉 & {
          in: 〈1;k20〉
        }).out
        k10: (〈0;f〉 & {
          in: 〈1;k30〉
        }).out
      }
    }
  }
  inline: {
    acrossFields: {
      ok1: {
        f: {
          in: number
          out: 〈0;in〉
        }
        k00: 0
        k10: (〈0;f〉 & {
          in: 〈1;k00〉
        }).out
        k20: (〈0;f〉 & {
          in: 〈1;k10〉
        }).out
        k30: (〈0;f〉 & {
          in: 〈1;k20〉
        }).out
        k10: (〈0;f〉 & {
          in: 〈1;k30〉
        }).out
      }
    }
  }
}
