See #193: We need to be able to extract this info (xlinks to master couplings) from the solution...
so GetNextSolution() needs to deduce Values (=XLinks) for all variables including FORCEDs
and that means they aren't really "forces" if they can change!!
For each one, there needs to be a constraint that doesn't really correspond to any of the existing ones. It only needs to do the coupling (equivalence) check and should already know which X node to check against.
See #170 - If agents are to be able to customise their coupling behaviour, then we need the agent for the master-coupled agent, and a SystemicConstraint for it, and a special mode that says "only check the coupling, and always against this X"
FREE/FORCED as a variable flag will have to go, since the new mode is on constraints themselves. Instead we want FREE/LOCATED on SystemicConstraint. A LOCATED SystemicConstraint:
won't report any child links/variables
is told where it is at about the time of SetForces() presently
won't ever run eg DecidedQuery(), but only run coupling checks.
Note: while distinct pattern links are being supplied as variables (see PopulateForSolver()) and distinct X links are apparently being supplied as Values (see StartCSPSolver()), nothing is being done in SystemicConstraint to constrain couplings, which are now free to be non-equivalent due to the distinct variables. This is bug.
So:
SystemicConstraints should be aware of having multiple incoming pattern links.
For FREE SystemicConstraints, these will consist of exactly one keyer and zero or more residuals
For LOCATED SystemicConstraints, all will be residuals
SystemicConstraint::Test() will NLQ() etc if it has keyer, and then apply coupling restrictions to residuals (if there are any)
The above logic then makes sense: a SystemicConstraint needs to be
LOCATED and will be keyed before the solve, or
FREE, has a keyer, so that it can key itself.
Self-keying triggers NormalLinkedQuery() etc because the keying must be determined valid. Residuals cannot be considered until we have a key, and no further NLQ() is needed for these.
Omitted to mention that the CompareBy flag (LOCATION/EQUIVALENCE) can go
We need to keep Freedom on variables (FREE/FORCED) because of the root x link
but this will now only be set to forced for the root link
SystemicConstraint should be constructed as FULL or COUPLING. FULL implies "keying and residuals; does NLQ()"
A FULL constraint requires, at planning time, the pattern link for the keyer
One day this requirement may disappear but for now we're doing asymmetric coupling restriction and engine must choose a keyer that won't MMAX, see #171
All constraints require their residual plinks as well.
See #193: We need to be able to extract this info (xlinks to master couplings) from the solution...
GetNextSolution()
needs to deduce Values (=XLinks) for all variables including FORCEDsFREE/FORCED as a variable flag will have to go, since the new mode is on constraints themselves. Instead we want FREE/LOCATED on SystemicConstraint. A LOCATED SystemicConstraint:
Note: while distinct pattern links are being supplied as variables (see PopulateForSolver()) and distinct X links are apparently being supplied as Values (see StartCSPSolver()), nothing is being done in SystemicConstraint to constrain couplings, which are now free to be non-equivalent due to the distinct variables. This is bug.
So: