Files
ortools-clone/docs/cpp/cp__model__expand_8cc_source.html
Mizux Seiha 3b81c981c2 Update doc
2022-03-04 00:19:15 +01:00

1764 lines
315 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- HTML header for doxygen 1.8.18-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.3"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>OR-Tools: cp_model_expand.cc Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="styleSheet.tmp.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="orLogo.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">OR-Tools
&#160;<span id="projectnumber">9.3</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.3 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('cp__model__expand_8cc_source.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle"><div class="title">cp_model_expand.cc</div></div>
</div><!--header-->
<div class="contents">
<a href="cp__model__expand_8cc.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a id="l00001" name="l00001"></a><span class="lineno"> 1</span><span class="comment">// Copyright 2010-2021 Google LLC</span></div>
<div class="line"><a id="l00002" name="l00002"></a><span class="lineno"> 2</span><span class="comment">// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div>
<div class="line"><a id="l00003" name="l00003"></a><span class="lineno"> 3</span><span class="comment">// you may not use this file except in compliance with the License.</span></div>
<div class="line"><a id="l00004" name="l00004"></a><span class="lineno"> 4</span><span class="comment">// You may obtain a copy of the License at</span></div>
<div class="line"><a id="l00005" name="l00005"></a><span class="lineno"> 5</span><span class="comment">//</span></div>
<div class="line"><a id="l00006" name="l00006"></a><span class="lineno"> 6</span><span class="comment">// http://www.apache.org/licenses/LICENSE-2.0</span></div>
<div class="line"><a id="l00007" name="l00007"></a><span class="lineno"> 7</span><span class="comment">//</span></div>
<div class="line"><a id="l00008" name="l00008"></a><span class="lineno"> 8</span><span class="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<div class="line"><a id="l00009" name="l00009"></a><span class="lineno"> 9</span><span class="comment">// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div>
<div class="line"><a id="l00010" name="l00010"></a><span class="lineno"> 10</span><span class="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<div class="line"><a id="l00011" name="l00011"></a><span class="lineno"> 11</span><span class="comment">// See the License for the specific language governing permissions and</span></div>
<div class="line"><a id="l00012" name="l00012"></a><span class="lineno"> 12</span><span class="comment">// limitations under the License.</span></div>
<div class="line"><a id="l00013" name="l00013"></a><span class="lineno"> 13</span> </div>
<div class="line"><a id="l00014" name="l00014"></a><span class="lineno"> 14</span><span class="preprocessor">#include &quot;<a class="code" href="cp__model__expand_8h.html">ortools/sat/cp_model_expand.h</a>&quot;</span></div>
<div class="line"><a id="l00015" name="l00015"></a><span class="lineno"> 15</span> </div>
<div class="line"><a id="l00016" name="l00016"></a><span class="lineno"> 16</span><span class="preprocessor">#include &lt;algorithm&gt;</span></div>
<div class="line"><a id="l00017" name="l00017"></a><span class="lineno"> 17</span><span class="preprocessor">#include &lt;cstdint&gt;</span></div>
<div class="line"><a id="l00018" name="l00018"></a><span class="lineno"> 18</span><span class="preprocessor">#include &lt;limits&gt;</span></div>
<div class="line"><a id="l00019" name="l00019"></a><span class="lineno"> 19</span><span class="preprocessor">#include &lt;string&gt;</span></div>
<div class="line"><a id="l00020" name="l00020"></a><span class="lineno"> 20</span><span class="preprocessor">#include &lt;utility&gt;</span></div>
<div class="line"><a id="l00021" name="l00021"></a><span class="lineno"> 21</span><span class="preprocessor">#include &lt;vector&gt;</span></div>
<div class="line"><a id="l00022" name="l00022"></a><span class="lineno"> 22</span> </div>
<div class="line"><a id="l00023" name="l00023"></a><span class="lineno"> 23</span><span class="preprocessor">#include &quot;absl/container/btree_map.h&quot;</span></div>
<div class="line"><a id="l00024" name="l00024"></a><span class="lineno"> 24</span><span class="preprocessor">#include &quot;absl/container/flat_hash_map.h&quot;</span></div>
<div class="line"><a id="l00025" name="l00025"></a><span class="lineno"> 25</span><span class="preprocessor">#include &quot;absl/container/flat_hash_set.h&quot;</span></div>
<div class="line"><a id="l00026" name="l00026"></a><span class="lineno"> 26</span><span class="preprocessor">#include &quot;absl/meta/type_traits.h&quot;</span></div>
<div class="line"><a id="l00027" name="l00027"></a><span class="lineno"> 27</span><span class="preprocessor">#include &quot;absl/strings/str_cat.h&quot;</span></div>
<div class="line"><a id="l00028" name="l00028"></a><span class="lineno"> 28</span><span class="preprocessor">#include &quot;absl/types/span.h&quot;</span></div>
<div class="line"><a id="l00029" name="l00029"></a><span class="lineno"> 29</span><span class="preprocessor">#include &quot;<a class="code" href="integral__types_8h.html">ortools/base/integral_types.h</a>&quot;</span></div>
<div class="line"><a id="l00030" name="l00030"></a><span class="lineno"> 30</span><span class="preprocessor">#include &quot;<a class="code" href="base_2logging_8h.html">ortools/base/logging.h</a>&quot;</span></div>
<div class="line"><a id="l00031" name="l00031"></a><span class="lineno"> 31</span><span class="preprocessor">#include &quot;<a class="code" href="stl__util_8h.html">ortools/base/stl_util.h</a>&quot;</span></div>
<div class="line"><a id="l00032" name="l00032"></a><span class="lineno"> 32</span><span class="preprocessor">#include &quot;<a class="code" href="port_2proto__utils_8h.html">ortools/port/proto_utils.h</a>&quot;</span></div>
<div class="line"><a id="l00033" name="l00033"></a><span class="lineno"> 33</span><span class="preprocessor">#include &quot;ortools/sat/cp_model.pb.h&quot;</span></div>
<div class="line"><a id="l00034" name="l00034"></a><span class="lineno"> 34</span><span class="preprocessor">#include &quot;<a class="code" href="cp__model__utils_8h.html">ortools/sat/cp_model_utils.h</a>&quot;</span></div>
<div class="line"><a id="l00035" name="l00035"></a><span class="lineno"> 35</span><span class="preprocessor">#include &quot;<a class="code" href="presolve__context_8h.html">ortools/sat/presolve_context.h</a>&quot;</span></div>
<div class="line"><a id="l00036" name="l00036"></a><span class="lineno"> 36</span><span class="preprocessor">#include &quot;ortools/sat/sat_parameters.pb.h&quot;</span></div>
<div class="line"><a id="l00037" name="l00037"></a><span class="lineno"> 37</span><span class="preprocessor">#include &quot;<a class="code" href="sat_2util_8h.html">ortools/sat/util.h</a>&quot;</span></div>
<div class="line"><a id="l00038" name="l00038"></a><span class="lineno"> 38</span><span class="preprocessor">#include &quot;<a class="code" href="util_2logging_8h.html">ortools/util/logging.h</a>&quot;</span></div>
<div class="line"><a id="l00039" name="l00039"></a><span class="lineno"> 39</span><span class="preprocessor">#include &quot;<a class="code" href="saturated__arithmetic_8h.html">ortools/util/saturated_arithmetic.h</a>&quot;</span></div>
<div class="line"><a id="l00040" name="l00040"></a><span class="lineno"> 40</span><span class="preprocessor">#include &quot;<a class="code" href="sorted__interval__list_8h.html">ortools/util/sorted_interval_list.h</a>&quot;</span></div>
<div class="line"><a id="l00041" name="l00041"></a><span class="lineno"> 41</span> </div>
<div class="line"><a id="l00042" name="l00042"></a><span class="lineno"> 42</span><span class="keyword">namespace </span><a class="code hl_namespace" href="namespaceoperations__research.html">operations_research</a> {</div>
<div class="line"><a id="l00043" name="l00043"></a><span class="lineno"> 43</span><span class="keyword">namespace </span>sat {</div>
<div class="line"><a id="l00044" name="l00044"></a><span class="lineno"> 44</span><span class="keyword">namespace </span>{</div>
<div class="line"><a id="l00045" name="l00045"></a><span class="lineno"> 45</span> </div>
<div class="line"><a id="l00046" name="l00046"></a><span class="lineno"> 46</span><span class="keywordtype">void</span> ExpandReservoir(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00047" name="l00047"></a><span class="lineno"> 47</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;reservoir().min_level() &gt; <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;reservoir().max_level()) {</div>
<div class="line"><a id="l00048" name="l00048"></a><span class="lineno"> 48</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty level domain in reservoir constraint.&quot;</span>;</div>
<div class="line"><a id="l00049" name="l00049"></a><span class="lineno"> 49</span> <span class="keywordflow">return</span> (<span class="keywordtype">void</span>)<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsUnsat();</div>
<div class="line"><a id="l00050" name="l00050"></a><span class="lineno"> 50</span> }</div>
<div class="line"><a id="l00051" name="l00051"></a><span class="lineno"> 51</span> </div>
<div class="line"><a id="l00052" name="l00052"></a><span class="lineno"> 52</span> <span class="keyword">const</span> ReservoirConstraintProto&amp; reservoir = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;reservoir();</div>
<div class="line"><a id="l00053" name="l00053"></a><span class="lineno"> 53</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_events = reservoir.time_exprs_size();</div>
<div class="line"><a id="l00054" name="l00054"></a><span class="lineno"> 54</span> </div>
<div class="line"><a id="l00055" name="l00055"></a><span class="lineno"> 55</span> <span class="keyword">const</span> <span class="keywordtype">int</span> true_literal = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateConstantVar(1);</div>
<div class="line"><a id="l00056" name="l00056"></a><span class="lineno"> 56</span> </div>
<div class="line"><a id="l00057" name="l00057"></a><span class="lineno"> 57</span> <span class="keyword">const</span> <span class="keyword">auto</span> is_active_literal = [&amp;reservoir, true_literal](<span class="keywordtype">int</span> <a class="code hl_variable" href="local__search_8cc.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>) {</div>
<div class="line"><a id="l00058" name="l00058"></a><span class="lineno"> 58</span> <span class="keywordflow">if</span> (reservoir.active_literals_size() == 0) <span class="keywordflow">return</span> true_literal;</div>
<div class="line"><a id="l00059" name="l00059"></a><span class="lineno"> 59</span> <span class="keywordflow">return</span> reservoir.active_literals(<a class="code hl_variable" href="local__search_8cc.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a>);</div>
<div class="line"><a id="l00060" name="l00060"></a><span class="lineno"> 60</span> };</div>
<div class="line"><a id="l00061" name="l00061"></a><span class="lineno"> 61</span> </div>
<div class="line"><a id="l00062" name="l00062"></a><span class="lineno"> 62</span> <span class="keywordtype">int</span> num_positives = 0;</div>
<div class="line"><a id="l00063" name="l00063"></a><span class="lineno"> 63</span> <span class="keywordtype">int</span> num_negatives = 0;</div>
<div class="line"><a id="l00064" name="l00064"></a><span class="lineno"> 64</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t <a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a> : reservoir.level_changes()) {</div>
<div class="line"><a id="l00065" name="l00065"></a><span class="lineno"> 65</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a> &gt; 0) {</div>
<div class="line"><a id="l00066" name="l00066"></a><span class="lineno"> 66</span> num_positives++;</div>
<div class="line"><a id="l00067" name="l00067"></a><span class="lineno"> 67</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a> &lt; 0) {</div>
<div class="line"><a id="l00068" name="l00068"></a><span class="lineno"> 68</span> num_negatives++;</div>
<div class="line"><a id="l00069" name="l00069"></a><span class="lineno"> 69</span> }</div>
<div class="line"><a id="l00070" name="l00070"></a><span class="lineno"> 70</span> }</div>
<div class="line"><a id="l00071" name="l00071"></a><span class="lineno"> 71</span> </div>
<div class="line"><a id="l00072" name="l00072"></a><span class="lineno"> 72</span> absl::flat_hash_map&lt;std::pair&lt;int, int&gt;, <span class="keywordtype">int</span>&gt; precedence_cache;</div>
<div class="line"><a id="l00073" name="l00073"></a><span class="lineno"> 73</span> </div>
<div class="line"><a id="l00074" name="l00074"></a><span class="lineno"> 74</span> <span class="keywordflow">if</span> (num_positives &gt; 0 &amp;&amp; num_negatives &gt; 0) {</div>
<div class="line"><a id="l00075" name="l00075"></a><span class="lineno"> 75</span> <span class="comment">// Creates Boolean variables equivalent to (start[i] &lt;= start[j]) i != j</span></div>
<div class="line"><a id="l00076" name="l00076"></a><span class="lineno"> 76</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_events - 1; ++i) {</div>
<div class="line"><a id="l00077" name="l00077"></a><span class="lineno"> 77</span> <span class="keyword">const</span> <span class="keywordtype">int</span> active_i = is_active_literal(i);</div>
<div class="line"><a id="l00078" name="l00078"></a><span class="lineno"> 78</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;LiteralIsFalse(active_i)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00079" name="l00079"></a><span class="lineno"> 79</span> <span class="keyword">const</span> LinearExpressionProto&amp; time_i = reservoir.time_exprs(i);</div>
<div class="line"><a id="l00080" name="l00080"></a><span class="lineno"> 80</span> </div>
<div class="line"><a id="l00081" name="l00081"></a><span class="lineno"> 81</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = i + 1; j &lt; num_events; ++j) {</div>
<div class="line"><a id="l00082" name="l00082"></a><span class="lineno"> 82</span> <span class="keyword">const</span> <span class="keywordtype">int</span> active_j = is_active_literal(j);</div>
<div class="line"><a id="l00083" name="l00083"></a><span class="lineno"> 83</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;LiteralIsFalse(active_j)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00084" name="l00084"></a><span class="lineno"> 84</span> <span class="keyword">const</span> LinearExpressionProto&amp; time_j = reservoir.time_exprs(j);</div>
<div class="line"><a id="l00085" name="l00085"></a><span class="lineno"> 85</span> </div>
<div class="line"><a id="l00086" name="l00086"></a><span class="lineno"> 86</span> <span class="keyword">const</span> <span class="keywordtype">int</span> i_lesseq_j = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateReifiedPrecedenceLiteral(</div>
<div class="line"><a id="l00087" name="l00087"></a><span class="lineno"> 87</span> time_i, time_j, active_i, active_j);</div>
<div class="line"><a id="l00088" name="l00088"></a><span class="lineno"> 88</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;mutable_variables(i_lesseq_j)</div>
<div class="line"><a id="l00089" name="l00089"></a><span class="lineno"> 89</span> -&gt;set_name(absl::StrCat(i, <span class="stringliteral">&quot; before &quot;</span>, j));</div>
<div class="line"><a id="l00090" name="l00090"></a><span class="lineno"> 90</span> precedence_cache[{i, j}] = i_lesseq_j;</div>
<div class="line"><a id="l00091" name="l00091"></a><span class="lineno"> 91</span> <span class="keyword">const</span> <span class="keywordtype">int</span> j_lesseq_i = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateReifiedPrecedenceLiteral(</div>
<div class="line"><a id="l00092" name="l00092"></a><span class="lineno"> 92</span> time_j, time_i, active_j, active_i);</div>
<div class="line"><a id="l00093" name="l00093"></a><span class="lineno"> 93</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;mutable_variables(j_lesseq_i)</div>
<div class="line"><a id="l00094" name="l00094"></a><span class="lineno"> 94</span> -&gt;set_name(absl::StrCat(j, <span class="stringliteral">&quot; before &quot;</span>, i));</div>
<div class="line"><a id="l00095" name="l00095"></a><span class="lineno"> 95</span> precedence_cache[{j, i}] = j_lesseq_i;</div>
<div class="line"><a id="l00096" name="l00096"></a><span class="lineno"> 96</span> }</div>
<div class="line"><a id="l00097" name="l00097"></a><span class="lineno"> 97</span> }</div>
<div class="line"><a id="l00098" name="l00098"></a><span class="lineno"> 98</span> </div>
<div class="line"><a id="l00099" name="l00099"></a><span class="lineno"> 99</span> <span class="comment">// Constrains the running level to be consistent at all time_exprs.</span></div>
<div class="line"><a id="l00100" name="l00100"></a><span class="lineno"> 100</span> <span class="comment">// For this we only add a constraint at the time a given demand</span></div>
<div class="line"><a id="l00101" name="l00101"></a><span class="lineno"> 101</span> <span class="comment">// take place. We also have a constraint for time zero if needed</span></div>
<div class="line"><a id="l00102" name="l00102"></a><span class="lineno"> 102</span> <span class="comment">// (added below).</span></div>
<div class="line"><a id="l00103" name="l00103"></a><span class="lineno"> 103</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_events; ++i) {</div>
<div class="line"><a id="l00104" name="l00104"></a><span class="lineno"> 104</span> <span class="keyword">const</span> <span class="keywordtype">int</span> active_i = is_active_literal(i);</div>
<div class="line"><a id="l00105" name="l00105"></a><span class="lineno"> 105</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;LiteralIsFalse(active_i)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00106" name="l00106"></a><span class="lineno"> 106</span> </div>
<div class="line"><a id="l00107" name="l00107"></a><span class="lineno"> 107</span> <span class="comment">// Accumulates level_changes of all predecessors.</span></div>
<div class="line"><a id="l00108" name="l00108"></a><span class="lineno"> 108</span> ConstraintProto* <span class="keyword">const</span> level = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00109" name="l00109"></a><span class="lineno"> 109</span> level-&gt;add_enforcement_literal(active_i);</div>
<div class="line"><a id="l00110" name="l00110"></a><span class="lineno"> 110</span> </div>
<div class="line"><a id="l00111" name="l00111"></a><span class="lineno"> 111</span> <span class="comment">// Add contributions from previous events.</span></div>
<div class="line"><a id="l00112" name="l00112"></a><span class="lineno"> 112</span> int64_t offset = 0;</div>
<div class="line"><a id="l00113" name="l00113"></a><span class="lineno"> 113</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; num_events; ++j) {</div>
<div class="line"><a id="l00114" name="l00114"></a><span class="lineno"> 114</span> <span class="keywordflow">if</span> (i == j) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00115" name="l00115"></a><span class="lineno"> 115</span> <span class="keyword">const</span> <span class="keywordtype">int</span> active_j = is_active_literal(j);</div>
<div class="line"><a id="l00116" name="l00116"></a><span class="lineno"> 116</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;LiteralIsFalse(active_j)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00117" name="l00117"></a><span class="lineno"> 117</span> </div>
<div class="line"><a id="l00118" name="l00118"></a><span class="lineno"> 118</span> <span class="keyword">const</span> <span class="keyword">auto</span> prec_it = precedence_cache.find({j, i});</div>
<div class="line"><a id="l00119" name="l00119"></a><span class="lineno"> 119</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(prec_it != precedence_cache.end());</div>
<div class="line"><a id="l00120" name="l00120"></a><span class="lineno"> 120</span> <span class="keyword">const</span> <span class="keywordtype">int</span> prec_lit = prec_it-&gt;second;</div>
<div class="line"><a id="l00121" name="l00121"></a><span class="lineno"> 121</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a> = reservoir.level_changes(j);</div>
<div class="line"><a id="l00122" name="l00122"></a><span class="lineno"> 122</span> <span class="keywordflow">if</span> (<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a217338425de4389014563f1f24331713">RefIsPositive</a>(prec_lit)) {</div>
<div class="line"><a id="l00123" name="l00123"></a><span class="lineno"> 123</span> level-&gt;mutable_linear()-&gt;add_vars(prec_lit);</div>
<div class="line"><a id="l00124" name="l00124"></a><span class="lineno"> 124</span> level-&gt;mutable_linear()-&gt;add_coeffs(<a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a>);</div>
<div class="line"><a id="l00125" name="l00125"></a><span class="lineno"> 125</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00126" name="l00126"></a><span class="lineno"> 126</span> level-&gt;mutable_linear()-&gt;add_vars(prec_lit);</div>
<div class="line"><a id="l00127" name="l00127"></a><span class="lineno"> 127</span> level-&gt;mutable_linear()-&gt;add_coeffs(-<a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a>);</div>
<div class="line"><a id="l00128" name="l00128"></a><span class="lineno"> 128</span> offset -= <a class="code hl_variable" href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a>;</div>
<div class="line"><a id="l00129" name="l00129"></a><span class="lineno"> 129</span> }</div>
<div class="line"><a id="l00130" name="l00130"></a><span class="lineno"> 130</span> }</div>
<div class="line"><a id="l00131" name="l00131"></a><span class="lineno"> 131</span> </div>
<div class="line"><a id="l00132" name="l00132"></a><span class="lineno"> 132</span> <span class="comment">// Accounts for own demand in the domain of the sum.</span></div>
<div class="line"><a id="l00133" name="l00133"></a><span class="lineno"> 133</span> <span class="keyword">const</span> int64_t demand_i = reservoir.level_changes(i);</div>
<div class="line"><a id="l00134" name="l00134"></a><span class="lineno"> 134</span> level-&gt;mutable_linear()-&gt;add_domain(</div>
<div class="line"><a id="l00135" name="l00135"></a><span class="lineno"> 135</span> <a class="code hl_function" href="namespaceoperations__research.html#a111f44b9b9cf67a8e8d83794ac9f5291">CapAdd</a>(<a class="code hl_function" href="namespaceoperations__research.html#a4a43d435871f16c321861fa5de32df82">CapSub</a>(reservoir.min_level(), demand_i), offset));</div>
<div class="line"><a id="l00136" name="l00136"></a><span class="lineno"> 136</span> level-&gt;mutable_linear()-&gt;add_domain(</div>
<div class="line"><a id="l00137" name="l00137"></a><span class="lineno"> 137</span> <a class="code hl_function" href="namespaceoperations__research.html#a111f44b9b9cf67a8e8d83794ac9f5291">CapAdd</a>(<a class="code hl_function" href="namespaceoperations__research.html#a4a43d435871f16c321861fa5de32df82">CapSub</a>(reservoir.max_level(), demand_i), offset));</div>
<div class="line"><a id="l00138" name="l00138"></a><span class="lineno"> 138</span> }</div>
<div class="line"><a id="l00139" name="l00139"></a><span class="lineno"> 139</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00140" name="l00140"></a><span class="lineno"> 140</span> <span class="comment">// If all level_changes have the same sign, we do not care about the order,</span></div>
<div class="line"><a id="l00141" name="l00141"></a><span class="lineno"> 141</span> <span class="comment">// just the sum.</span></div>
<div class="line"><a id="l00142" name="l00142"></a><span class="lineno"> 142</span> <span class="keyword">auto</span>* <span class="keyword">const</span> sum =</div>
<div class="line"><a id="l00143" name="l00143"></a><span class="lineno"> 143</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_linear();</div>
<div class="line"><a id="l00144" name="l00144"></a><span class="lineno"> 144</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_events; ++i) {</div>
<div class="line"><a id="l00145" name="l00145"></a><span class="lineno"> 145</span> sum-&gt;add_vars(is_active_literal(i));</div>
<div class="line"><a id="l00146" name="l00146"></a><span class="lineno"> 146</span> sum-&gt;add_coeffs(reservoir.level_changes(i));</div>
<div class="line"><a id="l00147" name="l00147"></a><span class="lineno"> 147</span> }</div>
<div class="line"><a id="l00148" name="l00148"></a><span class="lineno"> 148</span> sum-&gt;add_domain(reservoir.min_level());</div>
<div class="line"><a id="l00149" name="l00149"></a><span class="lineno"> 149</span> sum-&gt;add_domain(reservoir.max_level());</div>
<div class="line"><a id="l00150" name="l00150"></a><span class="lineno"> 150</span> }</div>
<div class="line"><a id="l00151" name="l00151"></a><span class="lineno"> 151</span> </div>
<div class="line"><a id="l00152" name="l00152"></a><span class="lineno"> 152</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00153" name="l00153"></a><span class="lineno"> 153</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;reservoir: expanded&quot;</span>);</div>
<div class="line"><a id="l00154" name="l00154"></a><span class="lineno"> 154</span>}</div>
<div class="line"><a id="l00155" name="l00155"></a><span class="lineno"> 155</span> </div>
<div class="line"><a id="l00156" name="l00156"></a><span class="lineno"> 156</span><span class="keywordtype">void</span> ExpandIntMod(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00157" name="l00157"></a><span class="lineno"> 157</span> <span class="keyword">const</span> LinearArgumentProto&amp; int_mod = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;int_mod();</div>
<div class="line"><a id="l00158" name="l00158"></a><span class="lineno"> 158</span> <span class="keyword">const</span> LinearExpressionProto&amp; mod_expr = int_mod.exprs(1);</div>
<div class="line"><a id="l00159" name="l00159"></a><span class="lineno"> 159</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(mod_expr)) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00160" name="l00160"></a><span class="lineno"> 160</span> </div>
<div class="line"><a id="l00161" name="l00161"></a><span class="lineno"> 161</span> <span class="keyword">const</span> LinearExpressionProto&amp; expr = int_mod.exprs(0);</div>
<div class="line"><a id="l00162" name="l00162"></a><span class="lineno"> 162</span> <span class="keyword">const</span> LinearExpressionProto&amp; target_expr = int_mod.target();</div>
<div class="line"><a id="l00163" name="l00163"></a><span class="lineno"> 163</span> </div>
<div class="line"><a id="l00164" name="l00164"></a><span class="lineno"> 164</span> <span class="comment">// We reduce the domain of target_expr to avoid later overflow.</span></div>
<div class="line"><a id="l00165" name="l00165"></a><span class="lineno"> 165</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(</div>
<div class="line"><a id="l00166" name="l00166"></a><span class="lineno"> 166</span> target_expr, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(expr).PositiveModuloBySuperset(</div>
<div class="line"><a id="l00167" name="l00167"></a><span class="lineno"> 167</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(mod_expr)))) {</div>
<div class="line"><a id="l00168" name="l00168"></a><span class="lineno"> 168</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00169" name="l00169"></a><span class="lineno"> 169</span> }</div>
<div class="line"><a id="l00170" name="l00170"></a><span class="lineno"> 170</span> </div>
<div class="line"><a id="l00171" name="l00171"></a><span class="lineno"> 171</span> <span class="comment">// Create a new constraint with the same enforcement as ct.</span></div>
<div class="line"><a id="l00172" name="l00172"></a><span class="lineno"> 172</span> <span class="keyword">auto</span> new_enforced_constraint = [&amp;]() {</div>
<div class="line"><a id="l00173" name="l00173"></a><span class="lineno"> 173</span> ConstraintProto* new_ct = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00174" name="l00174"></a><span class="lineno"> 174</span> *new_ct-&gt;mutable_enforcement_literal() = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;enforcement_literal();</div>
<div class="line"><a id="l00175" name="l00175"></a><span class="lineno"> 175</span> <span class="keywordflow">return</span> new_ct;</div>
<div class="line"><a id="l00176" name="l00176"></a><span class="lineno"> 176</span> };</div>
<div class="line"><a id="l00177" name="l00177"></a><span class="lineno"> 177</span> </div>
<div class="line"><a id="l00178" name="l00178"></a><span class="lineno"> 178</span> <span class="comment">// div_expr = expr / mod_expr.</span></div>
<div class="line"><a id="l00179" name="l00179"></a><span class="lineno"> 179</span> <span class="keyword">const</span> <span class="keywordtype">int</span> div_var = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewIntVar(</div>
<div class="line"><a id="l00180" name="l00180"></a><span class="lineno"> 180</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(expr).PositiveDivisionBySuperset(</div>
<div class="line"><a id="l00181" name="l00181"></a><span class="lineno"> 181</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(mod_expr)));</div>
<div class="line"><a id="l00182" name="l00182"></a><span class="lineno"> 182</span> LinearExpressionProto div_expr;</div>
<div class="line"><a id="l00183" name="l00183"></a><span class="lineno"> 183</span> div_expr.add_vars(div_var);</div>
<div class="line"><a id="l00184" name="l00184"></a><span class="lineno"> 184</span> div_expr.add_coeffs(1);</div>
<div class="line"><a id="l00185" name="l00185"></a><span class="lineno"> 185</span> </div>
<div class="line"><a id="l00186" name="l00186"></a><span class="lineno"> 186</span> LinearArgumentProto* <span class="keyword">const</span> div_proto =</div>
<div class="line"><a id="l00187" name="l00187"></a><span class="lineno"> 187</span> new_enforced_constraint()-&gt;mutable_int_div();</div>
<div class="line"><a id="l00188" name="l00188"></a><span class="lineno"> 188</span> *div_proto-&gt;mutable_target() = div_expr;</div>
<div class="line"><a id="l00189" name="l00189"></a><span class="lineno"> 189</span> *div_proto-&gt;add_exprs() = expr;</div>
<div class="line"><a id="l00190" name="l00190"></a><span class="lineno"> 190</span> *div_proto-&gt;add_exprs() = mod_expr;</div>
<div class="line"><a id="l00191" name="l00191"></a><span class="lineno"> 191</span> </div>
<div class="line"><a id="l00192" name="l00192"></a><span class="lineno"> 192</span> <span class="comment">// Create prod_expr = div_expr * mod_expr.</span></div>
<div class="line"><a id="l00193" name="l00193"></a><span class="lineno"> 193</span> <span class="keyword">const</span> Domain prod_domain =</div>
<div class="line"><a id="l00194" name="l00194"></a><span class="lineno"> 194</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(div_var)</div>
<div class="line"><a id="l00195" name="l00195"></a><span class="lineno"> 195</span> .ContinuousMultiplicationBy(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(mod_expr))</div>
<div class="line"><a id="l00196" name="l00196"></a><span class="lineno"> 196</span> .IntersectionWith(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(expr).AdditionWith(</div>
<div class="line"><a id="l00197" name="l00197"></a><span class="lineno"> 197</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(target_expr).Negation()));</div>
<div class="line"><a id="l00198" name="l00198"></a><span class="lineno"> 198</span> <span class="keyword">const</span> <span class="keywordtype">int</span> prod_var = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewIntVar(prod_domain);</div>
<div class="line"><a id="l00199" name="l00199"></a><span class="lineno"> 199</span> LinearExpressionProto prod_expr;</div>
<div class="line"><a id="l00200" name="l00200"></a><span class="lineno"> 200</span> prod_expr.add_vars(prod_var);</div>
<div class="line"><a id="l00201" name="l00201"></a><span class="lineno"> 201</span> prod_expr.add_coeffs(1);</div>
<div class="line"><a id="l00202" name="l00202"></a><span class="lineno"> 202</span> </div>
<div class="line"><a id="l00203" name="l00203"></a><span class="lineno"> 203</span> LinearArgumentProto* <span class="keyword">const</span> int_prod =</div>
<div class="line"><a id="l00204" name="l00204"></a><span class="lineno"> 204</span> new_enforced_constraint()-&gt;mutable_int_prod();</div>
<div class="line"><a id="l00205" name="l00205"></a><span class="lineno"> 205</span> *int_prod-&gt;mutable_target() = prod_expr;</div>
<div class="line"><a id="l00206" name="l00206"></a><span class="lineno"> 206</span> *int_prod-&gt;add_exprs() = div_expr;</div>
<div class="line"><a id="l00207" name="l00207"></a><span class="lineno"> 207</span> *int_prod-&gt;add_exprs() = mod_expr;</div>
<div class="line"><a id="l00208" name="l00208"></a><span class="lineno"> 208</span> </div>
<div class="line"><a id="l00209" name="l00209"></a><span class="lineno"> 209</span> <span class="comment">// expr - prod_expr = target_expr.</span></div>
<div class="line"><a id="l00210" name="l00210"></a><span class="lineno"> 210</span> LinearConstraintProto* <span class="keyword">const</span> lin =</div>
<div class="line"><a id="l00211" name="l00211"></a><span class="lineno"> 211</span> new_enforced_constraint()-&gt;mutable_linear();</div>
<div class="line"><a id="l00212" name="l00212"></a><span class="lineno"> 212</span> lin-&gt;add_domain(0);</div>
<div class="line"><a id="l00213" name="l00213"></a><span class="lineno"> 213</span> lin-&gt;add_domain(0);</div>
<div class="line"><a id="l00214" name="l00214"></a><span class="lineno"> 214</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(expr, 1, lin);</div>
<div class="line"><a id="l00215" name="l00215"></a><span class="lineno"> 215</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(prod_expr, -1, lin);</div>
<div class="line"><a id="l00216" name="l00216"></a><span class="lineno"> 216</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(target_expr, -1, lin);</div>
<div class="line"><a id="l00217" name="l00217"></a><span class="lineno"> 217</span> </div>
<div class="line"><a id="l00218" name="l00218"></a><span class="lineno"> 218</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00219" name="l00219"></a><span class="lineno"> 219</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;int_mod: expanded&quot;</span>);</div>
<div class="line"><a id="l00220" name="l00220"></a><span class="lineno"> 220</span>}</div>
<div class="line"><a id="l00221" name="l00221"></a><span class="lineno"> 221</span> </div>
<div class="line"><a id="l00222" name="l00222"></a><span class="lineno"> 222</span><span class="comment">// TODO(user): Move this into the presolve instead?</span></div>
<div class="line"><a id="l00223" name="l00223"></a><span class="lineno"> 223</span><span class="keywordtype">void</span> ExpandIntProdWithBoolean(<span class="keywordtype">int</span> bool_ref,</div>
<div class="line"><a id="l00224" name="l00224"></a><span class="lineno"> 224</span> <span class="keyword">const</span> LinearExpressionProto&amp; int_expr,</div>
<div class="line"><a id="l00225" name="l00225"></a><span class="lineno"> 225</span> <span class="keyword">const</span> LinearExpressionProto&amp; product_expr,</div>
<div class="line"><a id="l00226" name="l00226"></a><span class="lineno"> 226</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00227" name="l00227"></a><span class="lineno"> 227</span> ConstraintProto* <span class="keyword">const</span> one = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00228" name="l00228"></a><span class="lineno"> 228</span> one-&gt;add_enforcement_literal(bool_ref);</div>
<div class="line"><a id="l00229" name="l00229"></a><span class="lineno"> 229</span> one-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00230" name="l00230"></a><span class="lineno"> 230</span> one-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00231" name="l00231"></a><span class="lineno"> 231</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(int_expr, 1, one-&gt;mutable_linear());</div>
<div class="line"><a id="l00232" name="l00232"></a><span class="lineno"> 232</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(product_expr, -1,</div>
<div class="line"><a id="l00233" name="l00233"></a><span class="lineno"> 233</span> one-&gt;mutable_linear());</div>
<div class="line"><a id="l00234" name="l00234"></a><span class="lineno"> 234</span> </div>
<div class="line"><a id="l00235" name="l00235"></a><span class="lineno"> 235</span> ConstraintProto* <span class="keyword">const</span> zero = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00236" name="l00236"></a><span class="lineno"> 236</span> zero-&gt;add_enforcement_literal(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(bool_ref));</div>
<div class="line"><a id="l00237" name="l00237"></a><span class="lineno"> 237</span> zero-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00238" name="l00238"></a><span class="lineno"> 238</span> zero-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00239" name="l00239"></a><span class="lineno"> 239</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">AddLinearExpressionToLinearConstraint</a>(product_expr, 1,</div>
<div class="line"><a id="l00240" name="l00240"></a><span class="lineno"> 240</span> zero-&gt;mutable_linear());</div>
<div class="line"><a id="l00241" name="l00241"></a><span class="lineno"> 241</span>}</div>
<div class="line"><a id="l00242" name="l00242"></a><span class="lineno"> 242</span> </div>
<div class="line"><a id="l00243" name="l00243"></a><span class="lineno"> 243</span><span class="keywordtype">void</span> ExpandIntProd(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00244" name="l00244"></a><span class="lineno"> 244</span> <span class="keyword">const</span> LinearArgumentProto&amp; int_prod = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;int_prod();</div>
<div class="line"><a id="l00245" name="l00245"></a><span class="lineno"> 245</span> <span class="keywordflow">if</span> (int_prod.exprs_size() != 2) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00246" name="l00246"></a><span class="lineno"> 246</span> <span class="keyword">const</span> LinearExpressionProto&amp; <a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> = int_prod.exprs(0);</div>
<div class="line"><a id="l00247" name="l00247"></a><span class="lineno"> 247</span> <span class="keyword">const</span> LinearExpressionProto&amp; <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a> = int_prod.exprs(1);</div>
<div class="line"><a id="l00248" name="l00248"></a><span class="lineno"> 248</span> <span class="keyword">const</span> LinearExpressionProto&amp; p = int_prod.target();</div>
<div class="line"><a id="l00249" name="l00249"></a><span class="lineno"> 249</span> <span class="keywordtype">int</span> <a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>;</div>
<div class="line"><a id="l00250" name="l00250"></a><span class="lineno"> 250</span> <span class="keyword">const</span> <span class="keywordtype">bool</span> a_is_literal = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ExpressionIsALiteral(<a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, &amp;<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>);</div>
<div class="line"><a id="l00251" name="l00251"></a><span class="lineno"> 251</span> <span class="keyword">const</span> <span class="keywordtype">bool</span> b_is_literal = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ExpressionIsALiteral(<a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>, &amp;<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>);</div>
<div class="line"><a id="l00252" name="l00252"></a><span class="lineno"> 252</span> </div>
<div class="line"><a id="l00253" name="l00253"></a><span class="lineno"> 253</span> <span class="comment">// We expand if exactly one of {a, b} is a literal. If both are literals, it</span></div>
<div class="line"><a id="l00254" name="l00254"></a><span class="lineno"> 254</span> <span class="comment">// will be presolved into a better version.</span></div>
<div class="line"><a id="l00255" name="l00255"></a><span class="lineno"> 255</span> <span class="keywordflow">if</span> (a_is_literal &amp;&amp; !b_is_literal) {</div>
<div class="line"><a id="l00256" name="l00256"></a><span class="lineno"> 256</span> ExpandIntProdWithBoolean(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>, <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>, p, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00257" name="l00257"></a><span class="lineno"> 257</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00258" name="l00258"></a><span class="lineno"> 258</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;int_prod: expanded product with Boolean var&quot;</span>);</div>
<div class="line"><a id="l00259" name="l00259"></a><span class="lineno"> 259</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (b_is_literal) {</div>
<div class="line"><a id="l00260" name="l00260"></a><span class="lineno"> 260</span> ExpandIntProdWithBoolean(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>, <a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, p, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00261" name="l00261"></a><span class="lineno"> 261</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00262" name="l00262"></a><span class="lineno"> 262</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;int_prod: expanded product with Boolean var&quot;</span>);</div>
<div class="line"><a id="l00263" name="l00263"></a><span class="lineno"> 263</span> }</div>
<div class="line"><a id="l00264" name="l00264"></a><span class="lineno"> 264</span>}</div>
<div class="line"><a id="l00265" name="l00265"></a><span class="lineno"> 265</span> </div>
<div class="line"><a id="l00266" name="l00266"></a><span class="lineno"> 266</span><span class="keywordtype">void</span> ExpandInverse(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00267" name="l00267"></a><span class="lineno"> 267</span> <span class="keyword">const</span> <span class="keyword">auto</span>&amp; f_direct = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;inverse().f_direct();</div>
<div class="line"><a id="l00268" name="l00268"></a><span class="lineno"> 268</span> <span class="keyword">const</span> <span class="keyword">auto</span>&amp; f_inverse = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;inverse().f_inverse();</div>
<div class="line"><a id="l00269" name="l00269"></a><span class="lineno"> 269</span> <span class="keyword">const</span> <span class="keywordtype">int</span> n = f_direct.size();</div>
<div class="line"><a id="l00270" name="l00270"></a><span class="lineno"> 270</span> <a class="code hl_define" href="base_2logging_8h.html#a7c0ce053b28d53aa4eaf3eb7fb71663b">CHECK_EQ</a>(n, f_inverse.size());</div>
<div class="line"><a id="l00271" name="l00271"></a><span class="lineno"> 271</span> </div>
<div class="line"><a id="l00272" name="l00272"></a><span class="lineno"> 272</span> <span class="comment">// Make sure the domains are included in [0, n - 1).</span></div>
<div class="line"><a id="l00273" name="l00273"></a><span class="lineno"> 273</span> <span class="comment">// Note that if a variable and its negation appear, the domains will be set to</span></div>
<div class="line"><a id="l00274" name="l00274"></a><span class="lineno"> 274</span> <span class="comment">// zero here.</span></div>
<div class="line"><a id="l00275" name="l00275"></a><span class="lineno"> 275</span> <span class="comment">//</span></div>
<div class="line"><a id="l00276" name="l00276"></a><span class="lineno"> 276</span> <span class="comment">// TODO(user): Add support for UNSAT at expansion. This should create empty</span></div>
<div class="line"><a id="l00277" name="l00277"></a><span class="lineno"> 277</span> <span class="comment">// domain if UNSAT, so it should still work correctly.</span></div>
<div class="line"><a id="l00278" name="l00278"></a><span class="lineno"> 278</span> absl::flat_hash_set&lt;int&gt; used_variables;</div>
<div class="line"><a id="l00279" name="l00279"></a><span class="lineno"> 279</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> ref : f_direct) {</div>
<div class="line"><a id="l00280" name="l00280"></a><span class="lineno"> 280</span> used_variables.insert(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#acdbc8ad33149d45a6e6fcd8b72fd68ed">PositiveRef</a>(ref));</div>
<div class="line"><a id="l00281" name="l00281"></a><span class="lineno"> 281</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(ref, Domain(0, n - 1))) {</div>
<div class="line"><a id="l00282" name="l00282"></a><span class="lineno"> 282</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty domain for a variable in ExpandInverse()&quot;</span>;</div>
<div class="line"><a id="l00283" name="l00283"></a><span class="lineno"> 283</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00284" name="l00284"></a><span class="lineno"> 284</span> }</div>
<div class="line"><a id="l00285" name="l00285"></a><span class="lineno"> 285</span> }</div>
<div class="line"><a id="l00286" name="l00286"></a><span class="lineno"> 286</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> ref : f_inverse) {</div>
<div class="line"><a id="l00287" name="l00287"></a><span class="lineno"> 287</span> used_variables.insert(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#acdbc8ad33149d45a6e6fcd8b72fd68ed">PositiveRef</a>(ref));</div>
<div class="line"><a id="l00288" name="l00288"></a><span class="lineno"> 288</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(ref, Domain(0, n - 1))) {</div>
<div class="line"><a id="l00289" name="l00289"></a><span class="lineno"> 289</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty domain for a variable in ExpandInverse()&quot;</span>;</div>
<div class="line"><a id="l00290" name="l00290"></a><span class="lineno"> 290</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00291" name="l00291"></a><span class="lineno"> 291</span> }</div>
<div class="line"><a id="l00292" name="l00292"></a><span class="lineno"> 292</span> }</div>
<div class="line"><a id="l00293" name="l00293"></a><span class="lineno"> 293</span> </div>
<div class="line"><a id="l00294" name="l00294"></a><span class="lineno"> 294</span> <span class="comment">// If we have duplicate variables, we make sure the domain are reduced</span></div>
<div class="line"><a id="l00295" name="l00295"></a><span class="lineno"> 295</span> <span class="comment">// as the loop below might not detect incompatibilities.</span></div>
<div class="line"><a id="l00296" name="l00296"></a><span class="lineno"> 296</span> <span class="keywordflow">if</span> (used_variables.size() != 2 * n) {</div>
<div class="line"><a id="l00297" name="l00297"></a><span class="lineno"> 297</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; n; ++i) {</div>
<div class="line"><a id="l00298" name="l00298"></a><span class="lineno"> 298</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; n; ++j) {</div>
<div class="line"><a id="l00299" name="l00299"></a><span class="lineno"> 299</span> <span class="comment">// Note that if we don&#39;t have the same sign, both domain are at zero.</span></div>
<div class="line"><a id="l00300" name="l00300"></a><span class="lineno"> 300</span> <span class="keywordflow">if</span> (<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#acdbc8ad33149d45a6e6fcd8b72fd68ed">PositiveRef</a>(f_direct[i]) != <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#acdbc8ad33149d45a6e6fcd8b72fd68ed">PositiveRef</a>(f_inverse[j])) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00301" name="l00301"></a><span class="lineno"> 301</span> </div>
<div class="line"><a id="l00302" name="l00302"></a><span class="lineno"> 302</span> <span class="comment">// We can&#39;t have i or j as value if i != j.</span></div>
<div class="line"><a id="l00303" name="l00303"></a><span class="lineno"> 303</span> <span class="keywordflow">if</span> (i == j) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00304" name="l00304"></a><span class="lineno"> 304</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(</div>
<div class="line"><a id="l00305" name="l00305"></a><span class="lineno"> 305</span> f_direct[i], <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>({i, j}).<a class="code hl_function" href="classoperations__research_1_1_domain.html#a1f1de3874966a137f140748498f43e0c">Complement</a>())) {</div>
<div class="line"><a id="l00306" name="l00306"></a><span class="lineno"> 306</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00307" name="l00307"></a><span class="lineno"> 307</span> }</div>
<div class="line"><a id="l00308" name="l00308"></a><span class="lineno"> 308</span> }</div>
<div class="line"><a id="l00309" name="l00309"></a><span class="lineno"> 309</span> }</div>
<div class="line"><a id="l00310" name="l00310"></a><span class="lineno"> 310</span> }</div>
<div class="line"><a id="l00311" name="l00311"></a><span class="lineno"> 311</span> </div>
<div class="line"><a id="l00312" name="l00312"></a><span class="lineno"> 312</span> <span class="comment">// Reduce the domains of each variable by checking that the inverse value</span></div>
<div class="line"><a id="l00313" name="l00313"></a><span class="lineno"> 313</span> <span class="comment">// exists.</span></div>
<div class="line"><a id="l00314" name="l00314"></a><span class="lineno"> 314</span> std::vector&lt;int64_t&gt; possible_values;</div>
<div class="line"><a id="l00315" name="l00315"></a><span class="lineno"> 315</span> </div>
<div class="line"><a id="l00316" name="l00316"></a><span class="lineno"> 316</span> <span class="comment">// Propagate from one vector to its counterpart.</span></div>
<div class="line"><a id="l00317" name="l00317"></a><span class="lineno"> 317</span> <span class="keyword">const</span> <span class="keyword">auto</span> filter_inverse_domain =</div>
<div class="line"><a id="l00318" name="l00318"></a><span class="lineno"> 318</span> [<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>, n, &amp;possible_values](<span class="keyword">const</span> <span class="keyword">auto</span>&amp; direct, <span class="keyword">const</span> <span class="keyword">auto</span>&amp; inverse) {</div>
<div class="line"><a id="l00319" name="l00319"></a><span class="lineno"> 319</span> <span class="comment">// Propagate from the inverse vector to the direct vector.</span></div>
<div class="line"><a id="l00320" name="l00320"></a><span class="lineno"> 320</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; n; ++i) {</div>
<div class="line"><a id="l00321" name="l00321"></a><span class="lineno"> 321</span> possible_values.clear();</div>
<div class="line"><a id="l00322" name="l00322"></a><span class="lineno"> 322</span> <span class="keyword">const</span> Domain domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(direct[i]);</div>
<div class="line"><a id="l00323" name="l00323"></a><span class="lineno"> 323</span> <span class="keywordtype">bool</span> removed_value = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00324" name="l00324"></a><span class="lineno"> 324</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t j : domain.Values()) {</div>
<div class="line"><a id="l00325" name="l00325"></a><span class="lineno"> 325</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(inverse[j]).Contains(i)) {</div>
<div class="line"><a id="l00326" name="l00326"></a><span class="lineno"> 326</span> possible_values.push_back(j);</div>
<div class="line"><a id="l00327" name="l00327"></a><span class="lineno"> 327</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00328" name="l00328"></a><span class="lineno"> 328</span> removed_value = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00329" name="l00329"></a><span class="lineno"> 329</span> }</div>
<div class="line"><a id="l00330" name="l00330"></a><span class="lineno"> 330</span> }</div>
<div class="line"><a id="l00331" name="l00331"></a><span class="lineno"> 331</span> <span class="keywordflow">if</span> (removed_value) {</div>
<div class="line"><a id="l00332" name="l00332"></a><span class="lineno"> 332</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(</div>
<div class="line"><a id="l00333" name="l00333"></a><span class="lineno"> 333</span> direct[i], <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>(possible_values))) {</div>
<div class="line"><a id="l00334" name="l00334"></a><span class="lineno"> 334</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty domain for a variable in ExpandInverse()&quot;</span>;</div>
<div class="line"><a id="l00335" name="l00335"></a><span class="lineno"> 335</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"><a id="l00336" name="l00336"></a><span class="lineno"> 336</span> }</div>
<div class="line"><a id="l00337" name="l00337"></a><span class="lineno"> 337</span> }</div>
<div class="line"><a id="l00338" name="l00338"></a><span class="lineno"> 338</span> }</div>
<div class="line"><a id="l00339" name="l00339"></a><span class="lineno"> 339</span> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"><a id="l00340" name="l00340"></a><span class="lineno"> 340</span> };</div>
<div class="line"><a id="l00341" name="l00341"></a><span class="lineno"> 341</span> </div>
<div class="line"><a id="l00342" name="l00342"></a><span class="lineno"> 342</span> <span class="comment">// Note that this should reach the fixed point in one pass.</span></div>
<div class="line"><a id="l00343" name="l00343"></a><span class="lineno"> 343</span> <span class="comment">// However, if we have duplicate variable, I am not sure.</span></div>
<div class="line"><a id="l00344" name="l00344"></a><span class="lineno"> 344</span> <span class="keywordflow">if</span> (!filter_inverse_domain(f_direct, f_inverse)) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00345" name="l00345"></a><span class="lineno"> 345</span> <span class="keywordflow">if</span> (!filter_inverse_domain(f_inverse, f_direct)) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00346" name="l00346"></a><span class="lineno"> 346</span> </div>
<div class="line"><a id="l00347" name="l00347"></a><span class="lineno"> 347</span> <span class="comment">// Expand the inverse constraint by associating literal to var == value</span></div>
<div class="line"><a id="l00348" name="l00348"></a><span class="lineno"> 348</span> <span class="comment">// and sharing them between the direct and inverse variables.</span></div>
<div class="line"><a id="l00349" name="l00349"></a><span class="lineno"> 349</span> <span class="comment">//</span></div>
<div class="line"><a id="l00350" name="l00350"></a><span class="lineno"> 350</span> <span class="comment">// Note that this is only correct because the domain are tight now.</span></div>
<div class="line"><a id="l00351" name="l00351"></a><span class="lineno"> 351</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; n; ++i) {</div>
<div class="line"><a id="l00352" name="l00352"></a><span class="lineno"> 352</span> <span class="keyword">const</span> <span class="keywordtype">int</span> f_i = f_direct[i];</div>
<div class="line"><a id="l00353" name="l00353"></a><span class="lineno"> 353</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t j : <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(f_i).Values()) {</div>
<div class="line"><a id="l00354" name="l00354"></a><span class="lineno"> 354</span> <span class="comment">// We have f[i] == j &lt;=&gt; r[j] == i;</span></div>
<div class="line"><a id="l00355" name="l00355"></a><span class="lineno"> 355</span> <span class="keyword">const</span> <span class="keywordtype">int</span> r_j = f_inverse[j];</div>
<div class="line"><a id="l00356" name="l00356"></a><span class="lineno"> 356</span> <span class="keywordtype">int</span> r_j_i;</div>
<div class="line"><a id="l00357" name="l00357"></a><span class="lineno"> 357</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;HasVarValueEncoding(r_j, i, &amp;r_j_i)) {</div>
<div class="line"><a id="l00358" name="l00358"></a><span class="lineno"> 358</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InsertVarValueEncoding(r_j_i, f_i, j);</div>
<div class="line"><a id="l00359" name="l00359"></a><span class="lineno"> 359</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00360" name="l00360"></a><span class="lineno"> 360</span> <span class="keyword">const</span> <span class="keywordtype">int</span> f_i_j = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(f_i, j);</div>
<div class="line"><a id="l00361" name="l00361"></a><span class="lineno"> 361</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InsertVarValueEncoding(f_i_j, r_j, i);</div>
<div class="line"><a id="l00362" name="l00362"></a><span class="lineno"> 362</span> }</div>
<div class="line"><a id="l00363" name="l00363"></a><span class="lineno"> 363</span> }</div>
<div class="line"><a id="l00364" name="l00364"></a><span class="lineno"> 364</span> }</div>
<div class="line"><a id="l00365" name="l00365"></a><span class="lineno"> 365</span> </div>
<div class="line"><a id="l00366" name="l00366"></a><span class="lineno"> 366</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00367" name="l00367"></a><span class="lineno"> 367</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;inverse: expanded&quot;</span>);</div>
<div class="line"><a id="l00368" name="l00368"></a><span class="lineno"> 368</span>}</div>
<div class="line"><a id="l00369" name="l00369"></a><span class="lineno"> 369</span> </div>
<div class="line"><a id="l00370" name="l00370"></a><span class="lineno"> 370</span><span class="comment">// A[V] == V means for all i, V == i =&gt; A_i == i</span></div>
<div class="line"><a id="l00371" name="l00371"></a><span class="lineno"> 371</span><span class="keywordtype">void</span> ExpandElementWithTargetEqualIndex(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>,</div>
<div class="line"><a id="l00372" name="l00372"></a><span class="lineno"> 372</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00373" name="l00373"></a><span class="lineno"> 373</span> <span class="keyword">const</span> ElementConstraintProto&amp; element = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;element();</div>
<div class="line"><a id="l00374" name="l00374"></a><span class="lineno"> 374</span> <a class="code hl_define" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(element.index(), element.target());</div>
<div class="line"><a id="l00375" name="l00375"></a><span class="lineno"> 375</span> </div>
<div class="line"><a id="l00376" name="l00376"></a><span class="lineno"> 376</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_ref = element.index();</div>
<div class="line"><a id="l00377" name="l00377"></a><span class="lineno"> 377</span> std::vector&lt;int64_t&gt; valid_indices;</div>
<div class="line"><a id="l00378" name="l00378"></a><span class="lineno"> 378</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref).Values()) {</div>
<div class="line"><a id="l00379" name="l00379"></a><span class="lineno"> 379</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(element.vars(v), v)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00380" name="l00380"></a><span class="lineno"> 380</span> valid_indices.push_back(v);</div>
<div class="line"><a id="l00381" name="l00381"></a><span class="lineno"> 381</span> }</div>
<div class="line"><a id="l00382" name="l00382"></a><span class="lineno"> 382</span> <span class="keywordflow">if</span> (valid_indices.size() &lt; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref).Size()) {</div>
<div class="line"><a id="l00383" name="l00383"></a><span class="lineno"> 383</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(index_ref,</div>
<div class="line"><a id="l00384" name="l00384"></a><span class="lineno"> 384</span> <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>(valid_indices))) {</div>
<div class="line"><a id="l00385" name="l00385"></a><span class="lineno"> 385</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;No compatible variable domains in &quot;</span></div>
<div class="line"><a id="l00386" name="l00386"></a><span class="lineno"> 386</span> <span class="stringliteral">&quot;ExpandElementWithTargetEqualIndex()&quot;</span>;</div>
<div class="line"><a id="l00387" name="l00387"></a><span class="lineno"> 387</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00388" name="l00388"></a><span class="lineno"> 388</span> }</div>
<div class="line"><a id="l00389" name="l00389"></a><span class="lineno"> 389</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;element: reduced index domain&quot;</span>);</div>
<div class="line"><a id="l00390" name="l00390"></a><span class="lineno"> 390</span> }</div>
<div class="line"><a id="l00391" name="l00391"></a><span class="lineno"> 391</span> </div>
<div class="line"><a id="l00392" name="l00392"></a><span class="lineno"> 392</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref).Values()) {</div>
<div class="line"><a id="l00393" name="l00393"></a><span class="lineno"> 393</span> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a> = element.vars(v);</div>
<div class="line"><a id="l00394" name="l00394"></a><span class="lineno"> 394</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;MinOf(<a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>) == v &amp;&amp; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;MaxOf(<a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>) == v) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00395" name="l00395"></a><span class="lineno"> 395</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplyInDomain(</div>
<div class="line"><a id="l00396" name="l00396"></a><span class="lineno"> 396</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(index_ref, v), <a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>, Domain(v));</div>
<div class="line"><a id="l00397" name="l00397"></a><span class="lineno"> 397</span> }</div>
<div class="line"><a id="l00398" name="l00398"></a><span class="lineno"> 398</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(</div>
<div class="line"><a id="l00399" name="l00399"></a><span class="lineno"> 399</span> <span class="stringliteral">&quot;element: expanded with special case target = index&quot;</span>);</div>
<div class="line"><a id="l00400" name="l00400"></a><span class="lineno"> 400</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00401" name="l00401"></a><span class="lineno"> 401</span>}</div>
<div class="line"><a id="l00402" name="l00402"></a><span class="lineno"> 402</span> </div>
<div class="line"><a id="l00403" name="l00403"></a><span class="lineno"> 403</span><span class="comment">// Special case if the array of the element is filled with constant values.</span></div>
<div class="line"><a id="l00404" name="l00404"></a><span class="lineno"> 404</span><span class="keywordtype">void</span> ExpandConstantArrayElement(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00405" name="l00405"></a><span class="lineno"> 405</span> <span class="keyword">const</span> ElementConstraintProto&amp; element = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;element();</div>
<div class="line"><a id="l00406" name="l00406"></a><span class="lineno"> 406</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_ref = element.index();</div>
<div class="line"><a id="l00407" name="l00407"></a><span class="lineno"> 407</span> <span class="keyword">const</span> <span class="keywordtype">int</span> target_ref = element.target();</div>
<div class="line"><a id="l00408" name="l00408"></a><span class="lineno"> 408</span> </div>
<div class="line"><a id="l00409" name="l00409"></a><span class="lineno"> 409</span> <span class="comment">// Index and target domain have been reduced before calling this function.</span></div>
<div class="line"><a id="l00410" name="l00410"></a><span class="lineno"> 410</span> <span class="keyword">const</span> Domain index_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref);</div>
<div class="line"><a id="l00411" name="l00411"></a><span class="lineno"> 411</span> <span class="keyword">const</span> Domain target_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(target_ref);</div>
<div class="line"><a id="l00412" name="l00412"></a><span class="lineno"> 412</span> </div>
<div class="line"><a id="l00413" name="l00413"></a><span class="lineno"> 413</span> <span class="comment">// This BoolOrs implements the deduction that if all index literals pointing</span></div>
<div class="line"><a id="l00414" name="l00414"></a><span class="lineno"> 414</span> <span class="comment">// to the same value in the constant array are false, then this value is no</span></div>
<div class="line"><a id="l00415" name="l00415"></a><span class="lineno"> 415</span> <span class="comment">// no longer valid for the target variable. They are created only for values</span></div>
<div class="line"><a id="l00416" name="l00416"></a><span class="lineno"> 416</span> <span class="comment">// that have multiples literals supporting them.</span></div>
<div class="line"><a id="l00417" name="l00417"></a><span class="lineno"> 417</span> <span class="comment">// Order is not important.</span></div>
<div class="line"><a id="l00418" name="l00418"></a><span class="lineno"> 418</span> absl::flat_hash_map&lt;int64_t, BoolArgumentProto*&gt; supports;</div>
<div class="line"><a id="l00419" name="l00419"></a><span class="lineno"> 419</span> {</div>
<div class="line"><a id="l00420" name="l00420"></a><span class="lineno"> 420</span> absl::flat_hash_map&lt;int64_t, int&gt; constant_var_values_usage;</div>
<div class="line"><a id="l00421" name="l00421"></a><span class="lineno"> 421</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : index_domain.Values()) {</div>
<div class="line"><a id="l00422" name="l00422"></a><span class="lineno"> 422</span> <a class="code hl_define" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(element.vars(v)));</div>
<div class="line"><a id="l00423" name="l00423"></a><span class="lineno"> 423</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;MinOf(element.vars(v));</div>
<div class="line"><a id="l00424" name="l00424"></a><span class="lineno"> 424</span> <span class="keywordflow">if</span> (++constant_var_values_usage[<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>] == 2) {</div>
<div class="line"><a id="l00425" name="l00425"></a><span class="lineno"> 425</span> <span class="comment">// First time we cross &gt; 1.</span></div>
<div class="line"><a id="l00426" name="l00426"></a><span class="lineno"> 426</span> BoolArgumentProto* <span class="keyword">const</span> support =</div>
<div class="line"><a id="l00427" name="l00427"></a><span class="lineno"> 427</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00428" name="l00428"></a><span class="lineno"> 428</span> <span class="keyword">const</span> <span class="keywordtype">int</span> target_literal =</div>
<div class="line"><a id="l00429" name="l00429"></a><span class="lineno"> 429</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(target_ref, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l00430" name="l00430"></a><span class="lineno"> 430</span> support-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(target_literal));</div>
<div class="line"><a id="l00431" name="l00431"></a><span class="lineno"> 431</span> supports[<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>] = support;</div>
<div class="line"><a id="l00432" name="l00432"></a><span class="lineno"> 432</span> }</div>
<div class="line"><a id="l00433" name="l00433"></a><span class="lineno"> 433</span> }</div>
<div class="line"><a id="l00434" name="l00434"></a><span class="lineno"> 434</span> }</div>
<div class="line"><a id="l00435" name="l00435"></a><span class="lineno"> 435</span> </div>
<div class="line"><a id="l00436" name="l00436"></a><span class="lineno"> 436</span> {</div>
<div class="line"><a id="l00437" name="l00437"></a><span class="lineno"> 437</span> <span class="comment">// While this is not stricly needed since all value in the index will be</span></div>
<div class="line"><a id="l00438" name="l00438"></a><span class="lineno"> 438</span> <span class="comment">// covered, it allows to easily detect this fact in the presolve.</span></div>
<div class="line"><a id="l00439" name="l00439"></a><span class="lineno"> 439</span> <span class="keyword">auto</span>* exactly_one =</div>
<div class="line"><a id="l00440" name="l00440"></a><span class="lineno"> 440</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_exactly_one();</div>
<div class="line"><a id="l00441" name="l00441"></a><span class="lineno"> 441</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : index_domain.Values()) {</div>
<div class="line"><a id="l00442" name="l00442"></a><span class="lineno"> 442</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_literal =</div>
<div class="line"><a id="l00443" name="l00443"></a><span class="lineno"> 443</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(index_ref, v);</div>
<div class="line"><a id="l00444" name="l00444"></a><span class="lineno"> 444</span> exactly_one-&gt;add_literals(index_literal);</div>
<div class="line"><a id="l00445" name="l00445"></a><span class="lineno"> 445</span> </div>
<div class="line"><a id="l00446" name="l00446"></a><span class="lineno"> 446</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;MinOf(element.vars(v));</div>
<div class="line"><a id="l00447" name="l00447"></a><span class="lineno"> 447</span> <span class="keyword">const</span> <span class="keyword">auto</span>&amp; it = supports.find(<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l00448" name="l00448"></a><span class="lineno"> 448</span> <span class="keywordflow">if</span> (it != supports.end()) {</div>
<div class="line"><a id="l00449" name="l00449"></a><span class="lineno"> 449</span> <span class="comment">// The encoding literal for &#39;value&#39; of the target_ref has been</span></div>
<div class="line"><a id="l00450" name="l00450"></a><span class="lineno"> 450</span> <span class="comment">// created before.</span></div>
<div class="line"><a id="l00451" name="l00451"></a><span class="lineno"> 451</span> <span class="keyword">const</span> <span class="keywordtype">int</span> target_literal =</div>
<div class="line"><a id="l00452" name="l00452"></a><span class="lineno"> 452</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(target_ref, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l00453" name="l00453"></a><span class="lineno"> 453</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplication(index_literal, target_literal);</div>
<div class="line"><a id="l00454" name="l00454"></a><span class="lineno"> 454</span> it-&gt;second-&gt;add_literals(index_literal);</div>
<div class="line"><a id="l00455" name="l00455"></a><span class="lineno"> 455</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00456" name="l00456"></a><span class="lineno"> 456</span> <span class="comment">// Try to reuse the literal of the index.</span></div>
<div class="line"><a id="l00457" name="l00457"></a><span class="lineno"> 457</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InsertVarValueEncoding(index_literal, target_ref, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l00458" name="l00458"></a><span class="lineno"> 458</span> }</div>
<div class="line"><a id="l00459" name="l00459"></a><span class="lineno"> 459</span> }</div>
<div class="line"><a id="l00460" name="l00460"></a><span class="lineno"> 460</span> }</div>
<div class="line"><a id="l00461" name="l00461"></a><span class="lineno"> 461</span> </div>
<div class="line"><a id="l00462" name="l00462"></a><span class="lineno"> 462</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;element: expanded value element&quot;</span>);</div>
<div class="line"><a id="l00463" name="l00463"></a><span class="lineno"> 463</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00464" name="l00464"></a><span class="lineno"> 464</span>}</div>
<div class="line"><a id="l00465" name="l00465"></a><span class="lineno"> 465</span> </div>
<div class="line"><a id="l00466" name="l00466"></a><span class="lineno"> 466</span><span class="comment">// General element when the array contains non fixed variables.</span></div>
<div class="line"><a id="l00467" name="l00467"></a><span class="lineno"> 467</span><span class="keywordtype">void</span> ExpandVariableElement(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00468" name="l00468"></a><span class="lineno"> 468</span> <span class="keyword">const</span> ElementConstraintProto&amp; element = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;element();</div>
<div class="line"><a id="l00469" name="l00469"></a><span class="lineno"> 469</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_ref = element.index();</div>
<div class="line"><a id="l00470" name="l00470"></a><span class="lineno"> 470</span> <span class="keyword">const</span> <span class="keywordtype">int</span> target_ref = element.target();</div>
<div class="line"><a id="l00471" name="l00471"></a><span class="lineno"> 471</span> <span class="keyword">const</span> Domain index_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref);</div>
<div class="line"><a id="l00472" name="l00472"></a><span class="lineno"> 472</span> </div>
<div class="line"><a id="l00473" name="l00473"></a><span class="lineno"> 473</span> BoolArgumentProto* bool_or =</div>
<div class="line"><a id="l00474" name="l00474"></a><span class="lineno"> 474</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00475" name="l00475"></a><span class="lineno"> 475</span> </div>
<div class="line"><a id="l00476" name="l00476"></a><span class="lineno"> 476</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : index_domain.Values()) {</div>
<div class="line"><a id="l00477" name="l00477"></a><span class="lineno"> 477</span> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a> = element.vars(v);</div>
<div class="line"><a id="l00478" name="l00478"></a><span class="lineno"> 478</span> <span class="keyword">const</span> Domain var_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(<a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>);</div>
<div class="line"><a id="l00479" name="l00479"></a><span class="lineno"> 479</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_lit = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(index_ref, v);</div>
<div class="line"><a id="l00480" name="l00480"></a><span class="lineno"> 480</span> bool_or-&gt;add_literals(index_lit);</div>
<div class="line"><a id="l00481" name="l00481"></a><span class="lineno"> 481</span> </div>
<div class="line"><a id="l00482" name="l00482"></a><span class="lineno"> 482</span> <span class="keywordflow">if</span> (var_domain.IsFixed()) {</div>
<div class="line"><a id="l00483" name="l00483"></a><span class="lineno"> 483</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplyInDomain(index_lit, target_ref, var_domain);</div>
<div class="line"><a id="l00484" name="l00484"></a><span class="lineno"> 484</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00485" name="l00485"></a><span class="lineno"> 485</span> ConstraintProto* <span class="keyword">const</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00486" name="l00486"></a><span class="lineno"> 486</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;add_enforcement_literal(index_lit);</div>
<div class="line"><a id="l00487" name="l00487"></a><span class="lineno"> 487</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_vars(<a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>);</div>
<div class="line"><a id="l00488" name="l00488"></a><span class="lineno"> 488</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_coeffs(1);</div>
<div class="line"><a id="l00489" name="l00489"></a><span class="lineno"> 489</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_vars(target_ref);</div>
<div class="line"><a id="l00490" name="l00490"></a><span class="lineno"> 490</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_coeffs(-1);</div>
<div class="line"><a id="l00491" name="l00491"></a><span class="lineno"> 491</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00492" name="l00492"></a><span class="lineno"> 492</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_linear()-&gt;add_domain(0);</div>
<div class="line"><a id="l00493" name="l00493"></a><span class="lineno"> 493</span> }</div>
<div class="line"><a id="l00494" name="l00494"></a><span class="lineno"> 494</span> }</div>
<div class="line"><a id="l00495" name="l00495"></a><span class="lineno"> 495</span> </div>
<div class="line"><a id="l00496" name="l00496"></a><span class="lineno"> 496</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;element: expanded&quot;</span>);</div>
<div class="line"><a id="l00497" name="l00497"></a><span class="lineno"> 497</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00498" name="l00498"></a><span class="lineno"> 498</span>}</div>
<div class="line"><a id="l00499" name="l00499"></a><span class="lineno"> 499</span> </div>
<div class="line"><a id="l00500" name="l00500"></a><span class="lineno"> 500</span><span class="keywordtype">void</span> ExpandElement(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00501" name="l00501"></a><span class="lineno"> 501</span> <span class="keyword">const</span> ElementConstraintProto&amp; element = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;element();</div>
<div class="line"><a id="l00502" name="l00502"></a><span class="lineno"> 502</span> </div>
<div class="line"><a id="l00503" name="l00503"></a><span class="lineno"> 503</span> <span class="keyword">const</span> <span class="keywordtype">int</span> index_ref = element.index();</div>
<div class="line"><a id="l00504" name="l00504"></a><span class="lineno"> 504</span> <span class="keyword">const</span> <span class="keywordtype">int</span> target_ref = element.target();</div>
<div class="line"><a id="l00505" name="l00505"></a><span class="lineno"> 505</span> <span class="keyword">const</span> <span class="keywordtype">int</span> size = element.vars_size();</div>
<div class="line"><a id="l00506" name="l00506"></a><span class="lineno"> 506</span> </div>
<div class="line"><a id="l00507" name="l00507"></a><span class="lineno"> 507</span> <span class="comment">// Reduce the domain of the index to be compatible with the array of</span></div>
<div class="line"><a id="l00508" name="l00508"></a><span class="lineno"> 508</span> <span class="comment">// variables. Note that the element constraint is 0 based.</span></div>
<div class="line"><a id="l00509" name="l00509"></a><span class="lineno"> 509</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(index_ref, Domain(0, size - 1))) {</div>
<div class="line"><a id="l00510" name="l00510"></a><span class="lineno"> 510</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty domain for the index variable in ExpandElement()&quot;</span>;</div>
<div class="line"><a id="l00511" name="l00511"></a><span class="lineno"> 511</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00512" name="l00512"></a><span class="lineno"> 512</span> }</div>
<div class="line"><a id="l00513" name="l00513"></a><span class="lineno"> 513</span> </div>
<div class="line"><a id="l00514" name="l00514"></a><span class="lineno"> 514</span> <span class="comment">// Special case when index = target.</span></div>
<div class="line"><a id="l00515" name="l00515"></a><span class="lineno"> 515</span> <span class="keywordflow">if</span> (index_ref == target_ref) {</div>
<div class="line"><a id="l00516" name="l00516"></a><span class="lineno"> 516</span> ExpandElementWithTargetEqualIndex(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00517" name="l00517"></a><span class="lineno"> 517</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00518" name="l00518"></a><span class="lineno"> 518</span> }</div>
<div class="line"><a id="l00519" name="l00519"></a><span class="lineno"> 519</span> </div>
<div class="line"><a id="l00520" name="l00520"></a><span class="lineno"> 520</span> <span class="comment">// Reduces the domain of the index and the target.</span></div>
<div class="line"><a id="l00521" name="l00521"></a><span class="lineno"> 521</span> <span class="keywordtype">bool</span> all_constants = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00522" name="l00522"></a><span class="lineno"> 522</span> std::vector&lt;int64_t&gt; valid_indices;</div>
<div class="line"><a id="l00523" name="l00523"></a><span class="lineno"> 523</span> <span class="keyword">const</span> Domain index_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(index_ref);</div>
<div class="line"><a id="l00524" name="l00524"></a><span class="lineno"> 524</span> <span class="keyword">const</span> Domain target_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(target_ref);</div>
<div class="line"><a id="l00525" name="l00525"></a><span class="lineno"> 525</span> Domain reached_domain;</div>
<div class="line"><a id="l00526" name="l00526"></a><span class="lineno"> 526</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : index_domain.Values()) {</div>
<div class="line"><a id="l00527" name="l00527"></a><span class="lineno"> 527</span> <span class="keyword">const</span> Domain var_domain = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(element.vars(v));</div>
<div class="line"><a id="l00528" name="l00528"></a><span class="lineno"> 528</span> <span class="keywordflow">if</span> (var_domain.IntersectionWith(target_domain).IsEmpty()) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00529" name="l00529"></a><span class="lineno"> 529</span> </div>
<div class="line"><a id="l00530" name="l00530"></a><span class="lineno"> 530</span> valid_indices.push_back(v);</div>
<div class="line"><a id="l00531" name="l00531"></a><span class="lineno"> 531</span> reached_domain = reached_domain.UnionWith(var_domain);</div>
<div class="line"><a id="l00532" name="l00532"></a><span class="lineno"> 532</span> <span class="keywordflow">if</span> (var_domain.Min() != var_domain.Max()) {</div>
<div class="line"><a id="l00533" name="l00533"></a><span class="lineno"> 533</span> all_constants = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00534" name="l00534"></a><span class="lineno"> 534</span> }</div>
<div class="line"><a id="l00535" name="l00535"></a><span class="lineno"> 535</span> }</div>
<div class="line"><a id="l00536" name="l00536"></a><span class="lineno"> 536</span> </div>
<div class="line"><a id="l00537" name="l00537"></a><span class="lineno"> 537</span> <span class="keywordflow">if</span> (valid_indices.size() &lt; index_domain.Size()) {</div>
<div class="line"><a id="l00538" name="l00538"></a><span class="lineno"> 538</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(index_ref,</div>
<div class="line"><a id="l00539" name="l00539"></a><span class="lineno"> 539</span> <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>(valid_indices))) {</div>
<div class="line"><a id="l00540" name="l00540"></a><span class="lineno"> 540</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;No compatible variable domains in ExpandElement()&quot;</span>;</div>
<div class="line"><a id="l00541" name="l00541"></a><span class="lineno"> 541</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00542" name="l00542"></a><span class="lineno"> 542</span> }</div>
<div class="line"><a id="l00543" name="l00543"></a><span class="lineno"> 543</span> </div>
<div class="line"><a id="l00544" name="l00544"></a><span class="lineno"> 544</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;element: reduced index domain&quot;</span>);</div>
<div class="line"><a id="l00545" name="l00545"></a><span class="lineno"> 545</span> }</div>
<div class="line"><a id="l00546" name="l00546"></a><span class="lineno"> 546</span> </div>
<div class="line"><a id="l00547" name="l00547"></a><span class="lineno"> 547</span> <span class="comment">// We know the target_domain is not empty as this would have triggered the</span></div>
<div class="line"><a id="l00548" name="l00548"></a><span class="lineno"> 548</span> <span class="comment">// above check.</span></div>
<div class="line"><a id="l00549" name="l00549"></a><span class="lineno"> 549</span> <span class="keywordtype">bool</span> target_domain_changed = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00550" name="l00550"></a><span class="lineno"> 550</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(target_ref, reached_domain,</div>
<div class="line"><a id="l00551" name="l00551"></a><span class="lineno"> 551</span> &amp;target_domain_changed)) {</div>
<div class="line"><a id="l00552" name="l00552"></a><span class="lineno"> 552</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00553" name="l00553"></a><span class="lineno"> 553</span> }</div>
<div class="line"><a id="l00554" name="l00554"></a><span class="lineno"> 554</span> </div>
<div class="line"><a id="l00555" name="l00555"></a><span class="lineno"> 555</span> <span class="keywordflow">if</span> (target_domain_changed) {</div>
<div class="line"><a id="l00556" name="l00556"></a><span class="lineno"> 556</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;element: reduced target domain&quot;</span>);</div>
<div class="line"><a id="l00557" name="l00557"></a><span class="lineno"> 557</span> }</div>
<div class="line"><a id="l00558" name="l00558"></a><span class="lineno"> 558</span> </div>
<div class="line"><a id="l00559" name="l00559"></a><span class="lineno"> 559</span> <span class="keywordflow">if</span> (all_constants) {</div>
<div class="line"><a id="l00560" name="l00560"></a><span class="lineno"> 560</span> ExpandConstantArrayElement(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00561" name="l00561"></a><span class="lineno"> 561</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00562" name="l00562"></a><span class="lineno"> 562</span> }</div>
<div class="line"><a id="l00563" name="l00563"></a><span class="lineno"> 563</span> </div>
<div class="line"><a id="l00564" name="l00564"></a><span class="lineno"> 564</span> ExpandVariableElement(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00565" name="l00565"></a><span class="lineno"> 565</span>}</div>
<div class="line"><a id="l00566" name="l00566"></a><span class="lineno"> 566</span> </div>
<div class="line"><a id="l00567" name="l00567"></a><span class="lineno"> 567</span><span class="comment">// Adds clauses so that literals[i] true &lt;=&gt; encoding[values[i]] true.</span></div>
<div class="line"><a id="l00568" name="l00568"></a><span class="lineno"> 568</span><span class="comment">// This also implicitly use the fact that exactly one alternative is true.</span></div>
<div class="line"><a id="l00569" name="l00569"></a><span class="lineno"> 569</span><span class="keywordtype">void</span> LinkLiteralsAndValues(<span class="keyword">const</span> std::vector&lt;int&gt;&amp; literals,</div>
<div class="line"><a id="l00570" name="l00570"></a><span class="lineno"> 570</span> <span class="keyword">const</span> std::vector&lt;int64_t&gt;&amp; values,</div>
<div class="line"><a id="l00571" name="l00571"></a><span class="lineno"> 571</span> <span class="keyword">const</span> absl::flat_hash_map&lt;int64_t, int&gt;&amp; encoding,</div>
<div class="line"><a id="l00572" name="l00572"></a><span class="lineno"> 572</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00573" name="l00573"></a><span class="lineno"> 573</span> <a class="code hl_define" href="base_2logging_8h.html#a7c0ce053b28d53aa4eaf3eb7fb71663b">CHECK_EQ</a>(literals.size(), values.size());</div>
<div class="line"><a id="l00574" name="l00574"></a><span class="lineno"> 574</span> </div>
<div class="line"><a id="l00575" name="l00575"></a><span class="lineno"> 575</span> <span class="comment">// We use a map to make this method deterministic.</span></div>
<div class="line"><a id="l00576" name="l00576"></a><span class="lineno"> 576</span> <span class="comment">//</span></div>
<div class="line"><a id="l00577" name="l00577"></a><span class="lineno"> 577</span> <span class="comment">// TODO(user): Make sure this does not appear in the profile. We could use</span></div>
<div class="line"><a id="l00578" name="l00578"></a><span class="lineno"> 578</span> <span class="comment">// the same code as in ProcessOneVariable() otherwise.</span></div>
<div class="line"><a id="l00579" name="l00579"></a><span class="lineno"> 579</span> absl::btree_map&lt;int, std::vector&lt;int&gt;&gt; encoding_lit_to_support;</div>
<div class="line"><a id="l00580" name="l00580"></a><span class="lineno"> 580</span> </div>
<div class="line"><a id="l00581" name="l00581"></a><span class="lineno"> 581</span> <span class="comment">// If a value is false (i.e not possible), then the tuple with this</span></div>
<div class="line"><a id="l00582" name="l00582"></a><span class="lineno"> 582</span> <span class="comment">// value is false too (i.e not possible). Conversely, if the tuple is</span></div>
<div class="line"><a id="l00583" name="l00583"></a><span class="lineno"> 583</span> <span class="comment">// selected, the value must be selected.</span></div>
<div class="line"><a id="l00584" name="l00584"></a><span class="lineno"> 584</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; values.size(); ++i) {</div>
<div class="line"><a id="l00585" name="l00585"></a><span class="lineno"> 585</span> encoding_lit_to_support[encoding.at(values[i])].push_back(literals[i]);</div>
<div class="line"><a id="l00586" name="l00586"></a><span class="lineno"> 586</span> }</div>
<div class="line"><a id="l00587" name="l00587"></a><span class="lineno"> 587</span> </div>
<div class="line"><a id="l00588" name="l00588"></a><span class="lineno"> 588</span> <span class="comment">// If all tuples supporting a value are false, then this value must be</span></div>
<div class="line"><a id="l00589" name="l00589"></a><span class="lineno"> 589</span> <span class="comment">// false.</span></div>
<div class="line"><a id="l00590" name="l00590"></a><span class="lineno"> 590</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; [encoding_lit, support] : encoding_lit_to_support) {</div>
<div class="line"><a id="l00591" name="l00591"></a><span class="lineno"> 591</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(!support.empty());</div>
<div class="line"><a id="l00592" name="l00592"></a><span class="lineno"> 592</span> <span class="keywordflow">if</span> (support.size() == 1) {</div>
<div class="line"><a id="l00593" name="l00593"></a><span class="lineno"> 593</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;StoreBooleanEqualityRelation(encoding_lit, support[0]);</div>
<div class="line"><a id="l00594" name="l00594"></a><span class="lineno"> 594</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00595" name="l00595"></a><span class="lineno"> 595</span> BoolArgumentProto* bool_or =</div>
<div class="line"><a id="l00596" name="l00596"></a><span class="lineno"> 596</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00597" name="l00597"></a><span class="lineno"> 597</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(encoding_lit));</div>
<div class="line"><a id="l00598" name="l00598"></a><span class="lineno"> 598</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> lit : support) {</div>
<div class="line"><a id="l00599" name="l00599"></a><span class="lineno"> 599</span> bool_or-&gt;add_literals(lit);</div>
<div class="line"><a id="l00600" name="l00600"></a><span class="lineno"> 600</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplication(lit, encoding_lit);</div>
<div class="line"><a id="l00601" name="l00601"></a><span class="lineno"> 601</span> }</div>
<div class="line"><a id="l00602" name="l00602"></a><span class="lineno"> 602</span> }</div>
<div class="line"><a id="l00603" name="l00603"></a><span class="lineno"> 603</span> }</div>
<div class="line"><a id="l00604" name="l00604"></a><span class="lineno"> 604</span>}</div>
<div class="line"><a id="l00605" name="l00605"></a><span class="lineno"> 605</span> </div>
<div class="line"><a id="l00606" name="l00606"></a><span class="lineno"> 606</span><span class="comment">// Add the constraint literal =&gt; one_of(encoding[v]), for v in reachable_values.</span></div>
<div class="line"><a id="l00607" name="l00607"></a><span class="lineno"> 607</span><span class="comment">// Note that all possible values are the ones appearing in encoding.</span></div>
<div class="line"><a id="l00608" name="l00608"></a><span class="lineno"> 608</span><span class="keywordtype">void</span> AddImplyInReachableValues(<span class="keywordtype">int</span> <a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>,</div>
<div class="line"><a id="l00609" name="l00609"></a><span class="lineno"> 609</span> std::vector&lt;int64_t&gt;&amp; reachable_values,</div>
<div class="line"><a id="l00610" name="l00610"></a><span class="lineno"> 610</span> <span class="keyword">const</span> absl::flat_hash_map&lt;int64_t, int&gt; encoding,</div>
<div class="line"><a id="l00611" name="l00611"></a><span class="lineno"> 611</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00612" name="l00612"></a><span class="lineno"> 612</span> <a class="code hl_function" href="namespacegtl.html#a288a1dc92da5d3ad62d4bc4cec9e8b1d">gtl::STLSortAndRemoveDuplicates</a>(&amp;reachable_values);</div>
<div class="line"><a id="l00613" name="l00613"></a><span class="lineno"> 613</span> <span class="keywordflow">if</span> (reachable_values.size() == encoding.size()) <span class="keywordflow">return</span>; <span class="comment">// No constraint.</span></div>
<div class="line"><a id="l00614" name="l00614"></a><span class="lineno"> 614</span> <span class="keywordflow">if</span> (reachable_values.size() &lt;= encoding.size() / 2) {</div>
<div class="line"><a id="l00615" name="l00615"></a><span class="lineno"> 615</span> <span class="comment">// Bool or encoding.</span></div>
<div class="line"><a id="l00616" name="l00616"></a><span class="lineno"> 616</span> ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00617" name="l00617"></a><span class="lineno"> 617</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;add_enforcement_literal(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>);</div>
<div class="line"><a id="l00618" name="l00618"></a><span class="lineno"> 618</span> BoolArgumentProto* bool_or = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00619" name="l00619"></a><span class="lineno"> 619</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : reachable_values) {</div>
<div class="line"><a id="l00620" name="l00620"></a><span class="lineno"> 620</span> bool_or-&gt;add_literals(encoding.at(v));</div>
<div class="line"><a id="l00621" name="l00621"></a><span class="lineno"> 621</span> }</div>
<div class="line"><a id="l00622" name="l00622"></a><span class="lineno"> 622</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00623" name="l00623"></a><span class="lineno"> 623</span> <span class="comment">// Bool and encoding.</span></div>
<div class="line"><a id="l00624" name="l00624"></a><span class="lineno"> 624</span> absl::flat_hash_set&lt;int64_t&gt; set(reachable_values.begin(),</div>
<div class="line"><a id="l00625" name="l00625"></a><span class="lineno"> 625</span> reachable_values.end());</div>
<div class="line"><a id="l00626" name="l00626"></a><span class="lineno"> 626</span> ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints();</div>
<div class="line"><a id="l00627" name="l00627"></a><span class="lineno"> 627</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;add_enforcement_literal(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>);</div>
<div class="line"><a id="l00628" name="l00628"></a><span class="lineno"> 628</span> BoolArgumentProto* bool_and = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_bool_and();</div>
<div class="line"><a id="l00629" name="l00629"></a><span class="lineno"> 629</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span> [<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>, <a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>] : encoding) {</div>
<div class="line"><a id="l00630" name="l00630"></a><span class="lineno"> 630</span> <span class="keywordflow">if</span> (!set.contains(<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>)) {</div>
<div class="line"><a id="l00631" name="l00631"></a><span class="lineno"> 631</span> bool_and-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>));</div>
<div class="line"><a id="l00632" name="l00632"></a><span class="lineno"> 632</span> }</div>
<div class="line"><a id="l00633" name="l00633"></a><span class="lineno"> 633</span> }</div>
<div class="line"><a id="l00634" name="l00634"></a><span class="lineno"> 634</span> }</div>
<div class="line"><a id="l00635" name="l00635"></a><span class="lineno"> 635</span>}</div>
<div class="line"><a id="l00636" name="l00636"></a><span class="lineno"> 636</span> </div>
<div class="line"><a id="l00637" name="l00637"></a><span class="lineno"> 637</span><span class="keywordtype">void</span> ExpandAutomaton(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00638" name="l00638"></a><span class="lineno"> 638</span> AutomatonConstraintProto&amp; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a> = *<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_automaton();</div>
<div class="line"><a id="l00639" name="l00639"></a><span class="lineno"> 639</span> </div>
<div class="line"><a id="l00640" name="l00640"></a><span class="lineno"> 640</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.vars_size() == 0) {</div>
<div class="line"><a id="l00641" name="l00641"></a><span class="lineno"> 641</span> <span class="keyword">const</span> int64_t initial_state = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.starting_state();</div>
<div class="line"><a id="l00642" name="l00642"></a><span class="lineno"> 642</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t final_state : <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.final_states()) {</div>
<div class="line"><a id="l00643" name="l00643"></a><span class="lineno"> 643</span> <span class="keywordflow">if</span> (initial_state == final_state) {</div>
<div class="line"><a id="l00644" name="l00644"></a><span class="lineno"> 644</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;automaton: empty and trivially feasible&quot;</span>);</div>
<div class="line"><a id="l00645" name="l00645"></a><span class="lineno"> 645</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00646" name="l00646"></a><span class="lineno"> 646</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00647" name="l00647"></a><span class="lineno"> 647</span> }</div>
<div class="line"><a id="l00648" name="l00648"></a><span class="lineno"> 648</span> }</div>
<div class="line"><a id="l00649" name="l00649"></a><span class="lineno"> 649</span> <span class="keywordflow">return</span> (<span class="keywordtype">void</span>)<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsUnsat(</div>
<div class="line"><a id="l00650" name="l00650"></a><span class="lineno"> 650</span> <span class="stringliteral">&quot;automaton: empty with an initial state not in the final states.&quot;</span>);</div>
<div class="line"><a id="l00651" name="l00651"></a><span class="lineno"> 651</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_label_size() == 0) {</div>
<div class="line"><a id="l00652" name="l00652"></a><span class="lineno"> 652</span> <span class="keywordflow">return</span> (<span class="keywordtype">void</span>)<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsUnsat(</div>
<div class="line"><a id="l00653" name="l00653"></a><span class="lineno"> 653</span> <span class="stringliteral">&quot;automaton: non-empty with no transition.&quot;</span>);</div>
<div class="line"><a id="l00654" name="l00654"></a><span class="lineno"> 654</span> }</div>
<div class="line"><a id="l00655" name="l00655"></a><span class="lineno"> 655</span> </div>
<div class="line"><a id="l00656" name="l00656"></a><span class="lineno"> 656</span> <span class="keyword">const</span> <span class="keywordtype">int</span> n = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.vars_size();</div>
<div class="line"><a id="l00657" name="l00657"></a><span class="lineno"> 657</span> <span class="keyword">const</span> std::vector&lt;int&gt; vars = {<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.vars().begin(), <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.vars().end()};</div>
<div class="line"><a id="l00658" name="l00658"></a><span class="lineno"> 658</span> </div>
<div class="line"><a id="l00659" name="l00659"></a><span class="lineno"> 659</span> <span class="comment">// Compute the set of reachable state at each time point.</span></div>
<div class="line"><a id="l00660" name="l00660"></a><span class="lineno"> 660</span> <span class="keyword">const</span> absl::flat_hash_set&lt;int64_t&gt; final_states(</div>
<div class="line"><a id="l00661" name="l00661"></a><span class="lineno"> 661</span> {<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.final_states().begin(), <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.final_states().end()});</div>
<div class="line"><a id="l00662" name="l00662"></a><span class="lineno"> 662</span> std::vector&lt;absl::flat_hash_set&lt;int64_t&gt;&gt; reachable_states(n + 1);</div>
<div class="line"><a id="l00663" name="l00663"></a><span class="lineno"> 663</span> reachable_states[0].insert(<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.starting_state());</div>
<div class="line"><a id="l00664" name="l00664"></a><span class="lineno"> 664</span> </div>
<div class="line"><a id="l00665" name="l00665"></a><span class="lineno"> 665</span> <span class="comment">// Forward pass.</span></div>
<div class="line"><a id="l00666" name="l00666"></a><span class="lineno"> 666</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> = 0; <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> &lt; n; ++<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>) {</div>
<div class="line"><a id="l00667" name="l00667"></a><span class="lineno"> 667</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> t = 0; t &lt; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_tail_size(); ++t) {</div>
<div class="line"><a id="l00668" name="l00668"></a><span class="lineno"> 668</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_tail(t);</div>
<div class="line"><a id="l00669" name="l00669"></a><span class="lineno"> 669</span> <span class="keyword">const</span> int64_t label = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_label(t);</div>
<div class="line"><a id="l00670" name="l00670"></a><span class="lineno"> 670</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_head(t);</div>
<div class="line"><a id="l00671" name="l00671"></a><span class="lineno"> 671</span> <span class="keywordflow">if</span> (!reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>].contains(<a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00672" name="l00672"></a><span class="lineno"> 672</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], label)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00673" name="l00673"></a><span class="lineno"> 673</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> == n - 1 &amp;&amp; !final_states.contains(<a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00674" name="l00674"></a><span class="lineno"> 674</span> reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> + 1].insert(<a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a>);</div>
<div class="line"><a id="l00675" name="l00675"></a><span class="lineno"> 675</span> }</div>
<div class="line"><a id="l00676" name="l00676"></a><span class="lineno"> 676</span> }</div>
<div class="line"><a id="l00677" name="l00677"></a><span class="lineno"> 677</span> </div>
<div class="line"><a id="l00678" name="l00678"></a><span class="lineno"> 678</span> <span class="comment">// Backward pass.</span></div>
<div class="line"><a id="l00679" name="l00679"></a><span class="lineno"> 679</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> = n - 1; <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> &gt;= 0; --<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>) {</div>
<div class="line"><a id="l00680" name="l00680"></a><span class="lineno"> 680</span> absl::flat_hash_set&lt;int64_t&gt; new_set;</div>
<div class="line"><a id="l00681" name="l00681"></a><span class="lineno"> 681</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> t = 0; t &lt; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_tail_size(); ++t) {</div>
<div class="line"><a id="l00682" name="l00682"></a><span class="lineno"> 682</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_tail(t);</div>
<div class="line"><a id="l00683" name="l00683"></a><span class="lineno"> 683</span> <span class="keyword">const</span> int64_t label = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_label(t);</div>
<div class="line"><a id="l00684" name="l00684"></a><span class="lineno"> 684</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_head(t);</div>
<div class="line"><a id="l00685" name="l00685"></a><span class="lineno"> 685</span> </div>
<div class="line"><a id="l00686" name="l00686"></a><span class="lineno"> 686</span> <span class="keywordflow">if</span> (!reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>].contains(<a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00687" name="l00687"></a><span class="lineno"> 687</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], label)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00688" name="l00688"></a><span class="lineno"> 688</span> <span class="keywordflow">if</span> (!reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> + 1].contains(<a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00689" name="l00689"></a><span class="lineno"> 689</span> new_set.insert(<a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a>);</div>
<div class="line"><a id="l00690" name="l00690"></a><span class="lineno"> 690</span> }</div>
<div class="line"><a id="l00691" name="l00691"></a><span class="lineno"> 691</span> reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>].swap(new_set);</div>
<div class="line"><a id="l00692" name="l00692"></a><span class="lineno"> 692</span> }</div>
<div class="line"><a id="l00693" name="l00693"></a><span class="lineno"> 693</span> </div>
<div class="line"><a id="l00694" name="l00694"></a><span class="lineno"> 694</span> <span class="comment">// We will model at each time step the current automaton state using Boolean</span></div>
<div class="line"><a id="l00695" name="l00695"></a><span class="lineno"> 695</span> <span class="comment">// variables. We will have n+1 time step. At time zero, we start in the</span></div>
<div class="line"><a id="l00696" name="l00696"></a><span class="lineno"> 696</span> <span class="comment">// initial state, and at time n we should be in one of the final states. We</span></div>
<div class="line"><a id="l00697" name="l00697"></a><span class="lineno"> 697</span> <span class="comment">// don&#39;t need to create Booleans at at time when there is just one possible</span></div>
<div class="line"><a id="l00698" name="l00698"></a><span class="lineno"> 698</span> <span class="comment">// state (like at time zero).</span></div>
<div class="line"><a id="l00699" name="l00699"></a><span class="lineno"> 699</span> absl::flat_hash_map&lt;int64_t, int&gt; encoding;</div>
<div class="line"><a id="l00700" name="l00700"></a><span class="lineno"> 700</span> absl::flat_hash_map&lt;int64_t, int&gt; in_encoding;</div>
<div class="line"><a id="l00701" name="l00701"></a><span class="lineno"> 701</span> absl::flat_hash_map&lt;int64_t, int&gt; out_encoding;</div>
<div class="line"><a id="l00702" name="l00702"></a><span class="lineno"> 702</span> <span class="keywordtype">bool</span> removed_values = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00703" name="l00703"></a><span class="lineno"> 703</span> </div>
<div class="line"><a id="l00704" name="l00704"></a><span class="lineno"> 704</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> = 0; <a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> &lt; n; ++<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>) {</div>
<div class="line"><a id="l00705" name="l00705"></a><span class="lineno"> 705</span> <span class="comment">// All these vector have the same size. We will use them to enforce a</span></div>
<div class="line"><a id="l00706" name="l00706"></a><span class="lineno"> 706</span> <span class="comment">// local table constraint representing one step of the automaton at the</span></div>
<div class="line"><a id="l00707" name="l00707"></a><span class="lineno"> 707</span> <span class="comment">// given time.</span></div>
<div class="line"><a id="l00708" name="l00708"></a><span class="lineno"> 708</span> std::vector&lt;int64_t&gt; in_states;</div>
<div class="line"><a id="l00709" name="l00709"></a><span class="lineno"> 709</span> std::vector&lt;int64_t&gt; labels;</div>
<div class="line"><a id="l00710" name="l00710"></a><span class="lineno"> 710</span> std::vector&lt;int64_t&gt; out_states;</div>
<div class="line"><a id="l00711" name="l00711"></a><span class="lineno"> 711</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_label_size(); ++i) {</div>
<div class="line"><a id="l00712" name="l00712"></a><span class="lineno"> 712</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_tail(i);</div>
<div class="line"><a id="l00713" name="l00713"></a><span class="lineno"> 713</span> <span class="keyword">const</span> int64_t label = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_label(i);</div>
<div class="line"><a id="l00714" name="l00714"></a><span class="lineno"> 714</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a> = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.transition_head(i);</div>
<div class="line"><a id="l00715" name="l00715"></a><span class="lineno"> 715</span> </div>
<div class="line"><a id="l00716" name="l00716"></a><span class="lineno"> 716</span> <span class="keywordflow">if</span> (!reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>].contains(<a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00717" name="l00717"></a><span class="lineno"> 717</span> <span class="keywordflow">if</span> (!reachable_states[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> + 1].contains(<a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a>)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00718" name="l00718"></a><span class="lineno"> 718</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], label)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00719" name="l00719"></a><span class="lineno"> 719</span> </div>
<div class="line"><a id="l00720" name="l00720"></a><span class="lineno"> 720</span> <span class="comment">// TODO(user): if this transition correspond to just one in-state or</span></div>
<div class="line"><a id="l00721" name="l00721"></a><span class="lineno"> 721</span> <span class="comment">// one-out state or one variable value, we could reuse the corresponding</span></div>
<div class="line"><a id="l00722" name="l00722"></a><span class="lineno"> 722</span> <span class="comment">// Boolean variable instead of creating a new one!</span></div>
<div class="line"><a id="l00723" name="l00723"></a><span class="lineno"> 723</span> in_states.push_back(<a class="code hl_variable" href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a>);</div>
<div class="line"><a id="l00724" name="l00724"></a><span class="lineno"> 724</span> labels.push_back(label);</div>
<div class="line"><a id="l00725" name="l00725"></a><span class="lineno"> 725</span> </div>
<div class="line"><a id="l00726" name="l00726"></a><span class="lineno"> 726</span> <span class="comment">// On the last step we don&#39;t need to distinguish the output states, so</span></div>
<div class="line"><a id="l00727" name="l00727"></a><span class="lineno"> 727</span> <span class="comment">// we use zero.</span></div>
<div class="line"><a id="l00728" name="l00728"></a><span class="lineno"> 728</span> out_states.push_back(<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a> + 1 == n ? 0 : <a class="code hl_variable" href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a>);</div>
<div class="line"><a id="l00729" name="l00729"></a><span class="lineno"> 729</span> }</div>
<div class="line"><a id="l00730" name="l00730"></a><span class="lineno"> 730</span> </div>
<div class="line"><a id="l00731" name="l00731"></a><span class="lineno"> 731</span> <span class="comment">// Deal with single tuple.</span></div>
<div class="line"><a id="l00732" name="l00732"></a><span class="lineno"> 732</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_tuples = in_states.size();</div>
<div class="line"><a id="l00733" name="l00733"></a><span class="lineno"> 733</span> <span class="keywordflow">if</span> (num_tuples == 1) {</div>
<div class="line"><a id="l00734" name="l00734"></a><span class="lineno"> 734</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], Domain(labels.front()))) {</div>
<div class="line"><a id="l00735" name="l00735"></a><span class="lineno"> 735</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Infeasible automaton.&quot;</span>;</div>
<div class="line"><a id="l00736" name="l00736"></a><span class="lineno"> 736</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00737" name="l00737"></a><span class="lineno"> 737</span> }</div>
<div class="line"><a id="l00738" name="l00738"></a><span class="lineno"> 738</span> in_encoding.clear();</div>
<div class="line"><a id="l00739" name="l00739"></a><span class="lineno"> 739</span> <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00740" name="l00740"></a><span class="lineno"> 740</span> }</div>
<div class="line"><a id="l00741" name="l00741"></a><span class="lineno"> 741</span> </div>
<div class="line"><a id="l00742" name="l00742"></a><span class="lineno"> 742</span> <span class="comment">// Fully encode vars[time].</span></div>
<div class="line"><a id="l00743" name="l00743"></a><span class="lineno"> 743</span> {</div>
<div class="line"><a id="l00744" name="l00744"></a><span class="lineno"> 744</span> std::vector&lt;int64_t&gt; transitions = labels;</div>
<div class="line"><a id="l00745" name="l00745"></a><span class="lineno"> 745</span> <a class="code hl_function" href="namespacegtl.html#a288a1dc92da5d3ad62d4bc4cec9e8b1d">gtl::STLSortAndRemoveDuplicates</a>(&amp;transitions);</div>
<div class="line"><a id="l00746" name="l00746"></a><span class="lineno"> 746</span> </div>
<div class="line"><a id="l00747" name="l00747"></a><span class="lineno"> 747</span> encoding.clear();</div>
<div class="line"><a id="l00748" name="l00748"></a><span class="lineno"> 748</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(</div>
<div class="line"><a id="l00749" name="l00749"></a><span class="lineno"> 749</span> vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>(transitions), &amp;removed_values)) {</div>
<div class="line"><a id="l00750" name="l00750"></a><span class="lineno"> 750</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Infeasible automaton.&quot;</span>;</div>
<div class="line"><a id="l00751" name="l00751"></a><span class="lineno"> 751</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00752" name="l00752"></a><span class="lineno"> 752</span> }</div>
<div class="line"><a id="l00753" name="l00753"></a><span class="lineno"> 753</span> </div>
<div class="line"><a id="l00754" name="l00754"></a><span class="lineno"> 754</span> <span class="comment">// Fully encode the variable.</span></div>
<div class="line"><a id="l00755" name="l00755"></a><span class="lineno"> 755</span> <span class="comment">// We can leave the encoding empty for fixed vars.</span></div>
<div class="line"><a id="l00756" name="l00756"></a><span class="lineno"> 756</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>])) {</div>
<div class="line"><a id="l00757" name="l00757"></a><span class="lineno"> 757</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>]).Values()) {</div>
<div class="line"><a id="l00758" name="l00758"></a><span class="lineno"> 758</span> encoding[v] = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(vars[<a class="code hl_variable" href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a>], v);</div>
<div class="line"><a id="l00759" name="l00759"></a><span class="lineno"> 759</span> }</div>
<div class="line"><a id="l00760" name="l00760"></a><span class="lineno"> 760</span> }</div>
<div class="line"><a id="l00761" name="l00761"></a><span class="lineno"> 761</span> }</div>
<div class="line"><a id="l00762" name="l00762"></a><span class="lineno"> 762</span> </div>
<div class="line"><a id="l00763" name="l00763"></a><span class="lineno"> 763</span> <span class="comment">// Count how many time each value appear.</span></div>
<div class="line"><a id="l00764" name="l00764"></a><span class="lineno"> 764</span> <span class="comment">// We use this to reuse literals if possible.</span></div>
<div class="line"><a id="l00765" name="l00765"></a><span class="lineno"> 765</span> absl::flat_hash_map&lt;int64_t, int&gt; in_count;</div>
<div class="line"><a id="l00766" name="l00766"></a><span class="lineno"> 766</span> absl::flat_hash_map&lt;int64_t, int&gt; transition_count;</div>
<div class="line"><a id="l00767" name="l00767"></a><span class="lineno"> 767</span> absl::flat_hash_map&lt;int64_t, int&gt; out_count;</div>
<div class="line"><a id="l00768" name="l00768"></a><span class="lineno"> 768</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_tuples; ++i) {</div>
<div class="line"><a id="l00769" name="l00769"></a><span class="lineno"> 769</span> in_count[in_states[i]]++;</div>
<div class="line"><a id="l00770" name="l00770"></a><span class="lineno"> 770</span> transition_count[labels[i]]++;</div>
<div class="line"><a id="l00771" name="l00771"></a><span class="lineno"> 771</span> out_count[out_states[i]]++;</div>
<div class="line"><a id="l00772" name="l00772"></a><span class="lineno"> 772</span> }</div>
<div class="line"><a id="l00773" name="l00773"></a><span class="lineno"> 773</span> </div>
<div class="line"><a id="l00774" name="l00774"></a><span class="lineno"> 774</span> <span class="comment">// For each possible out states, create one Boolean variable.</span></div>
<div class="line"><a id="l00775" name="l00775"></a><span class="lineno"> 775</span> <span class="comment">//</span></div>
<div class="line"><a id="l00776" name="l00776"></a><span class="lineno"> 776</span> <span class="comment">// TODO(user): Add exactly one?</span></div>
<div class="line"><a id="l00777" name="l00777"></a><span class="lineno"> 777</span> {</div>
<div class="line"><a id="l00778" name="l00778"></a><span class="lineno"> 778</span> std::vector&lt;int64_t&gt; states = out_states;</div>
<div class="line"><a id="l00779" name="l00779"></a><span class="lineno"> 779</span> <a class="code hl_function" href="namespacegtl.html#a288a1dc92da5d3ad62d4bc4cec9e8b1d">gtl::STLSortAndRemoveDuplicates</a>(&amp;states);</div>
<div class="line"><a id="l00780" name="l00780"></a><span class="lineno"> 780</span> </div>
<div class="line"><a id="l00781" name="l00781"></a><span class="lineno"> 781</span> out_encoding.clear();</div>
<div class="line"><a id="l00782" name="l00782"></a><span class="lineno"> 782</span> <span class="keywordflow">if</span> (states.size() == 2) {</div>
<div class="line"><a id="l00783" name="l00783"></a><span class="lineno"> 783</span> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewBoolVar();</div>
<div class="line"><a id="l00784" name="l00784"></a><span class="lineno"> 784</span> out_encoding[states[0]] = <a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>;</div>
<div class="line"><a id="l00785" name="l00785"></a><span class="lineno"> 785</span> out_encoding[states[1]] = <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(<a class="code hl_variable" href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a>);</div>
<div class="line"><a id="l00786" name="l00786"></a><span class="lineno"> 786</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (states.size() &gt; 2) {</div>
<div class="line"><a id="l00787" name="l00787"></a><span class="lineno"> 787</span> <span class="keyword">struct </span>UniqueDetector {</div>
<div class="line"><a id="l00788" name="l00788"></a><span class="lineno"> 788</span> <span class="keywordtype">void</span> Set(int64_t v) {</div>
<div class="line"><a id="l00789" name="l00789"></a><span class="lineno"> 789</span> <span class="keywordflow">if</span> (!is_unique) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00790" name="l00790"></a><span class="lineno"> 790</span> <span class="keywordflow">if</span> (is_set) {</div>
<div class="line"><a id="l00791" name="l00791"></a><span class="lineno"> 791</span> <span class="keywordflow">if</span> (v != <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>) is_unique = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00792" name="l00792"></a><span class="lineno"> 792</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00793" name="l00793"></a><span class="lineno"> 793</span> is_set = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00794" name="l00794"></a><span class="lineno"> 794</span> <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = v;</div>
<div class="line"><a id="l00795" name="l00795"></a><span class="lineno"> 795</span> }</div>
<div class="line"><a id="l00796" name="l00796"></a><span class="lineno"> 796</span> }</div>
<div class="line"><a id="l00797" name="l00797"></a><span class="lineno"> 797</span> <span class="keywordtype">bool</span> is_set = <span class="keyword">false</span>;</div>
<div class="line"><a id="l00798" name="l00798"></a><span class="lineno"> 798</span> <span class="keywordtype">bool</span> is_unique = <span class="keyword">true</span>;</div>
<div class="line"><a id="l00799" name="l00799"></a><span class="lineno"> 799</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = 0;</div>
<div class="line"><a id="l00800" name="l00800"></a><span class="lineno"> 800</span> };</div>
<div class="line"><a id="l00801" name="l00801"></a><span class="lineno"> 801</span> </div>
<div class="line"><a id="l00802" name="l00802"></a><span class="lineno"> 802</span> <span class="comment">// Optimization to detect if we have an in state that is only matched to</span></div>
<div class="line"><a id="l00803" name="l00803"></a><span class="lineno"> 803</span> <span class="comment">// a single out state. Same with transition.</span></div>
<div class="line"><a id="l00804" name="l00804"></a><span class="lineno"> 804</span> absl::flat_hash_map&lt;int64_t, UniqueDetector&gt; out_to_in;</div>
<div class="line"><a id="l00805" name="l00805"></a><span class="lineno"> 805</span> absl::flat_hash_map&lt;int64_t, UniqueDetector&gt; out_to_transition;</div>
<div class="line"><a id="l00806" name="l00806"></a><span class="lineno"> 806</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_tuples; ++i) {</div>
<div class="line"><a id="l00807" name="l00807"></a><span class="lineno"> 807</span> out_to_in[out_states[i]].Set(in_states[i]);</div>
<div class="line"><a id="l00808" name="l00808"></a><span class="lineno"> 808</span> out_to_transition[out_states[i]].Set(labels[i]);</div>
<div class="line"><a id="l00809" name="l00809"></a><span class="lineno"> 809</span> }</div>
<div class="line"><a id="l00810" name="l00810"></a><span class="lineno"> 810</span> </div>
<div class="line"><a id="l00811" name="l00811"></a><span class="lineno"> 811</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t state : states) {</div>
<div class="line"><a id="l00812" name="l00812"></a><span class="lineno"> 812</span> <span class="comment">// If we have a relation in_state &lt;=&gt; out_state, then we can reuse</span></div>
<div class="line"><a id="l00813" name="l00813"></a><span class="lineno"> 813</span> <span class="comment">// the in Boolean and do not need to create a new one.</span></div>
<div class="line"><a id="l00814" name="l00814"></a><span class="lineno"> 814</span> <span class="keywordflow">if</span> (!in_encoding.empty() &amp;&amp; out_to_in[state].is_unique) {</div>
<div class="line"><a id="l00815" name="l00815"></a><span class="lineno"> 815</span> <span class="keyword">const</span> int64_t unique_in = out_to_in[state].value;</div>
<div class="line"><a id="l00816" name="l00816"></a><span class="lineno"> 816</span> <span class="keywordflow">if</span> (in_count[unique_in] == out_count[state]) {</div>
<div class="line"><a id="l00817" name="l00817"></a><span class="lineno"> 817</span> out_encoding[state] = in_encoding[unique_in];</div>
<div class="line"><a id="l00818" name="l00818"></a><span class="lineno"> 818</span> <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00819" name="l00819"></a><span class="lineno"> 819</span> }</div>
<div class="line"><a id="l00820" name="l00820"></a><span class="lineno"> 820</span> }</div>
<div class="line"><a id="l00821" name="l00821"></a><span class="lineno"> 821</span> </div>
<div class="line"><a id="l00822" name="l00822"></a><span class="lineno"> 822</span> <span class="comment">// Same if we have an unique transition value that correspond only to</span></div>
<div class="line"><a id="l00823" name="l00823"></a><span class="lineno"> 823</span> <span class="comment">// this state.</span></div>
<div class="line"><a id="l00824" name="l00824"></a><span class="lineno"> 824</span> <span class="keywordflow">if</span> (!encoding.empty() &amp;&amp; out_to_transition[state].is_unique) {</div>
<div class="line"><a id="l00825" name="l00825"></a><span class="lineno"> 825</span> <span class="keyword">const</span> int64_t unique_transition = out_to_transition[state].value;</div>
<div class="line"><a id="l00826" name="l00826"></a><span class="lineno"> 826</span> <span class="keywordflow">if</span> (transition_count[unique_transition] == out_count[state]) {</div>
<div class="line"><a id="l00827" name="l00827"></a><span class="lineno"> 827</span> out_encoding[state] = encoding[unique_transition];</div>
<div class="line"><a id="l00828" name="l00828"></a><span class="lineno"> 828</span> <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00829" name="l00829"></a><span class="lineno"> 829</span> }</div>
<div class="line"><a id="l00830" name="l00830"></a><span class="lineno"> 830</span> }</div>
<div class="line"><a id="l00831" name="l00831"></a><span class="lineno"> 831</span> </div>
<div class="line"><a id="l00832" name="l00832"></a><span class="lineno"> 832</span> out_encoding[state] = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewBoolVar();</div>
<div class="line"><a id="l00833" name="l00833"></a><span class="lineno"> 833</span> }</div>
<div class="line"><a id="l00834" name="l00834"></a><span class="lineno"> 834</span> }</div>
<div class="line"><a id="l00835" name="l00835"></a><span class="lineno"> 835</span> }</div>
<div class="line"><a id="l00836" name="l00836"></a><span class="lineno"> 836</span> </div>
<div class="line"><a id="l00837" name="l00837"></a><span class="lineno"> 837</span> <span class="comment">// Simple encoding. This is enough to properly enforce the constraint, but</span></div>
<div class="line"><a id="l00838" name="l00838"></a><span class="lineno"> 838</span> <span class="comment">// it propagate less. It creates a lot less Booleans though. Note that we</span></div>
<div class="line"><a id="l00839" name="l00839"></a><span class="lineno"> 839</span> <span class="comment">// use implicit &quot;exactly one&quot; on the encoding and do not add any extra</span></div>
<div class="line"><a id="l00840" name="l00840"></a><span class="lineno"> 840</span> <span class="comment">// exacly one if the simple encoding is used.</span></div>
<div class="line"><a id="l00841" name="l00841"></a><span class="lineno"> 841</span> <span class="comment">//</span></div>
<div class="line"><a id="l00842" name="l00842"></a><span class="lineno"> 842</span> <span class="comment">// We currently decide which encoding to use depending on the number of new</span></div>
<div class="line"><a id="l00843" name="l00843"></a><span class="lineno"> 843</span> <span class="comment">// literals needed by the &quot;heavy&quot; encoding compared to the number of states</span></div>
<div class="line"><a id="l00844" name="l00844"></a><span class="lineno"> 844</span> <span class="comment">// and labels. When the automaton is small, using the full encoding is</span></div>
<div class="line"><a id="l00845" name="l00845"></a><span class="lineno"> 845</span> <span class="comment">// better, see for instance on rotating-workforce_Example789 were the simple</span></div>
<div class="line"><a id="l00846" name="l00846"></a><span class="lineno"> 846</span> <span class="comment">// encoding make the problem hard to solve but the full encoding allow the</span></div>
<div class="line"><a id="l00847" name="l00847"></a><span class="lineno"> 847</span> <span class="comment">// solver to solve it in a couple of seconds!</span></div>
<div class="line"><a id="l00848" name="l00848"></a><span class="lineno"> 848</span> <span class="comment">//</span></div>
<div class="line"><a id="l00849" name="l00849"></a><span class="lineno"> 849</span> <span class="comment">// Note that both encoding create about the same number of constraints.</span></div>
<div class="line"><a id="l00850" name="l00850"></a><span class="lineno"> 850</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_involved_variables =</div>
<div class="line"><a id="l00851" name="l00851"></a><span class="lineno"> 851</span> in_encoding.size() + encoding.size() + out_encoding.size();</div>
<div class="line"><a id="l00852" name="l00852"></a><span class="lineno"> 852</span> <span class="keyword">const</span> <span class="keywordtype">bool</span> use_light_encoding = (num_tuples &gt; num_involved_variables);</div>
<div class="line"><a id="l00853" name="l00853"></a><span class="lineno"> 853</span> <span class="keywordflow">if</span> (use_light_encoding &amp;&amp; !in_encoding.empty() &amp;&amp; !encoding.empty() &amp;&amp;</div>
<div class="line"><a id="l00854" name="l00854"></a><span class="lineno"> 854</span> !out_encoding.empty()) {</div>
<div class="line"><a id="l00855" name="l00855"></a><span class="lineno"> 855</span> <span class="comment">// Part 1: If a in_state is selected, restrict the set of possible labels.</span></div>
<div class="line"><a id="l00856" name="l00856"></a><span class="lineno"> 856</span> <span class="comment">// We also restrict the set of possible out states, but this is not needed</span></div>
<div class="line"><a id="l00857" name="l00857"></a><span class="lineno"> 857</span> <span class="comment">// for correctness.</span></div>
<div class="line"><a id="l00858" name="l00858"></a><span class="lineno"> 858</span> absl::flat_hash_map&lt;int64_t, std::vector&lt;int64_t&gt;&gt; in_to_label;</div>
<div class="line"><a id="l00859" name="l00859"></a><span class="lineno"> 859</span> absl::flat_hash_map&lt;int64_t, std::vector&lt;int64_t&gt;&gt; in_to_out;</div>
<div class="line"><a id="l00860" name="l00860"></a><span class="lineno"> 860</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_tuples; ++i) {</div>
<div class="line"><a id="l00861" name="l00861"></a><span class="lineno"> 861</span> in_to_label[in_states[i]].push_back(labels[i]);</div>
<div class="line"><a id="l00862" name="l00862"></a><span class="lineno"> 862</span> in_to_out[in_states[i]].push_back(out_states[i]);</div>
<div class="line"><a id="l00863" name="l00863"></a><span class="lineno"> 863</span> }</div>
<div class="line"><a id="l00864" name="l00864"></a><span class="lineno"> 864</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span> [in_value, in_literal] : in_encoding) {</div>
<div class="line"><a id="l00865" name="l00865"></a><span class="lineno"> 865</span> AddImplyInReachableValues(in_literal, in_to_label[in_value], encoding,</div>
<div class="line"><a id="l00866" name="l00866"></a><span class="lineno"> 866</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00867" name="l00867"></a><span class="lineno"> 867</span> AddImplyInReachableValues(in_literal, in_to_out[in_value], out_encoding,</div>
<div class="line"><a id="l00868" name="l00868"></a><span class="lineno"> 868</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00869" name="l00869"></a><span class="lineno"> 869</span> }</div>
<div class="line"><a id="l00870" name="l00870"></a><span class="lineno"> 870</span> </div>
<div class="line"><a id="l00871" name="l00871"></a><span class="lineno"> 871</span> <span class="comment">// Part2, add all 3-clauses: (in_state, label) =&gt; out_state.</span></div>
<div class="line"><a id="l00872" name="l00872"></a><span class="lineno"> 872</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_tuples; ++i) {</div>
<div class="line"><a id="l00873" name="l00873"></a><span class="lineno"> 873</span> <span class="keyword">auto</span>* bool_or =</div>
<div class="line"><a id="l00874" name="l00874"></a><span class="lineno"> 874</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00875" name="l00875"></a><span class="lineno"> 875</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(in_encoding.at(in_states[i])));</div>
<div class="line"><a id="l00876" name="l00876"></a><span class="lineno"> 876</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(encoding.at(labels[i])));</div>
<div class="line"><a id="l00877" name="l00877"></a><span class="lineno"> 877</span> bool_or-&gt;add_literals(out_encoding.at(out_states[i]));</div>
<div class="line"><a id="l00878" name="l00878"></a><span class="lineno"> 878</span> }</div>
<div class="line"><a id="l00879" name="l00879"></a><span class="lineno"> 879</span> </div>
<div class="line"><a id="l00880" name="l00880"></a><span class="lineno"> 880</span> in_encoding.swap(out_encoding);</div>
<div class="line"><a id="l00881" name="l00881"></a><span class="lineno"> 881</span> out_encoding.clear();</div>
<div class="line"><a id="l00882" name="l00882"></a><span class="lineno"> 882</span> <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00883" name="l00883"></a><span class="lineno"> 883</span> }</div>
<div class="line"><a id="l00884" name="l00884"></a><span class="lineno"> 884</span> </div>
<div class="line"><a id="l00885" name="l00885"></a><span class="lineno"> 885</span> <span class="comment">// Create the tuple literals.</span></div>
<div class="line"><a id="l00886" name="l00886"></a><span class="lineno"> 886</span> <span class="comment">//</span></div>
<div class="line"><a id="l00887" name="l00887"></a><span class="lineno"> 887</span> <span class="comment">// TODO(user): Call and use the same heuristics as the table constraint to</span></div>
<div class="line"><a id="l00888" name="l00888"></a><span class="lineno"> 888</span> <span class="comment">// expand this small table with 3 columns (i.e. compress, negate, etc...).</span></div>
<div class="line"><a id="l00889" name="l00889"></a><span class="lineno"> 889</span> std::vector&lt;int&gt; tuple_literals;</div>
<div class="line"><a id="l00890" name="l00890"></a><span class="lineno"> 890</span> <span class="keywordflow">if</span> (num_tuples == 2) {</div>
<div class="line"><a id="l00891" name="l00891"></a><span class="lineno"> 891</span> <span class="keyword">const</span> <span class="keywordtype">int</span> bool_var = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewBoolVar();</div>
<div class="line"><a id="l00892" name="l00892"></a><span class="lineno"> 892</span> tuple_literals.push_back(bool_var);</div>
<div class="line"><a id="l00893" name="l00893"></a><span class="lineno"> 893</span> tuple_literals.push_back(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(bool_var));</div>
<div class="line"><a id="l00894" name="l00894"></a><span class="lineno"> 894</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00895" name="l00895"></a><span class="lineno"> 895</span> <span class="comment">// Note that we do not need the ExactlyOneConstraint(tuple_literals)</span></div>
<div class="line"><a id="l00896" name="l00896"></a><span class="lineno"> 896</span> <span class="comment">// because it is already implicitly encoded since we have exactly one</span></div>
<div class="line"><a id="l00897" name="l00897"></a><span class="lineno"> 897</span> <span class="comment">// transition value. But adding one seems to help.</span></div>
<div class="line"><a id="l00898" name="l00898"></a><span class="lineno"> 898</span> BoolArgumentProto* exactly_one =</div>
<div class="line"><a id="l00899" name="l00899"></a><span class="lineno"> 899</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_exactly_one();</div>
<div class="line"><a id="l00900" name="l00900"></a><span class="lineno"> 900</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_tuples; ++i) {</div>
<div class="line"><a id="l00901" name="l00901"></a><span class="lineno"> 901</span> <span class="keywordtype">int</span> tuple_literal;</div>
<div class="line"><a id="l00902" name="l00902"></a><span class="lineno"> 902</span> <span class="keywordflow">if</span> (in_count[in_states[i]] == 1 &amp;&amp; !in_encoding.empty()) {</div>
<div class="line"><a id="l00903" name="l00903"></a><span class="lineno"> 903</span> tuple_literal = in_encoding[in_states[i]];</div>
<div class="line"><a id="l00904" name="l00904"></a><span class="lineno"> 904</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (transition_count[labels[i]] == 1 &amp;&amp; !encoding.empty()) {</div>
<div class="line"><a id="l00905" name="l00905"></a><span class="lineno"> 905</span> tuple_literal = encoding[labels[i]];</div>
<div class="line"><a id="l00906" name="l00906"></a><span class="lineno"> 906</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (out_count[out_states[i]] == 1 &amp;&amp; !out_encoding.empty()) {</div>
<div class="line"><a id="l00907" name="l00907"></a><span class="lineno"> 907</span> tuple_literal = out_encoding[out_states[i]];</div>
<div class="line"><a id="l00908" name="l00908"></a><span class="lineno"> 908</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l00909" name="l00909"></a><span class="lineno"> 909</span> tuple_literal = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewBoolVar();</div>
<div class="line"><a id="l00910" name="l00910"></a><span class="lineno"> 910</span> }</div>
<div class="line"><a id="l00911" name="l00911"></a><span class="lineno"> 911</span> </div>
<div class="line"><a id="l00912" name="l00912"></a><span class="lineno"> 912</span> tuple_literals.push_back(tuple_literal);</div>
<div class="line"><a id="l00913" name="l00913"></a><span class="lineno"> 913</span> exactly_one-&gt;add_literals(tuple_literal);</div>
<div class="line"><a id="l00914" name="l00914"></a><span class="lineno"> 914</span> }</div>
<div class="line"><a id="l00915" name="l00915"></a><span class="lineno"> 915</span> }</div>
<div class="line"><a id="l00916" name="l00916"></a><span class="lineno"> 916</span> </div>
<div class="line"><a id="l00917" name="l00917"></a><span class="lineno"> 917</span> <span class="keywordflow">if</span> (!in_encoding.empty()) {</div>
<div class="line"><a id="l00918" name="l00918"></a><span class="lineno"> 918</span> LinkLiteralsAndValues(tuple_literals, in_states, in_encoding, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00919" name="l00919"></a><span class="lineno"> 919</span> }</div>
<div class="line"><a id="l00920" name="l00920"></a><span class="lineno"> 920</span> <span class="keywordflow">if</span> (!encoding.empty()) {</div>
<div class="line"><a id="l00921" name="l00921"></a><span class="lineno"> 921</span> LinkLiteralsAndValues(tuple_literals, labels, encoding, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00922" name="l00922"></a><span class="lineno"> 922</span> }</div>
<div class="line"><a id="l00923" name="l00923"></a><span class="lineno"> 923</span> <span class="keywordflow">if</span> (!out_encoding.empty()) {</div>
<div class="line"><a id="l00924" name="l00924"></a><span class="lineno"> 924</span> LinkLiteralsAndValues(tuple_literals, out_states, out_encoding, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l00925" name="l00925"></a><span class="lineno"> 925</span> }</div>
<div class="line"><a id="l00926" name="l00926"></a><span class="lineno"> 926</span> </div>
<div class="line"><a id="l00927" name="l00927"></a><span class="lineno"> 927</span> in_encoding.swap(out_encoding);</div>
<div class="line"><a id="l00928" name="l00928"></a><span class="lineno"> 928</span> out_encoding.clear();</div>
<div class="line"><a id="l00929" name="l00929"></a><span class="lineno"> 929</span> }</div>
<div class="line"><a id="l00930" name="l00930"></a><span class="lineno"> 930</span> </div>
<div class="line"><a id="l00931" name="l00931"></a><span class="lineno"> 931</span> <span class="keywordflow">if</span> (removed_values) {</div>
<div class="line"><a id="l00932" name="l00932"></a><span class="lineno"> 932</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;automaton: reduced variable domains&quot;</span>);</div>
<div class="line"><a id="l00933" name="l00933"></a><span class="lineno"> 933</span> }</div>
<div class="line"><a id="l00934" name="l00934"></a><span class="lineno"> 934</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;automaton: expanded&quot;</span>);</div>
<div class="line"><a id="l00935" name="l00935"></a><span class="lineno"> 935</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00936" name="l00936"></a><span class="lineno"> 936</span>}</div>
<div class="line"><a id="l00937" name="l00937"></a><span class="lineno"> 937</span> </div>
<div class="line"><a id="l00938" name="l00938"></a><span class="lineno"> 938</span><span class="keywordtype">void</span> ExpandNegativeTable(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00939" name="l00939"></a><span class="lineno"> 939</span> TableConstraintProto&amp; table = *<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_table();</div>
<div class="line"><a id="l00940" name="l00940"></a><span class="lineno"> 940</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_vars = table.vars_size();</div>
<div class="line"><a id="l00941" name="l00941"></a><span class="lineno"> 941</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_original_tuples = table.values_size() / num_vars;</div>
<div class="line"><a id="l00942" name="l00942"></a><span class="lineno"> 942</span> std::vector&lt;std::vector&lt;int64_t&gt;&gt; tuples(num_original_tuples);</div>
<div class="line"><a id="l00943" name="l00943"></a><span class="lineno"> 943</span> <span class="keywordtype">int</span> count = 0;</div>
<div class="line"><a id="l00944" name="l00944"></a><span class="lineno"> 944</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_original_tuples; ++i) {</div>
<div class="line"><a id="l00945" name="l00945"></a><span class="lineno"> 945</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; num_vars; ++j) {</div>
<div class="line"><a id="l00946" name="l00946"></a><span class="lineno"> 946</span> tuples[i].push_back(table.values(count++));</div>
<div class="line"><a id="l00947" name="l00947"></a><span class="lineno"> 947</span> }</div>
<div class="line"><a id="l00948" name="l00948"></a><span class="lineno"> 948</span> }</div>
<div class="line"><a id="l00949" name="l00949"></a><span class="lineno"> 949</span> </div>
<div class="line"><a id="l00950" name="l00950"></a><span class="lineno"> 950</span> <span class="keywordflow">if</span> (tuples.empty()) { <span class="comment">// Early exit.</span></div>
<div class="line"><a id="l00951" name="l00951"></a><span class="lineno"> 951</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: empty negated constraint&quot;</span>);</div>
<div class="line"><a id="l00952" name="l00952"></a><span class="lineno"> 952</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00953" name="l00953"></a><span class="lineno"> 953</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l00954" name="l00954"></a><span class="lineno"> 954</span> }</div>
<div class="line"><a id="l00955" name="l00955"></a><span class="lineno"> 955</span> </div>
<div class="line"><a id="l00956" name="l00956"></a><span class="lineno"> 956</span> <span class="comment">// Compress tuples.</span></div>
<div class="line"><a id="l00957" name="l00957"></a><span class="lineno"> 957</span> <span class="keyword">const</span> int64_t any_value = <a class="code hl_variable" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::numeric_limits&lt;int64_t&gt;::min</a>();</div>
<div class="line"><a id="l00958" name="l00958"></a><span class="lineno"> 958</span> std::vector&lt;int64_t&gt; domain_sizes;</div>
<div class="line"><a id="l00959" name="l00959"></a><span class="lineno"> 959</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_vars; ++i) {</div>
<div class="line"><a id="l00960" name="l00960"></a><span class="lineno"> 960</span> domain_sizes.push_back(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(table.vars(i)).Size());</div>
<div class="line"><a id="l00961" name="l00961"></a><span class="lineno"> 961</span> }</div>
<div class="line"><a id="l00962" name="l00962"></a><span class="lineno"> 962</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a3e5f39b52251ad02e571592493b4d39f">CompressTuples</a>(domain_sizes, any_value, &amp;tuples);</div>
<div class="line"><a id="l00963" name="l00963"></a><span class="lineno"> 963</span> </div>
<div class="line"><a id="l00964" name="l00964"></a><span class="lineno"> 964</span> <span class="comment">// For each tuple, forbid the variables values to be this tuple.</span></div>
<div class="line"><a id="l00965" name="l00965"></a><span class="lineno"> 965</span> std::vector&lt;int&gt; clause;</div>
<div class="line"><a id="l00966" name="l00966"></a><span class="lineno"> 966</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> std::vector&lt;int64_t&gt;&amp; tuple : tuples) {</div>
<div class="line"><a id="l00967" name="l00967"></a><span class="lineno"> 967</span> clause.clear();</div>
<div class="line"><a id="l00968" name="l00968"></a><span class="lineno"> 968</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_vars; ++i) {</div>
<div class="line"><a id="l00969" name="l00969"></a><span class="lineno"> 969</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = tuple[i];</div>
<div class="line"><a id="l00970" name="l00970"></a><span class="lineno"> 970</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> == any_value) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l00971" name="l00971"></a><span class="lineno"> 971</span> </div>
<div class="line"><a id="l00972" name="l00972"></a><span class="lineno"> 972</span> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a> =</div>
<div class="line"><a id="l00973" name="l00973"></a><span class="lineno"> 973</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(table.vars(i), <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l00974" name="l00974"></a><span class="lineno"> 974</span> clause.push_back(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(<a class="code hl_variable" href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a>));</div>
<div class="line"><a id="l00975" name="l00975"></a><span class="lineno"> 975</span> }</div>
<div class="line"><a id="l00976" name="l00976"></a><span class="lineno"> 976</span> </div>
<div class="line"><a id="l00977" name="l00977"></a><span class="lineno"> 977</span> <span class="comment">// Note: if the clause is empty, then the model is infeasible.</span></div>
<div class="line"><a id="l00978" name="l00978"></a><span class="lineno"> 978</span> BoolArgumentProto* bool_or =</div>
<div class="line"><a id="l00979" name="l00979"></a><span class="lineno"> 979</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l00980" name="l00980"></a><span class="lineno"> 980</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> lit : clause) {</div>
<div class="line"><a id="l00981" name="l00981"></a><span class="lineno"> 981</span> bool_or-&gt;add_literals(lit);</div>
<div class="line"><a id="l00982" name="l00982"></a><span class="lineno"> 982</span> }</div>
<div class="line"><a id="l00983" name="l00983"></a><span class="lineno"> 983</span> }</div>
<div class="line"><a id="l00984" name="l00984"></a><span class="lineno"> 984</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: expanded negated constraint&quot;</span>);</div>
<div class="line"><a id="l00985" name="l00985"></a><span class="lineno"> 985</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l00986" name="l00986"></a><span class="lineno"> 986</span>}</div>
<div class="line"><a id="l00987" name="l00987"></a><span class="lineno"> 987</span> </div>
<div class="line"><a id="l00988" name="l00988"></a><span class="lineno"> 988</span><span class="comment">// Add the implications and clauses to link one variable of a table to the</span></div>
<div class="line"><a id="l00989" name="l00989"></a><span class="lineno"> 989</span><span class="comment">// literals controlling if the tuples are possible or not. The parallel vectors</span></div>
<div class="line"><a id="l00990" name="l00990"></a><span class="lineno"> 990</span><span class="comment">// (tuple_literals, values) contains all valid projected tuples.</span></div>
<div class="line"><a id="l00991" name="l00991"></a><span class="lineno"> 991</span><span class="comment">//</span></div>
<div class="line"><a id="l00992" name="l00992"></a><span class="lineno"> 992</span><span class="comment">// The special value &quot;any_value&quot; is used to indicate literal that will support</span></div>
<div class="line"><a id="l00993" name="l00993"></a><span class="lineno"> 993</span><span class="comment">// any value.</span></div>
<div class="line"><a id="l00994" name="l00994"></a><span class="lineno"> 994</span><span class="keywordtype">void</span> ProcessOneVariable(<span class="keyword">const</span> std::vector&lt;int&gt;&amp; tuple_literals,</div>
<div class="line"><a id="l00995" name="l00995"></a><span class="lineno"> 995</span> <span class="keyword">const</span> std::vector&lt;int64_t&gt;&amp; values, <span class="keywordtype">int</span> variable,</div>
<div class="line"><a id="l00996" name="l00996"></a><span class="lineno"> 996</span> int64_t any_value, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l00997" name="l00997"></a><span class="lineno"> 997</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(2) &lt;&lt; <span class="stringliteral">&quot;Process var(&quot;</span> &lt;&lt; variable &lt;&lt; <span class="stringliteral">&quot;) with domain &quot;</span></div>
<div class="line"><a id="l00998" name="l00998"></a><span class="lineno"> 998</span> &lt;&lt; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(variable) &lt;&lt; <span class="stringliteral">&quot; and &quot;</span> &lt;&lt; values.size()</div>
<div class="line"><a id="l00999" name="l00999"></a><span class="lineno"> 999</span> &lt;&lt; <span class="stringliteral">&quot; tuples.&quot;</span>;</div>
<div class="line"><a id="l01000" name="l01000"></a><span class="lineno"> 1000</span> <a class="code hl_define" href="base_2logging_8h.html#a7c0ce053b28d53aa4eaf3eb7fb71663b">CHECK_EQ</a>(tuple_literals.size(), values.size());</div>
<div class="line"><a id="l01001" name="l01001"></a><span class="lineno"> 1001</span> </div>
<div class="line"><a id="l01002" name="l01002"></a><span class="lineno"> 1002</span> <span class="comment">// Collect pairs of value-literal.</span></div>
<div class="line"><a id="l01003" name="l01003"></a><span class="lineno"> 1003</span> std::vector&lt;int&gt; tuples_with_any;</div>
<div class="line"><a id="l01004" name="l01004"></a><span class="lineno"> 1004</span> std::vector&lt;std::pair&lt;int64_t, int&gt;&gt; pairs;</div>
<div class="line"><a id="l01005" name="l01005"></a><span class="lineno"> 1005</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; values.size(); ++i) {</div>
<div class="line"><a id="l01006" name="l01006"></a><span class="lineno"> 1006</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = values[i];</div>
<div class="line"><a id="l01007" name="l01007"></a><span class="lineno"> 1007</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> == any_value) {</div>
<div class="line"><a id="l01008" name="l01008"></a><span class="lineno"> 1008</span> tuples_with_any.push_back(tuple_literals[i]);</div>
<div class="line"><a id="l01009" name="l01009"></a><span class="lineno"> 1009</span> <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l01010" name="l01010"></a><span class="lineno"> 1010</span> }</div>
<div class="line"><a id="l01011" name="l01011"></a><span class="lineno"> 1011</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(variable, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>));</div>
<div class="line"><a id="l01012" name="l01012"></a><span class="lineno"> 1012</span> pairs.emplace_back(<a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>, tuple_literals[i]);</div>
<div class="line"><a id="l01013" name="l01013"></a><span class="lineno"> 1013</span> }</div>
<div class="line"><a id="l01014" name="l01014"></a><span class="lineno"> 1014</span> </div>
<div class="line"><a id="l01015" name="l01015"></a><span class="lineno"> 1015</span> <span class="comment">// Regroup literal with the same value and add for each the clause: If all the</span></div>
<div class="line"><a id="l01016" name="l01016"></a><span class="lineno"> 1016</span> <span class="comment">// tuples containing a value are false, then this value must be false too.</span></div>
<div class="line"><a id="l01017" name="l01017"></a><span class="lineno"> 1017</span> std::vector&lt;int&gt; selected;</div>
<div class="line"><a id="l01018" name="l01018"></a><span class="lineno"> 1018</span> std::sort(pairs.begin(), pairs.end());</div>
<div class="line"><a id="l01019" name="l01019"></a><span class="lineno"> 1019</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; pairs.size();) {</div>
<div class="line"><a id="l01020" name="l01020"></a><span class="lineno"> 1020</span> selected.clear();</div>
<div class="line"><a id="l01021" name="l01021"></a><span class="lineno"> 1021</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = pairs[i].first;</div>
<div class="line"><a id="l01022" name="l01022"></a><span class="lineno"> 1022</span> <span class="keywordflow">for</span> (; i &lt; pairs.size() &amp;&amp; pairs[i].first == <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>; ++i) {</div>
<div class="line"><a id="l01023" name="l01023"></a><span class="lineno"> 1023</span> selected.push_back(pairs[i].second);</div>
<div class="line"><a id="l01024" name="l01024"></a><span class="lineno"> 1024</span> }</div>
<div class="line"><a id="l01025" name="l01025"></a><span class="lineno"> 1025</span> </div>
<div class="line"><a id="l01026" name="l01026"></a><span class="lineno"> 1026</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(!selected.empty() || !tuples_with_any.empty());</div>
<div class="line"><a id="l01027" name="l01027"></a><span class="lineno"> 1027</span> <span class="keywordflow">if</span> (selected.size() == 1 &amp;&amp; tuples_with_any.empty()) {</div>
<div class="line"><a id="l01028" name="l01028"></a><span class="lineno"> 1028</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InsertVarValueEncoding(selected.front(), variable, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l01029" name="l01029"></a><span class="lineno"> 1029</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01030" name="l01030"></a><span class="lineno"> 1030</span> <span class="keyword">const</span> <span class="keywordtype">int</span> value_literal =</div>
<div class="line"><a id="l01031" name="l01031"></a><span class="lineno"> 1031</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(variable, <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div>
<div class="line"><a id="l01032" name="l01032"></a><span class="lineno"> 1032</span> BoolArgumentProto* no_support =</div>
<div class="line"><a id="l01033" name="l01033"></a><span class="lineno"> 1033</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l01034" name="l01034"></a><span class="lineno"> 1034</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> lit : selected) {</div>
<div class="line"><a id="l01035" name="l01035"></a><span class="lineno"> 1035</span> no_support-&gt;add_literals(lit);</div>
<div class="line"><a id="l01036" name="l01036"></a><span class="lineno"> 1036</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplication(lit, value_literal);</div>
<div class="line"><a id="l01037" name="l01037"></a><span class="lineno"> 1037</span> }</div>
<div class="line"><a id="l01038" name="l01038"></a><span class="lineno"> 1038</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> lit : tuples_with_any) {</div>
<div class="line"><a id="l01039" name="l01039"></a><span class="lineno"> 1039</span> no_support-&gt;add_literals(lit);</div>
<div class="line"><a id="l01040" name="l01040"></a><span class="lineno"> 1040</span> }</div>
<div class="line"><a id="l01041" name="l01041"></a><span class="lineno"> 1041</span> </div>
<div class="line"><a id="l01042" name="l01042"></a><span class="lineno"> 1042</span> <span class="comment">// And the &quot;value&quot; literal.</span></div>
<div class="line"><a id="l01043" name="l01043"></a><span class="lineno"> 1043</span> no_support-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(value_literal));</div>
<div class="line"><a id="l01044" name="l01044"></a><span class="lineno"> 1044</span> }</div>
<div class="line"><a id="l01045" name="l01045"></a><span class="lineno"> 1045</span> }</div>
<div class="line"><a id="l01046" name="l01046"></a><span class="lineno"> 1046</span>}</div>
<div class="line"><a id="l01047" name="l01047"></a><span class="lineno"> 1047</span> </div>
<div class="line"><a id="l01048" name="l01048"></a><span class="lineno"> 1048</span><span class="comment">// Simpler encoding for table constraints with 2 variables.</span></div>
<div class="line"><a id="l01049" name="l01049"></a><span class="lineno"> 1049</span><span class="keywordtype">void</span> AddSizeTwoTable(</div>
<div class="line"><a id="l01050" name="l01050"></a><span class="lineno"> 1050</span> <span class="keyword">const</span> std::vector&lt;int&gt;&amp; vars,</div>
<div class="line"><a id="l01051" name="l01051"></a><span class="lineno"> 1051</span> <span class="keyword">const</span> std::vector&lt;std::vector&lt;int64_t&gt;&gt;&amp; tuples,</div>
<div class="line"><a id="l01052" name="l01052"></a><span class="lineno"> 1052</span> <span class="keyword">const</span> std::vector&lt;absl::flat_hash_set&lt;int64_t&gt;&gt;&amp; values_per_var,</div>
<div class="line"><a id="l01053" name="l01053"></a><span class="lineno"> 1053</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01054" name="l01054"></a><span class="lineno"> 1054</span> <a class="code hl_define" href="base_2logging_8h.html#a7c0ce053b28d53aa4eaf3eb7fb71663b">CHECK_EQ</a>(vars.size(), 2);</div>
<div class="line"><a id="l01055" name="l01055"></a><span class="lineno"> 1055</span> <span class="keyword">const</span> <span class="keywordtype">int</span> left_var = vars[0];</div>
<div class="line"><a id="l01056" name="l01056"></a><span class="lineno"> 1056</span> <span class="keyword">const</span> <span class="keywordtype">int</span> right_var = vars[1];</div>
<div class="line"><a id="l01057" name="l01057"></a><span class="lineno"> 1057</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(left_var).IsFixed() ||</div>
<div class="line"><a id="l01058" name="l01058"></a><span class="lineno"> 1058</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(right_var).IsFixed()) {</div>
<div class="line"><a id="l01059" name="l01059"></a><span class="lineno"> 1059</span> <span class="comment">// A table constraint with at most one variable not fixed is trivially</span></div>
<div class="line"><a id="l01060" name="l01060"></a><span class="lineno"> 1060</span> <span class="comment">// enforced after domain reduction.</span></div>
<div class="line"><a id="l01061" name="l01061"></a><span class="lineno"> 1061</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01062" name="l01062"></a><span class="lineno"> 1062</span> }</div>
<div class="line"><a id="l01063" name="l01063"></a><span class="lineno"> 1063</span> </div>
<div class="line"><a id="l01064" name="l01064"></a><span class="lineno"> 1064</span> absl::btree_map&lt;int, std::vector&lt;int&gt;&gt; left_to_right;</div>
<div class="line"><a id="l01065" name="l01065"></a><span class="lineno"> 1065</span> absl::btree_map&lt;int, std::vector&lt;int&gt;&gt; right_to_left;</div>
<div class="line"><a id="l01066" name="l01066"></a><span class="lineno"> 1066</span> </div>
<div class="line"><a id="l01067" name="l01067"></a><span class="lineno"> 1067</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; tuple : tuples) {</div>
<div class="line"><a id="l01068" name="l01068"></a><span class="lineno"> 1068</span> <span class="keyword">const</span> int64_t left_value(tuple[0]);</div>
<div class="line"><a id="l01069" name="l01069"></a><span class="lineno"> 1069</span> <span class="keyword">const</span> int64_t right_value(tuple[1]);</div>
<div class="line"><a id="l01070" name="l01070"></a><span class="lineno"> 1070</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(left_var, left_value));</div>
<div class="line"><a id="l01071" name="l01071"></a><span class="lineno"> 1071</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(right_var, right_value));</div>
<div class="line"><a id="l01072" name="l01072"></a><span class="lineno"> 1072</span> </div>
<div class="line"><a id="l01073" name="l01073"></a><span class="lineno"> 1073</span> <span class="keyword">const</span> <span class="keywordtype">int</span> left_literal =</div>
<div class="line"><a id="l01074" name="l01074"></a><span class="lineno"> 1074</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(left_var, left_value);</div>
<div class="line"><a id="l01075" name="l01075"></a><span class="lineno"> 1075</span> <span class="keyword">const</span> <span class="keywordtype">int</span> right_literal =</div>
<div class="line"><a id="l01076" name="l01076"></a><span class="lineno"> 1076</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(right_var, right_value);</div>
<div class="line"><a id="l01077" name="l01077"></a><span class="lineno"> 1077</span> left_to_right[left_literal].push_back(right_literal);</div>
<div class="line"><a id="l01078" name="l01078"></a><span class="lineno"> 1078</span> right_to_left[right_literal].push_back(left_literal);</div>
<div class="line"><a id="l01079" name="l01079"></a><span class="lineno"> 1079</span> }</div>
<div class="line"><a id="l01080" name="l01080"></a><span class="lineno"> 1080</span> </div>
<div class="line"><a id="l01081" name="l01081"></a><span class="lineno"> 1081</span> <span class="keywordtype">int</span> num_implications = 0;</div>
<div class="line"><a id="l01082" name="l01082"></a><span class="lineno"> 1082</span> <span class="keywordtype">int</span> num_clause_added = 0;</div>
<div class="line"><a id="l01083" name="l01083"></a><span class="lineno"> 1083</span> <span class="keywordtype">int</span> num_large_clause_added = 0;</div>
<div class="line"><a id="l01084" name="l01084"></a><span class="lineno"> 1084</span> <span class="keyword">auto</span> add_support_constraint =</div>
<div class="line"><a id="l01085" name="l01085"></a><span class="lineno"> 1085</span> [<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>, &amp;num_clause_added, &amp;num_large_clause_added, &amp;num_implications](</div>
<div class="line"><a id="l01086" name="l01086"></a><span class="lineno"> 1086</span> <span class="keywordtype">int</span> lit, <span class="keyword">const</span> std::vector&lt;int&gt;&amp; support_literals,</div>
<div class="line"><a id="l01087" name="l01087"></a><span class="lineno"> 1087</span> <span class="keywordtype">int</span> max_support_size) {</div>
<div class="line"><a id="l01088" name="l01088"></a><span class="lineno"> 1088</span> <span class="keywordflow">if</span> (support_literals.size() == max_support_size) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01089" name="l01089"></a><span class="lineno"> 1089</span> <span class="keywordflow">if</span> (support_literals.size() == 1) {</div>
<div class="line"><a id="l01090" name="l01090"></a><span class="lineno"> 1090</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;AddImplication(lit, support_literals.front());</div>
<div class="line"><a id="l01091" name="l01091"></a><span class="lineno"> 1091</span> num_implications++;</div>
<div class="line"><a id="l01092" name="l01092"></a><span class="lineno"> 1092</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01093" name="l01093"></a><span class="lineno"> 1093</span> BoolArgumentProto* bool_or =</div>
<div class="line"><a id="l01094" name="l01094"></a><span class="lineno"> 1094</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l01095" name="l01095"></a><span class="lineno"> 1095</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> support_literal : support_literals) {</div>
<div class="line"><a id="l01096" name="l01096"></a><span class="lineno"> 1096</span> bool_or-&gt;add_literals(support_literal);</div>
<div class="line"><a id="l01097" name="l01097"></a><span class="lineno"> 1097</span> }</div>
<div class="line"><a id="l01098" name="l01098"></a><span class="lineno"> 1098</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(lit));</div>
<div class="line"><a id="l01099" name="l01099"></a><span class="lineno"> 1099</span> num_clause_added++;</div>
<div class="line"><a id="l01100" name="l01100"></a><span class="lineno"> 1100</span> <span class="keywordflow">if</span> (support_literals.size() &gt; max_support_size / 2) {</div>
<div class="line"><a id="l01101" name="l01101"></a><span class="lineno"> 1101</span> num_large_clause_added++;</div>
<div class="line"><a id="l01102" name="l01102"></a><span class="lineno"> 1102</span> }</div>
<div class="line"><a id="l01103" name="l01103"></a><span class="lineno"> 1103</span> }</div>
<div class="line"><a id="l01104" name="l01104"></a><span class="lineno"> 1104</span> };</div>
<div class="line"><a id="l01105" name="l01105"></a><span class="lineno"> 1105</span> </div>
<div class="line"><a id="l01106" name="l01106"></a><span class="lineno"> 1106</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; it : left_to_right) {</div>
<div class="line"><a id="l01107" name="l01107"></a><span class="lineno"> 1107</span> add_support_constraint(it.first, it.second, values_per_var[1].size());</div>
<div class="line"><a id="l01108" name="l01108"></a><span class="lineno"> 1108</span> }</div>
<div class="line"><a id="l01109" name="l01109"></a><span class="lineno"> 1109</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; it : right_to_left) {</div>
<div class="line"><a id="l01110" name="l01110"></a><span class="lineno"> 1110</span> add_support_constraint(it.first, it.second, values_per_var[0].size());</div>
<div class="line"><a id="l01111" name="l01111"></a><span class="lineno"> 1111</span> }</div>
<div class="line"><a id="l01112" name="l01112"></a><span class="lineno"> 1112</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(2) &lt;&lt; <span class="stringliteral">&quot;Table: 2 variables, &quot;</span> &lt;&lt; tuples.size() &lt;&lt; <span class="stringliteral">&quot; tuples encoded using &quot;</span></div>
<div class="line"><a id="l01113" name="l01113"></a><span class="lineno"> 1113</span> &lt;&lt; num_clause_added &lt;&lt; <span class="stringliteral">&quot; clauses, including &quot;</span></div>
<div class="line"><a id="l01114" name="l01114"></a><span class="lineno"> 1114</span> &lt;&lt; num_large_clause_added &lt;&lt; <span class="stringliteral">&quot; large clauses, &quot;</span> &lt;&lt; num_implications</div>
<div class="line"><a id="l01115" name="l01115"></a><span class="lineno"> 1115</span> &lt;&lt; <span class="stringliteral">&quot; implications&quot;</span>;</div>
<div class="line"><a id="l01116" name="l01116"></a><span class="lineno"> 1116</span>}</div>
<div class="line"><a id="l01117" name="l01117"></a><span class="lineno"> 1117</span> </div>
<div class="line"><a id="l01118" name="l01118"></a><span class="lineno"> 1118</span><span class="keywordtype">void</span> ExpandPositiveTable(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01119" name="l01119"></a><span class="lineno"> 1119</span> <span class="keyword">const</span> TableConstraintProto&amp; table = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;table();</div>
<div class="line"><a id="l01120" name="l01120"></a><span class="lineno"> 1120</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_vars = table.vars_size();</div>
<div class="line"><a id="l01121" name="l01121"></a><span class="lineno"> 1121</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_original_tuples = table.values_size() / num_vars;</div>
<div class="line"><a id="l01122" name="l01122"></a><span class="lineno"> 1122</span> </div>
<div class="line"><a id="l01123" name="l01123"></a><span class="lineno"> 1123</span> <span class="comment">// Read tuples flat array and recreate the vector of tuples.</span></div>
<div class="line"><a id="l01124" name="l01124"></a><span class="lineno"> 1124</span> <span class="keyword">const</span> std::vector&lt;int&gt; vars(table.vars().begin(), table.vars().end());</div>
<div class="line"><a id="l01125" name="l01125"></a><span class="lineno"> 1125</span> std::vector&lt;std::vector&lt;int64_t&gt;&gt; tuples(num_original_tuples);</div>
<div class="line"><a id="l01126" name="l01126"></a><span class="lineno"> 1126</span> <span class="keywordtype">int</span> count = 0;</div>
<div class="line"><a id="l01127" name="l01127"></a><span class="lineno"> 1127</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> tuple_index = 0; tuple_index &lt; num_original_tuples; ++tuple_index) {</div>
<div class="line"><a id="l01128" name="l01128"></a><span class="lineno"> 1128</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01129" name="l01129"></a><span class="lineno"> 1129</span> tuples[tuple_index].push_back(table.values(count++));</div>
<div class="line"><a id="l01130" name="l01130"></a><span class="lineno"> 1130</span> }</div>
<div class="line"><a id="l01131" name="l01131"></a><span class="lineno"> 1131</span> }</div>
<div class="line"><a id="l01132" name="l01132"></a><span class="lineno"> 1132</span> </div>
<div class="line"><a id="l01133" name="l01133"></a><span class="lineno"> 1133</span> <span class="comment">// Compute the set of possible values for each variable (from the table).</span></div>
<div class="line"><a id="l01134" name="l01134"></a><span class="lineno"> 1134</span> <span class="comment">// Remove invalid tuples along the way.</span></div>
<div class="line"><a id="l01135" name="l01135"></a><span class="lineno"> 1135</span> std::vector&lt;absl::flat_hash_set&lt;int64_t&gt;&gt; values_per_var(num_vars);</div>
<div class="line"><a id="l01136" name="l01136"></a><span class="lineno"> 1136</span> <span class="keywordtype">int</span> new_size = 0;</div>
<div class="line"><a id="l01137" name="l01137"></a><span class="lineno"> 1137</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> tuple_index = 0; tuple_index &lt; num_original_tuples; ++tuple_index) {</div>
<div class="line"><a id="l01138" name="l01138"></a><span class="lineno"> 1138</span> <span class="keywordtype">bool</span> keep = <span class="keyword">true</span>;</div>
<div class="line"><a id="l01139" name="l01139"></a><span class="lineno"> 1139</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01140" name="l01140"></a><span class="lineno"> 1140</span> <span class="keyword">const</span> int64_t <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a> = tuples[tuple_index][var_index];</div>
<div class="line"><a id="l01141" name="l01141"></a><span class="lineno"> 1141</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(vars[var_index], <a class="code hl_variable" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>)) {</div>
<div class="line"><a id="l01142" name="l01142"></a><span class="lineno"> 1142</span> keep = <span class="keyword">false</span>;</div>
<div class="line"><a id="l01143" name="l01143"></a><span class="lineno"> 1143</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01144" name="l01144"></a><span class="lineno"> 1144</span> }</div>
<div class="line"><a id="l01145" name="l01145"></a><span class="lineno"> 1145</span> }</div>
<div class="line"><a id="l01146" name="l01146"></a><span class="lineno"> 1146</span> <span class="keywordflow">if</span> (keep) {</div>
<div class="line"><a id="l01147" name="l01147"></a><span class="lineno"> 1147</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01148" name="l01148"></a><span class="lineno"> 1148</span> values_per_var[var_index].insert(tuples[tuple_index][var_index]);</div>
<div class="line"><a id="l01149" name="l01149"></a><span class="lineno"> 1149</span> }</div>
<div class="line"><a id="l01150" name="l01150"></a><span class="lineno"> 1150</span> <a class="code hl_function" href="namespaceoperations__research_1_1math__opt.html#a5de89a1f6e3f80a49a0d76136d8044e2">std::swap</a>(tuples[tuple_index], tuples[new_size]);</div>
<div class="line"><a id="l01151" name="l01151"></a><span class="lineno"> 1151</span> new_size++;</div>
<div class="line"><a id="l01152" name="l01152"></a><span class="lineno"> 1152</span> }</div>
<div class="line"><a id="l01153" name="l01153"></a><span class="lineno"> 1153</span> }</div>
<div class="line"><a id="l01154" name="l01154"></a><span class="lineno"> 1154</span> tuples.resize(new_size);</div>
<div class="line"><a id="l01155" name="l01155"></a><span class="lineno"> 1155</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_valid_tuples = tuples.size();</div>
<div class="line"><a id="l01156" name="l01156"></a><span class="lineno"> 1156</span> </div>
<div class="line"><a id="l01157" name="l01157"></a><span class="lineno"> 1157</span> <span class="keywordflow">if</span> (tuples.empty()) {</div>
<div class="line"><a id="l01158" name="l01158"></a><span class="lineno"> 1158</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: empty&quot;</span>);</div>
<div class="line"><a id="l01159" name="l01159"></a><span class="lineno"> 1159</span> <span class="keywordflow">return</span> (<span class="keywordtype">void</span>)<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsUnsat();</div>
<div class="line"><a id="l01160" name="l01160"></a><span class="lineno"> 1160</span> }</div>
<div class="line"><a id="l01161" name="l01161"></a><span class="lineno"> 1161</span> </div>
<div class="line"><a id="l01162" name="l01162"></a><span class="lineno"> 1162</span> <span class="comment">// Update variable domains. It is redundant with presolve, but we could be</span></div>
<div class="line"><a id="l01163" name="l01163"></a><span class="lineno"> 1163</span> <span class="comment">// here with presolve = false.</span></div>
<div class="line"><a id="l01164" name="l01164"></a><span class="lineno"> 1164</span> <span class="comment">// Also counts the number of fixed variables.</span></div>
<div class="line"><a id="l01165" name="l01165"></a><span class="lineno"> 1165</span> <span class="keywordtype">int</span> num_fixed_variables = 0;</div>
<div class="line"><a id="l01166" name="l01166"></a><span class="lineno"> 1166</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01167" name="l01167"></a><span class="lineno"> 1167</span> <a class="code hl_define" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(</div>
<div class="line"><a id="l01168" name="l01168"></a><span class="lineno"> 1168</span> vars[var_index],</div>
<div class="line"><a id="l01169" name="l01169"></a><span class="lineno"> 1169</span> <a class="code hl_function" href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">Domain::FromValues</a>({values_per_var[var_index].begin(),</div>
<div class="line"><a id="l01170" name="l01170"></a><span class="lineno"> 1170</span> values_per_var[var_index].end()})));</div>
<div class="line"><a id="l01171" name="l01171"></a><span class="lineno"> 1171</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(vars[var_index]).IsFixed()) {</div>
<div class="line"><a id="l01172" name="l01172"></a><span class="lineno"> 1172</span> num_fixed_variables++;</div>
<div class="line"><a id="l01173" name="l01173"></a><span class="lineno"> 1173</span> }</div>
<div class="line"><a id="l01174" name="l01174"></a><span class="lineno"> 1174</span> }</div>
<div class="line"><a id="l01175" name="l01175"></a><span class="lineno"> 1175</span> </div>
<div class="line"><a id="l01176" name="l01176"></a><span class="lineno"> 1176</span> <span class="keywordflow">if</span> (num_fixed_variables == num_vars - 1) {</div>
<div class="line"><a id="l01177" name="l01177"></a><span class="lineno"> 1177</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: one variable not fixed&quot;</span>);</div>
<div class="line"><a id="l01178" name="l01178"></a><span class="lineno"> 1178</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01179" name="l01179"></a><span class="lineno"> 1179</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01180" name="l01180"></a><span class="lineno"> 1180</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (num_fixed_variables == num_vars) {</div>
<div class="line"><a id="l01181" name="l01181"></a><span class="lineno"> 1181</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: all variables fixed&quot;</span>);</div>
<div class="line"><a id="l01182" name="l01182"></a><span class="lineno"> 1182</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01183" name="l01183"></a><span class="lineno"> 1183</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01184" name="l01184"></a><span class="lineno"> 1184</span> }</div>
<div class="line"><a id="l01185" name="l01185"></a><span class="lineno"> 1185</span> </div>
<div class="line"><a id="l01186" name="l01186"></a><span class="lineno"> 1186</span> <span class="comment">// Tables with two variables do not need tuple literals.</span></div>
<div class="line"><a id="l01187" name="l01187"></a><span class="lineno"> 1187</span> <span class="keywordflow">if</span> (num_vars == 2) {</div>
<div class="line"><a id="l01188" name="l01188"></a><span class="lineno"> 1188</span> AddSizeTwoTable(vars, tuples, values_per_var, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01189" name="l01189"></a><span class="lineno"> 1189</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(</div>
<div class="line"><a id="l01190" name="l01190"></a><span class="lineno"> 1190</span> <span class="stringliteral">&quot;table: expanded positive constraint with two variables&quot;</span>);</div>
<div class="line"><a id="l01191" name="l01191"></a><span class="lineno"> 1191</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01192" name="l01192"></a><span class="lineno"> 1192</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01193" name="l01193"></a><span class="lineno"> 1193</span> }</div>
<div class="line"><a id="l01194" name="l01194"></a><span class="lineno"> 1194</span> </div>
<div class="line"><a id="l01195" name="l01195"></a><span class="lineno"> 1195</span> <span class="comment">// It is easier to compute this before compression, as compression will merge</span></div>
<div class="line"><a id="l01196" name="l01196"></a><span class="lineno"> 1196</span> <span class="comment">// tuples.</span></div>
<div class="line"><a id="l01197" name="l01197"></a><span class="lineno"> 1197</span> <span class="keywordtype">int</span> num_prefix_tuples = 0;</div>
<div class="line"><a id="l01198" name="l01198"></a><span class="lineno"> 1198</span> {</div>
<div class="line"><a id="l01199" name="l01199"></a><span class="lineno"> 1199</span> absl::flat_hash_set&lt;absl::Span&lt;const int64_t&gt;&gt; prefixes;</div>
<div class="line"><a id="l01200" name="l01200"></a><span class="lineno"> 1200</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> std::vector&lt;int64_t&gt;&amp; tuple : tuples) {</div>
<div class="line"><a id="l01201" name="l01201"></a><span class="lineno"> 1201</span> prefixes.insert(absl::MakeSpan(tuple.data(), num_vars - 1));</div>
<div class="line"><a id="l01202" name="l01202"></a><span class="lineno"> 1202</span> }</div>
<div class="line"><a id="l01203" name="l01203"></a><span class="lineno"> 1203</span> num_prefix_tuples = prefixes.size();</div>
<div class="line"><a id="l01204" name="l01204"></a><span class="lineno"> 1204</span> }</div>
<div class="line"><a id="l01205" name="l01205"></a><span class="lineno"> 1205</span> </div>
<div class="line"><a id="l01206" name="l01206"></a><span class="lineno"> 1206</span> <span class="comment">// TODO(user): reinvestigate ExploreSubsetOfVariablesAndAddNegatedTables.</span></div>
<div class="line"><a id="l01207" name="l01207"></a><span class="lineno"> 1207</span> </div>
<div class="line"><a id="l01208" name="l01208"></a><span class="lineno"> 1208</span> <span class="comment">// Compress tuples.</span></div>
<div class="line"><a id="l01209" name="l01209"></a><span class="lineno"> 1209</span> <span class="keyword">const</span> int64_t any_value = <a class="code hl_variable" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::numeric_limits&lt;int64_t&gt;::min</a>();</div>
<div class="line"><a id="l01210" name="l01210"></a><span class="lineno"> 1210</span> std::vector&lt;int64_t&gt; domain_sizes;</div>
<div class="line"><a id="l01211" name="l01211"></a><span class="lineno"> 1211</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_vars; ++i) {</div>
<div class="line"><a id="l01212" name="l01212"></a><span class="lineno"> 1212</span> domain_sizes.push_back(values_per_var[i].size());</div>
<div class="line"><a id="l01213" name="l01213"></a><span class="lineno"> 1213</span> }</div>
<div class="line"><a id="l01214" name="l01214"></a><span class="lineno"> 1214</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_tuples_before_compression = tuples.size();</div>
<div class="line"><a id="l01215" name="l01215"></a><span class="lineno"> 1215</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a3e5f39b52251ad02e571592493b4d39f">CompressTuples</a>(domain_sizes, any_value, &amp;tuples);</div>
<div class="line"><a id="l01216" name="l01216"></a><span class="lineno"> 1216</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_compressed_tuples = tuples.size();</div>
<div class="line"><a id="l01217" name="l01217"></a><span class="lineno"> 1217</span> <span class="keywordflow">if</span> (num_compressed_tuples &lt; num_tuples_before_compression) {</div>
<div class="line"><a id="l01218" name="l01218"></a><span class="lineno"> 1218</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: compress tuples&quot;</span>);</div>
<div class="line"><a id="l01219" name="l01219"></a><span class="lineno"> 1219</span> }</div>
<div class="line"><a id="l01220" name="l01220"></a><span class="lineno"> 1220</span> </div>
<div class="line"><a id="l01221" name="l01221"></a><span class="lineno"> 1221</span> <span class="keywordflow">if</span> (num_compressed_tuples == 1) {</div>
<div class="line"><a id="l01222" name="l01222"></a><span class="lineno"> 1222</span> <span class="comment">// Domains are propagated. We can remove the constraint.</span></div>
<div class="line"><a id="l01223" name="l01223"></a><span class="lineno"> 1223</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: one tuple&quot;</span>);</div>
<div class="line"><a id="l01224" name="l01224"></a><span class="lineno"> 1224</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01225" name="l01225"></a><span class="lineno"> 1225</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01226" name="l01226"></a><span class="lineno"> 1226</span> }</div>
<div class="line"><a id="l01227" name="l01227"></a><span class="lineno"> 1227</span> </div>
<div class="line"><a id="l01228" name="l01228"></a><span class="lineno"> 1228</span> <span class="comment">// Detect if prefix tuples are all different.</span></div>
<div class="line"><a id="l01229" name="l01229"></a><span class="lineno"> 1229</span> <span class="keyword">const</span> <span class="keywordtype">bool</span> prefixes_are_all_different = num_prefix_tuples == num_valid_tuples;</div>
<div class="line"><a id="l01230" name="l01230"></a><span class="lineno"> 1230</span> <span class="keywordflow">if</span> (prefixes_are_all_different) {</div>
<div class="line"><a id="l01231" name="l01231"></a><span class="lineno"> 1231</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(</div>
<div class="line"><a id="l01232" name="l01232"></a><span class="lineno"> 1232</span> <span class="stringliteral">&quot;TODO table: last value implied by previous values&quot;</span>);</div>
<div class="line"><a id="l01233" name="l01233"></a><span class="lineno"> 1233</span> }</div>
<div class="line"><a id="l01234" name="l01234"></a><span class="lineno"> 1234</span> <span class="comment">// TODO(user): if 2 table constraints share the same valid prefix, the</span></div>
<div class="line"><a id="l01235" name="l01235"></a><span class="lineno"> 1235</span> <span class="comment">// tuple literals can be reused.</span></div>
<div class="line"><a id="l01236" name="l01236"></a><span class="lineno"> 1236</span> <span class="comment">// TODO(user): investigate different encoding for prefix tables. Maybe</span></div>
<div class="line"><a id="l01237" name="l01237"></a><span class="lineno"> 1237</span> <span class="comment">// we can remove the need to create tuple literals.</span></div>
<div class="line"><a id="l01238" name="l01238"></a><span class="lineno"> 1238</span> </div>
<div class="line"><a id="l01239" name="l01239"></a><span class="lineno"> 1239</span> <span class="comment">// Debug message to log the status of the expansion.</span></div>
<div class="line"><a id="l01240" name="l01240"></a><span class="lineno"> 1240</span> <span class="keywordflow">if</span> (<a class="code hl_define" href="vlog__is__on_8h.html#a956152cad330225654d128f35c00efce">VLOG_IS_ON</a>(2)) {</div>
<div class="line"><a id="l01241" name="l01241"></a><span class="lineno"> 1241</span> <span class="comment">// Compute the maximum number of prefix tuples.</span></div>
<div class="line"><a id="l01242" name="l01242"></a><span class="lineno"> 1242</span> int64_t max_num_prefix_tuples = 1;</div>
<div class="line"><a id="l01243" name="l01243"></a><span class="lineno"> 1243</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index + 1 &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01244" name="l01244"></a><span class="lineno"> 1244</span> max_num_prefix_tuples =</div>
<div class="line"><a id="l01245" name="l01245"></a><span class="lineno"> 1245</span> <a class="code hl_function" href="namespaceoperations__research.html#aa64bf49d041052c7cb3f40f7496d7534">CapProd</a>(max_num_prefix_tuples, values_per_var[var_index].size());</div>
<div class="line"><a id="l01246" name="l01246"></a><span class="lineno"> 1246</span> }</div>
<div class="line"><a id="l01247" name="l01247"></a><span class="lineno"> 1247</span> </div>
<div class="line"><a id="l01248" name="l01248"></a><span class="lineno"> 1248</span> std::string <a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a> =</div>
<div class="line"><a id="l01249" name="l01249"></a><span class="lineno"> 1249</span> absl::StrCat(<span class="stringliteral">&quot;Table: &quot;</span>, num_vars,</div>
<div class="line"><a id="l01250" name="l01250"></a><span class="lineno"> 1250</span> <span class="stringliteral">&quot; variables, original tuples = &quot;</span>, num_original_tuples);</div>
<div class="line"><a id="l01251" name="l01251"></a><span class="lineno"> 1251</span> <span class="keywordflow">if</span> (num_valid_tuples != num_original_tuples) {</div>
<div class="line"><a id="l01252" name="l01252"></a><span class="lineno"> 1252</span> absl::StrAppend(&amp;<a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>, <span class="stringliteral">&quot;, valid tuples = &quot;</span>, num_valid_tuples);</div>
<div class="line"><a id="l01253" name="l01253"></a><span class="lineno"> 1253</span> }</div>
<div class="line"><a id="l01254" name="l01254"></a><span class="lineno"> 1254</span> <span class="keywordflow">if</span> (prefixes_are_all_different) {</div>
<div class="line"><a id="l01255" name="l01255"></a><span class="lineno"> 1255</span> <span class="keywordflow">if</span> (num_prefix_tuples &lt; max_num_prefix_tuples) {</div>
<div class="line"><a id="l01256" name="l01256"></a><span class="lineno"> 1256</span> absl::StrAppend(&amp;<a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>, <span class="stringliteral">&quot;, partial prefix = &quot;</span>, num_prefix_tuples, <span class="stringliteral">&quot;/&quot;</span>,</div>
<div class="line"><a id="l01257" name="l01257"></a><span class="lineno"> 1257</span> max_num_prefix_tuples);</div>
<div class="line"><a id="l01258" name="l01258"></a><span class="lineno"> 1258</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01259" name="l01259"></a><span class="lineno"> 1259</span> absl::StrAppend(&amp;<a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>, <span class="stringliteral">&quot;, full prefix = true&quot;</span>);</div>
<div class="line"><a id="l01260" name="l01260"></a><span class="lineno"> 1260</span> }</div>
<div class="line"><a id="l01261" name="l01261"></a><span class="lineno"> 1261</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01262" name="l01262"></a><span class="lineno"> 1262</span> absl::StrAppend(&amp;<a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>, <span class="stringliteral">&quot;, num prefix tuples = &quot;</span>, num_prefix_tuples);</div>
<div class="line"><a id="l01263" name="l01263"></a><span class="lineno"> 1263</span> }</div>
<div class="line"><a id="l01264" name="l01264"></a><span class="lineno"> 1264</span> <span class="keywordflow">if</span> (num_compressed_tuples != num_valid_tuples) {</div>
<div class="line"><a id="l01265" name="l01265"></a><span class="lineno"> 1265</span> absl::StrAppend(&amp;<a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>,</div>
<div class="line"><a id="l01266" name="l01266"></a><span class="lineno"> 1266</span> <span class="stringliteral">&quot;, compressed tuples = &quot;</span>, num_compressed_tuples);</div>
<div class="line"><a id="l01267" name="l01267"></a><span class="lineno"> 1267</span> }</div>
<div class="line"><a id="l01268" name="l01268"></a><span class="lineno"> 1268</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(2) &lt;&lt; <a class="code hl_variable" href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a>;</div>
<div class="line"><a id="l01269" name="l01269"></a><span class="lineno"> 1269</span> }</div>
<div class="line"><a id="l01270" name="l01270"></a><span class="lineno"> 1270</span> </div>
<div class="line"><a id="l01271" name="l01271"></a><span class="lineno"> 1271</span> <span class="comment">// Log if we have only two tuples.</span></div>
<div class="line"><a id="l01272" name="l01272"></a><span class="lineno"> 1272</span> <span class="keywordflow">if</span> (num_compressed_tuples == 2) {</div>
<div class="line"><a id="l01273" name="l01273"></a><span class="lineno"> 1273</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;TODO table: two tuples&quot;</span>);</div>
<div class="line"><a id="l01274" name="l01274"></a><span class="lineno"> 1274</span> }</div>
<div class="line"><a id="l01275" name="l01275"></a><span class="lineno"> 1275</span> </div>
<div class="line"><a id="l01276" name="l01276"></a><span class="lineno"> 1276</span> <span class="comment">// Create one Boolean variable per tuple to indicate if it can still be</span></div>
<div class="line"><a id="l01277" name="l01277"></a><span class="lineno"> 1277</span> <span class="comment">// selected or not.</span></div>
<div class="line"><a id="l01278" name="l01278"></a><span class="lineno"> 1278</span> std::vector&lt;int&gt; tuple_literals(num_compressed_tuples);</div>
<div class="line"><a id="l01279" name="l01279"></a><span class="lineno"> 1279</span> BoolArgumentProto* exactly_one =</div>
<div class="line"><a id="l01280" name="l01280"></a><span class="lineno"> 1280</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_exactly_one();</div>
<div class="line"><a id="l01281" name="l01281"></a><span class="lineno"> 1281</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_compressed_tuples; ++i) {</div>
<div class="line"><a id="l01282" name="l01282"></a><span class="lineno"> 1282</span> tuple_literals[i] = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NewBoolVar();</div>
<div class="line"><a id="l01283" name="l01283"></a><span class="lineno"> 1283</span> exactly_one-&gt;add_literals(tuple_literals[i]);</div>
<div class="line"><a id="l01284" name="l01284"></a><span class="lineno"> 1284</span> }</div>
<div class="line"><a id="l01285" name="l01285"></a><span class="lineno"> 1285</span> </div>
<div class="line"><a id="l01286" name="l01286"></a><span class="lineno"> 1286</span> std::vector&lt;int64_t&gt; values(num_compressed_tuples);</div>
<div class="line"><a id="l01287" name="l01287"></a><span class="lineno"> 1287</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> var_index = 0; var_index &lt; num_vars; ++var_index) {</div>
<div class="line"><a id="l01288" name="l01288"></a><span class="lineno"> 1288</span> <span class="keywordflow">if</span> (values_per_var[var_index].size() == 1) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l01289" name="l01289"></a><span class="lineno"> 1289</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_compressed_tuples; ++i) {</div>
<div class="line"><a id="l01290" name="l01290"></a><span class="lineno"> 1290</span> values[i] = tuples[i][var_index];</div>
<div class="line"><a id="l01291" name="l01291"></a><span class="lineno"> 1291</span> }</div>
<div class="line"><a id="l01292" name="l01292"></a><span class="lineno"> 1292</span> ProcessOneVariable(tuple_literals, values, vars[var_index], any_value,</div>
<div class="line"><a id="l01293" name="l01293"></a><span class="lineno"> 1293</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01294" name="l01294"></a><span class="lineno"> 1294</span> }</div>
<div class="line"><a id="l01295" name="l01295"></a><span class="lineno"> 1295</span> </div>
<div class="line"><a id="l01296" name="l01296"></a><span class="lineno"> 1296</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;table: expanded positive constraint&quot;</span>);</div>
<div class="line"><a id="l01297" name="l01297"></a><span class="lineno"> 1297</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01298" name="l01298"></a><span class="lineno"> 1298</span>}</div>
<div class="line"><a id="l01299" name="l01299"></a><span class="lineno"> 1299</span> </div>
<div class="line"><a id="l01300" name="l01300"></a><span class="lineno"> 1300</span><span class="keywordtype">bool</span> AllDiffShouldBeExpanded(<span class="keyword">const</span> Domain&amp; union_of_domains,</div>
<div class="line"><a id="l01301" name="l01301"></a><span class="lineno"> 1301</span> ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01302" name="l01302"></a><span class="lineno"> 1302</span> <span class="keyword">const</span> AllDifferentConstraintProto&amp; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a> = *<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_all_diff();</div>
<div class="line"><a id="l01303" name="l01303"></a><span class="lineno"> 1303</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_exprs = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs_size();</div>
<div class="line"><a id="l01304" name="l01304"></a><span class="lineno"> 1304</span> <span class="keywordtype">int</span> num_fully_encoded = 0;</div>
<div class="line"><a id="l01305" name="l01305"></a><span class="lineno"> 1305</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_exprs; ++i) {</div>
<div class="line"><a id="l01306" name="l01306"></a><span class="lineno"> 1306</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFullyEncoded(<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs(i))) {</div>
<div class="line"><a id="l01307" name="l01307"></a><span class="lineno"> 1307</span> num_fully_encoded++;</div>
<div class="line"><a id="l01308" name="l01308"></a><span class="lineno"> 1308</span> }</div>
<div class="line"><a id="l01309" name="l01309"></a><span class="lineno"> 1309</span> }</div>
<div class="line"><a id="l01310" name="l01310"></a><span class="lineno"> 1310</span> </div>
<div class="line"><a id="l01311" name="l01311"></a><span class="lineno"> 1311</span> <span class="keywordflow">if</span> ((union_of_domains.Size() &lt;= 2 * <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs_size()) ||</div>
<div class="line"><a id="l01312" name="l01312"></a><span class="lineno"> 1312</span> (union_of_domains.Size() &lt;= 32)) {</div>
<div class="line"><a id="l01313" name="l01313"></a><span class="lineno"> 1313</span> <span class="comment">// Small domains.</span></div>
<div class="line"><a id="l01314" name="l01314"></a><span class="lineno"> 1314</span> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"><a id="l01315" name="l01315"></a><span class="lineno"> 1315</span> }</div>
<div class="line"><a id="l01316" name="l01316"></a><span class="lineno"> 1316</span> </div>
<div class="line"><a id="l01317" name="l01317"></a><span class="lineno"> 1317</span> <span class="keywordflow">if</span> (num_fully_encoded == num_exprs &amp;&amp; union_of_domains.Size() &lt; 256) {</div>
<div class="line"><a id="l01318" name="l01318"></a><span class="lineno"> 1318</span> <span class="comment">// All variables fully encoded, and domains are small enough.</span></div>
<div class="line"><a id="l01319" name="l01319"></a><span class="lineno"> 1319</span> <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line"><a id="l01320" name="l01320"></a><span class="lineno"> 1320</span> }</div>
<div class="line"><a id="l01321" name="l01321"></a><span class="lineno"> 1321</span> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"><a id="l01322" name="l01322"></a><span class="lineno"> 1322</span>}</div>
<div class="line"><a id="l01323" name="l01323"></a><span class="lineno"> 1323</span> </div>
<div class="line"><a id="l01324" name="l01324"></a><span class="lineno"> 1324</span><span class="keywordtype">void</span> ExpandAllDiff(<span class="keywordtype">bool</span> force_alldiff_expansion, ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>,</div>
<div class="line"><a id="l01325" name="l01325"></a><span class="lineno"> 1325</span> PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01326" name="l01326"></a><span class="lineno"> 1326</span> AllDifferentConstraintProto&amp; <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a> = *<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;mutable_all_diff();</div>
<div class="line"><a id="l01327" name="l01327"></a><span class="lineno"> 1327</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs_size() &lt;= 1) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01328" name="l01328"></a><span class="lineno"> 1328</span> </div>
<div class="line"><a id="l01329" name="l01329"></a><span class="lineno"> 1329</span> <span class="keyword">const</span> <span class="keywordtype">int</span> num_exprs = <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs_size();</div>
<div class="line"><a id="l01330" name="l01330"></a><span class="lineno"> 1330</span> Domain union_of_domains = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs(0));</div>
<div class="line"><a id="l01331" name="l01331"></a><span class="lineno"> 1331</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 1; i &lt; num_exprs; ++i) {</div>
<div class="line"><a id="l01332" name="l01332"></a><span class="lineno"> 1332</span> union_of_domains =</div>
<div class="line"><a id="l01333" name="l01333"></a><span class="lineno"> 1333</span> union_of_domains.UnionWith(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainSuperSetOf(<a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs(i)));</div>
<div class="line"><a id="l01334" name="l01334"></a><span class="lineno"> 1334</span> }</div>
<div class="line"><a id="l01335" name="l01335"></a><span class="lineno"> 1335</span> </div>
<div class="line"><a id="l01336" name="l01336"></a><span class="lineno"> 1336</span> <span class="keywordflow">if</span> (!AllDiffShouldBeExpanded(union_of_domains, <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) &amp;&amp;</div>
<div class="line"><a id="l01337" name="l01337"></a><span class="lineno"> 1337</span> !force_alldiff_expansion) {</div>
<div class="line"><a id="l01338" name="l01338"></a><span class="lineno"> 1338</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01339" name="l01339"></a><span class="lineno"> 1339</span> }</div>
<div class="line"><a id="l01340" name="l01340"></a><span class="lineno"> 1340</span> </div>
<div class="line"><a id="l01341" name="l01341"></a><span class="lineno"> 1341</span> <span class="keyword">const</span> <span class="keywordtype">bool</span> is_a_permutation = num_exprs == union_of_domains.Size();</div>
<div class="line"><a id="l01342" name="l01342"></a><span class="lineno"> 1342</span> </div>
<div class="line"><a id="l01343" name="l01343"></a><span class="lineno"> 1343</span> <span class="comment">// Collect all possible variables that can take each value, and add one linear</span></div>
<div class="line"><a id="l01344" name="l01344"></a><span class="lineno"> 1344</span> <span class="comment">// equation per value stating that this value can be assigned at most once, or</span></div>
<div class="line"><a id="l01345" name="l01345"></a><span class="lineno"> 1345</span> <span class="comment">// exactly once in case of permutation.</span></div>
<div class="line"><a id="l01346" name="l01346"></a><span class="lineno"> 1346</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t v : union_of_domains.Values()) {</div>
<div class="line"><a id="l01347" name="l01347"></a><span class="lineno"> 1347</span> <span class="comment">// Collect references which domain contains v.</span></div>
<div class="line"><a id="l01348" name="l01348"></a><span class="lineno"> 1348</span> std::vector&lt;LinearExpressionProto&gt; possible_exprs;</div>
<div class="line"><a id="l01349" name="l01349"></a><span class="lineno"> 1349</span> <span class="keywordtype">int</span> fixed_expression_count = 0;</div>
<div class="line"><a id="l01350" name="l01350"></a><span class="lineno"> 1350</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> LinearExpressionProto&amp; expr : <a class="code hl_variable" href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a>.exprs()) {</div>
<div class="line"><a id="l01351" name="l01351"></a><span class="lineno"> 1351</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(expr, v)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l01352" name="l01352"></a><span class="lineno"> 1352</span> possible_exprs.push_back(expr);</div>
<div class="line"><a id="l01353" name="l01353"></a><span class="lineno"> 1353</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(expr)) {</div>
<div class="line"><a id="l01354" name="l01354"></a><span class="lineno"> 1354</span> fixed_expression_count++;</div>
<div class="line"><a id="l01355" name="l01355"></a><span class="lineno"> 1355</span> }</div>
<div class="line"><a id="l01356" name="l01356"></a><span class="lineno"> 1356</span> }</div>
<div class="line"><a id="l01357" name="l01357"></a><span class="lineno"> 1357</span> </div>
<div class="line"><a id="l01358" name="l01358"></a><span class="lineno"> 1358</span> <span class="keywordflow">if</span> (fixed_expression_count &gt; 1) {</div>
<div class="line"><a id="l01359" name="l01359"></a><span class="lineno"> 1359</span> <span class="comment">// Violates the definition of AllDifferent.</span></div>
<div class="line"><a id="l01360" name="l01360"></a><span class="lineno"> 1360</span> <span class="keywordflow">return</span> (<span class="keywordtype">void</span>)<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsUnsat();</div>
<div class="line"><a id="l01361" name="l01361"></a><span class="lineno"> 1361</span> } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (fixed_expression_count == 1) {</div>
<div class="line"><a id="l01362" name="l01362"></a><span class="lineno"> 1362</span> <span class="comment">// Remove values from other domains.</span></div>
<div class="line"><a id="l01363" name="l01363"></a><span class="lineno"> 1363</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> LinearExpressionProto&amp; expr : possible_exprs) {</div>
<div class="line"><a id="l01364" name="l01364"></a><span class="lineno"> 1364</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(expr)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l01365" name="l01365"></a><span class="lineno"> 1365</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IntersectDomainWith(expr, Domain(v).Complement())) {</div>
<div class="line"><a id="l01366" name="l01366"></a><span class="lineno"> 1366</span> <a class="code hl_define" href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a>(1) &lt;&lt; <span class="stringliteral">&quot;Empty domain for a variable in ExpandAllDiff()&quot;</span>;</div>
<div class="line"><a id="l01367" name="l01367"></a><span class="lineno"> 1367</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01368" name="l01368"></a><span class="lineno"> 1368</span> }</div>
<div class="line"><a id="l01369" name="l01369"></a><span class="lineno"> 1369</span> }</div>
<div class="line"><a id="l01370" name="l01370"></a><span class="lineno"> 1370</span> }</div>
<div class="line"><a id="l01371" name="l01371"></a><span class="lineno"> 1371</span> </div>
<div class="line"><a id="l01372" name="l01372"></a><span class="lineno"> 1372</span> BoolArgumentProto* at_most_or_equal_one =</div>
<div class="line"><a id="l01373" name="l01373"></a><span class="lineno"> 1373</span> is_a_permutation</div>
<div class="line"><a id="l01374" name="l01374"></a><span class="lineno"> 1374</span> ? <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_exactly_one()</div>
<div class="line"><a id="l01375" name="l01375"></a><span class="lineno"> 1375</span> : <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_at_most_one();</div>
<div class="line"><a id="l01376" name="l01376"></a><span class="lineno"> 1376</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> LinearExpressionProto&amp; expr : possible_exprs) {</div>
<div class="line"><a id="l01377" name="l01377"></a><span class="lineno"> 1377</span> <span class="comment">// The above propagation can remove a value after the expressions was</span></div>
<div class="line"><a id="l01378" name="l01378"></a><span class="lineno"> 1378</span> <span class="comment">// added to possible_exprs.</span></div>
<div class="line"><a id="l01379" name="l01379"></a><span class="lineno"> 1379</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(expr, v)) <span class="keywordflow">continue</span>;</div>
<div class="line"><a id="l01380" name="l01380"></a><span class="lineno"> 1380</span> </div>
<div class="line"><a id="l01381" name="l01381"></a><span class="lineno"> 1381</span> <span class="comment">// If the expression is fixed, the created literal will be the true</span></div>
<div class="line"><a id="l01382" name="l01382"></a><span class="lineno"> 1382</span> <span class="comment">// literal. We still need to fail if two expressions are fixed to the same</span></div>
<div class="line"><a id="l01383" name="l01383"></a><span class="lineno"> 1383</span> <span class="comment">// value.</span></div>
<div class="line"><a id="l01384" name="l01384"></a><span class="lineno"> 1384</span> <span class="keyword">const</span> <span class="keywordtype">int</span> encoding = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateAffineValueEncoding(expr, v);</div>
<div class="line"><a id="l01385" name="l01385"></a><span class="lineno"> 1385</span> at_most_or_equal_one-&gt;add_literals(encoding);</div>
<div class="line"><a id="l01386" name="l01386"></a><span class="lineno"> 1386</span> }</div>
<div class="line"><a id="l01387" name="l01387"></a><span class="lineno"> 1387</span> }</div>
<div class="line"><a id="l01388" name="l01388"></a><span class="lineno"> 1388</span> <span class="keywordflow">if</span> (is_a_permutation) {</div>
<div class="line"><a id="l01389" name="l01389"></a><span class="lineno"> 1389</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;all_diff: permutation expanded&quot;</span>);</div>
<div class="line"><a id="l01390" name="l01390"></a><span class="lineno"> 1390</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01391" name="l01391"></a><span class="lineno"> 1391</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;all_diff: expanded&quot;</span>);</div>
<div class="line"><a id="l01392" name="l01392"></a><span class="lineno"> 1392</span> }</div>
<div class="line"><a id="l01393" name="l01393"></a><span class="lineno"> 1393</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01394" name="l01394"></a><span class="lineno"> 1394</span>}</div>
<div class="line"><a id="l01395" name="l01395"></a><span class="lineno"> 1395</span> </div>
<div class="line"><a id="l01396" name="l01396"></a><span class="lineno"> 1396</span><span class="comment">// Replaces a constraint literal =&gt; ax + by != cte by a set of clauses.</span></div>
<div class="line"><a id="l01397" name="l01397"></a><span class="lineno"> 1397</span><span class="comment">// This is performed if the domains are small enough, and the variables are</span></div>
<div class="line"><a id="l01398" name="l01398"></a><span class="lineno"> 1398</span><span class="comment">// fully encoded.</span></div>
<div class="line"><a id="l01399" name="l01399"></a><span class="lineno"> 1399</span><span class="comment">//</span></div>
<div class="line"><a id="l01400" name="l01400"></a><span class="lineno"> 1400</span><span class="comment">// We do it during the expansion as we want the first pass of the presolve to be</span></div>
<div class="line"><a id="l01401" name="l01401"></a><span class="lineno"> 1401</span><span class="comment">// complete.</span></div>
<div class="line"><a id="l01402" name="l01402"></a><span class="lineno"> 1402</span><span class="keywordtype">void</span> ExpandSomeLinearOfSizeTwo(ConstraintProto* <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, PresolveContext* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01403" name="l01403"></a><span class="lineno"> 1403</span> <span class="keyword">const</span> LinearConstraintProto&amp; arg = <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;linear();</div>
<div class="line"><a id="l01404" name="l01404"></a><span class="lineno"> 1404</span> <span class="keywordflow">if</span> (arg.vars_size() != 2) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01405" name="l01405"></a><span class="lineno"> 1405</span> </div>
<div class="line"><a id="l01406" name="l01406"></a><span class="lineno"> 1406</span> <span class="keyword">const</span> <span class="keywordtype">int</span> var1 = arg.vars(0);</div>
<div class="line"><a id="l01407" name="l01407"></a><span class="lineno"> 1407</span> <span class="keyword">const</span> <span class="keywordtype">int</span> var2 = arg.vars(1);</div>
<div class="line"><a id="l01408" name="l01408"></a><span class="lineno"> 1408</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(var1) || <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;IsFixed(var2)) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01409" name="l01409"></a><span class="lineno"> 1409</span> </div>
<div class="line"><a id="l01410" name="l01410"></a><span class="lineno"> 1410</span> <span class="keyword">const</span> int64_t coeff1 = arg.coeffs(0);</div>
<div class="line"><a id="l01411" name="l01411"></a><span class="lineno"> 1411</span> <span class="keyword">const</span> int64_t coeff2 = arg.coeffs(1);</div>
<div class="line"><a id="l01412" name="l01412"></a><span class="lineno"> 1412</span> </div>
<div class="line"><a id="l01413" name="l01413"></a><span class="lineno"> 1413</span> <span class="keyword">const</span> Domain reachable_rhs_superset =</div>
<div class="line"><a id="l01414" name="l01414"></a><span class="lineno"> 1414</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var1).MultiplicationBy(coeff1).AdditionWith(</div>
<div class="line"><a id="l01415" name="l01415"></a><span class="lineno"> 1415</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var2).MultiplicationBy(coeff2));</div>
<div class="line"><a id="l01416" name="l01416"></a><span class="lineno"> 1416</span> </div>
<div class="line"><a id="l01417" name="l01417"></a><span class="lineno"> 1417</span> <span class="keyword">const</span> Domain infeasible_reachable_values =</div>
<div class="line"><a id="l01418" name="l01418"></a><span class="lineno"> 1418</span> reachable_rhs_superset.IntersectionWith(</div>
<div class="line"><a id="l01419" name="l01419"></a><span class="lineno"> 1419</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ab1240060466ba48a36a4b36379bce26a">ReadDomainFromProto</a>(arg).Complement());</div>
<div class="line"><a id="l01420" name="l01420"></a><span class="lineno"> 1420</span> </div>
<div class="line"><a id="l01421" name="l01421"></a><span class="lineno"> 1421</span> <span class="comment">// We only deal with != cte constraints.</span></div>
<div class="line"><a id="l01422" name="l01422"></a><span class="lineno"> 1422</span> <span class="keywordflow">if</span> (infeasible_reachable_values.Size() != 1) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01423" name="l01423"></a><span class="lineno"> 1423</span> </div>
<div class="line"><a id="l01424" name="l01424"></a><span class="lineno"> 1424</span> <span class="comment">// coeff1 * v1 + coeff2 * v2 != cte.</span></div>
<div class="line"><a id="l01425" name="l01425"></a><span class="lineno"> 1425</span> int64_t <a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> = coeff1;</div>
<div class="line"><a id="l01426" name="l01426"></a><span class="lineno"> 1426</span> int64_t <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a> = coeff2;</div>
<div class="line"><a id="l01427" name="l01427"></a><span class="lineno"> 1427</span> int64_t cte = infeasible_reachable_values.FixedValue();</div>
<div class="line"><a id="l01428" name="l01428"></a><span class="lineno"> 1428</span> int64_t x0 = 0;</div>
<div class="line"><a id="l01429" name="l01429"></a><span class="lineno"> 1429</span> int64_t y0 = 0;</div>
<div class="line"><a id="l01430" name="l01430"></a><span class="lineno"> 1430</span> <span class="keywordflow">if</span> (!<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a852a51b53f6217d6bfd1aef455f53f8c">SolveDiophantineEquationOfSizeTwo</a>(<a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>, cte, x0, y0)) {</div>
<div class="line"><a id="l01431" name="l01431"></a><span class="lineno"> 1431</span> <span class="comment">// no solution.</span></div>
<div class="line"><a id="l01432" name="l01432"></a><span class="lineno"> 1432</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;linear: expand always feasible ax + by != cte&quot;</span>);</div>
<div class="line"><a id="l01433" name="l01433"></a><span class="lineno"> 1433</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01434" name="l01434"></a><span class="lineno"> 1434</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01435" name="l01435"></a><span class="lineno"> 1435</span> }</div>
<div class="line"><a id="l01436" name="l01436"></a><span class="lineno"> 1436</span> <span class="keyword">const</span> Domain reduced_domain =</div>
<div class="line"><a id="l01437" name="l01437"></a><span class="lineno"> 1437</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var1)</div>
<div class="line"><a id="l01438" name="l01438"></a><span class="lineno"> 1438</span> .AdditionWith(Domain(-x0))</div>
<div class="line"><a id="l01439" name="l01439"></a><span class="lineno"> 1439</span> .InverseMultiplicationBy(<a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>)</div>
<div class="line"><a id="l01440" name="l01440"></a><span class="lineno"> 1440</span> .IntersectionWith(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var2)</div>
<div class="line"><a id="l01441" name="l01441"></a><span class="lineno"> 1441</span> .AdditionWith(Domain(-y0))</div>
<div class="line"><a id="l01442" name="l01442"></a><span class="lineno"> 1442</span> .InverseMultiplicationBy(-<a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>));</div>
<div class="line"><a id="l01443" name="l01443"></a><span class="lineno"> 1443</span> </div>
<div class="line"><a id="l01444" name="l01444"></a><span class="lineno"> 1444</span> <span class="keywordflow">if</span> (reduced_domain.Size() &gt; 16) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01445" name="l01445"></a><span class="lineno"> 1445</span> </div>
<div class="line"><a id="l01446" name="l01446"></a><span class="lineno"> 1446</span> <span class="comment">// Check if all the needed values are encoded.</span></div>
<div class="line"><a id="l01447" name="l01447"></a><span class="lineno"> 1447</span> <span class="comment">// TODO(user): Do we force encoding for very small domains? Current</span></div>
<div class="line"><a id="l01448" name="l01448"></a><span class="lineno"> 1448</span> <span class="comment">// experiments says no, but revisit later.</span></div>
<div class="line"><a id="l01449" name="l01449"></a><span class="lineno"> 1449</span> <span class="keyword">const</span> int64_t size1 = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var1).Size();</div>
<div class="line"><a id="l01450" name="l01450"></a><span class="lineno"> 1450</span> <span class="keyword">const</span> int64_t size2 = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(var2).Size();</div>
<div class="line"><a id="l01451" name="l01451"></a><span class="lineno"> 1451</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t z : reduced_domain.Values()) {</div>
<div class="line"><a id="l01452" name="l01452"></a><span class="lineno"> 1452</span> <span class="keyword">const</span> int64_t value1 = x0 + <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a> * z;</div>
<div class="line"><a id="l01453" name="l01453"></a><span class="lineno"> 1453</span> <span class="keyword">const</span> int64_t value2 = y0 - <a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> * z;</div>
<div class="line"><a id="l01454" name="l01454"></a><span class="lineno"> 1454</span> <a class="code hl_define" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(var1, value1)) &lt;&lt; <span class="stringliteral">&quot;value1 = &quot;</span> &lt;&lt; value1;</div>
<div class="line"><a id="l01455" name="l01455"></a><span class="lineno"> 1455</span> <a class="code hl_define" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainContains(var2, value2)) &lt;&lt; <span class="stringliteral">&quot;value2 = &quot;</span> &lt;&lt; value2;</div>
<div class="line"><a id="l01456" name="l01456"></a><span class="lineno"> 1456</span> <a class="code hl_define" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(coeff1 * value1 + coeff2 * value2,</div>
<div class="line"><a id="l01457" name="l01457"></a><span class="lineno"> 1457</span> infeasible_reachable_values.FixedValue());</div>
<div class="line"><a id="l01458" name="l01458"></a><span class="lineno"> 1458</span> <span class="comment">// TODO(user, fdid): Presolve if one or two variables are Boolean.</span></div>
<div class="line"><a id="l01459" name="l01459"></a><span class="lineno"> 1459</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;HasVarValueEncoding(var1, value1, <span class="keyword">nullptr</span>) || size1 == 2) {</div>
<div class="line"><a id="l01460" name="l01460"></a><span class="lineno"> 1460</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01461" name="l01461"></a><span class="lineno"> 1461</span> }</div>
<div class="line"><a id="l01462" name="l01462"></a><span class="lineno"> 1462</span> <span class="keywordflow">if</span> (!<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;HasVarValueEncoding(var2, value2, <span class="keyword">nullptr</span>) || size2 == 2) {</div>
<div class="line"><a id="l01463" name="l01463"></a><span class="lineno"> 1463</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01464" name="l01464"></a><span class="lineno"> 1464</span> }</div>
<div class="line"><a id="l01465" name="l01465"></a><span class="lineno"> 1465</span> }</div>
<div class="line"><a id="l01466" name="l01466"></a><span class="lineno"> 1466</span> </div>
<div class="line"><a id="l01467" name="l01467"></a><span class="lineno"> 1467</span> <span class="comment">// All encoding literals already exist and the number of clauses to create</span></div>
<div class="line"><a id="l01468" name="l01468"></a><span class="lineno"> 1468</span> <span class="comment">// is small enough. We can encode the constraint using just clauses.</span></div>
<div class="line"><a id="l01469" name="l01469"></a><span class="lineno"> 1469</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> int64_t z : reduced_domain.Values()) {</div>
<div class="line"><a id="l01470" name="l01470"></a><span class="lineno"> 1470</span> <span class="keyword">const</span> int64_t value1 = x0 + <a class="code hl_variable" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a> * z;</div>
<div class="line"><a id="l01471" name="l01471"></a><span class="lineno"> 1471</span> <span class="keyword">const</span> int64_t value2 = y0 - <a class="code hl_variable" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> * z;</div>
<div class="line"><a id="l01472" name="l01472"></a><span class="lineno"> 1472</span> <span class="comment">// We cannot have both lit1 and lit2 true.</span></div>
<div class="line"><a id="l01473" name="l01473"></a><span class="lineno"> 1473</span> <span class="keyword">const</span> <span class="keywordtype">int</span> lit1 = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(var1, value1);</div>
<div class="line"><a id="l01474" name="l01474"></a><span class="lineno"> 1474</span> <span class="keyword">const</span> <span class="keywordtype">int</span> lit2 = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;GetOrCreateVarValueEncoding(var2, value2);</div>
<div class="line"><a id="l01475" name="l01475"></a><span class="lineno"> 1475</span> <span class="keyword">auto</span>* bool_or =</div>
<div class="line"><a id="l01476" name="l01476"></a><span class="lineno"> 1476</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;add_constraints()-&gt;mutable_bool_or();</div>
<div class="line"><a id="l01477" name="l01477"></a><span class="lineno"> 1477</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(lit1));</div>
<div class="line"><a id="l01478" name="l01478"></a><span class="lineno"> 1478</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(lit2));</div>
<div class="line"><a id="l01479" name="l01479"></a><span class="lineno"> 1479</span> <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keywordtype">int</span> lit : <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;enforcement_literal()) {</div>
<div class="line"><a id="l01480" name="l01480"></a><span class="lineno"> 1480</span> bool_or-&gt;add_literals(<a class="code hl_function" href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">NegatedRef</a>(lit));</div>
<div class="line"><a id="l01481" name="l01481"></a><span class="lineno"> 1481</span> }</div>
<div class="line"><a id="l01482" name="l01482"></a><span class="lineno"> 1482</span> }</div>
<div class="line"><a id="l01483" name="l01483"></a><span class="lineno"> 1483</span> </div>
<div class="line"><a id="l01484" name="l01484"></a><span class="lineno"> 1484</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateRuleStats(<span class="stringliteral">&quot;linear: expand small ax + by != cte&quot;</span>);</div>
<div class="line"><a id="l01485" name="l01485"></a><span class="lineno"> 1485</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;Clear();</div>
<div class="line"><a id="l01486" name="l01486"></a><span class="lineno"> 1486</span>}</div>
<div class="line"><a id="l01487" name="l01487"></a><span class="lineno"> 1487</span> </div>
<div class="line"><a id="l01488" name="l01488"></a><span class="lineno"> 1488</span>} <span class="comment">// namespace</span></div>
<div class="line"><a id="l01489" name="l01489"></a><span class="lineno"> 1489</span> </div>
<div class="line"><a id="l01490" name="l01490"></a><span class="lineno"><a class="line" href="namespaceoperations__research_1_1sat.html#a4d700795b2500705ef3031ec994fe472"> 1490</a></span><span class="keywordtype">void</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a4d700795b2500705ef3031ec994fe472">ExpandCpModel</a>(<a class="code hl_class" href="classoperations__research_1_1sat_1_1_presolve_context.html">PresolveContext</a>* <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>) {</div>
<div class="line"><a id="l01491" name="l01491"></a><span class="lineno"> 1491</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;params().disable_constraint_expansion()) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01492" name="l01492"></a><span class="lineno"> 1492</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ModelIsUnsat()) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01493" name="l01493"></a><span class="lineno"> 1493</span> </div>
<div class="line"><a id="l01494" name="l01494"></a><span class="lineno"> 1494</span> <span class="comment">// None of the function here need to be run twice. This is because we never</span></div>
<div class="line"><a id="l01495" name="l01495"></a><span class="lineno"> 1495</span> <span class="comment">// create constraint that need to be expanded during presolve.</span></div>
<div class="line"><a id="l01496" name="l01496"></a><span class="lineno"> 1496</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ModelIsExpanded()) <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01497" name="l01497"></a><span class="lineno"> 1497</span> </div>
<div class="line"><a id="l01498" name="l01498"></a><span class="lineno"> 1498</span> <span class="comment">// Make sure all domains are initialized.</span></div>
<div class="line"><a id="l01499" name="l01499"></a><span class="lineno"> 1499</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InitializeNewDomains();</div>
<div class="line"><a id="l01500" name="l01500"></a><span class="lineno"> 1500</span> </div>
<div class="line"><a id="l01501" name="l01501"></a><span class="lineno"> 1501</span> <span class="comment">// Clear the precedence cache.</span></div>
<div class="line"><a id="l01502" name="l01502"></a><span class="lineno"> 1502</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ClearPrecedenceCache();</div>
<div class="line"><a id="l01503" name="l01503"></a><span class="lineno"> 1503</span> </div>
<div class="line"><a id="l01504" name="l01504"></a><span class="lineno"> 1504</span> <span class="comment">// First pass: we look at constraints that may fully encode variables.</span></div>
<div class="line"><a id="l01505" name="l01505"></a><span class="lineno"> 1505</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;constraints_size(); ++i) {</div>
<div class="line"><a id="l01506" name="l01506"></a><span class="lineno"> 1506</span> ConstraintProto* <span class="keyword">const</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;mutable_constraints(i);</div>
<div class="line"><a id="l01507" name="l01507"></a><span class="lineno"> 1507</span> <span class="keywordtype">bool</span> skip = <span class="keyword">false</span>;</div>
<div class="line"><a id="l01508" name="l01508"></a><span class="lineno"> 1508</span> <span class="keywordflow">switch</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;constraint_case()) {</div>
<div class="line"><a id="l01509" name="l01509"></a><span class="lineno"> 1509</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kReservoir:</div>
<div class="line"><a id="l01510" name="l01510"></a><span class="lineno"> 1510</span> ExpandReservoir(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01511" name="l01511"></a><span class="lineno"> 1511</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01512" name="l01512"></a><span class="lineno"> 1512</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kIntMod:</div>
<div class="line"><a id="l01513" name="l01513"></a><span class="lineno"> 1513</span> ExpandIntMod(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01514" name="l01514"></a><span class="lineno"> 1514</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01515" name="l01515"></a><span class="lineno"> 1515</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kIntProd:</div>
<div class="line"><a id="l01516" name="l01516"></a><span class="lineno"> 1516</span> ExpandIntProd(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01517" name="l01517"></a><span class="lineno"> 1517</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01518" name="l01518"></a><span class="lineno"> 1518</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kElement:</div>
<div class="line"><a id="l01519" name="l01519"></a><span class="lineno"> 1519</span> ExpandElement(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01520" name="l01520"></a><span class="lineno"> 1520</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01521" name="l01521"></a><span class="lineno"> 1521</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kInverse:</div>
<div class="line"><a id="l01522" name="l01522"></a><span class="lineno"> 1522</span> ExpandInverse(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01523" name="l01523"></a><span class="lineno"> 1523</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01524" name="l01524"></a><span class="lineno"> 1524</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kAutomaton:</div>
<div class="line"><a id="l01525" name="l01525"></a><span class="lineno"> 1525</span> ExpandAutomaton(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01526" name="l01526"></a><span class="lineno"> 1526</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01527" name="l01527"></a><span class="lineno"> 1527</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kTable:</div>
<div class="line"><a id="l01528" name="l01528"></a><span class="lineno"> 1528</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;table().negated()) {</div>
<div class="line"><a id="l01529" name="l01529"></a><span class="lineno"> 1529</span> ExpandNegativeTable(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01530" name="l01530"></a><span class="lineno"> 1530</span> } <span class="keywordflow">else</span> {</div>
<div class="line"><a id="l01531" name="l01531"></a><span class="lineno"> 1531</span> ExpandPositiveTable(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01532" name="l01532"></a><span class="lineno"> 1532</span> }</div>
<div class="line"><a id="l01533" name="l01533"></a><span class="lineno"> 1533</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01534" name="l01534"></a><span class="lineno"> 1534</span> <span class="keywordflow">default</span>:</div>
<div class="line"><a id="l01535" name="l01535"></a><span class="lineno"> 1535</span> skip = <span class="keyword">true</span>;</div>
<div class="line"><a id="l01536" name="l01536"></a><span class="lineno"> 1536</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01537" name="l01537"></a><span class="lineno"> 1537</span> }</div>
<div class="line"><a id="l01538" name="l01538"></a><span class="lineno"> 1538</span> <span class="keywordflow">if</span> (skip) <span class="keywordflow">continue</span>; <span class="comment">// Nothing was done for this constraint.</span></div>
<div class="line"><a id="l01539" name="l01539"></a><span class="lineno"> 1539</span> </div>
<div class="line"><a id="l01540" name="l01540"></a><span class="lineno"> 1540</span> <span class="comment">// Update variable-constraint graph.</span></div>
<div class="line"><a id="l01541" name="l01541"></a><span class="lineno"> 1541</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateNewConstraintsVariableUsage();</div>
<div class="line"><a id="l01542" name="l01542"></a><span class="lineno"> 1542</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;constraint_case() == ConstraintProto::CONSTRAINT_NOT_SET) {</div>
<div class="line"><a id="l01543" name="l01543"></a><span class="lineno"> 1543</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateConstraintVariableUsage(i);</div>
<div class="line"><a id="l01544" name="l01544"></a><span class="lineno"> 1544</span> }</div>
<div class="line"><a id="l01545" name="l01545"></a><span class="lineno"> 1545</span> </div>
<div class="line"><a id="l01546" name="l01546"></a><span class="lineno"> 1546</span> <span class="comment">// Early exit if the model is unsat.</span></div>
<div class="line"><a id="l01547" name="l01547"></a><span class="lineno"> 1547</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ModelIsUnsat()) {</div>
<div class="line"><a id="l01548" name="l01548"></a><span class="lineno"> 1548</span> <a class="code hl_define" href="util_2logging_8h.html#a5f67b653dd99ddbe5e3367e3b4b7b532">SOLVER_LOG</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;logger(), <span class="stringliteral">&quot;UNSAT after expansion of &quot;</span>,</div>
<div class="line"><a id="l01549" name="l01549"></a><span class="lineno"> 1549</span> <a class="code hl_function" href="namespaceoperations__research.html#a87d7aa58897e0042898d1c2207deda18">ProtobufShortDebugString</a>(*<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>));</div>
<div class="line"><a id="l01550" name="l01550"></a><span class="lineno"> 1550</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01551" name="l01551"></a><span class="lineno"> 1551</span> }</div>
<div class="line"><a id="l01552" name="l01552"></a><span class="lineno"> 1552</span> }</div>
<div class="line"><a id="l01553" name="l01553"></a><span class="lineno"> 1553</span> </div>
<div class="line"><a id="l01554" name="l01554"></a><span class="lineno"> 1554</span> <span class="comment">// Second pass. We may decide to expand constraints if all their variables</span></div>
<div class="line"><a id="l01555" name="l01555"></a><span class="lineno"> 1555</span> <span class="comment">// are fully encoded.</span></div>
<div class="line"><a id="l01556" name="l01556"></a><span class="lineno"> 1556</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;constraints_size(); ++i) {</div>
<div class="line"><a id="l01557" name="l01557"></a><span class="lineno"> 1557</span> ConstraintProto* <span class="keyword">const</span> <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a> = <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;mutable_constraints(i);</div>
<div class="line"><a id="l01558" name="l01558"></a><span class="lineno"> 1558</span> <span class="keywordtype">bool</span> skip = <span class="keyword">false</span>;</div>
<div class="line"><a id="l01559" name="l01559"></a><span class="lineno"> 1559</span> <span class="keywordflow">switch</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;constraint_case()) {</div>
<div class="line"><a id="l01560" name="l01560"></a><span class="lineno"> 1560</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kAllDiff:</div>
<div class="line"><a id="l01561" name="l01561"></a><span class="lineno"> 1561</span> ExpandAllDiff(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;params().expand_alldiff_constraints(), <a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>,</div>
<div class="line"><a id="l01562" name="l01562"></a><span class="lineno"> 1562</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01563" name="l01563"></a><span class="lineno"> 1563</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01564" name="l01564"></a><span class="lineno"> 1564</span> <span class="keywordflow">case</span> ConstraintProto::ConstraintCase::kLinear:</div>
<div class="line"><a id="l01565" name="l01565"></a><span class="lineno"> 1565</span> ExpandSomeLinearOfSizeTwo(<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>, <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>);</div>
<div class="line"><a id="l01566" name="l01566"></a><span class="lineno"> 1566</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01567" name="l01567"></a><span class="lineno"> 1567</span> <span class="keywordflow">default</span>:</div>
<div class="line"><a id="l01568" name="l01568"></a><span class="lineno"> 1568</span> skip = <span class="keyword">true</span>;</div>
<div class="line"><a id="l01569" name="l01569"></a><span class="lineno"> 1569</span> <span class="keywordflow">break</span>;</div>
<div class="line"><a id="l01570" name="l01570"></a><span class="lineno"> 1570</span> }</div>
<div class="line"><a id="l01571" name="l01571"></a><span class="lineno"> 1571</span> </div>
<div class="line"><a id="l01572" name="l01572"></a><span class="lineno"> 1572</span> <span class="keywordflow">if</span> (skip) <span class="keywordflow">continue</span>; <span class="comment">// Nothing was done for this constraint.</span></div>
<div class="line"><a id="l01573" name="l01573"></a><span class="lineno"> 1573</span> </div>
<div class="line"><a id="l01574" name="l01574"></a><span class="lineno"> 1574</span> <span class="comment">// Update variable-constraint graph.</span></div>
<div class="line"><a id="l01575" name="l01575"></a><span class="lineno"> 1575</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateNewConstraintsVariableUsage();</div>
<div class="line"><a id="l01576" name="l01576"></a><span class="lineno"> 1576</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>-&gt;constraint_case() == ConstraintProto::CONSTRAINT_NOT_SET) {</div>
<div class="line"><a id="l01577" name="l01577"></a><span class="lineno"> 1577</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;UpdateConstraintVariableUsage(i);</div>
<div class="line"><a id="l01578" name="l01578"></a><span class="lineno"> 1578</span> }</div>
<div class="line"><a id="l01579" name="l01579"></a><span class="lineno"> 1579</span> </div>
<div class="line"><a id="l01580" name="l01580"></a><span class="lineno"> 1580</span> <span class="comment">// Early exit if the model is unsat.</span></div>
<div class="line"><a id="l01581" name="l01581"></a><span class="lineno"> 1581</span> <span class="keywordflow">if</span> (<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ModelIsUnsat()) {</div>
<div class="line"><a id="l01582" name="l01582"></a><span class="lineno"> 1582</span> <a class="code hl_define" href="util_2logging_8h.html#a5f67b653dd99ddbe5e3367e3b4b7b532">SOLVER_LOG</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;logger(), <span class="stringliteral">&quot;UNSAT after expansion of &quot;</span>,</div>
<div class="line"><a id="l01583" name="l01583"></a><span class="lineno"> 1583</span> <a class="code hl_function" href="namespaceoperations__research.html#a87d7aa58897e0042898d1c2207deda18">ProtobufShortDebugString</a>(*<a class="code hl_variable" href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a>));</div>
<div class="line"><a id="l01584" name="l01584"></a><span class="lineno"> 1584</span> <span class="keywordflow">return</span>;</div>
<div class="line"><a id="l01585" name="l01585"></a><span class="lineno"> 1585</span> }</div>
<div class="line"><a id="l01586" name="l01586"></a><span class="lineno"> 1586</span> }</div>
<div class="line"><a id="l01587" name="l01587"></a><span class="lineno"> 1587</span> </div>
<div class="line"><a id="l01588" name="l01588"></a><span class="lineno"> 1588</span> <span class="comment">// The precedence cache can become invalid during presolve as it does not</span></div>
<div class="line"><a id="l01589" name="l01589"></a><span class="lineno"> 1589</span> <span class="comment">// handle variable substitution. It is safer just to clear it at the end</span></div>
<div class="line"><a id="l01590" name="l01590"></a><span class="lineno"> 1590</span> <span class="comment">// of the expansion phase.</span></div>
<div class="line"><a id="l01591" name="l01591"></a><span class="lineno"> 1591</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;ClearPrecedenceCache();</div>
<div class="line"><a id="l01592" name="l01592"></a><span class="lineno"> 1592</span> </div>
<div class="line"><a id="l01593" name="l01593"></a><span class="lineno"> 1593</span> <span class="comment">// Make sure the context is consistent.</span></div>
<div class="line"><a id="l01594" name="l01594"></a><span class="lineno"> 1594</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;InitializeNewDomains();</div>
<div class="line"><a id="l01595" name="l01595"></a><span class="lineno"> 1595</span> </div>
<div class="line"><a id="l01596" name="l01596"></a><span class="lineno"> 1596</span> <span class="comment">// Update any changed domain from the context.</span></div>
<div class="line"><a id="l01597" name="l01597"></a><span class="lineno"> 1597</span> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;variables_size(); ++i) {</div>
<div class="line"><a id="l01598" name="l01598"></a><span class="lineno"> 1598</span> <a class="code hl_function" href="namespaceoperations__research_1_1sat.html#a901c19b12842f8af153e588a689a90b5">FillDomainInProto</a>(<a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;DomainOf(i),</div>
<div class="line"><a id="l01599" name="l01599"></a><span class="lineno"> 1599</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;working_model-&gt;mutable_variables(i));</div>
<div class="line"><a id="l01600" name="l01600"></a><span class="lineno"> 1600</span> }</div>
<div class="line"><a id="l01601" name="l01601"></a><span class="lineno"> 1601</span> </div>
<div class="line"><a id="l01602" name="l01602"></a><span class="lineno"> 1602</span> <a class="code hl_variable" href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a>-&gt;NotifyThatModelIsExpanded();</div>
<div class="line"><a id="l01603" name="l01603"></a><span class="lineno"> 1603</span>}</div>
<div class="line"><a id="l01604" name="l01604"></a><span class="lineno"> 1604</span> </div>
<div class="line"><a id="l01605" name="l01605"></a><span class="lineno"> 1605</span>} <span class="comment">// namespace sat</span></div>
<div class="line"><a id="l01606" name="l01606"></a><span class="lineno"> 1606</span>} <span class="comment">// namespace operations_research</span></div>
<div class="ttc" id="aalldiff__cst_8cc_html_ad10edae0a852d72fb76afb1c77735045"><div class="ttname"><a href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">min</a></div><div class="ttdeci">int64_t min</div><div class="ttdef"><b>Definition:</b> <a href="alldiff__cst_8cc_source.html#l00139">alldiff_cst.cc:139</a></div></div>
<div class="ttc" id="abase_2logging_8h_html"><div class="ttname"><a href="base_2logging_8h.html">logging.h</a></div></div>
<div class="ttc" id="abase_2logging_8h_html_a3e1cfef60e774a81f30eaddf26a3a274"><div class="ttname"><a href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a></div><div class="ttdeci">#define CHECK(condition)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00495">base/logging.h:495</a></div></div>
<div class="ttc" id="abase_2logging_8h_html_a7c0ce053b28d53aa4eaf3eb7fb71663b"><div class="ttname"><a href="base_2logging_8h.html#a7c0ce053b28d53aa4eaf3eb7fb71663b">CHECK_EQ</a></div><div class="ttdeci">#define CHECK_EQ(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00703">base/logging.h:703</a></div></div>
<div class="ttc" id="abase_2logging_8h_html_ae17f8119c108cf3070bad3449c7e0006"><div class="ttname"><a href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a></div><div class="ttdeci">#define DCHECK(condition)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00890">base/logging.h:890</a></div></div>
<div class="ttc" id="abase_2logging_8h_html_ae89df3243bbb8341130c7b3f44145ea0"><div class="ttname"><a href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a></div><div class="ttdeci">#define DCHECK_EQ(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00891">base/logging.h:891</a></div></div>
<div class="ttc" id="abase_2logging_8h_html_afcaa7cadd41741bb855c2ada1d2ef927"><div class="ttname"><a href="base_2logging_8h.html#afcaa7cadd41741bb855c2ada1d2ef927">VLOG</a></div><div class="ttdeci">#define VLOG(verboselevel)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00984">base/logging.h:984</a></div></div>
<div class="ttc" id="aclassoperations__research_1_1_domain_html_a1f1de3874966a137f140748498f43e0c"><div class="ttname"><a href="classoperations__research_1_1_domain.html#a1f1de3874966a137f140748498f43e0c">operations_research::Domain::Complement</a></div><div class="ttdeci">Domain Complement() const</div><div class="ttdoc">Returns the set Int64 D.</div><div class="ttdef"><b>Definition:</b> <a href="sorted__interval__list_8cc_source.html#l00266">sorted_interval_list.cc:266</a></div></div>
<div class="ttc" id="aclassoperations__research_1_1_domain_html_ac2d88de67793063ad5f5e923ffd1c0eb"><div class="ttname"><a href="classoperations__research_1_1_domain.html#ac2d88de67793063ad5f5e923ffd1c0eb">operations_research::Domain::FromValues</a></div><div class="ttdeci">static Domain FromValues(std::vector&lt; int64_t &gt; values)</div><div class="ttdoc">Creates a domain from the union of an unsorted list of integer values.</div><div class="ttdef"><b>Definition:</b> <a href="sorted__interval__list_8cc_source.html#l00144">sorted_interval_list.cc:144</a></div></div>
<div class="ttc" id="aclassoperations__research_1_1sat_1_1_presolve_context_html"><div class="ttname"><a href="classoperations__research_1_1sat_1_1_presolve_context.html">operations_research::sat::PresolveContext</a></div><div class="ttdef"><b>Definition:</b> <a href="presolve__context_8h_source.html#l00079">presolve_context.h:79</a></div></div>
<div class="ttc" id="aconstraint__solver_2table_8cc_html_a9293e4d29cac928301645070dd307683"><div class="ttname"><a href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a></div><div class="ttdeci">int64_t b</div><div class="ttdef"><b>Definition:</b> <a href="constraint__solver_2table_8cc_source.html#l00047">constraint_solver/table.cc:47</a></div></div>
<div class="ttc" id="aconstraint__solver_2table_8cc_html_acb18315d548212835cd8ed4287e6c0b6"><div class="ttname"><a href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a></div><div class="ttdeci">int64_t a</div><div class="ttdef"><b>Definition:</b> <a href="constraint__solver_2table_8cc_source.html#l00046">constraint_solver/table.cc:46</a></div></div>
<div class="ttc" id="acp__model__expand_8h_html"><div class="ttname"><a href="cp__model__expand_8h.html">cp_model_expand.h</a></div></div>
<div class="ttc" id="acp__model__fz__solver_8cc_html_aed003f5eb5197bc586b7ef2c36a63da2"><div class="ttname"><a href="cp__model__fz__solver_8cc.html#aed003f5eb5197bc586b7ef2c36a63da2">proto</a></div><div class="ttdeci">CpModelProto proto</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__fz__solver_8cc_source.html#l00118">cp_model_fz_solver.cc:118</a></div></div>
<div class="ttc" id="acp__model__utils_8h_html"><div class="ttname"><a href="cp__model__utils_8h.html">cp_model_utils.h</a></div></div>
<div class="ttc" id="ademon__profiler_8cc_html_a05da18ca9c7b657a4a6ea24e07c9b695"><div class="ttname"><a href="demon__profiler_8cc.html#a05da18ca9c7b657a4a6ea24e07c9b695">ct</a></div><div class="ttdeci">const Constraint * ct</div><div class="ttdef"><b>Definition:</b> <a href="demon__profiler_8cc_source.html#l00043">demon_profiler.cc:43</a></div></div>
<div class="ttc" id="ademon__profiler_8cc_html_ac072af30c4ffbc834bb4c681f6ecb514"><div class="ttname"><a href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a></div><div class="ttdeci">int64_t value</div><div class="ttdef"><b>Definition:</b> <a href="demon__profiler_8cc_source.html#l00044">demon_profiler.cc:44</a></div></div>
<div class="ttc" id="aexpr__array_8cc_html_a472a99923cbe11ae7b5a5d157d9ad465"><div class="ttname"><a href="expr__array_8cc.html#a472a99923cbe11ae7b5a5d157d9ad465">var</a></div><div class="ttdeci">IntVar * var</div><div class="ttdef"><b>Definition:</b> <a href="expr__array_8cc_source.html#l01874">expr_array.cc:1874</a></div></div>
<div class="ttc" id="agurobi__interface_8cc_html_a5f287b83a753915ae862fed64f8640a6"><div class="ttname"><a href="gurobi__interface_8cc.html#a5f287b83a753915ae862fed64f8640a6">context</a></div><div class="ttdeci">GurobiMPCallbackContext * context</div><div class="ttdef"><b>Definition:</b> <a href="gurobi__interface_8cc_source.html#l00514">gurobi_interface.cc:514</a></div></div>
<div class="ttc" id="aintegral__types_8h_html"><div class="ttname"><a href="integral__types_8h.html">integral_types.h</a></div></div>
<div class="ttc" id="alocal__search_8cc_html_a750b5d744c39a06bfb13e6eb010e35d0"><div class="ttname"><a href="local__search_8cc.html#a750b5d744c39a06bfb13e6eb010e35d0">index</a></div><div class="ttdeci">int index</div><div class="ttdef"><b>Definition:</b> <a href="local__search_8cc_source.html#l02750">local_search.cc:2750</a></div></div>
<div class="ttc" id="anamespacegtl_html_a288a1dc92da5d3ad62d4bc4cec9e8b1d"><div class="ttname"><a href="namespacegtl.html#a288a1dc92da5d3ad62d4bc4cec9e8b1d">gtl::STLSortAndRemoveDuplicates</a></div><div class="ttdeci">void STLSortAndRemoveDuplicates(T *v, const LessFunc &amp;less_func)</div><div class="ttdef"><b>Definition:</b> <a href="stl__util_8h_source.html#l00058">stl_util.h:58</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1math__opt_html_a5de89a1f6e3f80a49a0d76136d8044e2"><div class="ttname"><a href="namespaceoperations__research_1_1math__opt.html#a5de89a1f6e3f80a49a0d76136d8044e2">operations_research::math_opt::swap</a></div><div class="ttdeci">void swap(IdMap&lt; K, V &gt; &amp;a, IdMap&lt; K, V &gt; &amp;b)</div><div class="ttdef"><b>Definition:</b> <a href="id__map_8h_source.html#l00262">id_map.h:262</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_a217338425de4389014563f1f24331713"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#a217338425de4389014563f1f24331713">operations_research::sat::RefIsPositive</a></div><div class="ttdeci">bool RefIsPositive(int ref)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8h_source.html#l00036">cp_model_utils.h:36</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_a3e5f39b52251ad02e571592493b4d39f"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#a3e5f39b52251ad02e571592493b4d39f">operations_research::sat::CompressTuples</a></div><div class="ttdeci">void CompressTuples(absl::Span&lt; const int64_t &gt; domain_sizes, int64_t any_value, std::vector&lt; std::vector&lt; int64_t &gt; &gt; *tuples)</div><div class="ttdef"><b>Definition:</b> <a href="sat_2util_8cc_source.html#l00370">sat/util.cc:370</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_a4d700795b2500705ef3031ec994fe472"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#a4d700795b2500705ef3031ec994fe472">operations_research::sat::ExpandCpModel</a></div><div class="ttdeci">void ExpandCpModel(PresolveContext *context)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__expand_8cc_source.html#l01490">cp_model_expand.cc:1490</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_a852a51b53f6217d6bfd1aef455f53f8c"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#a852a51b53f6217d6bfd1aef455f53f8c">operations_research::sat::SolveDiophantineEquationOfSizeTwo</a></div><div class="ttdeci">bool SolveDiophantineEquationOfSizeTwo(int64_t &amp;a, int64_t &amp;b, int64_t &amp;cte, int64_t &amp;x0, int64_t &amp;y0)</div><div class="ttdef"><b>Definition:</b> <a href="sat_2util_8cc_source.html#l00147">sat/util.cc:147</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_a901c19b12842f8af153e588a689a90b5"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#a901c19b12842f8af153e588a689a90b5">operations_research::sat::FillDomainInProto</a></div><div class="ttdeci">void FillDomainInProto(const Domain &amp;domain, ProtoWithDomain *proto)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8h_source.html#l00093">cp_model_utils.h:93</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_ab1240060466ba48a36a4b36379bce26a"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#ab1240060466ba48a36a4b36379bce26a">operations_research::sat::ReadDomainFromProto</a></div><div class="ttdeci">Domain ReadDomainFromProto(const ProtoWithDomain &amp;proto)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8h_source.html#l00104">cp_model_utils.h:104</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_acdbc8ad33149d45a6e6fcd8b72fd68ed"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#acdbc8ad33149d45a6e6fcd8b72fd68ed">operations_research::sat::PositiveRef</a></div><div class="ttdeci">int PositiveRef(int ref)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8h_source.html#l00035">cp_model_utils.h:35</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_aced7df5982ab26894efec32543e459f7"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#aced7df5982ab26894efec32543e459f7">operations_research::sat::AddLinearExpressionToLinearConstraint</a></div><div class="ttdeci">void AddLinearExpressionToLinearConstraint(const LinearExpressionProto &amp;expr, int64_t coefficient, LinearConstraintProto *linear)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8cc_source.html#l00541">cp_model_utils.cc:541</a></div></div>
<div class="ttc" id="anamespaceoperations__research_1_1sat_html_ae0803b8198728cd4f6e58498d9c60091"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#ae0803b8198728cd4f6e58498d9c60091">operations_research::sat::NegatedRef</a></div><div class="ttdeci">int NegatedRef(int ref)</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__utils_8h_source.html#l00034">cp_model_utils.h:34</a></div></div>
<div class="ttc" id="anamespaceoperations__research_html"><div class="ttname"><a href="namespaceoperations__research.html">operations_research</a></div><div class="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><div class="ttdef"><b>Definition:</b> <a href="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>
<div class="ttc" id="anamespaceoperations__research_html_a111f44b9b9cf67a8e8d83794ac9f5291"><div class="ttname"><a href="namespaceoperations__research.html#a111f44b9b9cf67a8e8d83794ac9f5291">operations_research::CapAdd</a></div><div class="ttdeci">int64_t CapAdd(int64_t x, int64_t y)</div><div class="ttdef"><b>Definition:</b> <a href="saturated__arithmetic_8h_source.html#l00126">saturated_arithmetic.h:126</a></div></div>
<div class="ttc" id="anamespaceoperations__research_html_a4a43d435871f16c321861fa5de32df82"><div class="ttname"><a href="namespaceoperations__research.html#a4a43d435871f16c321861fa5de32df82">operations_research::CapSub</a></div><div class="ttdeci">int64_t CapSub(int64_t x, int64_t y)</div><div class="ttdef"><b>Definition:</b> <a href="saturated__arithmetic_8h_source.html#l00158">saturated_arithmetic.h:158</a></div></div>
<div class="ttc" id="anamespaceoperations__research_html_a87d7aa58897e0042898d1c2207deda18"><div class="ttname"><a href="namespaceoperations__research.html#a87d7aa58897e0042898d1c2207deda18">operations_research::ProtobufShortDebugString</a></div><div class="ttdeci">std::string ProtobufShortDebugString(const P &amp;message)</div><div class="ttdef"><b>Definition:</b> <a href="port_2proto__utils_8h_source.html#l00038">port/proto_utils.h:38</a></div></div>
<div class="ttc" id="anamespaceoperations__research_html_aa64bf49d041052c7cb3f40f7496d7534"><div class="ttname"><a href="namespaceoperations__research.html#aa64bf49d041052c7cb3f40f7496d7534">operations_research::CapProd</a></div><div class="ttdeci">int64_t CapProd(int64_t x, int64_t y)</div><div class="ttdef"><b>Definition:</b> <a href="saturated__arithmetic_8h_source.html#l00235">saturated_arithmetic.h:235</a></div></div>
<div class="ttc" id="aoptimization_8cc_html_af63dcc00f2023fdf498e0829e6fb8a6b"><div class="ttname"><a href="optimization_8cc.html#af63dcc00f2023fdf498e0829e6fb8a6b">literal</a></div><div class="ttdeci">Literal literal</div><div class="ttdef"><b>Definition:</b> <a href="optimization_8cc_source.html#l00089">optimization.cc:89</a></div></div>
<div class="ttc" id="aport_2proto__utils_8h_html"><div class="ttname"><a href="port_2proto__utils_8h.html">proto_utils.h</a></div></div>
<div class="ttc" id="apresolve__context_8h_html"><div class="ttname"><a href="presolve__context_8h.html">presolve_context.h</a></div></div>
<div class="ttc" id="aresource_8cc_html_a29fb0dd9484d890b12b280c41c150e20"><div class="ttname"><a href="resource_8cc.html#a29fb0dd9484d890b12b280c41c150e20">demand</a></div><div class="ttdeci">int64_t demand</div><div class="ttdef"><b>Definition:</b> <a href="resource_8cc_source.html#l00125">resource.cc:125</a></div></div>
<div class="ttc" id="aresource_8cc_html_aee52de7b225665566aa47246b9d6b8fa"><div class="ttname"><a href="resource_8cc.html#aee52de7b225665566aa47246b9d6b8fa">time</a></div><div class="ttdeci">int64_t time</div><div class="ttdef"><b>Definition:</b> <a href="resource_8cc_source.html#l01693">resource.cc:1693</a></div></div>
<div class="ttc" id="arouting__flow_8cc_html_a64e7efc5529154ba56903e75f5300990"><div class="ttname"><a href="routing__flow_8cc.html#a64e7efc5529154ba56903e75f5300990">tail</a></div><div class="ttdeci">int64_t tail</div><div class="ttdef"><b>Definition:</b> <a href="routing__flow_8cc_source.html#l00149">routing_flow.cc:149</a></div></div>
<div class="ttc" id="arouting__flow_8cc_html_afca32f65388659a4b0956496169488b4"><div class="ttname"><a href="routing__flow_8cc.html#afca32f65388659a4b0956496169488b4">head</a></div><div class="ttdeci">int64_t head</div><div class="ttdef"><b>Definition:</b> <a href="routing__flow_8cc_source.html#l00150">routing_flow.cc:150</a></div></div>
<div class="ttc" id="asat_2util_8h_html"><div class="ttname"><a href="sat_2util_8h.html">util.h</a></div></div>
<div class="ttc" id="asaturated__arithmetic_8h_html"><div class="ttname"><a href="saturated__arithmetic_8h.html">saturated_arithmetic.h</a></div></div>
<div class="ttc" id="asorted__interval__list_8h_html"><div class="ttname"><a href="sorted__interval__list_8h.html">sorted_interval_list.h</a></div></div>
<div class="ttc" id="astl__util_8h_html"><div class="ttname"><a href="stl__util_8h.html">stl_util.h</a></div></div>
<div class="ttc" id="atrace_8cc_html_a36bd74109f547f7f8198faf5a12d2879"><div class="ttname"><a href="trace_8cc.html#a36bd74109f547f7f8198faf5a12d2879">message</a></div><div class="ttdeci">std::string message</div><div class="ttdef"><b>Definition:</b> <a href="trace_8cc_source.html#l00398">trace.cc:398</a></div></div>
<div class="ttc" id="autil_2logging_8h_html"><div class="ttname"><a href="util_2logging_8h.html">logging.h</a></div></div>
<div class="ttc" id="autil_2logging_8h_html_a5f67b653dd99ddbe5e3367e3b4b7b532"><div class="ttname"><a href="util_2logging_8h.html#a5f67b653dd99ddbe5e3367e3b4b7b532">SOLVER_LOG</a></div><div class="ttdeci">#define SOLVER_LOG(logger,...)</div><div class="ttdef"><b>Definition:</b> <a href="util_2logging_8h_source.html#l00069">util/logging.h:69</a></div></div>
<div class="ttc" id="avlog__is__on_8h_html_a956152cad330225654d128f35c00efce"><div class="ttname"><a href="vlog__is__on_8h.html#a956152cad330225654d128f35c00efce">VLOG_IS_ON</a></div><div class="ttdeci">#define VLOG_IS_ON(verboselevel)</div><div class="ttdef"><b>Definition:</b> <a href="vlog__is__on_8h_source.html#l00044">vlog_is_on.h:44</a></div></div>
</div><!-- fragment --></div><!-- contents -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.18-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="dir_a7cc1eeded8f693d0da6c729bc88c45a.html">ortools</a></li><li class="navelem"><a class="el" href="dir_dddac007a45022d9da6ea1dee012c3b9.html">sat</a></li><li class="navelem"><a class="el" href="cp__model__expand_8cc.html">cp_model_expand.cc</a></li>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.9.3 </li>
</ul>
</div>
</body>
</html>