<ahref="var__domination_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aid="l00001"name="l00001"></a><spanclass="lineno"> 1</span><spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aid="l00002"name="l00002"></a><spanclass="lineno"> 2</span><spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aid="l00003"name="l00003"></a><spanclass="lineno"> 3</span><spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aid="l00004"name="l00004"></a><spanclass="lineno"> 4</span><spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aid="l00008"name="l00008"></a><spanclass="lineno"> 8</span><spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aid="l00009"name="l00009"></a><spanclass="lineno"> 9</span><spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aid="l00010"name="l00010"></a><spanclass="lineno"> 10</span><spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aid="l00011"name="l00011"></a><spanclass="lineno"> 11</span><spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aid="l00012"name="l00012"></a><spanclass="lineno"> 12</span><spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aid="l00032"name="l00032"></a><spanclass="lineno"> 32</span><spanclass="comment">// A variable X is say to dominate a variable Y if, from any feasible solution,</span></div>
<divclass="line"><aid="l00033"name="l00033"></a><spanclass="lineno"> 33</span><spanclass="comment">// doing X++ and Y-- is also feasible (modulo the domain of X and Y) and has the</span></div>
<divclass="line"><aid="l00034"name="l00034"></a><spanclass="lineno"> 34</span><spanclass="comment">// same or a better objective value.</span></div>
<divclass="line"><aid="l00036"name="l00036"></a><spanclass="lineno"> 36</span><spanclass="comment">// Note that we also look for dominance between the negation of the variables.</span></div>
<divclass="line"><aid="l00037"name="l00037"></a><spanclass="lineno"> 37</span><spanclass="comment">// So we detect all (X++, Y++), (X--, Y--), (X++, Y--) and (X--, Y++) cases.</span></div>
<divclass="line"><aid="l00038"name="l00038"></a><spanclass="lineno"> 38</span><spanclass="comment">// We reuse both ref / Negated(ref) and translate that to IntegerVariable for</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// Once detected, dominance relation can lead to more propagation. Note however,</span></div>
<divclass="line"><aid="l00042"name="l00042"></a><spanclass="lineno"> 42</span><spanclass="comment">// that we will loose feasible solution that are dominated by better solutions.</span></div>
<divclass="line"><aid="l00043"name="l00043"></a><spanclass="lineno"> 43</span><spanclass="comment">// In particular, in a linear constraint sum coeff * Xi <= rhs with positive</span></div>
<divclass="line"><aid="l00044"name="l00044"></a><spanclass="lineno"> 44</span><spanclass="comment">// coeff, if an X is dominated by a set of other variable in the constraint,</span></div>
<divclass="line"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// then its upper bound can be propagated assuming the dominating variables are</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// at their upper bound. This can in many case result in X being fixed to its</span></div>
<divclass="line"><aid="l00049"name="l00049"></a><spanclass="lineno"> 49</span><spanclass="comment">// TODO(user): We have a lot of benchmarks and tests that shows that we don't</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// report wrong relations, but we lack unit test that make sure we don't miss</span></div>
<divclass="line"><aid="l00051"name="l00051"></a><spanclass="lineno"> 51</span><spanclass="comment">// any. Try to improve the situation.</span></div>
<divclass="line"><aid="l00056"name="l00056"></a><spanclass="lineno"> 56</span><spanclass="comment">// This is the translation used from "ref" to IntegerVariable. The API</span></div>
<divclass="line"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// understand the cp_mode.proto ref, but internally we only store</span></div>
<divclass="line"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// Reset the class to a clean state.</span></div>
<divclass="line"><aid="l00069"name="l00069"></a><spanclass="lineno"> 69</span><spanclass="comment">// At the beginning, we assume that there is no constraint.</span></div>
<divclass="line"><aid="l00072"name="l00072"></a><spanclass="lineno"> 72</span><spanclass="comment">// These functions are used to encode all of our constraints.</span></div>
<divclass="line"><aid="l00073"name="l00073"></a><spanclass="lineno"> 73</span><spanclass="comment">// The algorithm work in two passes, so one should do:</span></div>
<divclass="line"><aid="l00074"name="l00074"></a><spanclass="lineno"> 74</span><spanclass="comment">// - 1/ Convert all problem constraints to one or more calls</span></div>
<divclass="line"><aid="l00076"name="l00076"></a><spanclass="lineno"> 76</span><spanclass="comment">// - 3/ Redo 1. Only the one sided constraint need to be processed again. But</span></div>
<divclass="line"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// calling the others will just do nothing, so it is fine too.</span></div>
<divclass="line"><aid="l00080"name="l00080"></a><spanclass="lineno"> 80</span><spanclass="comment">// The names are pretty self-explanatory. A few linear constraint ex:</span></div>
<divclass="line"><aid="l00081"name="l00081"></a><spanclass="lineno"> 81</span><spanclass="comment">// - To encode terms = cte, one should call ActivityShouldNotChange()</span></div>
<divclass="line"><aid="l00082"name="l00082"></a><spanclass="lineno"> 82</span><spanclass="comment">// - To encode terms >= cte, one should call ActivityShouldNotDecrease()</span></div>
<divclass="line"><aid="l00083"name="l00083"></a><spanclass="lineno"> 83</span><spanclass="comment">// - To encode terms <= cte, one should call ActivityShouldNotIncrease()</span></div>
<divclass="line"><aid="l00085"name="l00085"></a><spanclass="lineno"> 85</span><spanclass="comment">// The coeffs vector can be left empty, in which case all variable are assumed</span></div>
<divclass="line"><aid="l00086"name="l00086"></a><spanclass="lineno"> 86</span><spanclass="comment">// to have the same coefficients. CanOnlyDominateEachOther() is basically the</span></div>
<divclass="line"><aid="l00087"name="l00087"></a><spanclass="lineno"> 87</span><spanclass="comment">// same as ActivityShouldNotChange() without any coefficients.</span></div>
<divclass="line"><aid="l00089"name="l00089"></a><spanclass="lineno"> 89</span><spanclass="comment">// Note(user): It is better complexity wise to first refine the underlying</span></div>
<divclass="line"><aid="l00090"name="l00090"></a><spanclass="lineno"> 90</span><spanclass="comment">// partition as much as possible, and then process all</span></div>
<divclass="line"><aid="l00091"name="l00091"></a><spanclass="lineno"> 91</span><spanclass="comment">// ActivityShouldNotIncrease() and ActivityShouldNotDecrease() in two passes.</span></div>
<divclass="line"><aid="l00092"name="l00092"></a><spanclass="lineno"> 92</span><spanclass="comment">// Experiment with it, it might require changing the API slightly since the</span></div>
<divclass="line"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// increase / decrease functions also refine the partition.</span></div>
<divclass="line"><aid="l00104"name="l00104"></a><spanclass="lineno"> 104</span><spanclass="comment">// EndFirstPhase() must be called once all constraints have been processed</span></div>
<divclass="line"><aid="l00105"name="l00105"></a><spanclass="lineno"> 105</span><spanclass="comment">// once. One then needs to redo the calls to ActivityShouldNotIncrease() and</span></div>
<divclass="line"><aid="l00106"name="l00106"></a><spanclass="lineno"> 106</span><spanclass="comment">// ActivityShouldNotDecrease(). And finally call EndSecondPhase() before</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// querying the domination information.</span></div>
<divclass="line"><aid="l00111"name="l00111"></a><spanclass="lineno"> 111</span><spanclass="comment">// This is true if this variable was never restricted by any call. We can thus</span></div>
<divclass="line"><aid="l00112"name="l00112"></a><spanclass="lineno"> 112</span><spanclass="comment">// fix it to its lower bound.</span></div>
<divclass="line"><aid="l00116"name="l00116"></a><spanclass="lineno"> 116</span><spanclass="comment">// Returns a set of variable dominating the given ones. Note that to keep the</span></div>
<divclass="line"><aid="l00117"name="l00117"></a><spanclass="lineno"> 117</span><spanclass="comment">// algo efficient, this might not include all the possible dominations.</span></div>
<divclass="line"><aid="l00119"name="l00119"></a><spanclass="lineno"> 119</span><spanclass="comment">// Note: we never include as part of the dominating candidate variables that</span></div>
<divclass="line"><aid="l00120"name="l00120"></a><spanclass="lineno"> 120</span><spanclass="comment">// can freely increase.</span></div>
<divclass="line"><aid="l00125"name="l00125"></a><spanclass="lineno"> 125</span><spanclass="comment">// Returns readable string with the possible valid combinations of the form</span></div>
<divclass="line"><aid="l00126"name="l00126"></a><spanclass="lineno"> 126</span><spanclass="comment">// (var++/--, dom++/--) to facilitate debugging.</span></div>
<divclass="line"><aid="l00140"name="l00140"></a><spanclass="lineno"> 140</span><spanclass="comment">// This refine the partition can_dominate_partition_ with the given set.</span></div>
<divclass="line"><aid="l00143"name="l00143"></a><spanclass="lineno"> 143</span><spanclass="comment">// Convert the input from the public API into tmp_ranks_.</span></div>
<divclass="line"><aid="l00150"name="l00150"></a><spanclass="lineno"> 150</span><spanclass="comment">// First phase functions. We will keep for each variable a list of possible</span></div>
<divclass="line"><aid="l00151"name="l00151"></a><spanclass="lineno"> 151</span><spanclass="comment">// candidates which is as short as possible.</span></div>
<divclass="line"><aid="l00157"name="l00157"></a><spanclass="lineno"> 157</span><spanclass="comment">// Second phase function to filter the current candidate lists.</span></div>
<divclass="line"><aid="l00163"name="l00163"></a><spanclass="lineno"> 163</span><spanclass="comment">// Starts at zero on Reset(), move to one on EndFirstPhase() and to 2 on</span></div>
<divclass="line"><aid="l00164"name="l00164"></a><spanclass="lineno"> 164</span><spanclass="comment">// EndSecondPhase(). This is used for debug checks and to control what happen</span></div>
<divclass="line"><aid="l00165"name="l00165"></a><spanclass="lineno"> 165</span><spanclass="comment">// on the constraint processing functions.</span></div>
<divclass="line"><aid="l00168"name="l00168"></a><spanclass="lineno"> 168</span><spanclass="comment">// The variables will be sorted by non-decreasking rank. The rank is also the</span></div>
<divclass="line"><aid="l00169"name="l00169"></a><spanclass="lineno"> 169</span><spanclass="comment">// start of the first variable in tmp_ranks_ with this rank.</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// Note that the rank should be int, but to reuse the same vector when we</span></div>
<divclass="line"><aid="l00172"name="l00172"></a><spanclass="lineno"> 172</span><spanclass="comment">// construct it, we need int64_t. See FillTempRanks().</span></div>
<divclass="line"><aid="l00175"name="l00175"></a><spanclass="lineno"> 175</span><spanclass="comment">// This do not change after EndFirstPhase().</span></div>
<divclass="line"><aid="l00177"name="l00177"></a><spanclass="lineno"> 177</span><spanclass="comment">// We will add to the Dynamic partion, a set of subset S, each meaning that</span></div>
<divclass="line"><aid="l00178"name="l00178"></a><spanclass="lineno"> 178</span><spanclass="comment">// any variable in S can only dominate or be dominated by another variable in</span></div>
<divclass="line"><aid="l00184"name="l00184"></a><spanclass="lineno"> 184</span><spanclass="comment">// For all one sided constraints, we keep the bitmap of constraint indices</span></div>
<divclass="line"><aid="l00185"name="l00185"></a><spanclass="lineno"> 185</span><spanclass="comment">// modulo 64 that block on the lower side each variable.</span></div>
<divclass="line"><aid="l00193"name="l00193"></a><spanclass="lineno"> 193</span><spanclass="comment">// We don't use absl::Span() because the underlying buffer can be resized.</span></div>
<divclass="line"><aid="l00194"name="l00194"></a><spanclass="lineno"> 194</span><spanclass="comment">// This however serve the same purpose.</span></div>
<divclass="line"><aid="l00200"name="l00200"></a><spanclass="lineno"> 200</span><spanclass="comment">// This hold the first phase best candidate.</span></div>
<divclass="line"><aid="l00201"name="l00201"></a><spanclass="lineno"> 201</span><spanclass="comment">// Warning, the initial candidates span can overlap in the shared_buffer_.</span></div>
<divclass="line"><aid="l00205"name="l00205"></a><spanclass="lineno"> 205</span><spanclass="comment">// This will hold the final result.</span></div>
<divclass="line"><aid="l00206"name="l00206"></a><spanclass="lineno"> 206</span><spanclass="comment">// Buffer with independent content for each vars.</span></div>
<divclass="line"><aid="l00211"name="l00211"></a><spanclass="lineno"> 211</span><spanclass="comment">// This detects variables that can move freely in one direction, or that can</span></div>
<divclass="line"><aid="l00212"name="l00212"></a><spanclass="lineno"> 212</span><spanclass="comment">// move freely as long as their value do not cross a bound.</span></div>
<divclass="line"><aid="l00214"name="l00214"></a><spanclass="lineno"> 214</span><spanclass="comment">// TODO(user): This is actually an important step to do before scaling as it can</span></div>
<divclass="line"><aid="l00215"name="l00215"></a><spanclass="lineno"> 215</span><spanclass="comment">// usually reduce really large bounds!</span></div>
<divclass="line"><aid="l00218"name="l00218"></a><spanclass="lineno"> 218</span><spanclass="comment">// Reset the class to a clean state.</span></div>
<divclass="line"><aid="l00219"name="l00219"></a><spanclass="lineno"> 219</span><spanclass="comment">// This must be called before processing the constraints.</span></div>
<divclass="line"><aid="l00226"name="l00226"></a><spanclass="lineno"> 226</span><spanclass="comment">// All constraints should be mapped to one of more call to these functions.</span></div>
<divclass="line"><aid="l00231"name="l00231"></a><spanclass="lineno"> 231</span><spanclass="comment">// Most of the logic here deals with linear constraints.</span></div>
<divclass="line"><aid="l00238"name="l00238"></a><spanclass="lineno"> 238</span><spanclass="comment">// Once ALL constraints have been processed, call this to fix variables or</span></div>
<divclass="line"><aid="l00239"name="l00239"></a><spanclass="lineno"> 239</span><spanclass="comment">// reduce their domain if possible.</span></div>
<divclass="line"><aid="l00241"name="l00241"></a><spanclass="lineno"> 241</span><spanclass="comment">// Note that this also tighten some constraint that are the only one blocking</span></div>
<divclass="line"><aid="l00242"name="l00242"></a><spanclass="lineno"> 242</span><spanclass="comment">// in one direction. Currently we only do that for implication, so that if we</span></div>
<divclass="line"><aid="l00243"name="l00243"></a><spanclass="lineno"> 243</span><spanclass="comment">// have two Booleans such that a + b <= 1 we transform that to = 1 and we</span></div>
<divclass="line"><aid="l00244"name="l00244"></a><spanclass="lineno"> 244</span><spanclass="comment">// remove one variable since we have now an equivalence relation.</span></div>
<divclass="line"><aid="l00247"name="l00247"></a><spanclass="lineno"> 247</span><spanclass="comment">// The given ref can always freely decrease until the returned value.</span></div>
<divclass="line"><aid="l00248"name="l00248"></a><spanclass="lineno"> 248</span><spanclass="comment">// Note that this does not take into account the domain of the variable.</span></div>
<divclass="line"><aid="l00254"name="l00254"></a><spanclass="lineno"> 254</span><spanclass="comment">// We encode proto ref as IntegerVariable for indexing vectors.</span></div>
<divclass="line"><aid="l00260"name="l00260"></a><spanclass="lineno"> 260</span><spanclass="comment">// Starts with kMaxIntegerValue, and decrease as constraints are processed.</span></div>
<divclass="line"><aid="l00263"name="l00263"></a><spanclass="lineno"> 263</span><spanclass="comment">// How many times can_freely_decrease_until_[var] was set by a constraints.</span></div>
<divclass="line"><aid="l00264"name="l00264"></a><spanclass="lineno"> 264</span><spanclass="comment">// If only one constraint is blocking, we can do more presolve.</span></div>
<divclass="line"><aid="l00267"name="l00267"></a><spanclass="lineno"> 267</span><spanclass="comment">// If num_locks_[var] == 1, this will be the unique constraint that block var</span></div>
<divclass="line"><aid="l00268"name="l00268"></a><spanclass="lineno"> 268</span><spanclass="comment">// in this direction. Note that it can be set to -1 if this wasn't recorded.</span></div>
<divclass="line"><aid="l00272"name="l00272"></a><spanclass="lineno"> 272</span><spanclass="comment">// Detect the variable dominance relations within the given model. Note that</span></div>
<divclass="line"><aid="l00273"name="l00273"></a><spanclass="lineno"> 273</span><spanclass="comment">// to avoid doing too much work, we might miss some relations. This does two</span></div>
<divclass="line"><aid="l00274"name="l00274"></a><spanclass="lineno"> 274</span><spanclass="comment">// full scan of the model.</span></div>
<divclass="line"><aid="l00279"name="l00279"></a><spanclass="lineno"> 279</span><spanclass="comment">// Once detected, exploit the dominance relations that appear in the same</span></div>
<divclass="line"><aid="l00280"name="l00280"></a><spanclass="lineno"> 280</span><spanclass="comment">// constraint. This does a full scan of the model.</span></div>
<divclass="line"><aid="l00282"name="l00282"></a><spanclass="lineno"> 282</span><spanclass="comment">// Return false if the problem is infeasible.</span></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_dual_bound_strengthening_html_a9ecedf5a2848b791246943eac3c970bd"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_dual_bound_strengthening.html#a9ecedf5a2848b791246943eac3c970bd">operations_research::sat::DualBoundStrengthening::CannotMove</a></div><divclass="ttdeci">void CannotMove(absl::Span< const int > refs)</div><divclass="ttdef"><b>Definition:</b><ahref="var__domination_8cc_source.html#l00560">var_domination.cc:560</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_dual_bound_strengthening_html_ad16c26465ee937d28e44dbdafb640aee"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_dual_bound_strengthening.html#ad16c26465ee937d28e44dbdafb640aee">operations_research::sat::DualBoundStrengthening::CannotIncrease</a></div><divclass="ttdeci">void CannotIncrease(absl::Span< const int > refs, int ct_index=-1)</div><divclass="ttdef"><b>Definition:</b><ahref="var__domination_8cc_source.html#l00550">var_domination.cc:550</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_dual_bound_strengthening_html_adbbaa71d83a6aabd04fd33913211556e"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_dual_bound_strengthening.html#adbbaa71d83a6aabd04fd33913211556e">operations_research::sat::DualBoundStrengthening::CannotDecrease</a></div><divclass="ttdeci">void CannotDecrease(absl::Span< const int > refs, int ct_index=-1)</div><divclass="ttdef"><b>Definition:</b><ahref="var__domination_8cc_source.html#l00540">var_domination.cc:540</a></div></div>
<divclass="ttc"id="aclassoperations__research_1_1sat_1_1_var_domination_html_a4e3d2a5f5d96d1c22e6e0744a9b8db05"><divclass="ttname"><ahref="classoperations__research_1_1sat_1_1_var_domination.html#a4e3d2a5f5d96d1c22e6e0744a9b8db05">operations_research::sat::VarDomination::IntegerVariableToRef</a></div><divclass="ttdeci">static int IntegerVariableToRef(IntegerVariable var)</div><divclass="ttdef"><b>Definition:</b><ahref="var__domination_8h_source.html#l00063">var_domination.h:63</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>