func BoolAnd(l, r Term) Op {
	return Op{OpCode: AndOp, L: l, R: r}
}
BoolAnd takes Terms l and r and returns (l && r).
package term
import (
	"fmt"
	"math"
	"sort"
	"strings"
)
type Term interface {
	isTerm()
}
type Universe int
func (Universe) isTerm() {}
const (
	Type Universe = iota
	Kind
	Sort
)
type Builtin string
func (Builtin) isTerm() {}
const (
	Double   Builtin = "Double"
	Text     Builtin = "Text"
	Bool     Builtin = "Bool"
	Natural  Builtin = "Natural"
	Integer  Builtin = "Integer"
	List     Builtin = "List"
	Optional Builtin = "Optional"
	None     Builtin = "None"
	NaturalBuild     Builtin = "Natural/build"
	NaturalFold      Builtin = "Natural/fold"
	NaturalIsZero    Builtin = "Natural/isZero"
	NaturalEven      Builtin = "Natural/even"
	NaturalOdd       Builtin = "Natural/odd"
	NaturalToInteger Builtin = "Natural/toInteger"
	NaturalShow      Builtin = "Natural/show"
	NaturalSubtract  Builtin = "Natural/subtract"
	IntegerClamp    Builtin = "Integer/clamp"
	IntegerNegate   Builtin = "Integer/negate"
	IntegerToDouble Builtin = "Integer/toDouble"
	IntegerShow     Builtin = "Integer/show"
	DoubleShow Builtin = "Double/show"
	TextShow    Builtin = "Text/show"
	TextReplace Builtin = "Text/replace"
	ListBuild   Builtin = "List/build"
	ListFold    Builtin = "List/fold"
	ListLength  Builtin = "List/length"
	ListHead    Builtin = "List/head"
	ListLast    Builtin = "List/last"
	ListIndexed Builtin = "List/indexed"
	ListReverse Builtin = "List/reverse"
)
type BoolLit bool
func (BoolLit) isTerm() {}
const (
	True  BoolLit = true
	False BoolLit = false
)
type Var struct {
	Name  string
	Index int
}
func (Var) isTerm() {}
func NewVar(name string) Var {
	return Var{Name: name}
}
type LocalVar struct {
	Name  string
	Index int
}
func (LocalVar) isTerm() {}
type (
	Lambda struct {
		Label string
		Type  Term
		Body  Term
	}
	Pi struct {
		Label string
		Type  Term
		Body  Term
	}
	App struct {
		Fn  Term
		Arg Term
	}
	Op struct {
		OpCode OpCode
		L      Term
		R      Term
	}
)
func (Lambda) isTerm() {}
func (Pi) isTerm()     {}
func (App) isTerm()    {}
func (Op) isTerm()     {}
func NewLambda(label string, t Term, body Term) Lambda {
	return Lambda{
		Label: label,
		Type:  t,
		Body:  body,
	}
}
func NewPi(label string, t Term, body Term) Pi {
	return Pi{
		Label: label,
		Type:  t,
		Body:  body,
	}
}
func NewAnonPi(domain Term, codomain Term) Pi {
	return NewPi("_", domain, codomain)
}
func Apply(fn Term, args ...Term) Term {
	out := fn
	for _, arg := range args {
		out = App{Fn: out, Arg: arg}
	}
	return out
}
type OpCode int
const (
	OrOp  OpCode = iota  
	AndOp                
	EqOp                 
	NeOp                 
	PlusOp   
	TimesOp  
	TextAppendOp  
	ListAppendOp  
	RecordMergeOp             
	RightBiasedRecordMergeOp  
	RecordTypeMergeOp         
	ImportAltOp  
	EquivOp      
	CompleteOp   
)
func NaturalPlus(l, r Term) Op {
	return Op{OpCode: PlusOp, L: l, R: r}
}
func NaturalTimes(l, r Term) Op {
	return Op{OpCode: TimesOp, L: l, R: r}
}
func BoolOr(l, r Term) Op {
	return Op{OpCode: OrOp, L: l, R: r}
}