Jip Dekker's PhD Thesis
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Work on the reification chapter

- Comments by Peter
- Additional reference
- Listings

+94 -74
+12
assets/bibliography/references.bib
··· 706 706 year = {2020}, 707 707 } 708 708 709 + @inbook{lodi-2013-variability, 710 + author = {Andrea Lodi and Andrea Tramontani}, 711 + title = {Performance Variability in Mixed-Integer Programming}, 712 + booktitle = {Theory Driven by Influential Applications}, 713 + chapter = {Chapter 1}, 714 + year = 2013, 715 + pages = {1-12}, 716 + doi = {10.1287/educ.2013.0112}, 717 + URL = {https://pubsonline.informs.org/doi/abs/10.1287/educ.2013.0112}, 718 + eprint = {https://pubsonline.informs.org/doi/pdf/10.1287/educ.2013.0112}, 719 + } 720 + 709 721 @article{lougee-heimer-2003-coin, 710 722 author = {Robin Lougee{-}Heimer}, 711 723 title = {The Common Optimization INterface for Operations Research: Promoting
+4
assets/listing/half_alldiff.mzn
··· 1 + predicate all_different(array[int] of var int: x) = 2 + forall(i,j in index_set(x) where i < j)( 3 + x[i] != x[j] 4 + );
+5
assets/listing/half_impli.mzn
··· 1 + predicate impli( 2 + var bool: x ::promise_ctx_antitone, 3 + var bool: y ::promise_ctx_monotone 4 + ) = 5 + not x \/ y;
+15
assets/listing/half_reif_check.mzn
··· 1 + predicate _int_lin_le_imp( 2 + array[int] of int: c, 3 + array[int] of var int: x, 4 + int: d, 5 + var bool: b 6 + ) = 7 + if is_fixed(b) then 8 + if fix(b) then 9 + int_lin_le(c, x, d) 10 + else 11 + true 12 + endif 13 + else 14 + int_lin_le_imp(c, x, d, b) 15 + endif;
+2 -2
chapters/2_background.tex
··· 155 155 \item and the \gls{objective} is included as a solving goal. 156 156 \end{itemize} 157 157 158 - More complex models also include definitions for custom types, user defined functions, and a custom output format. 158 + More complex models also include definitions for custom types, user-defined functions, and a custom output format. 159 159 These items are not constrained to occur in any particular order. 160 160 We briefly discuss the most important model items. 161 161 Note that these items already refer to \minizinc{} expressions, which will be discussed in \cref{subsec:back-mzn-expr}. ··· 180 180 The type of a \parameter{} can similarly be marked by the \mzninline{par} keyword, but this is not required. 181 181 These types are used both as normal \parameters{} and as \variables{}. 182 182 To better structure models, \minizinc{} allows collections of these types to be contained in \glspl{array}. 183 - Unlike other languages, \glspl{array} have a user defined index set, which can start at any value, but they have to be a continuous range. 183 + Unlike other languages, \glspl{array} have a user-defined index set, which can start at any value, but they have to be a continuous range. 184 184 For example, the following declaration declares an array going from 5 to 10 of new Boolean \variables{}. 185 185 186 186 \begin{mzn}
+53 -69
chapters/4_half_reif.tex
··· 30 30 31 31 \begin{enumerate} 32 32 \item \Gls{rewriting} using \glspl{half-reif} naturally produces \glspl{rel-sem}. 33 - \item \Glspl{propagator} for a \glspl{half-reif} can often be constructed by merely altering a \gls{propagator} implementation for its regular \constraint{}. 33 + \item \Glspl{propagator} for a \glspl{half-reif} can usually be constructed by merely altering a \gls{propagator} implementation for its regular \constraint{}. 34 34 \item \Gls{half-reif} does not often interact with its \gls{cvar}, limiting the amount of triggered \glspl{propagator} that are known to be unable to prune any \domains{}. 35 35 \end{enumerate} 36 36 ··· 76 76 \end{description} 77 77 78 78 As previously explained, \gls{half-reif} can be used for expressions in \posc{} context. 79 - Although expressions in a \negc{} context cannot be directly \gls{half-reified}, the negation of a expression in a \negc{} context can be \gls{half-reified}. 79 + Although expressions in a \negc{} context cannot be directly \gls{half-reified}, the negation of an expression in a \negc{} context can be \gls{half-reified}. 80 80 81 81 \begin{example} 82 82 Consider, for example, the following \constraint{}. ··· 98 98 \end{example} 99 99 100 100 Expressions in a \mixc{} context are in a position where \gls{half-reif} is impossible. 101 - Only full \gls{reif} can be used for expressions in that are in this context. 101 + Only full \gls{reif} can be used for expressions that are in this context. 102 102 This occurs, for example, when using an exclusive or expression in a \constraint{}. 103 103 The value that one side must take directly depends on the value that the other side takes. 104 104 Each side can thus be forced to be true or false. ··· 122 122 123 123 \begin{algorithm} 124 124 125 - \KwIn{A function \(check\), that returns false when the \constraint{} \(c\) cannot be satisfied, a function \(prune\), that eliminates values from \variable{} \glspl{domain} that violate\glsadd{violated} the \constraint{} \(c\), and a Boolean control \variable{} \texttt{b}. 125 + \KwIn{A function \(check\), that returns false when the \constraint{} \(c\) cannot be satisfied, a function \(prune\), that eliminates values from \variable{} \glspl{domain} that violate\glsadd{violated} the \constraint{} \(c\), and a Boolean \gls{cvar} \texttt{b}. 126 126 } 127 127 \KwResult{This pseudo code propagates the \gls{half-reif} of \(c\) (\ie{} \(\texttt{b} \implies\ c\)).} 128 128 ··· 191 191 For all these \glspl{reif}, its replacement by a \gls{half-reif} can remove half of the implications required for the \gls{reif}. 192 192 193 193 For \gls{sat} solvers, a \gls{decomp} for a \gls{half-reif} can be created from its regular \gls{decomp}. 194 - Any \constraint{} \(c\) will \gls{decomp} into \gls{cnf}. 194 + Any \constraint{} \(c\) will \gls{decomp} into \gls{cnf} of the following form. 195 195 \[ c = \forall_{i} \exists_{j} lit_{ij} \] 196 196 The \gls{half-reif}, with \gls{cvar} \texttt{b}, could take the following encoding. 197 197 \[ \texttt{b} \implies c = \forall_{i} \neg \texttt{b} \lor \exists_{j} lit_{ij} \] ··· 340 340 341 341 \begin{example} 342 342 343 - Consider the following user-defined \minizinc{} implementation of a logical implication. 343 + Consider the user-defined \minizinc{} implementation of a logical implication in \cref{lst:half-impli}. 344 344 345 - \begin{mzn} 346 - predicate impli( 347 - var bool: x ::promise_ctx_antitone, 348 - var bool: y ::promise_ctx_monotone 349 - ) = 350 - not x \/ y; 351 - \end{mzn} 345 + \begin{listing} 346 + \mznfile{assets/listing/half_impli.mzn} 347 + \caption{\label{lst:half-impli} A user-defined predicate of a logical implication using \glspl{annotation} to define the context usage of its arguments.} 348 + \end{listing} 352 349 353 - The annotations placed on the argument of the \mzninline{impli} function will apply the same context transformations as the \mzninline{->} operator shown in \cref{alg:arg-ctx}. 350 + The \glspl{annotation} placed on the argument of the \mzninline{impli} function will apply the same context transformations as the \mzninline{->} operator shown in \cref{alg:arg-ctx}. 354 351 In term of context analysis, this function now is equivalent to the \minizinc{} operator. 355 352 356 353 \end{example} ··· 373 370 \Case{\mzninline{ > }, \mzninline{>= }, \mzninline{- }}{ 374 371 \Return{\tuple{\changepos{}ctx, \changeneg{}ctx}} 375 372 } 376 - \Case{\mzninline{ <-> }, \mzninline{xor }, \mzninline{* }}{ 373 + \Case{\mzninline{ <-> }, \mzninline{= }, \mzninline{xor }, \mzninline{* }}{ 377 374 \Return{\tuple{\mixc, \mixc}} 378 375 } 379 376 \Case{\mzninline{ /\ }}{ ··· 409 406 Note that this can only occur when a \gls{native} \constraint{} does not define a \gls{reif}. 410 407 \end{enumerate} 411 408 412 - The (Access) and (ITE) rules show the context inference for \gls{array} access and if-then-else expressions respectively. 409 + The (Access) and (ITE) rules show the context inference for \gls{array} access and \gls{conditional} expressions respectively. 413 410 Their inner expressions are evaluated in \(\changepos{}ctx\). 414 411 The inner expressions cannot be simply be evaluated in \(ctx\), because it is not yet certain which expression will be chosen. 415 412 This is important for when \(ctx\) is \rootc{}, since we, at compile time, cannot say which expression will hold globally. ··· 505 502 \label{subsec:half-?root} 506 503 507 504 In the previous section, we briefly discussed the context transformations for the (Access) and (ITE) rules in \cref{fig:half-analysis-expr}. 508 - Different from the rules described, when an \gls{array} access or if-then-else expression is found in \rootc{} context, it often makes sense to evaluate its sub-expression in \rootc{} context as well. 505 + Different from the rules described, when an \gls{array} access or \gls{conditional} expression is found in \rootc{} context, it often makes sense to evaluate its sub-expression in \rootc{} context as well. 509 506 It is, however, not always safe to do so. 510 507 511 508 \begin{example} ··· 514 511 For example, consider the following \microzinc{} fragment. 515 512 516 513 \begin{mzn} 517 - \constraint{} if b then 514 + constraint if b then 518 515 F(x, y, z) 519 516 else 520 517 G(x, y, z) 521 518 endif; 522 519 \end{mzn} 523 520 524 - In this case, since only one side of the if-then-else expression is evaluated, the compiler can output calls to the \rootc{} variant of the functions. 521 + Let us assume that \mzninline{b} is a \parameter{}, but that its value is not known during the compilation from \minizinc{} to \microzinc{}. 522 + In this case, we know that only one side of the \gls{conditional} expression will evaluated, and that call will then globally constrain the \cmodel{}. 523 + As such, the \compiler{} can output calls to the \rootc{} variant of the functions. 525 524 This will enforce the \constraint{} in the most efficient way. 526 525 527 526 Things, however, change when the situation gets more complex. ··· 536 535 } in ret; 537 536 \end{mzn} 538 537 539 - One side of the if-then-else expression is also used in a disjunction. 538 + One side of the \gls{conditional} expression is also used in a disjunction. 540 539 If \mzninline{b} evaluates to \mzninline{true}, then \mzninline{p} is evaluated in \rootc{} context, and \mzninline{p} can take the value \mzninline{true} in the disjunction. 541 540 Otherwise, \mzninline{q} is evaluated in \rootc{} context, and \mzninline{p} in the disjunction must be evaluated in \posc{} context. 542 - It is, therefore, not safe to assume that all sides of the if-then-else expressions are evaluated in \rootc{} context. 541 + In this situation, it is not safe for the \compiler{} to output calls for the \rootc{} variants of these calls. 543 542 \end{example} 544 543 545 544 Using the \changepos{} transformation for sub-expression contexts is safe, but it places a large burden on the \solver{}. 546 545 The solver performs better when the no \gls{reif} has to be used. 547 546 548 - To detect situation where the sub-expression are only used in an \gls{array} access or if-then-else expression we introduce the \mayberootc{} context. 547 + To detect situation where the sub-expression are only used in an \gls{array} access or \gls{conditional} expression we introduce the \mayberootc{} context. 549 548 This context functions as a ``weak'' \rootc{} context. 550 549 If it is joined with any other context, then it acts as \posc{}. 551 550 The extended join operation is shown in \cref{fig:half-maybe-join}. ··· 580 579 \caption{\label{fig:half-analysis-maybe-root} Updated context inference rules for \mayberootc{}.} 581 580 \end{figure*} 582 581 583 - \Cref{fig:half-analysis-maybe-root} shows the additional inference rules for \gls{array} access and if-then-else expressions. 582 + \Cref{fig:half-analysis-maybe-root} shows the additional inference rules for \gls{array} access and \gls{conditional} expressions. 584 583 Looking back at \cref{ex:half-maybe-root}, these additional rules and updated join operation will ensure that the first case will correctly use \rootc{} context calls. 585 584 For the second case, however, it detects that \mzninline{p} is used in both \posc{} and \mayberootc{} context. 586 585 Therefore, it will output the \posc{} call for the right hand side of \mzninline{p}, even when \mzninline{b} evaluates to \mzninline{true}. ··· 590 589 \section{Rewriting and Half Reification}% 591 590 \label{sec:half-rewriting} 592 591 593 - During the \gls{rewriting} process the contexts assigned to the different expressions can be used directly to determine if and how a expression has to be \gls{reified}. 592 + During the \gls{rewriting} process the contexts assigned to the different expressions can be used directly to determine if and how an expression has to be \gls{reified}. 594 593 595 594 \begin{example} 596 595 \label{ex:half-rewriting} ··· 626 625 constraint bool_clause([b1, b2], []); % b1 \/ b2 627 626 constraint bool_clause_imp([b3], [y], b1); % b1 -> (y -> b3) 628 627 constraint f_imp(x, b3); % b3 -> f(x) 629 - constraint int_ne_imp(x, 5, b4); % b4 -> x != 5 628 + constraint int_ne_imp(x, 5, b2); % b2 -> x != 5 630 629 \end{mzn} 631 630 632 631 We are able to replace the two \glspl{reif} and push the negation inwards, transforming the equals \constraint{} into a not equals \constraint{}. ··· 634 633 If the Boolean \mzninline{y} was not further \constraint{} in the problem, then we could further reduce it to the following \constraints{}. 635 634 636 635 \begin{mzn} 637 - constraint bool_clause([y, b2], []); % y \/ b2 638 - constraint f_imp(x, y); % b3 -> f(x) 639 - constraint int_ne_imp(x, 5, b4); % b4 -> x != 5 636 + constraint bool_clause([y, b2], []); % y \/ b2 637 + constraint f_imp(x, y); % y -> f(x) 638 + constraint int_ne_imp(x, 5, b2); % b2 -> x != 5 640 639 \end{mzn} 641 640 642 641 \end{example} ··· 650 649 The \gls{rewriting} with \gls{half-reif} also interacts with some of the optimisation methods used during the \gls{rewriting} process. 651 650 Most importantly, \gls{half-reif} has to be considered when using \gls{cse} and \gls{propagation} can change the context of expression. 652 651 In \cref{subsec:half-cse} we will discuss how \gls{cse} can be adjusted to handle \gls{half-reif}. 653 - Finally, in \cref{subsec:half-dyn-context} we will discuss how the context in which a expression is executed can be adjusted during the \gls{rewriting} process. 652 + Finally, in \cref{subsec:half-dyn-context} we will discuss how the context in which an expression is executed can be adjusted during the \gls{rewriting} process. 654 653 655 654 \subsection{Chain compression}% 656 655 \label{subsec:half-compress} ··· 660 659 The case shown in the example can be generalised to 661 660 662 661 \begin{mzn} 663 - b1 -> b2 /\ forall(i in N)(b2 -> c[i]) 662 + constraint b1 -> b2 /\ forall(i in N)(b2 -> c[i]) 664 663 \end{mzn} 665 664 666 665 \noindent{}which, if \texttt{b2} has no other usage in the instance, can be resolved to 667 666 668 667 \begin{mzn} 669 - forall(i in N)(b1 -> c[i]) 668 + constraint forall(i in N)(b1 -> c[i]) 670 669 \end{mzn} 671 670 672 671 \noindent{}after which \texttt{b2} can be removed from the model. ··· 708 707 These can be split up into multiple implications. 709 708 710 709 \begin{mzn} 711 - b -> forall(x in N)(x) 710 + constraint b -> forall(x in N)(x) 712 711 \end{mzn} 713 712 714 713 The expression above is logically equivalent to the following expression. 715 714 716 715 \begin{mzn} 717 - forall(x in N)(b -> x) 716 + constraint forall(x in N)(b -> x) 718 717 \end{mzn} 719 718 720 719 Adopting this transformation both simplifies a complicated \constraint{} and possibly allows for the further compression of \glspl{implication-chain}. 721 720 It should however be noted that although this transformation can increase the number of \constraints{} in the \gls{slv-mod}, it generally increases the \gls{propagation} efficiency. 722 721 723 - To adjust the algorithm to simplify implied conjunctions more introspection from the \minizinc{} \compiler{} is required. 722 + To adjust the algorithm to simplify implied conjunctions, more introspection from the \minizinc{} \compiler{} is required. 724 723 The \compiler{} must be able to tell if a \variable{} is (only) a \gls{cvar} of a reified conjunction and what the elements of that conjunction are. 725 - In the case where a \variable{} has one incoming edge, but it is marked as used in other \constraint{}, we can now check if it is only a \gls{cvar} for a \gls{reified} conjunction and perform the transformation in this case. 724 + In the case where a \variable{} has one incoming edge, but it is marked as used in another \constraint{}, we can now check if it is only a \gls{cvar} for a \gls{reified} conjunction and perform the transformation in this case. 726 725 727 726 \subsection{Common Sub-expression Elimination}% 728 727 \label{subsec:half-cse} ··· 759 758 The dependency tracking through the use of \constraints{} attached to \variables{} ensures no defining \constraints are left in the model. 760 759 This ensures that all \variables{} and \constraints{} created the earlier version are correctly removed. 761 760 762 - Because the expression itself is changed when a negation is moved inwards, it may not always be clear when the same expression is used in both \posc{} and negc{} context. 761 + Because the expression itself is changed when a negation is moved inwards, it may not always be clear when the same expression is used in both \posc{} and \negc{} context. 763 762 This problem is solved by introducing a canonical form for expressions where negations can be pushed inwards. 764 763 In this form the result of \gls{rewriting} an expression and its negation are collected in the same place within the \gls{cse} table. 765 764 If it is found that for an expression that is about to be \gls{half-reified} there already exists an \gls{half-reif} for its negation, then we instead evaluate the expression in \mixc{} context. ··· 771 770 When its expression is negated, pushing the negation inwards will result in a \mzninline{!=} operator, a \mzninline{int_ne} call. 772 771 The opposite happens when a negation is pushed inwards for an expression using \mzninline{!=} operator. 773 772 So to ensure that a \negc{} occurrence of \mzninline{int_eq} and a \posc{} occurrence of \mzninline{int_ne} use the same \gls{cvar} they are both mapped to \mzninline{int_eq} in the \gls{cse} table. 774 - The mapping ensures that the context is correctly transformed when accessing the \gls{cse} table for a \mzninline{int_ne} call. 773 + The mapping ensures that the context is correctly transformed when accessing the \gls{cse} table for an \mzninline{int_ne} call. 775 774 776 775 \end{example} 777 776 ··· 799 798 constraint b -> (2*x = y); 800 799 \end{mzn} 801 800 802 - Since the \domain{} of \mzninline{x} is strictly smaller than the \domain{} of \mzninline{y}, \gls{propagation} of \mzninline{b} will set it to the value \mzninline{true}. 801 + Since the values in the \domain{} of \mzninline{x} are strictly smaller than the values in the \domain{} of \mzninline{y}, \gls{propagation} of \mzninline{b} will set it to the value \mzninline{true}. 803 802 This however means that the \constraint{} is equivalent to the following \constraint{}. 804 803 805 804 \begin{mzn} ··· 811 810 \end{example} 812 811 813 812 The situation shown in the example is the most common change of context. 814 - If the control \variable{} of a \gls{reif} is fixed, the context often changes to either \rootc{} or a negated \rootc{} context. 813 + If the \gls{cvar} of a \gls{reif} is fixed, the context often changes to either \rootc{} or a negated \rootc{} context. 815 814 If, on the other hand, the \gls{cvar} of a \gls{half-reif} is fixed, then either the context becomes \rootc{} or the \constraint{} already holds. 816 815 Since direct \constraints{} are strongly preferred over any form of \gls{reif}, it is important to dynamically pick the correct form during the \gls{rewriting} process. 817 816 818 817 This problem can be solved by the \compiler{}. 819 818 For each \gls{reif} and \gls{half-reif} the \compiler{} introduces another layer of \gls{decomp}. 820 819 In this layer, it checks its \gls{cvar}. 821 - If the control \variable{} is already fixed, then it rewrites itself into its form in another context. 820 + If the \gls{cvar} is already fixed, then it rewrites itself into its form in another context. 822 821 Otherwise, it behaves as it would have done normally. 823 822 The \gls{cvar} is thus used to communicate the change in context. 824 823 ··· 826 825 827 826 Let's assume the \compiler{} finds a call to \mzninline{int_lin_le} in \posc{} context. 828 827 Instead of outputting the call to \mzninline{int_lin_le_imp} directly, it will instead output a call to \mzninline{_int_lin_le_imp}. 829 - This predicate is then generated as follows: 828 + This predicate is then generated as shown in \cref{lst:half-check-reif}. 829 + This new predicate (calls) can then be rewritten normally. 830 830 831 - \begin{mzn} 832 - predicate _int_lin_le_imp( 833 - array[int] of int: c, 834 - array[int] of var int: x, 835 - int: d, 836 - var bool: b 837 - ) = 838 - if is_fixed(b) then 839 - if fix(b) then 840 - int_lin_le(c, x, d) 841 - else 842 - true 843 - endif 844 - else 845 - int_lin_le_reif(c, x, d, b) 846 - endif; 847 - \end{mzn} 831 + \begin{listing} 832 + \mznfile{assets/listing/half_reif_check.mzn} 833 + \caption{\label{lst:half-check-reif}A generated predicate for \mzninline{int_lin_le_imp} that checks its \gls{cvar} to ensure a \gls{half-reif} is still required.} 834 + \end{listing} 848 835 849 - This new predicate can then be compiled using the normal methods. 850 836 \end{example} 851 837 852 838 \section{Experiments} ··· 889 875 Since \gls{chuffed} is a \gls{lcg} \solver{}, the explanations created by the \gls{propagator} have to be adjusted as well. 890 876 These adjustments happen in a similar fashion to the adjustments of the general algorithm: explanations used for the violation of the \constraint{} can now be used to set the \gls{cvar} to \mzninline{false} and the explanations given to prune a variable are appended by requirement that the \gls{cvar} is \mzninline{true}. 891 877 892 - In our second configuration the \mzninline{all_different} \constraint{} is enforced using the following \gls{decomp}. 893 - 894 - \begin{mzn} 895 - predicate all_different(array[int] of var int: x) = 896 - forall(i,j in index_set(x) where i < j)( 897 - x[i] != x[j] 898 - ); 899 - \end{mzn} 900 - 878 + In our second configuration the \mzninline{all_different} \constraint{} is enforced using the \gls{decomp} shown in \cref{lst:half-alldiff}. 901 879 The \mzninline{!=} \constraints{} produced by this redefinition are \gls{reified}. 902 880 Their conjunction, then represent the \gls{reif} of the \mzninline{all_different} \constraint{}. 881 + 882 + \begin{listing} 883 + \mznfile{assets/listing/half_alldiff.mzn} 884 + \caption{\label{lst:half-alldiff}The standard \gls{decomp} for \mzninline{all_different} in the \minizinc{} standard library.} 885 + \end{listing} 886 + 903 887 904 888 \begin{table} 905 889 \begin{center} ··· 1039 1023 However, we can imagine that the removed \constraints{} in some cases help the \gls{mip} solver. 1040 1024 An important technique used by \gls{mip} solvers is to detect certain pattern, such as cliques, during the pre-processing of the \gls{mip} instance. 1041 1025 Some patterns can only be detected when using a full \gls{reif}. 1042 - Furthermore, the performance of \gls{mip} solvers is often dependent on the order and form in which the \constraints{} are given \autocite{fischetti-2014-erratiscism}. 1026 + Furthermore, the performance of \gls{mip} solvers is often dependent on the order and form in which the \constraints{} are given \autocite{lodi-2013-variability,fischetti-2014-erratiscism}. 1043 1027 With the usage of the \gls{aggregation} and \gls{del-rew}, these can be exceedingly different when using \gls{half-reif}. 1044 1028 1045 1029 The solving statistics for \gls{openwbo} might be most positive.
+3 -3
chapters/4_half_reif_preamble.tex
··· 1 1 \noindent{}Whether a \constraint{} has to be \gls{reified} is a crucial decision made during \gls{rewriting}. 2 2 \minizinc{} allows us to write complex \constraints{} that in the process of \gls{rewriting} result in multiple \constraints{} that reason about each other. 3 - However, determining whether a \constraint{} holds, \(\texttt{b} \leftrightarrow{} c\), requires significantly more effort from the \solver{} than merely enforcing the \constraint{} \(c\). 3 + However, determining whether a \constraint{} holds, \(b \leftrightarrow{} c\), requires significantly more effort from the \solver{} than merely enforcing the \constraint{} \(c\). 4 4 A \gls{reified} \constraint{} results in a larger \gls{decomp} or a more complex \gls{native} \constraint{}. 5 5 It it thus important that \gls{rewriting} avoids the use of \gls{reif}, whenever it is not required. 6 6 7 7 In this chapter we present an extended \gls{reif} analysis to help minimise the required \solver{} effort. 8 8 Not only does it consider if a \constraint{} must be \gls{reified} or not, but it also considers whether it could instead be \gls{half-reified}. 9 9 10 - The notion of \gls{half-reif} \(\texttt{b} \rightarrow{} c\) for a \constraint{} \(c\) was introduced by \textcite{feydy-2011-half-reif}. 11 - It is shown \gls{half-reif} can relief some of the problems and expenses of the use of \gls{reif}. 10 + The notion of \gls{half-reif} \(b \rightarrow{} c\) for a \constraint{} \(c\) was introduced by \textcite{feydy-2011-half-reif}. 11 + It is shown \gls{half-reif} can relieve some of the problems and expenses of the use of \gls{reif}. 12 12 It is not always possible, however, to use a \gls{half-reif} instead of a \gls{reif}. 13 13 The authors identify the conditions required for its usage and provide an algorithm that rewrites a subset of the \minizinc{} language using the technique. 14 14 Crucially, because of the omission of \gls{let} and multiple occurrences of identifiers, this algorithm does not directly generalise to the full \minizinc{} language.