Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context Dependent Piecewise Linear Constraint #422

Merged

Conversation

AleksandarZeljic
Copy link
Collaborator

This PR introduces an implementation of PiecewiseLinearConstraint using
context-dependent (CD) data structures from CVC4, which lazily and automatically
backtrack in sync with the central context object. These data structures
are delicate and require that data stored is safe to memcopy around.

Members are initialized using the initializeCDOs( Context context ) method.
Subclasses need to call initializeDuplicatesCDOs() method in the
duplicateConstraint() method to avoid sharing context-dependent members.
CDOs need not be initialized for pre-processing purposes.

The class uses CDOs to record:

  • _cdConstraintActive
  • _cdPhaseStatus
  • _cdInfeasibleCases

PhaseStatus enumeration is used to keep track of current phase of the
object, as well as to record previously explored phases. This replaces
moving PiecewiseLinearCaseSplits around.

ContextDependentPiecewiseLinearConstraint stores locally which phases have
been explored so far using _cdInfeasibleCases. To communicate with the
search it implements two methods:

  • markInfeasible( PhaseStatus caseId ) - marks explored phase
  • nextFeasibleCase() - obtains next unexplored case if one exists

These methods rely on subclass properly handling:

  • _numCases field, which denotes the number of piecewise linear
    segments the constraint has, initialized by the constructor.
  • getAllCases() virtual method returns all possible phases represented using
    PhaseStatus enumeration. The order of returned cases will determine the
    search order, so this method should implement any search heuristics.

src/engine/ContextDependentPiecewiseLinearConstraint.h Outdated Show resolved Hide resolved
src/engine/ContextDependentPiecewiseLinearConstraint.h Outdated Show resolved Hide resolved
/*
If the constraint's phase has been fixed, get the (valid) case split.
*/
virtual PiecewiseLinearCaseSplit getImpliedCaseSplit() const = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a side note, we said we wanted to change this name, right? Maybe getImpliedCase, to be consistent with getAllCases()?

Copy link
Collaborator Author

@AleksandarZeljic AleksandarZeljic Feb 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I would keep the name as is because there is a distinction in the return type - get*Case(s) all return PhaseStatus enumeration in some form, while this one returns an actual PiecewiseLinearCaseSplit. In the long run this should be the only method to return a PiecewiseLinearCaseSplit.

src/engine/ContextDependentPiecewiseLinearConstraint.h Outdated Show resolved Hide resolved
src/engine/ContextDependentPiecewiseLinearConstraint.h Outdated Show resolved Hide resolved
src/engine/ContextDependentPiecewiseLinearConstraint.h Outdated Show resolved Hide resolved
/*
Returns true if there is only one feasible case remaining.
*/
bool isImplication()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make function const?
Also, we usually do == 1 ad not 1 ==.

Copy link
Collaborator Author

@AleksandarZeljic AleksandarZeljic Feb 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, changed style. The idea is to avoid accidental assignment, but I understand that with our style and reviews this should be unnecessary.

src/engine/ContextDependentPiecewiseLinearConstraint.cpp Outdated Show resolved Hide resolved
src/engine/ContextDependentPiecewiseLinearConstraint.cpp Outdated Show resolved Hide resolved

/*
Returns phaseStatus representing next feasible case.
Returns PHASE_NOT_FIXED if no feasible case exists.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we perhaps add a dedicated sentinel? CONSTRAINT_INFEASIBLE or something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not done that because it would make dealing with Max and Disjunction trickier, but I will see what I can do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was overthinking things, I added a high-valued entry to PhaseStatus enumeration, and updated this method accordingly.

@AleksandarZeljic
Copy link
Collaborator Author

@guykatzz I think I've addressed all the concerns you raised, assuming the check passes, you can take another look. And if everything is fine I will rebase the branch onto master for a merge. Wasn't sure if rebase and force push would lose the review discussion or not.

@AleksandarZeljic AleksandarZeljic self-assigned this Feb 11, 2021
Copy link
Collaborator

@guykatzz guykatzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (but see my one comment)

@AleksandarZeljic AleksandarZeljic merged commit f7cf1a9 into NeuralNetworkVerification:master Feb 13, 2021
@AleksandarZeljic AleksandarZeljic deleted the cdPWLC branch February 13, 2021 00:09
matanost pushed a commit that referenced this pull request Nov 2, 2021
* Add virtual class ContextDependentPiecewiseLinearConstraint

WIP

* Remove virtual methods common to CDPWLC and PWLC

* Add CDPWLC class description

* Remove PhaseStatus enum (already present on master)

* Move cdoCleanup behind initialization methods

* Move simple methods to header, fix comments

* Fix formatting

* Update nextFeasibleCase to match assumptions

* Remove redeclaration of inherited virtual methods that are still virtual

* Add comments

* Update header comment

* Update header description

* Fix comments

* Remove virtual inheritance

* Make debugging methods return const pointers

* Remove empty line

* Make testers consts

* Add virtual to nextFeasibleCase()

* Flip argument order in comparisons with constants

* Fix initialization of _cdConstraintActive

* Fix comparison order for consistency

* Add sentinel value CONSTRAINT_INFEASIBLE to PhaseStatus enum

* Use relative maraboupy path for code coverage

* Fix initialization of _cdPhaseStatus
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.

2 participants