def
Lean.Elab.Term.elabBinRelCore
(noProp : Bool)
(stx : Lean.Syntax)
(expectedType? : Option Lean.Expr)
:
Equations
- Lean.Elab.Term.elabBinRelCore noProp stx expectedType? = (fun toBoolIfNecessary => do let a ← Lean.Elab.Term.resolveId? (Lean.Syntax.getOp stx 1) "term" false match a with | some f => do let s ← Lean.saveState let discr ← Lean.Elab.Term.withSynthesize (do let lhs ← Lean.Elab.Term.elabTerm (Lean.Syntax.getOp stx 2) none true true let rhs ← Lean.Elab.Term.elabTerm (Lean.Syntax.getOp stx 3) none true true let _do_jp : Lean.Expr → Lean.Expr → PUnit → Lean.Elab.TermElabM (Lean.Expr × Lean.Expr) := fun lhs rhs y => pure (lhs, rhs) if Lean.Expr.isAppOfArity lhs `OfNat.ofNat 3 = true then do let a ← liftM (Lean.Meta.inferType rhs) let r ← Lean.Elab.Term.ensureHasType (some a) lhs none let lhs : Lean.Expr := r let y ← pure PUnit.unit _do_jp lhs rhs y else if Lean.Expr.isAppOfArity rhs `OfNat.ofNat 3 = true then do let a ← liftM (Lean.Meta.inferType lhs) let r ← Lean.Elab.Term.ensureHasType (some a) rhs none let rhs : Lean.Expr := r let y ← pure PUnit.unit _do_jp lhs rhs y else do let y ← pure PUnit.unit _do_jp lhs rhs y) true let x : Lean.Expr × Lean.Expr := discr match x with | (lhs, rhs) => do let lhs ← toBoolIfNecessary lhs let rhs ← toBoolIfNecessary rhs let lhsType ← liftM (Lean.Meta.inferType lhs) let rhsType ← liftM (Lean.Meta.inferType rhs) let _do_jp : Lean.Expr × Lean.Expr → Lean.Elab.TermElabM Lean.Expr := fun discr => let x := discr; match x with | (lhs, rhs) => Lean.Elab.Term.elabAppArgs f #[] #[Lean.Elab.Term.Arg.expr lhs, Lean.Elab.Term.Arg.expr rhs] expectedType? false false let y ← tryCatch (do let a ← Lean.withRef (Lean.Syntax.getOp stx 3) (Lean.Elab.Term.ensureHasType (some lhsType) rhs none) pure (lhs, a)) fun x => tryCatch (do let a ← Lean.withRef (Lean.Syntax.getOp stx 2) (Lean.Elab.Term.ensureHasType (some rhsType) lhs none) pure (a, rhs)) fun x => do Lean.Elab.Term.SavedState.restore s false let lhs ← Lean.Elab.Term.elabTerm (Lean.Syntax.getOp stx 2) none true true let rhs ← Lean.Elab.Term.elabTerm (Lean.Syntax.getOp stx 3) none true true let lhsType ← liftM (Lean.Meta.inferType lhs) let _ ← liftM (Lean.Meta.inferType rhs) let a ← Lean.withRef (Lean.Syntax.getOp stx 3) (Lean.Elab.Term.ensureHasType (some lhsType) rhs none) pure (lhs, a) _do_jp y | none => Lean.throwUnknownConstant (Lean.Syntax.getId (Lean.Syntax.getOp stx 1))) (Lean.Elab.Term.elabBinRelCore.toBoolIfNecessary noProp)
Equations
- Lean.Elab.Term.elabBinRelCore.toBoolIfNecessary noProp e = let _do_jp := fun y => pure e; if noProp = true then do let a ← liftM (Lean.Meta.inferType e) let a ← Lean.Meta.withNewMCtxDepth (liftM (Lean.Meta.isDefEq a (Lean.mkSort Lean.levelZero))) if a = true then do let a ← Lean.Elab.Term.ensureHasType (some (Lean.mkConst `Bool)) e none pure a else do let y ← pure PUnit.unit _do_jp y else do let y ← pure PUnit.unit _do_jp y
Equations
- Lean.Elab.Term.elabForIn = (fun getMonad throwFailure stx expectedType? => let discr := stx; if Lean.Syntax.isOfKind discr `Lean.Parser.Term.forInMacro = true then let discr_1 := Lean.Syntax.getArg discr 0; let discr_2 := Lean.Syntax.getArg discr 1; let discr_3 := Lean.Syntax.getArg discr 2; let discr := Lean.Syntax.getArg discr 3; let body := discr; let init := discr_3; let col := discr_2; do let a ← Lean.Elab.Term.isLocalIdent? col match a with | none => do let a ← do let info ← Lean.MonadRef.mkInfoFromRefPos let scp ← Lean.getCurrMacroScope let mainModule ← Lean.getMainModule pure (Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Term.let #[Lean.Syntax.atom info "let", Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Term.letDecl #[Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Term.letIdDecl #[Lean.Syntax.ident info (String.toSubstring "col") (Lean.addMacroScope mainModule `col scp) [], Lean.Syntax.node Lean.SourceInfo.none `null #[], Lean.Syntax.node Lean.SourceInfo.none `null #[], Lean.Syntax.atom info ":=", col]], Lean.Syntax.node Lean.SourceInfo.none `null #[Lean.Syntax.atom info ";"], Lean.Syntax.node Lean.SourceInfo.none `Lean.Parser.Term.forInMacro #[Lean.Syntax.atom info "for_in%", Lean.Syntax.ident info (String.toSubstring "col") (Lean.addMacroScope mainModule `col scp) [], init, body]]) Lean.Elab.Term.elabTerm a expectedType? true true | some colFVar => do Lean.Elab.Term.tryPostponeIfNoneOrMVar expectedType? let m ← getMonad expectedType? let colType ← liftM (Lean.Meta.inferType colFVar) let a ← liftM Lean.Meta.mkFreshLevelMVar let elemType ← liftM (Lean.Meta.mkFreshExprMVar (some (Lean.mkSort (Lean.mkLevelSucc a))) Lean.MetavarKind.natural Lean.Name.anonymous) let _do_jp : Lean.Expr → Lean.Elab.TermElabM Lean.Expr := fun forInInstance => do let a ← liftM (Lean.Meta.trySynthInstance forInInstance none) match a with | Lean.LOption.some val => do let _ ← Lean.getRef let forInFn ← Lean.Elab.Term.mkConst `ForIn.forIn [] Lean.Elab.Term.elabAppArgs forInFn #[] #[Lean.Elab.Term.Arg.stx col, Lean.Elab.Term.Arg.stx init, Lean.Elab.Term.Arg.stx body] expectedType? false false | Lean.LOption.undef => do Lean.Elab.Term.tryPostpone throwFailure forInInstance | Lean.LOption.none => throwFailure forInInstance let y ← tryCatch (liftM (Lean.Meta.mkAppM `ForIn #[m, colType, elemType])) fun ex => do Lean.Elab.Term.tryPostpone Lean.throwError (Lean.toMessageData "failed to construct 'ForIn' instance for collection" ++ Lean.toMessageData (Lean.indentExpr colType) ++ Lean.toMessageData "\nand monad" ++ Lean.toMessageData (Lean.indentExpr m) ++ Lean.toMessageData "") _do_jp y else let discr := stx; Lean.Elab.throwUnsupportedSyntax) Lean.Elab.Term.elabForIn.getMonad Lean.Elab.Term.elabForIn.throwFailure
Equations
- Lean.Elab.Term.elabForIn.getMonad expectedType? = match expectedType? with | none => Lean.throwError (Lean.toMessageData "invalid 'for_in%' notation, expected type is not available") | some expectedType => do let a ← Lean.Elab.Term.isTypeApp? expectedType match a with | some (m, x) => pure m | none => Lean.throwError (Lean.toMessageData "invalid 'for_in%' notation, expected type is not of of the form `M α`" ++ Lean.toMessageData (Lean.indentExpr expectedType) ++ Lean.toMessageData "")
Equations
- Lean.Elab.Term.elabForIn.throwFailure forInInstance = Lean.throwError (Lean.toMessageData "failed to synthesize instance for 'for_in%' notation" ++ Lean.toMessageData (Lean.indentExpr forInInstance) ++ Lean.toMessageData "")
Equations
- Lean.Elab.Term.BinOp.elabBinOp stx expectedType? = do let tree ← Lean.Elab.Term.BinOp.toTree stx let r ← Lean.Elab.Term.BinOp.analyze tree expectedType? let cls : Lean.Name := `Elab.binop let a ← Lean.isTracingEnabledFor cls let _do_jp : Unit → Lean.Elab.TermElabM Lean.Expr := fun y => if (r.hasUncomparable || Option.isNone r.max?) = true then do let result ← Lean.Elab.Term.BinOp.toExpr tree Lean.Elab.Term.ensureHasType expectedType? result none else do let a ← Lean.Elab.Term.BinOp.applyCoe tree (Option.get! r.max?) let result ← Lean.Elab.Term.BinOp.toExpr a let cls : Lean.Name := `Elab.binop let a ← Lean.isTracingEnabledFor cls let _do_jp : Unit → Lean.Elab.TermElabM Lean.Expr := fun y => Lean.Elab.Term.ensureHasType expectedType? result none if a = true then do let y ← Lean.addTrace cls (Lean.toMessageData "result: " ++ Lean.toMessageData result ++ Lean.toMessageData "") _do_jp y else do let y ← pure PUnit.unit _do_jp y if a = true then do let y ← Lean.addTrace cls (Lean.toMessageData "hasUncomparable: " ++ Lean.toMessageData r.hasUncomparable ++ Lean.toMessageData ", maxType: " ++ Lean.toMessageData r.max? ++ Lean.toMessageData "") _do_jp y else do let y ← pure PUnit.unit _do_jp y
Equations
- Lean.Elab.Term.BinOp.elabBinCalc stx expectedType? = let stepStxs := Lean.Syntax.getArgs (Lean.Syntax.getOp stx 1); let proofs := #[]; let types := #[]; do let r ← forIn stepStxs { fst := types, snd := proofs } fun stepStx r => let types := r.fst; let proofs := r.snd; do let type ← Lean.Elab.Term.elabType (Lean.Syntax.getOp stepStx 0) let discr ← liftM (Lean.Elab.Term.BinOp.relation? type) match discr with | some (x, lhs, x_1) => let _do_jp := fun types proofs y => let types := Array.push types type; do let proof ← Lean.Elab.Term.elabTermEnsuringType (Lean.Syntax.getOp stepStx 2) (some type) true true none Lean.Elab.Term.synthesizeSyntheticMVars true false let proofs : Array Lean.Expr := Array.push proofs proof pure PUnit.unit pure (ForInStep.yield { fst := types, snd := proofs }); if Array.size types > 0 then do let discr ← liftM (Lean.Elab.Term.BinOp.relation? (Array.back types)) match discr with | some (x, x_2, prevRhs) => do let a ← liftM (Lean.Meta.isDefEqGuarded lhs prevRhs) if a = true then do let y ← pure PUnit.unit _do_jp types proofs y else do let a ← liftM (Lean.Meta.inferType lhs) let a_1 ← liftM (Lean.Meta.inferType prevRhs) let y ← Lean.throwErrorAt (Lean.Syntax.getOp stepStx 0) (Lean.toMessageData "invalid 'calc' step, left-hand-side is " ++ Lean.toMessageData (Lean.indentD (Lean.toMessageData "" ++ Lean.toMessageData lhs ++ Lean.toMessageData " : " ++ Lean.toMessageData a ++ Lean.toMessageData "")) ++ Lean.toMessageData "\nprevious right-hand-side is" ++ Lean.toMessageData (Lean.indentD (Lean.toMessageData "" ++ Lean.toMessageData prevRhs ++ Lean.toMessageData " : " ++ Lean.toMessageData a_1 ++ Lean.toMessageData "")) ++ Lean.toMessageData "") _do_jp types proofs y | x => do let y ← panicWithPosWithDecl "Lean.Elab.Extra" "Lean.Elab.Term.BinOp.elabBinCalc" 290 56 "unreachable code has been reached" _do_jp types proofs y else do let y ← pure PUnit.unit _do_jp types proofs y | x => do Lean.throwErrorAt (Lean.Syntax.getOp stepStx 0) (Lean.toMessageData "invalid 'calc' step, relation expected" ++ Lean.toMessageData (Lean.indentExpr type) ++ Lean.toMessageData "") pure (ForInStep.yield { fst := types, snd := proofs }) let x : MProd (Array Lean.Expr) (Array Lean.Expr) := r match x with | { fst := types, snd := proofs } => let result := Array.getOp proofs 0; let resultType := Array.getOp types 0; do let r ← let col := { start := 1, stop := Array.size proofs, step := 1 }; forIn col { fst := resultType, snd := result } fun i r => let resultType := r.fst; let result := r.snd; do let discr ← liftM (Lean.Elab.Term.BinOp.relation? resultType) match discr with | some (r, a, b) => do let a_1 ← liftM (Lean.Meta.instantiateMVars (Array.getOp types i)) let discr ← liftM (Lean.Elab.Term.BinOp.relation? a_1) match discr with | some (s, x, c) => do let a_2 ← liftM (Lean.Meta.inferType a) let a_3 ← liftM (Lean.Meta.inferType b) let a_4 ← liftM (Lean.Meta.inferType c) let x : Lean.Expr × Lean.Expr × Lean.Expr := (a_2, a_3, a_4) match x with | (α, β, γ) => do let a_5 ← liftM (Lean.Meta.getLevel α) let a_6 ← liftM (Lean.Meta.getLevel β) let a_7 ← liftM (Lean.Meta.getLevel γ) let x : Lean.Level × Lean.Level × Lean.Level := (a_5, a_6, a_7) match x with | (u_1, u_2, u_3) => do let a_8 ← liftM (Lean.Meta.mkArrow γ (Lean.mkSort Lean.levelZero)) let a_9 ← liftM (Lean.Meta.mkArrow α a_8) let t ← liftM (Lean.Meta.mkFreshExprMVar (some a_9) Lean.MetavarKind.natural Lean.Name.anonymous) let selfType : Lean.Expr := Lean.mkAppN (Lean.mkConst `Trans [u_1, u_2, u_3]) #[α, β, γ, r, s, t] let a_10 ← liftM (Lean.Meta.trySynthInstance selfType none) let _do_jp : Lean.Expr → Lean.Expr → PUnit → Lean.Elab.TermElabM (ForInStep (MProd Lean.Expr Lean.Expr)) := fun resultType result y => do pure () pure (ForInStep.yield { fst := resultType, snd := result }) match a_10 with | Lean.LOption.some self => let result := Lean.mkAppN (Lean.mkConst `Trans.trans [u_1, u_2, u_3]) #[α, β, γ, r, s, t, self, a, b, c, result, Array.getOp proofs i]; do let a ← liftM (Lean.Meta.inferType result) let a ← liftM (Lean.Meta.instantiateMVars a) let resultType : Lean.Expr := Lean.Expr.headBeta a let a ← liftM (Lean.Elab.Term.BinOp.relation? resultType) if Option.isSome a = true then do let y ← pure PUnit.unit _do_jp resultType result y else do let y ← Lean.throwErrorAt (Array.getOp stepStxs i) (Lean.toMessageData "invalid 'calc' step, step result is not a relation" ++ Lean.toMessageData (Lean.indentExpr resultType) ++ Lean.toMessageData "") _do_jp resultType result y | x => do let y ← Lean.throwErrorAt (Array.getOp stepStxs i) (Lean.toMessageData "invalid 'calc' step, failed to synthesize `Trans` instance" ++ Lean.toMessageData (Lean.indentExpr selfType) ++ Lean.toMessageData "") _do_jp resultType result y | x => do panicWithPosWithDecl "Lean.Elab.Extra" "Lean.Elab.Term.BinOp.elabBinCalc" 301 67 "unreachable code has been reached" pure (ForInStep.yield { fst := resultType, snd := result }) | x => do panicWithPosWithDecl "Lean.Elab.Extra" "Lean.Elab.Term.BinOp.elabBinCalc" 300 48 "unreachable code has been reached" pure (ForInStep.yield { fst := resultType, snd := result }) let x : MProd Lean.Expr Lean.Expr := r match x with | { fst := resultType, snd := result } => Lean.Elab.Term.ensureHasType expectedType? result none
Equations
- Lean.Elab.Term.BinOp.elabDefaultOrNonempty stx expectedType? = do Lean.Elab.Term.tryPostponeIfNoneOrMVar expectedType? match expectedType? with | none => Lean.throwError (Lean.toMessageData "invalid 'default_or_ofNonempty%', expected type is not known") | some expectedType => tryCatch (liftM (Lean.Meta.mkDefault expectedType)) fun ex => tryCatch (liftM (Lean.Meta.mkOfNonempty expectedType)) fun x => throw ex