build $let definitions of Boolean symbols as formulas - #885
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.
Clarify comments regarding simultaneous Boolean bindings in $let.
|
Sorry for not being able to look at this earlier. My tests suggests that this solves 5 TPTP crashes. Great work! |
|
@shalashaska117 Regarding the issue with |
I will, being Vampire a project so big I thought that issues in non-main branches were not worth being published |
As far as I understand this already affects master when using SMTLIB, but merging this will also affect it when parsing TPTP, right? |
Yes, just it was not exposed |
|
For full closure I ran some tests with |
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.