Skip to content

fix(clone): proof * [-tag] should not drop untagged axioms - #1098

Open
namasikanam wants to merge 1 commit into
mainfrom
fix/clone-proofstar-tags
Open

fix(clone): proof * [-tag] should not drop untagged axioms#1098
namasikanam wants to merge 1 commit into
mainfrom
fix/clone-proofstar-tags

Conversation

@namasikanam

Copy link
Copy Markdown
Collaborator

Summary

clone ... proof * [tag]. silently drops untagged axioms from the set of obligations it
forces, so a cloned theory's untagged axiom can be assumed without proof. This lets a clone
instantiate a false instance of an untagged axiom (e.g. FinType.enum_spec) and derive
false.

Root cause

check_evtags (src/ecTheoryReplay.ml) decides whether an axiom is forced by mapping the
directive's tag test over the axiom's own tag list src. For an untagged axiom src = [],
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, testing
membership of each directive tag in the axiom's src. Untagged axioms now correctly fall
back to the default (forced), while explicit [-tag] exclusions still apply to tagged
axioms.

Test

tests/ko/clone-proofstar-tagdrop.ec (must-fail): a proof * [-dummy] clone that previously
dropped an untagged axiom is now rejected. Contrast: the no-bracket proof * form already
rejected, confirming this was a genuine drop rather than the by-design "clone assumes its
axioms" behaviour.

`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); explicit `[-tag]` exclusions still apply to tagged axioms.

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>
@namasikanam
namasikanam force-pushed the fix/clone-proofstar-tags branch from 36150f0 to 70586cc Compare August 24, 2026 10:02
@strub

strub commented Aug 24, 2026

Copy link
Copy Markdown
Member

I don't understand the problem here:

require import AllCore.

theory T.
  axiom A : false.
end T.

clone T as U proof * [foo].

print U.

gives:

theory U.
  (* import *) axiom A: false.
end U.

@oskgo

oskgo commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Yeah. This one isn't a soundness issue. I would consider it unexpected that proof * [-foo] excludes not just axioms tagged foo but also those without a tag though.

@namasikanam

Copy link
Copy Markdown
Collaborator Author

I'm trying to understand and getting confused. What are the expected behavior of clone ... proof * [tag] and clone ... proof * [-tag]?

@strub

strub commented Aug 26, 2026

Copy link
Copy Markdown
Member

I'm trying to understand and getting confused. What are the expected behavior of clone ... proof * [tag] and clone ... proof * [-tag]?

  • proof * [tag] -> realize the axioms tagged with foo
  • proof * [-tag] -> realize the axioms not tagged with foo

As @oskgo said, with your PR, proof * [-tag] remove the untagged lemmas from the realization set.

Closing this PR. This is not a soundness issue and this is the desired behavior.

@strub strub closed this Aug 26, 2026
@oskgo

oskgo commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@strub It's the other way around. The current behaviour is that proof * [-tag] excludes the untagged axioms from the realization set. The PR changes it so only the axioms tagged by tag are removed.

@oskgo oskgo reopened this Aug 26, 2026
@fdupress fdupress changed the title fix(clone): proof * [tag] must not drop untagged axioms fix(clone): proof * [-tag] should not drop untagged axioms Aug 26, 2026
@fdupress

Copy link
Copy Markdown
Member

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.

@strub

strub commented Aug 26, 2026

Copy link
Copy Markdown
Member

Ah yes I tested with this PR binary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants