@@ -2125,15 +2125,39 @@ and theorems are (mostly) opaque in Lean. For `Acc.rec`, we may unfold theorems
21252125during type-checking, but we are assuming this is not an issue in practice,
21262126and we are planning to address this issue in the future.
21272127-/
2128- private def subsumesInfo (cinfo₁ cinfo₂ : ConstantInfo) : Bool :=
2128+ private def subsumesInfo (constMap : Std.HashMap Name ConstantInfo) ( cinfo₁ cinfo₂ : ConstantInfo) : Bool :=
21292129 cinfo₁.name == cinfo₂.name &&
21302130 cinfo₁.type == cinfo₂.type &&
21312131 cinfo₁.levelParams == cinfo₂.levelParams &&
21322132 match cinfo₁, cinfo₂ with
21332133 | .thmInfo tval₁, .thmInfo tval₂ => tval₁.all == tval₂.all
21342134 | .thmInfo tval₁, .axiomInfo aval₂ => tval₁.all == [aval₂.name] && !aval₂.isUnsafe
2135- | .axiomInfo aval₁, .axiomInfo aval₂ => aval₁.isUnsafe == aval₂.isUnsafe
2135+ | .axiomInfo aval₁, .axiomInfo aval₂ =>
2136+ -- In this case, we cannot a priori assume that both axioms came from theorems and thus their
2137+ -- former bodies are irrelevant - they could be both from definitions with different bodies
2138+ -- that were used to derive statements that would be contradictory if the axioms were merged.
2139+ -- Thus we do a rough, pure approximation of `Lean.Meta.isProp` that is sufficient for the
2140+ -- restricted types we use for realizable theorems and ensures the former bodies of the two
2141+ -- axioms must be irrelevant after all.
2142+ aval₁.isUnsafe == aval₂.isUnsafe && isPropCheap aval₁.type
21362143 | _, _ => false
2144+ where
2145+ /--
2146+ Check if `ty = ∀ ..., p xs...` and `p : ∀ args..., Prop` where `xs` and `args` are of the same
2147+ length.
2148+ -/
2149+ isPropCheap (ty : Expr) : Bool := Id.run do
2150+ let mut ty := ty
2151+ while ty.isForall do
2152+ let .forallE (body := body) .. := ty | return false
2153+ ty := body
2154+ let .const n .. := ty.getAppFn | return false
2155+ let some decl := constMap[n]? | return false
2156+ let mut p := decl.type
2157+ for _ in 0 ...ty.getAppNumArgs do
2158+ let .forallE (body := body) .. := p | return false
2159+ p := body
2160+ p.isProp
21372161
21382162/--
21392163Constructs environment from `importModulesCore` results.
@@ -2172,9 +2196,9 @@ def finalizeImport (s : ImportState) (imports : Array Import) (opts : Options) (
21722196 privateConstantMap := constantMap'
21732197 if let some cinfoPrev := cinfoPrev? then
21742198 -- Recall that the map has not been modified when `cinfoPrev? = some _`.
2175- if subsumesInfo cinfo cinfoPrev then
2199+ if subsumesInfo privateConstantMap cinfo cinfoPrev then
21762200 privateConstantMap := privateConstantMap.insert cname cinfo
2177- else if !subsumesInfo cinfoPrev cinfo then
2201+ else if !subsumesInfo privateConstantMap cinfoPrev cinfo then
21782202 throwAlreadyImported s const2ModIdx modIdx cname
21792203 const2ModIdx := const2ModIdx.insertIfNew cname modIdx
21802204 if let some data := irData[modIdx]? then
@@ -2189,7 +2213,7 @@ def finalizeImport (s : ImportState) (imports : Array Import) (opts : Options) (
21892213 | (cinfoPrev?, constantMap') =>
21902214 publicConstantMap := constantMap'
21912215 if let some cinfoPrev := cinfoPrev? then
2192- if subsumesInfo cinfo cinfoPrev then
2216+ if subsumesInfo publicConstantMap cinfo cinfoPrev then
21932217 publicConstantMap := publicConstantMap.insert cname cinfo
21942218 -- no need to check for duplicates again, `privateConstMap` should be a superset
21952219
0 commit comments