code: func NewCompiler() *Compiler {
  
  	c := &Compiler{
  		Modules: map[string]*Module{},
  		TypeEnv: NewTypeEnv(),
  		ruleIndices: util.NewHashMap(func(a, b util.T) bool {
  			r1, r2 := a.(Ref), b.(Ref)
  			return r1.Equal(r2)
  		}, func(x util.T) int {
  			return x.(Ref).Hash()
  		}),
  		maxErrs: CompileErrorLimitDefault,
  		after:   map[string][]CompilerStage{},
  	}
  
  	c.ModuleTree = NewModuleTree(nil)
  	c.RuleTree = NewRuleTree(c.ModuleTree)
  
  	checker := newTypeChecker()
  	c.TypeEnv = checker.checkLanguageBuiltins()
  
  	c.stages = []struct {
  		name string
  		f    func()
  	}{
  		// Reference resolution should run first as it may be used to lazily
  		// load additional modules. If any stages run before resolution, they
  		// need to be re-run after resolution.
  		{"ResolveRefs", c.resolveAllRefs},
  		{"RewriteAssignments", c.rewriteLocalAssignments},
  		{"RewriteExprTerms", c.rewriteExprTerms},
  		{"SetModuleTree", c.setModuleTree},
  		{"SetRuleTree", c.setRuleTree},
  		{"SetGraph", c.setGraph},
  		{"RewriteComprehensionTerms", c.rewriteComprehensionTerms},
  		{"RewriteRefsInHead", c.rewriteRefsInHead},
  		{"RewriteWithValues", c.rewriteWithModifiers},
  		{"CheckRuleConflicts", c.checkRuleConflicts},
  		{"CheckSafetyRuleHeads", c.checkSafetyRuleHeads},
  		{"CheckSafetyRuleBodies", c.checkSafetyRuleBodies},
  		{"RewriteEquals", c.rewriteEquals},
  		{"RewriteDynamicTerms", c.rewriteDynamicTerms},
  		{"CheckRecursion", c.checkRecursion},
  		{"CheckTypes", c.checkTypes},
  		{"BuildRuleIndices", c.buildRuleIndices},
  	}
  
  	return c
  }
docs: // NewCompiler returns a new empty compiler.