fix(clone): proof * [-tag] should force (realize) untagged axioms - #1098
fix(clone): proof * [-tag] should force (realize) untagged axioms#1098namasikanam wants to merge 1 commit into
proof * [-tag] should force (realize) untagged axioms#1098Conversation
36150f0 to
70586cc
Compare
|
I don't understand the problem here: gives: |
|
Yeah. This one isn't a soundness issue. I would consider it unexpected that |
|
I'm trying to understand and getting confused. What are the expected behavior of |
As @oskgo said, with your PR, Closing this PR. This is not a soundness issue and this is the desired behavior. |
|
@strub It's the other way around. The current behaviour is that |
proof * [-tag] should not drop untagged axioms
|
I fixed the title, but I'll leave it to @namasikanam to fix the description. Please do check those for accuracy—it helps with triaging and review. This is still not a logical soundness bug, although it may be a "perceptual soundness" issue: the axioms still exist, they are simply not discharged when a reader/reviewer might expect them to be. |
|
Ah yes I tested with this PR binary. |
70586cc to
c7f0721
Compare
`check_evtags` (`ecTheoryReplay.ml`) decided whether an axiom was forced by a bracketed `proof * [-tag]` directive by mapping the directive's tag test over the *axiom's own* tag list `src`. For an untagged axiom `src = []`, the test `List.mem true (List.map _ [])` is `false`, so the axiom was silently NOT forced and the correct default `dfl` was never consulted. A clone could then assume an untagged axiom without proof (e.g. instantiate `FinType.enum_spec` falsely and derive `false`). Fold the directive tags starting from the default `dfl`, testing membership of each directive tag in the axiom's `src`. Untagged axioms now fall back to the default (forced when the bracket list is exclusion-only); positive include lists (`proof * [tag]`) are unaffected, since their default is not-forced. Regression: tests/clone-proofstar-tagdrop.ec (asserts the bracketed clone that dropped the untagged axiom now fails, via the `fail` idiom). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c7f0721 to
1848724
Compare
proof * [-tag] should not drop untagged axiomsproof * [-tag] should force (realize) untagged axioms
|
I've fixed the PR description and commit message. I think it's indeed a soundness issue. Look at the example in the PR description. |
|
Even though it looks like you have an axiom-free proof of false here, you don't actually have one. In your example if you do I like François' term of "perceptual soundness". The logic is still solid, but the presentation is not. |
|
Just to reinforce the point, the following is not a soundness issue. The example in your PR description is that, with a rug placed over the I do dislike the fact that the current behaviour is not what one would expect, which means that we currently expect the user to use |
Summary
clone ... proof * [-tag].leaves untagged axioms as they are. This lets a cloneinstantiate a false instance of an untagged axiom (e.g.
FinType.enum_spec) and derivefalse(see the example below).Root cause
check_evtags(src/ecTheoryReplay.ml) decides whether an axiom is forced by mapping thedirective's tag test over the axiom's own tag list
src. For an untagged axiomsrc = [],List.mem true (List.map _ []) = false, so it is never forced — and the correct default(
dfl) is never consulted.Fix (
src/ecTheoryReplay.ml)Rewrite the tag-matching so the directive is folded starting from the default
dfl, testingmembership of each directive tag in the axiom's
src. Untagged axioms now correctly fallback to the default (forced), while explicit
[-tag]exclusions still apply to taggedaxioms.
Test
tests/clone-proofstar-tagdrop.ec(must-fail): aproof * [-dummy]clone that previouslydropped an untagged axiom is now rejected. Contrast: the no-bracket
proof *form alreadyrejected, confirming this was a genuine drop rather than the by-design "clone assumes its
axioms" behaviour.