|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Leonardo de Moura |
| 5 | +-/ |
| 6 | +module |
| 7 | +prelude |
| 8 | +public import Lean.Meta.Tactic.Grind.Order.OrderM |
| 9 | +public import Lean.Meta.Tactic.Grind.Arith.CommRing.RingM |
| 10 | +import Init.Grind.Order |
| 11 | +namespace Lean.Meta.Grind.Order |
| 12 | +/-- |
| 13 | +Returns `declName α leInst isPreorderInst` |
| 14 | +-/ |
| 15 | +def mkLePreorderPrefix (declName : Name) : OrderM Expr := do |
| 16 | + let s ← getStruct |
| 17 | + return mkApp3 (mkConst declName [s.u]) s.type s.leInst s.isPreorderInst |
| 18 | + |
| 19 | +/-- |
| 20 | +Returns `declName α leInst ltInst lawfulOrderLtInst isPreorderInst` |
| 21 | +-/ |
| 22 | +def mkLeLtPrefix (declName : Name) : OrderM Expr := do |
| 23 | + let s ← getStruct |
| 24 | + return mkApp5 (mkConst declName [s.u]) s.type s.leInst s.ltInst?.get! s.lawfulOrderLTInst?.get! s.isPreorderInst |
| 25 | + |
| 26 | +/-- |
| 27 | +Returns `declName α leInst ltInst lawfulOrderLtInst isPreorderInst ringInst ordRingInst` |
| 28 | +-/ |
| 29 | +def mkOrdRingPrefix (declName : Name) : OrderM Expr := do |
| 30 | + let s ← getStruct |
| 31 | + let h ← mkLeLtPrefix declName |
| 32 | + return mkApp2 h s.ringInst?.get! s.orderedRingInst?.get! |
| 33 | + |
| 34 | +/-- |
| 35 | +Assume `p₁` is `{ w := u, k := k₁, proof := p₁ }` and `p₂` is `{ w := w, k := k₂, proof := p₂ }` |
| 36 | +`p₁` is the proof for edge `u → w` and `p₂` the proof for edge `w -> v`. |
| 37 | +Then, this function returns a proof for edge `u -> v`. |
| 38 | +
|
| 39 | +Remark: for orders that do not support offsets. |
| 40 | +-/ |
| 41 | +def mkTransCore (p₁ : ProofInfo) (p₂ : ProofInfo) (v : NodeId) : OrderM ProofInfo := do |
| 42 | + let { w := u, k.strict := s₁, proof := h₁, .. } := p₁ |
| 43 | + let { w, k.strict := s₂, proof := h₂, .. } := p₂ |
| 44 | + let h ← match s₁, s₂ with |
| 45 | + | false, false => mkLePreorderPrefix ``Grind.Order.le_trans |
| 46 | + | false, true => mkLeLtPrefix ``Grind.Order.le_lt_trans |
| 47 | + | true, false => mkLeLtPrefix ``Grind.Order.lt_le_trans |
| 48 | + | true, true => mkLeLtPrefix ``Grind.Order.lt_trans |
| 49 | + let ns := (← getStruct).nodes |
| 50 | + let h := mkApp5 h ns[u]! ns[w]! ns[v]! h₁ h₂ |
| 51 | + return { w := p₁.w, k.strict := s₁ || s₂, proof := h } |
| 52 | + |
| 53 | +/-- |
| 54 | +Assume `p₁` is `{ w := u, k := k₁, proof := p₁ }` and `p₂` is `{ w := w, k := k₂, proof := p₂ }` |
| 55 | +`p₁` is the proof for edge `u -(k₁)→ w` and `p₂` the proof for edge `w -(k₂)-> v`. |
| 56 | +Then, this function returns a proof for edge `u -(k₁+k₂) -> v`. |
| 57 | +
|
| 58 | +Remark: for orders that support offsets. |
| 59 | +-/ |
| 60 | +def mkTransOffset (p₁ : ProofInfo) (p₂ : ProofInfo) (v : NodeId) : OrderM ProofInfo := do |
| 61 | + let { w := u, k.k := k₁, k.strict := s₁, proof := h₁, .. } := p₁ |
| 62 | + let { w, k.k := k₂, k.strict := s₂, proof := h₂, .. } := p₂ |
| 63 | + let h ← match s₁, s₂ with |
| 64 | + | false, false => mkOrdRingPrefix ``Grind.Order.le_trans_k |
| 65 | + | false, true => mkOrdRingPrefix ``Grind.Order.le_lt_trans_k |
| 66 | + | true, false => mkOrdRingPrefix ``Grind.Order.lt_le_trans_k |
| 67 | + | true, true => mkOrdRingPrefix ``Grind.Order.lt_trans_k |
| 68 | + let k := k₁ + k₂ |
| 69 | + let ns := (← getStruct).nodes |
| 70 | + let h := mkApp6 h ns[u]! ns[w]! ns[v]! (toExpr k₁) (toExpr k₂) (toExpr k) |
| 71 | + let h := mkApp3 h h₁ h₂ eagerReflBoolTrue |
| 72 | + return { w := p₁.w, k.k := k, k.strict := s₁ || s₂, proof := h } |
| 73 | + |
| 74 | +/-- |
| 75 | +Assume `p₁` is `{ w := u, k := k₁, proof := p₁ }` and `p₂` is `{ w := w, k := k₂, proof := p₂ }` |
| 76 | +`p₁` is the proof for edge `u -(k₁)→ w` and `p₂` the proof for edge `w -(k₂)-> v`. |
| 77 | +Then, this function returns a proof for edge `u -(k₁+k₂) -> v`. |
| 78 | +
|
| 79 | +Remark: if the order does not support offset `k₁` and `k₂` are zero. |
| 80 | +-/ |
| 81 | +public def mkTrans (p₁ : ProofInfo) (p₂ : ProofInfo) (v : NodeId) : OrderM ProofInfo := do |
| 82 | + let s ← getStruct |
| 83 | + if s.orderedRingInst?.isSome then |
| 84 | + mkTransOffset p₁ p₂ v |
| 85 | + else |
| 86 | + mkTransCore p₁ p₂ v |
| 87 | + |
| 88 | +end Lean.Meta.Grind.Order |
0 commit comments