vprover / vampire

The Vampire Theorem Prover
https://vprover.github.io/
Other
283 stars 49 forks source link

Refactoring and Extending Unification with Abstraction #508

Closed joe-hauns closed 7 months ago

joe-hauns commented 9 months ago

Main motivation for this PR was implementing our LPAR23 paper "Refining Unification With Abstraction". In this paper we introduced a new algorithm for unification with abstraction that generalizes the original unification with abstraction (UWA) algorithm, and gives us more control over how and when to perform UWA. For example in the old algorithm when unifying f(a + x + y) with f(b + a) we were only introduce a constraint a + x + y != b + a, while the new algorithm allows introducing the simplified constraint x + y != b straight away. Another example is unifying f(a + x + b) with f(b + a), where we now can straight derive the substitution { x -> 0 }, instead of introducing the constraint a + x + b != b + a. More examples motivation and explanation can be found in the paper.

In order to implement this new algorithm without compromising the performance of ordinary unification there are now two distinct unification algorithms:

Additionally to do unification with abstraction as introduced in the paper we need to be able to create TermSpecs in unification that contain variables of two different variable banks: Say we want to unify x + f(y) <- var bank 0 and
f(y) <- var bank 1 Then an mgu is x -> -f(y/0) + f(y/1) This cannot be directly represented in vampire as our TermSpec can only hold 1 variable bank per term, and not multiple per subterm. So what we want to do instead is introduce two new glue variables varibles G0, G1

G0 -> -f(y)/0
G1 ->  f(y)/1

and return as mgu {x -> G0 + G1, G0 -> -f(y)/0, G1 -> f(y)/1} For this in RobSubstition we introduced a new constant GLUE_INDEX, and helper functions createTerm, and introGlueVariable.

Further quite a lot of tidying/refactoring around substitution trees and how they interface with UWA as well as some library code (e.g. Metaiterators that is being used there) has been done. The main changes are:

quickbeam123 commented 9 months ago

Some randomized testing with discount10 on TPTP:

Master: Expect 8746.846343722325 +/- 11.23557282358998
Branch: Expect 8763.348315603816 +/- 11.218682373124999

So some nice performance improvement!

MichaelRawson commented 9 months ago

Merge conflicts are probably due to my crude USE_ALLOCATOR deletion spree. Thinking about it I should have waited with that until this was in. Oh well - it's probably quite easy to fix @joe-hauns, if I've deleted a USE_ALLOCATOR it can probably go on this branch too unless you have some reason to believe it's worthwhile.

joe-hauns commented 9 months ago

Merge conflicts are probably due to my crude USE_ALLOCATOR deletion spree. Thinking about it I should have waited with that until this was in. Oh well - it's probably quite easy to fix @joe-hauns, if I've deleted a USE_ALLOCATOR it can probably go on this branch too unless you have some reason to believe it's worthwhile.

From my side all USE_ALLOCATOR calls can go. I just put them there to satisfy the old allocator and not get any assertion violations because of that.

quickbeam123 commented 9 months ago

I tried to merge master in, to start a new round of tests (some bugs got fixed in master), but the merge felt tricky. Could you please do the merge when you have time?

MichaelRawson commented 9 months ago

From my side all USE_ALLOCATOR calls can go. I just put them there to satisfy the old allocator and not get any assertion violations because of that.

OK - my last deletion round was just the "obviously useless" ones - if you have any objects that are small and frequently allocated you might want to keep it for now otherwise you might dent performance on this branch without meaning to. Of course, the rest can go!