build $let definitions of Boolean symbols as formulas - #885
Open
shalashaska117 wants to merge 2 commits into
Open
build $let definitions of Boolean symbols as formulas#885shalashaska117 wants to merge 2 commits into
shalashaska117 wants to merge 2 commits into
Conversation
endLet passed the bound symbol straight to Term::create. For a $let binding a Boolean symbol that number is a predicate number, so Term::create looked it up in the function part of the signature and read off the end of the stack. Any $let over a Boolean symbol crashed, whether or not it shadowed anything: tff(c,conjecture, $let(p: $o, p := $true, p ) ). Wrap the left hand side as a formula in that case, which is what SMTLIB2::parseLet already does for the same reason.
mezpusz
reviewed
Jul 29, 2026
| @@ -0,0 +1,9 @@ | |||
| % Two Boolean symbols bound in one $let, so endLet builds a definition for each. | |||
Contributor
There was a problem hiding this comment.
What do you mean two Boolean symbols? I see only one.
Contributor
Author
There was a problem hiding this comment.
Sorry, you're right, the first line is wrong because b is a boolean and k is $int, i wrote that both were boolean here but in the next line I correct myself. I was talking about a test that I did for this and placed the wrong line there.
Clarify comments regarding simultaneous Boolean bindings in $let.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #863.
TPTP::endLetbuilt the definition withTerm::create(symbol, args). When the$letbinds a Boolean symbol,symbolis a predicate number, soTerm::createlooked it up in the function half of the signature:Signature::functionAritythen indexed past the end of the function stack. In a debug build it trips the bounds assertion inLib::Stack::operator[], in a release build it segfaults.SMTLIB2::parseLetalready handles this, with a comment about preserving the term-formula boundary, so this makes the TPTP parser do the same thing.Shadowing is not the cause
The issue puts it down to shadowing, and
SWX006_1.pdoes shadowbad,maxandirepeatedly, but shadowing turns out to be irrelevant. This is enough on its own:Any
$letover a Boolean symbol crashes on master, shadowing or not, fresh name or not.SWX006_1.pis just the first problem anyone ran into that contains one.With the fix,
SWX006_1.pgivesSZS status Theorem, which matches its TPTP header, and--show_everything onno longer dies while printing.A separate problem this uncovers
Once the crash is gone,
-newcnf ongives a wrong answer for a conjecture holding two or more Boolean$lets. It reportsCounterSatisfiablefor this theorem:That one predates this change and I have left it alone. NewCNF gets the same shape from the SMT-LIB parser, which has always built Boolean let definitions this way, so it reproduces on master with no parser change at all:
vampire --input_syntax smtlib2 -newcnf onanswersSatisfiable, on master and with this branch alike, where the default clausifier answersUnsatisfiable. A single Boolean$letis fine in both. Worth its own issue, and I am happy to file one with the reduction if that helps.The regression tests below therefore use one Boolean
$letper file, so they pass in all four clausifier configurations instead of encoding the NewCNF bug as expected behaviour.Testing
checks/theory/let-bool.p(nullary) andchecks/theory/let-bool-pred.p(arity 1), each shadowing a global of the same name, both under the default clausifier and-newcnf on, with and without-ile off. All eight combinations giveTheoremwith the fix and segfault without it.checks/theory/let-bool-simultaneous.pcovers two symbols bound in one$let, soendLetbuilds a definition per symbol; on master that one is a sort error rather than a crash.Theoremin default,-newcnf onand-ile off, each a segfault on master: predicate of arity 2, a Boolean$letnested in another one's definition, a Boolean$letunder an outer quantifier whose definition uses the bound variable, a Boolean$letwhose body rebinds the same name again, and two Boolean symbols bound simultaneously.$let(p: !>[A: $tType]: A > $o, ...)and its implicit form$let(p: A > $o, ...). Both are rejected earlier with aUser error, identically on master and on this branch. So theiTypeArgspart of the newargs.size()is not covered by anything I could construct, and I have left that path as it was.checks/sanitypasses, 74 checks, built against Z3 4.14.0.Inferences_HOL_Injectivityfails the same way withParse/TPTP.cppreverted, so it is not from here.theory/let-*.pones. Nothing fires on the new tests.theory/let-tuple-bool.pin default mode does tripShell/LispParser.hpp:109, but it does so on master too: the TPTP parser raises its own "set --newcnf on if using tuples" error, auto mode then falls back to SMT-LIB, and the Lisp parser asserts on the way out. That is presumably whychecks/sanityonly runs the tuple tests with-newcnf on.