1/*
2 * jacop.scala
3 * This file is part of JaCoP.
4 * <p>
5 * JaCoP is a Java Constraint Programming solver.
6 * <p>
7 * Copyright (C) 2000-2008 Krzysztof Kuchcinski and Radoslaw Szymanek
8 * <p>
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 * <p>
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU Affero General Public License for more details.
18 * <p>
19 * Notwithstanding any other provision of this License, the copyright
20 * owners of this work supplement the terms of this License with terms
21 * prohibiting misrepresentation of the origin of this work and requiring
22 * that modified versions of this work be marked in reasonable ways as
23 * different from the original version. This supplement of the license
24 * terms is in accordance with Section 7 of GNU Affero General Public
25 * License version 3.
26 * <p>
27 * You should have received a copy of the GNU Affero General Public License
28 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
29 */
30
31/**
32  * Package for defining variables, constraints, global constraints and search methods for [[org.jacop]] constraint solver in Scala.
33  *
34  * @author Krzysztof Kuchcinski and Radoslaw Szymanek
35  * @version 4.5
36  */
37package org.jacop.scala
38
39import org.jacop.constraints._
40import org.jacop.core._
41import org.jacop.floats.constraints._
42import org.jacop.set.constraints._
43
44import scala.collection.mutable
45import scala.language.implicitConversions
46
47/**
48  * Manages all variables, constraints and global constraints for [[org.jacop]] constraint solver.
49  * Keeps also labels for search.
50  */
51class Model extends org.jacop.core.Store {
52
53  var n = 0
54
55  import scala.collection.mutable.ListBuffer
56
57  val constr = new ListBuffer[Constraint]
58
59  def imposeAllConstraints() : Unit = {
60    this.constr.foreach(e => this.impose(e))
61    if (trace)
62      this.constr.foreach(println(_))
63    this.constr.clear()
64  }
65}
66
67/**
68  * Implicit conversions of Int and Bool to IntVar and BoolVar. Used in overloaded operators.
69  */
70trait jacop {
71  /**
72    * Converts integer to IntVar.
73    *
74    * @param i integer to be converted.
75    */
76  implicit def intToIntVar(i: Int): IntVar = {
77    val v = new IntVar(i, i)
78    v
79  }
80
81  /**
82    * Converts integer to BoolVar.
83    *
84    * @param b boolean to be converted.
85    */
86  implicit def boolToBoolVar(b: Boolean): BoolVar = {
87    val i = if (b) 1 else 0
88    val v = new BoolVar(i, i)
89    v
90  }
91
92  /**
93    * Converts double to FloatVar.
94    *
95    * @param d float to be converted.
96    */
97  implicit def doubleToFloatVar(d: Double): FloatVar = {
98    val v = new FloatVar(d, d)
99    v
100  }
101
102  /**
103    * Converts Array to List, if needed.
104    *
105    * @param a array to be converted.
106    */
107  implicit def arrayToList[A](a: Array[A]) = a.toList
108
109  implicit def makeReifiable[T <: PrimitiveConstraint](reifC: T): Reifier[T] = new Reifier(reifC)
110
111}
112
113/**
114  * Defines an ordered set of integers and basic operations on these sets.
115  */
116class IntSet extends org.jacop.core.IntervalDomain {
117
118  /**
119    * Defines an ordered set of integers and basic operations on these sets.
120    *
121    * @constructor Create a new ordered set of integers.
122    * @param min minimal value of a set interval.
123    * @param max maximal value of a set interval.
124    */
125  def this(min: Int, max: Int) {
126    this()
127    addDom(new org.jacop.core.IntervalDomain(min, max))
128  }
129
130  /**
131    * Defines an ordered set of integers and basic operations on these sets.
132    *
133    * @constructor Create a new ordered set containing one element.
134    * @param el element of set.
135    */
136  def this(el: Int) {
137    this()
138    addDom(new org.jacop.core.IntervalDomain(el, el))
139  }
140
141  /**
142    * Set union operation on a set and a set with one value.
143    *
144    * @param n element of set.
145    */
146  def +(n: Int): IntSet = {
147    val tmp = new IntSet
148    tmp.unionAdapt(this)
149    tmp.unionAdapt(n)
150    tmp
151  }
152
153  /**
154    * Set union operation on two sets.
155    *
156    * @param that set variable.
157    */
158  def +(that: IntSet): IntSet = {
159    val tmp = new IntSet
160    tmp.unionAdapt(this)
161    tmp.unionAdapt(that)
162    tmp
163  }
164
165  /**
166    * Set intersection operation on a set and a set with one value.
167    *
168    * @param n element of set.
169    */
170  def *(n: Int): IntSet = {
171    val tmp = new IntSet
172    tmp.unionAdapt(this)
173    tmp.intersectAdapt(n, n)
174    tmp
175  }
176
177  /**
178    * Set intersection operation on two sets.
179    *
180    * @param that set variable.
181    */
182  def *(that: IntSet): IntSet = {
183    val tmp = new IntSet
184    tmp.unionAdapt(this)
185    tmp.intersectAdapt(that)
186    tmp
187  }
188
189  /**
190    * Set subtraction constraint on a set variable and a set of one value.
191    *
192    * @param n element of set.
193    */
194  def \(n: Int): IntSet = {
195    val tmp = new IntSet
196    tmp.unionAdapt(this)
197    tmp.subtractAdapt(n)
198    tmp
199  }
200
201  /**
202    * Set subtraction  operation on a set and a set with one value.
203    *
204    * @param that element of set.
205    */
206  def \(that: IntSet): IntSet = {
207    val tmp = new IntSet
208    tmp.unionAdapt(this)
209    for (i <- 0 until that.size) {
210      tmp.subtractAdapt(that.intervals(i).min, that.intervals(i).max)
211    }
212    tmp
213  }
214
215  /**
216    * Set complement operation on a set.
217    *
218    */
219  def unary_~ : IntSet = {
220    val tmp = new IntSet(org.jacop.core.IntDomain.MinInt, org.jacop.core.IntDomain.MaxInt)
221    for (i <- 0 until this.size)
222      tmp.subtractAdapt(intervals(i).min, intervals(i).max)
223    tmp
224  }
225
226  /**
227    * Produces string representation of a set.
228    *
229    */
230  override def toString: String = {
231    val s = if (singleton) "{" + value + "}" else super.toString
232    s
233  }
234}
235
236/**
237  * Defines a finite domain integer variable and its primitive constraints.
238  *
239  * @constructor Creates a new finite domain integer variable.
240  * @param name variable identifier.
241  * @param min  minimal value of variable's domain.
242  * @param max  maximal value of variable's domain.
243  */
244class IntVar(name: String, min: Int, max: Int) extends org.jacop.core.IntVar(getModel, name, min, max) with jacop {
245
246  /**
247    * Defines an anonymous finite domain integer variable.
248    *
249    * @constructor Creates a new finite domain integer variable.
250    * @param min minimal value of variable's domain.
251    * @param max maximal value of variable's domain.
252    */
253  def this(min: Int, max: Int) = {
254    this("_$" + getModel.n, min, max)
255    getModel.n += 1
256  }
257
258  /**
259    * Defines an anonymous finite domain integer variable.
260    *
261    * @constructor Creates a new finite domain integer variable with minimal and maximal
262    *              values in the domain defined by org.jacop.
263    * @param name variable's identifier.
264    */
265  def this(name: String) = {
266    this(name, org.jacop.core.IntDomain.MinInt, org.jacop.core.IntDomain.MaxInt)
267    getModel.n += 1
268  }
269
270  /**
271    * Defines an anonymous finite domain integer variable.
272    *
273    * @constructor Creates a new finite domain integer variable with minimal and maximal
274    *              values in the domain defined by org.jacop.
275    */
276  def this() = {
277    this(org.jacop.core.IntDomain.MinInt, org.jacop.core.IntDomain.MaxInt)
278    getModel.n += 1
279  }
280
281  /**
282    * Defines a finite domain integer variable.
283    *
284    * @constructor Create a new finite domain integer variable with the domain defined by IntSet.
285    * @param dom variable's domain defined as a set of integers (IntSet).
286    */
287  def this(dom: IntSet) = {
288    this()
289    this.dom.intersectAdapt(dom)
290    getModel.n += 1
291  }
292
293  /**
294    * Defines a finite domain integer variable.
295    *
296    * @constructor Create a new finite domain integer variable with the domain
297    *              defined by IntSet.
298    * @param name variable's identifier.
299    * @param dom  variable's domain defined as a set of integers (IntSet).
300    */
301  def this(name: String, dom: IntSet) = {
302    this(name)
303    this.dom.intersectAdapt(dom)
304    getModel.n += 1
305  }
306
307  /**
308    * Defines add constraint between two IntVar.
309    *
310    * @param that a second parameter for the addition constraint.
311    * @return IntVar variable being the result of the addition constraint.
312    */
313  def +(that: org.jacop.core.IntVar) = {
314    val result = new IntVar(IntDomain.addInt(this.min(), that.min()), IntDomain.addInt(this.max(), that.max()))
315    val c = new XplusYeqZ(this, that, result)
316    getModel.constr += c
317    result
318  }
319
320  /**
321    * Defines add constraint between IntVar and an integer value.
322    *
323    * @param that a second integer parameter for the addition constraint.
324    * @return IntVar variable being the result of the addition constraint.
325    */
326  def +(that: Int) = {
327    val result = new IntVar(IntDomain.addInt(this.min(), that), IntDomain.addInt(this.max(), that))
328    val c = new XplusCeqZ(this, that, result)
329    getModel.constr += c
330    result
331  }
332
333  /**
334    * Defines subtract constraint between two IntVar.
335    *
336    * @param that a second parameter for the subtraction constraint.
337    * @return IntVar variable being the result of the subtraction constraint.
338    */
339  def -(that: org.jacop.core.IntVar) = {
340    val result = new IntVar(IntDomain.subtractInt(this.min(), that.max()), IntDomain.subtractInt(this.max(), that.min()))
341    val c = new XplusYeqZ(result, that, this)
342    getModel.constr += c
343    result
344  }
345
346  /**
347    * Defines subtract constraint between IntVar and an integer value.
348    *
349    * @param that a second integer parameter for the subtraction constraint.
350    * @return IntVar variable being the result of the subtraction constraint.
351    */
352  def -(that: Int) = {
353    val result = new IntVar(IntDomain.subtractInt(this.min(), that), IntDomain.subtractInt(this.max(), that))
354    val c = new XplusCeqZ(result, that, this)
355    getModel.constr += c
356    result
357  }
358
359  /**
360    * Defines multiplication constraint between two IntVar.
361    *
362    * @param that a second parameter for the multiplication constraint.
363    * @return IntVar variable being the result of the multiplication constraint.
364    */
365  def *(that: org.jacop.core.IntVar) = {
366    val bounds = IntDomain.mulBounds(this.min(), this.max(), that.min(), that.max())
367    val result = new IntVar(bounds.min(), bounds.max())
368    val c = new XmulYeqZ(this, that, result)
369    getModel.constr += c
370    result
371  }
372
373  /**
374    * Defines multiplication constraint between IntVar and an integer value.
375    *
376    * @param that a second integer parameter for the multiplication constraint.
377    * @return IntVar variable being the result of the multiplication constraint.
378    */
379  def *(that: Int) = {
380    val bounds = IntDomain.mulBounds(this.min(), this.max(), that, that)
381    val result = new IntVar(bounds.min(), bounds.max())
382    val c = new XmulCeqZ(this, that, result)
383    getModel.constr += c
384    result
385  }
386
387  /**
388    * Defines integer division constraint between two IntVar.
389    *
390    * @param that a second parameter for the integer division constraint.
391    * @return IntVar variable being the result of the integer division constraint.
392    */
393  def div(that: org.jacop.core.IntVar) = {
394    val bounds = IntDomain.divBounds(this.min(), this.max(), that.min(), that.max())
395    val result = new IntVar(bounds.min(), bounds.max())
396    val c = new XdivYeqZ(this, that, result)
397    getModel.constr += c
398    result
399  }
400
401  /**
402    * Defines constraint for integer reminder from division between two IntVar.
403    *
404    * @param that a second parameter for integer reminder from division constraint.
405    * @return IntVar variable being the result of the integer reminder from division constraint.
406    */
407  def mod(that: org.jacop.core.IntVar) = {
408    var reminderMin: Int = 0;
409    var reminderMax: Int = 0;
410
411    if (this.min() >= 0) {
412      reminderMin = 0
413      reminderMax = Math.max(Math.abs(that.min()), Math.abs(that.max())) - 1
414    }
415    else if (this.max() < 0) {
416      reminderMax = 0
417      reminderMin = -Math.max(Math.abs(that.min()), Math.abs(that.max())) + 1
418    }
419    else {
420      reminderMin = Math.min(Math.min(that.min(), -that.min()), Math.min(that.max(), -that.max())) + 1
421      reminderMax = Math.max(Math.max(that.min(), -that.min()), Math.max(that.max(), -that.max())) - 1
422    }
423
424    val result = new IntVar(reminderMin, reminderMax)
425    val c = new XmodYeqZ(this, that, result)
426    getModel.constr += c
427    result
428  }
429
430  /**
431    * Defines exponentiation constraint between two IntVar.
432    *
433    * @param that exponent for the exponentiation constraint.
434    * @return IntVar variable being the result of the exponentiation constraint.
435    */
436  def ^(that: org.jacop.core.IntVar) = {
437    val result = new IntVar()
438    val c = new XexpYeqZ(this, that, result)
439    getModel.constr += c
440    result
441  }
442
443  /**
444    * Defines unary "-" constraint for IntVar.
445    *
446    * @return the defined constraint.
447    */
448  def unary_- = {
449    val result = new IntVar(-this.max(), -this.min())
450    val c = new XplusYeqC(this, result, 0)
451    getModel.constr += c
452    result
453  }
454
455  /**
456    * Defines equation constraint between two IntVar.
457    *
458    * @param that a second parameter for equation constraint.
459    * @return the defined constraint.
460    */
461  @deprecated("use #= instead", "1.0")
462  def ==(that: org.jacop.core.IntVar) = {
463    val c = new XeqY(this, that)
464    getModel.constr += c
465    c
466  }
467
468  /**
469    * Defines equation constraint between two IntVar.
470    *
471    * @param that a second parameter for equation constraint.
472    * @return the defined constraint.
473    */
474  def #=(that: org.jacop.core.IntVar) = {
475    val c = new XeqY(this, that)
476    getModel.constr += c
477    c
478  }
479
480
481  /**
482    * Defines equation constraint between an IntVar and FloatVar.
483    *
484    * @param that a second parameter for equation constraint.
485    * @return the defined constraint.
486    */
487  def #=(that: org.jacop.floats.core.FloatVar) = {
488    val c = new org.jacop.floats.constraints.XeqP(this, that)
489    getModel.constr += c
490    c
491  }
492
493  /**
494    * Defines equation constraint between IntVar and a integer constant.
495    *
496    * @param that a second parameter for equation constraint.
497    * @return the defined constraint.
498    */
499  @deprecated("use #= instead", "1.0")
500  def ==(that: Int) = {
501    val c = new XeqC(this, that)
502    getModel.constr += c
503    c
504  }
505
506  /**
507    * Defines equation constraint between IntVar and a integer constant.
508    *
509    * @param that a second parameter for equation constraint.
510    * @return the defined constraint.
511    */
512  def #=(that: Int) = {
513    val c = new XeqC(this, that)
514    getModel.constr += c
515    c
516  }
517
518  /**
519    * Defines inequality constraint between two IntVar.
520    *
521    * @param that a second parameter for inequality constraint.
522    * @return the defined constraint.
523    */
524  @deprecated("use #\\= instead", "1.0")
525  def !=(that: org.jacop.core.IntVar) = {
526    val c = new XneqY(this, that)
527    getModel.constr += c
528    c
529  }
530
531  /**
532    * Defines inequality constraint between two IntVar.
533    *
534    * @param that a second parameter for inequality constraint.
535    * @return the defined constraint.
536    */
537  def #\=(that: org.jacop.core.IntVar) = {
538    val c = new XneqY(this, that)
539    getModel.constr += c
540    c
541  }
542
543
544  /**
545    * Defines inequality constraint between IntVar and integer constant.
546    *
547    * @param that a second parameter for inequality constraint.
548    * @return the defined constraint.
549    */
550  @deprecated("use #\\= instead", "1.0")
551  def !=(that: Int) = {
552    val c = new XneqC(this, that)
553    getModel.constr += c
554    c
555  }
556
557  /**
558    * Defines inequality constraint between IntVar and integer constant.
559    *
560    * @param that a second parameter for inequality constraint.
561    * @return the defined constraint.
562    */
563  def #\=(that: Int) = {
564    val c = new XneqC(this, that)
565    getModel.constr += c
566    c
567  }
568
569  /**
570    * Defines "less than" constraint between two IntVar.
571    *
572    * @param that a second parameter for "less than" constraint.
573    * @return the defined constraint.
574    */
575  @deprecated("use #< instead", "1.0")
576  def <(that: org.jacop.core.IntVar) = {
577    val c = new XltY(this, that)
578    getModel.constr += c
579    c
580  }
581
582  /**
583    * Defines "less than" constraint between two IntVar.
584    *
585    * @param that a second parameter for "less than" constraint.
586    * @return the defined constraint.
587    */
588  def #<(that: org.jacop.core.IntVar) = {
589    val c = new XltY(this, that)
590    getModel.constr += c
591    c
592  }
593
594  /**
595    * Defines "less than" constraint between IntVar and integer constant.
596    *
597    * @param that a second parameter for "less than" constraint.
598    * @return the equation constraint.
599    */
600  @deprecated("use #< instead", "1.0")
601  def <(that: Int) = {
602    val c = new XltC(this, that)
603    getModel.constr += c
604    c
605  }
606
607  /**
608    * Defines "less than" constraint between IntVar and integer constant.
609    *
610    * @param that a second parameter for "less than" constraint.
611    * @return the equation constraint.
612    */
613  def #<(that: Int) = {
614    val c = new XltC(this, that)
615    getModel.constr += c
616    c
617  }
618
619  /**
620    * Defines "less than or equal" constraint between two IntVar.
621    *
622    * @param that a second parameter for "less than or equal" constraint.
623    * @return the defined constraint.
624    */
625  @deprecated("use #<= instead", "1.0")
626  def <=(that: org.jacop.core.IntVar) = {
627    val c = new XlteqY(this, that)
628    getModel.constr += c
629    c
630  }
631
632  /**
633    * Defines "less than or equal" constraint between two IntVar.
634    *
635    * @param that a second parameter for "less than or equal" constraint.
636    * @return the defined constraint.
637    */
638  def #<=(that: org.jacop.core.IntVar) = {
639    val c = new XlteqY(this, that)
640    getModel.constr += c
641    c
642  }
643
644  /**
645    * Defines "less than or equal" constraint between IntVar and integer constant.
646    *
647    * @param that a second parameter for "less than or equal" constraint.
648    * @return the equation constraint.
649    */
650  @deprecated("use #<= instead", "1.0")
651  def <=(that: Int) = {
652    val c = new XlteqC(this, that)
653    getModel.constr += c
654    c
655  }
656
657  /**
658    * Defines "less than or equal" constraint between IntVar and integer constant.
659    *
660    * @param that a second parameter for "less than or equal" constraint.
661    * @return the equation constraint.
662    */
663  def #<=(that: Int) = {
664    val c = new XlteqC(this, that)
665    getModel.constr += c
666    c
667  }
668
669  /**
670    * Defines "greater than" constraint between two IntVar.
671    *
672    * @param that a second parameter for "greater than" constraint.
673    * @return the defined constraint.
674    */
675  @deprecated("use #> instead", "1.0")
676  def >(that: org.jacop.core.IntVar) = {
677    val c = new XgtY(this, that)
678    getModel.constr += c
679    c
680  }
681
682  /**
683    * Defines "greater than" constraint between two IntVar.
684    *
685    * @param that a second parameter for "greater than" constraint.
686    * @return the defined constraint.
687    */
688  def #>(that: org.jacop.core.IntVar) = {
689    val c = new XgtY(this, that)
690    getModel.constr += c
691    c
692  }
693
694  /**
695    * Defines "greater than" constraint between IntVar and integer constant.
696    *
697    * @param that a second parameter for "greater than" constraint.
698    * @return the equation constraint.
699    */
700  @deprecated("use #> instead", "1.0")
701  def >(that: Int) = {
702    val c = new XgtC(this, that)
703    getModel.constr += c
704    c
705  }
706
707  /**
708    * Defines "greater than" constraint between IntVar and integer constant.
709    *
710    * @param that a second parameter for "greater than" constraint.
711    * @return the equation constraint.
712    */
713  def #>(that: Int) = {
714    val c = new XgtC(this, that)
715    getModel.constr += c
716    c
717  }
718
719  /**
720    * Defines "greater than or equal" constraint between two IntVar.
721    *
722    * @param that a second parameter for "greater than or equal" constraint.
723    * @return the defined constraint.
724    */
725  @deprecated("use #>= instead", "1.0")
726  def >=(that: org.jacop.core.IntVar) = {
727    val c = new XgteqY(this, that)
728    getModel.constr += c
729    c
730  }
731
732  /**
733    * Defines "greater than or equal" constraint between two IntVar.
734    *
735    * @param that a second parameter for "greater than or equal" constraint.
736    * @return the defined constraint.
737    */
738  def #>=(that: org.jacop.core.IntVar) = {
739    val c = new XgteqY(this, that)
740    getModel.constr += c
741    c
742  }
743
744  /**
745    * Defines "greater than or equal" constraint between IntVar and integer constant.
746    *
747    * @param that a second parameter for "greater than or equal" constraint.
748    * @return the equation constraint.
749    */
750  @deprecated("use #>= instead", "1.0")
751  def >=(that: Int) = {
752    val c = new XgteqC(this, that)
753    getModel.constr += c
754    c
755  }
756
757  /**
758    * Defines "greater than or equal" constraint between IntVar and integer constant.
759    *
760    * @param that a second parameter for "greater than or equal" constraint.
761    * @return the equation constraint.
762    */
763  def #>=(that: Int) = {
764    val c = new XgteqC(this, that)
765    getModel.constr += c
766    c
767  }
768
769  /**
770    * Defines constraint on inclusion of a IntVar variable value in a set.
771    *
772    * @param that set that this variable's value must be included.
773    * @return the equation constraint.
774    */
775  def in(that: SetVar): PrimitiveConstraint = {
776    if (min == max) {
777      val c = new EinA(min, that)
778      getModel.constr += c
779      c
780    }
781    else {
782      val c = new XinA(this, that)
783      getModel.constr += c
784      c
785    }
786  }
787}
788
789/**
790  * Defines a floating point variable and its primitive constraints.
791  *
792  * @constructor Creates a new floating point variable.
793  * @param name variable identifier.
794  * @param min  minimal value of variable's domain.
795  * @param max  maximal value of variable's domain.
796  */
797class FloatVar(name: String, min: Double, max: Double) extends org.jacop.floats.core.FloatVar(getModel, name, min, max) with jacop {
798
799  /**
800    * Defines an anonymous finite domain integer variable.
801    *
802    * @constructor Creates a new finite domain integer variable.
803    * @param min minimal value of variable's domain.
804    * @param max maximal value of variable's domain.
805    */
806  def this(min: Double, max: Double) = {
807    this("_$" + getModel.n, min, max)
808    getModel.n += 1
809  }
810
811  /**
812    * Defines an anonymous floating point variable.
813    *
814    * @constructor Creates a new floating point variable with minimal and maximal
815    * @param name variable's identifier.
816    */
817  def this(name: String) = {
818    this(name, -1e150, 1e150)
819    getModel.n += 1
820  }
821
822  /**
823    * Defines an anonymous floating point variable.
824    *
825    * @constructor Creates a new floating point variable with minimal and maximal
826    *              values in the domain defined by org.jacop.
827    */
828  def this() = {
829    this(-1e150, 1e150)
830    getModel.n += 1
831  }
832
833
834  /**
835    * Defines add constraint between two FloatVar.
836    *
837    * @param that a second parameter for the addition constraint.
838    * @return FloatVar variable being the result of the addition constraint.
839    */
840  def +(that: org.jacop.floats.core.FloatVar) = {
841    val result = new FloatVar()
842    val c = new PplusQeqR(this, that, result)
843    getModel.constr += c
844    result
845  }
846
847  /**
848    * Defines add constraint between FloatVar and an Double value.
849    *
850    * @param that a second double parameter for the addition constraint.
851    * @return FloatVar variable being the result of the addition constraint.
852    */
853  def +(that: Double) = {
854    val result = new FloatVar()
855    val c = new PplusCeqR(this, that, result)
856    getModel.constr += c
857    result
858  }
859
860  /**
861    * Defines subtract constraint between two FloatVar.
862    *
863    * @param that a second parameter for the subtraction constraint.
864    * @return FloatVar variable being the result of the subtraction constraint.
865    */
866  def -(that: org.jacop.floats.core.FloatVar) = {
867    val result = new FloatVar()
868    val c = new PminusQeqR(this, that, result)
869    getModel.constr += c
870    result
871  }
872
873  /**
874    * Defines subtract constraint between FloatVar and an double value.
875    *
876    * @param that a second double parameter for the subtraction constraint.
877    * @return FloatVar variable being the result of the subtraction constraint.
878    */
879  def -(that: Double) = {
880    val result = new FloatVar()
881    val c = new PminusCeqR(this, that, result)
882    getModel.constr += c
883    result
884  }
885
886  /**
887    * Defines multiplication constraint between two FloatVar.
888    *
889    * @param that a second parameter for the multiplication constraint.
890    * @return FloatVar variable being the result of the multiplication constraint.
891    */
892  def *(that: org.jacop.floats.core.FloatVar) = {
893    val result = new FloatVar()
894    val c = new PmulQeqR(this, that, result)
895    getModel.constr += c
896    result
897  }
898
899  /**
900    * Defines multiplication constraint between FloatVar and an double value.
901    *
902    * @param that a second parameter for the multiplication constraint.
903    * @return FloatVar variable being the result of the multiplication constraint.
904    */
905  def *(that: Double) = {
906    val result = new FloatVar()
907    val c = new PmulCeqR(this, that, result)
908    getModel.constr += c
909    result
910  }
911
912  /**
913    * Defines division constraint between two FlaotVar.
914    *
915    * @param that a second parameter for the division constraint.
916    * @return FloatVar variable being the result of the division constraint.
917    */
918  def div(that: org.jacop.floats.core.FloatVar) = {
919    val result = new FloatVar()
920    val c = new PdivQeqR(this, that, result)
921    getModel.constr += c
922    result
923  }
924
925  /**
926    * Defines unary "-" constraint for FlaotVar.
927    *
928    * @return the defined constraint.
929    */
930  def unary_- = {
931    val result = new FloatVar()
932    val c = new PplusQeqR(this, result, new FloatVar(0.0, 0.0))
933    getModel.constr += c
934    result
935  }
936
937
938  /**
939    * Defines equation constraint between two FloatVar.
940    *
941    * @param that a second parameter for equation constraint.
942    * @return the defined constraint.
943    */
944  def #=(that: org.jacop.floats.core.FloatVar) = {
945    val c = new PeqQ(this, that)
946    getModel.constr += c
947    c
948  }
949
950  /**
951    * Defines equation constraint between an IntVar and FloatVar.
952    *
953    * @param that a second parameter for equation constraint.
954    * @return the defined constraint.
955    */
956  def #=(that: org.jacop.core.IntVar) = {
957    val c = new org.jacop.floats.constraints.XeqP(that, this)
958    getModel.constr += c
959    c
960  }
961
962  /**
963    * Defines equation constraint between FlaotVar and a double constant.
964    *
965    * @param that a second parameter for equation constraint.
966    * @return the defined constraint.
967    */
968  def #=(that: Double) = {
969    val c = new PeqC(this, that)
970    getModel.constr += c
971    c
972  }
973
974  /**
975    * Defines inequality constraint between two FloatVar.
976    *
977    * @param that a second parameter for inequality constraint.
978    * @return the defined constraint.
979    */
980  def #\=(that: org.jacop.floats.core.FloatVar) = {
981    val c = new PneqQ(this, that)
982    getModel.constr += c
983    c
984  }
985
986  /**
987    * Defines inequality constraint between FloatVar and double constant.
988    *
989    * @param that a second parameter for inequality constraint.
990    * @return the defined constraint.
991    */
992  def #\=(that: Double) = {
993    val c = new PneqC(this, that)
994    getModel.constr += c
995    c
996  }
997
998  /**
999    * Defines "less than" constraint between two FloatVar.
1000    *
1001    * @param that a second parameter for "less than" constraint.
1002    * @return the defined constraint.
1003    */
1004  def #<(that: org.jacop.floats.core.FloatVar) = {
1005    val c = new PltQ(this, that)
1006    getModel.constr += c
1007    c
1008  }
1009
1010  /**
1011    * Defines "less than" constraint between FloatVar and double constant.
1012    *
1013    * @param that a second parameter for "less than" constraint.
1014    * @return the equation constraint.
1015    */
1016  def #<(that: Double) = {
1017    val c = new PltC(this, that)
1018    getModel.constr += c
1019    c
1020  }
1021
1022  /**
1023    * Defines "less than or equal" constraint between two FloatVar.
1024    *
1025    * @param that a second parameter for "less than or equal" constraint.
1026    * @return the defined constraint.
1027    */
1028  def #<=(that: org.jacop.floats.core.FloatVar) = {
1029    val c = new PlteqQ(this, that)
1030    getModel.constr += c
1031    c
1032  }
1033
1034  /**
1035    * Defines "less than or equal" constraint between FloatVar and double constant.
1036    *
1037    * @param that a second parameter for "less than or equal" constraint.
1038    * @return the equation constraint.
1039    */
1040  def #<=(that: Double) = {
1041    val c = new PlteqC(this, that)
1042    getModel.constr += c
1043    c
1044  }
1045
1046  /**
1047    * Defines "greater than" constraint between two FlaotVar.
1048    *
1049    * @param that a second parameter for "greater than" constraint.
1050    * @return the defined constraint.
1051    */
1052  def #>(that: org.jacop.floats.core.FloatVar) = {
1053    val c = new PgtQ(this, that)
1054    getModel.constr += c
1055    c
1056  }
1057
1058  /**
1059    * Defines "greater than" constraint between FloatVar and double constant.
1060    *
1061    * @param that a second parameter for "greater than" constraint.
1062    * @return the equation constraint.
1063    */
1064  def #>(that: Double) = {
1065    val c = new PgtC(this, that)
1066    getModel.constr += c
1067    c
1068  }
1069
1070  /**
1071    * Defines "greater than or equal" constraint between two FloatVar.
1072    *
1073    * @param that a second parameter for "greater than or equal" constraint.
1074    * @return the defined constraint.
1075    */
1076  def #>=(that: org.jacop.floats.core.FloatVar) = {
1077    val c = new PgteqQ(this, that)
1078    getModel.constr += c
1079    c
1080  }
1081
1082  /**
1083    * Defines "greater than or equal" constraint between FloatVar and integer constant.
1084    *
1085    * @param that a second parameter for "greater than or equal" constraint.
1086    * @return the equation constraint.
1087    */
1088  def #>=(that: Double) = {
1089    val c = new PgteqC(this, that)
1090    getModel.constr += c
1091    c
1092  }
1093}
1094
1095
1096/**
1097  * Defines a set variable and its primitive constraints.
1098  *
1099  * @constructor Creates a new set variable.
1100  * @param name variable's identifier.
1101  * @param glb  greatest lower bound for variable's domain.
1102  * @param lub  least upper bound on variable's domain.
1103  */
1104class SetVar(name: String, glb: Int, lub: Int) extends org.jacop.set.core.SetVar(getModel, name, glb, lub) {
1105
1106  /**
1107    * Defines an anonymous set variable.
1108    *
1109    * @constructor Creates a new set variable.
1110    * @param glb greatest lower bound for variable's domain.
1111    * @param lub least upper bound on variable's domain.
1112    */
1113  def this(glb: Int, lub: Int) = {
1114    this("_$" + getModel.n, glb, lub)
1115    getModel.n += 1
1116  }
1117
1118  /**
1119    * Defines an anonymous set variable with maximal set domain.
1120    *
1121    * @constructor Creates a new finite domain integer variable.
1122    */
1123  def this() = {
1124    this("_$" + getModel.n, org.jacop.core.IntDomain.MinInt, org.jacop.core.IntDomain.MaxInt)
1125    getModel.n += 1
1126  }
1127
1128  /**
1129    * Defines set intersection constraint between two set variables.
1130    *
1131    * @param that second parameter for the constraint.
1132    * @return result set variable that is the result for this constraint.
1133    */
1134  def *(that: SetVar) = {
1135    val result = new SetVar()
1136    val c = new AintersectBeqC(this, that, result)
1137    getModel.constr += c
1138    result
1139  }
1140
1141  /**
1142    * Defines set union constraint between two set variables.
1143    *
1144    * @param that second parameter for the constraint.
1145    * @return result set variable that is the result for this constraint.
1146    */
1147  def +(that: SetVar) = {
1148    val result = new SetVar()
1149    val c = new AunionBeqC(this, that, result)
1150    getModel.constr += c
1151    result
1152  }
1153
1154  /**
1155    * Defines set subtraction constraint between two set variables.
1156    *
1157    * @param that second parameter for the constraint.
1158    * @return result set variable that is the result for this constraint.
1159    */
1160  def \(that: SetVar) = {
1161    val result = new SetVar()
1162    val c = new AdiffBeqC(this, that, result)
1163    getModel.constr += c
1164    result
1165  }
1166
1167  /**
1168    * Defines set disjoint constraint between two set variables.
1169    *
1170    * @param that second parameter for the constraint.
1171    * @return result this constraint.
1172    */
1173  def <>(that: SetVar) = {
1174    val c = new AdisjointB(this, that)
1175    getModel.constr += c
1176    c
1177  }
1178
1179  /**
1180    * Defines set inclusion constraint between two set variables.
1181    *
1182    * @param that second parameter for the constraint.
1183    * @return result this constraint.
1184    */
1185  def in(that: SetVar) = {
1186    val c = new AinB(this, that)
1187    getModel.constr += c
1188    c
1189  }
1190
1191  /**
1192    * Defines set inclusion constraint between a set variables and a set.
1193    *
1194    * @param that second parameter for the constraint.
1195    * @return result this constraint.
1196    */
1197  def in(that: IntSet) = {
1198    val c = new AinS(this, that)
1199    getModel.constr += c
1200    c
1201  }
1202
1203  /**
1204    * Defines set equality constraint between two set variables.
1205    *
1206    * @param that second parameter for the constraint.
1207    * @return result this constraint.
1208    */
1209  @deprecated("use #= instead", "1.0")
1210  def ==(that: SetVar) = {
1211    val c = new AeqB(this, that)
1212    getModel.constr += c
1213    c
1214  }
1215
1216  /**
1217    * Defines set equality constraint between two set variables.
1218    *
1219    * @param that second parameter for the constraint.
1220    * @return result this constraint.
1221    */
1222  def #=(that: SetVar) = {
1223    val c = new AeqB(this, that)
1224    getModel.constr += c
1225    c
1226  }
1227
1228  /**
1229    * Defines set equality constraint between a set variable and a set.
1230    *
1231    * @param that second parameter for the constraint.
1232    * @return result this constraint.
1233    */
1234  @deprecated("use #= instead", "1.0")
1235  def ==(that: IntSet) = {
1236    val c = new AeqS(this, that)
1237    getModel.constr += c
1238    c
1239  }
1240
1241  /**
1242    * Defines set equality constraint between a set variable and a set.
1243    *
1244    * @param that second parameter for the constraint.
1245    * @return result this constraint.
1246    */
1247  def #=(that: IntSet) = {
1248    val c = new AeqS(this, that)
1249    getModel.constr += c
1250    c
1251  }
1252
1253  /**
1254    * Defines constraint this ordered set is lexicographically greater or equal than set "that".
1255    *
1256    * @param that second parameter for the constraint.
1257    * @return result this constraint.
1258    */
1259  @deprecated("use #>= instead", "1.0")
1260  def >=(that: SetVar) = {
1261    val c = new org.jacop.set.constraints.AleB(that, this)
1262    getModel.constr += c
1263    c
1264  }
1265
1266  /**
1267    * Defines constraint this ordered set is lexicographically greater or equal than set "that".
1268    *
1269    * @param that second parameter for the constraint.
1270    * @return result this constraint.
1271    */
1272  def #>=(that: SetVar) = {
1273    val c = new org.jacop.set.constraints.AleB(that, this)
1274    getModel.constr += c
1275    c
1276  }
1277
1278  /**
1279    * Defines constraint this ordered set is lexicographically less or equal than set "that".
1280    *
1281    * @param that second parameter for the constraint.
1282    * @return result this constraint.
1283    */
1284  @deprecated("use #<= instead", "1.0")
1285  def <=(that: SetVar) = {
1286    val c = new org.jacop.set.constraints.AleB(this, that)
1287    getModel.constr += c
1288    c
1289  }
1290
1291  /**
1292    * Defines constraint this ordered set is lexicographically less or equal than set "that".
1293    *
1294    * @param that second parameter for the constraint.
1295    * @return result this constraint.
1296    */
1297  def #<=(that: SetVar) = {
1298    val c = new org.jacop.set.constraints.AleB(this, that)
1299    getModel.constr += c
1300    c
1301  }
1302}
1303
1304/**
1305  * Define a boolean variable and its primitive constraints.
1306  *
1307  * @constructor Creates a new boolean variable.
1308  * @param name variable's identifier.
1309  * @param min1 minimal value for variable's domain.
1310  * @param max1 maximal value for variable's domain.
1311  */
1312class BoolVar(name: String, min1: Int, max1: Int) extends org.jacop.core.BooleanVar(getModel, name, min1, max1)
1313  with jacop {
1314
1315  /**
1316    * Define a boolean variable with {0..1} domain.
1317    *
1318    * @constructor Creates a new boolean variable.
1319    * @param name variable's identifier.
1320    */
1321  def this(name: String) = {
1322    this(name, 0, 1)
1323    getModel.n += 1
1324  }
1325
1326  /**
1327    * Define an anonymous boolean variable with {0..1} domain.
1328    *
1329    * @constructor Creates a new boolean variable.
1330    */
1331  def this() = {
1332    this("_$" + getModel.n, 0, 1)
1333    getModel.n += 1
1334  }
1335
1336  /**
1337    * Define an anonymous boolean variable.
1338    *
1339    * @constructor Creates a new boolean variable.
1340    * @param l minimal value for variable's domain.
1341    * @param r maximal value for variable's domain.
1342    */
1343  def this(l: Int, r: Int) = {
1344    this("_$" + getModel.n, l, r)
1345    getModel.n += 1
1346  }
1347
1348  /**
1349    * Defines equation constraint between two BoolVar.
1350    *
1351    * @param that a second parameter for equation constraint.
1352    * @return the defined constraint.
1353    */
1354  @deprecated("use #= instead", "1.0")
1355  def ==(that: org.jacop.core.IntVar) = {
1356    val c = new org.jacop.constraints.XeqY(this, that)
1357    getModel.constr += c
1358    c
1359  }
1360
1361  /**
1362    * Defines equation constraint between two BoolVar.
1363    *
1364    * @param that a second parameter for equation constraint.
1365    * @return the defined constraint.
1366    */
1367  def #=(that: org.jacop.core.IntVar) = {
1368    val c = new org.jacop.constraints.XeqY(this, that)
1369    getModel.constr += c
1370    c
1371  }
1372
1373  /**
1374    * Defines equation constraint a BoolVar and a integer value.
1375    *
1376    * @param that a second parameter for equation constraint.
1377    * @return the defined constraint.
1378    */
1379  @deprecated("use #= instead", "1.0")
1380  def ==(that: Int) = {
1381    val c = new XeqC(this, that)
1382    getModel.constr += c
1383    c
1384  }
1385
1386  /**
1387    * Defines equation constraint between an IntVar and FloatVar.
1388    *
1389    * @param that a second parameter for equation constraint.
1390    * @return the defined constraint.
1391    */
1392  def #=(that: org.jacop.floats.core.FloatVar) = {
1393    val c = new org.jacop.floats.constraints.XeqP(this, that)
1394    getModel.constr += c
1395    c
1396  }
1397
1398
1399  /**
1400    * Defines equation constraint a BoolVar and a integer value.
1401    *
1402    * @param that a second parameter for equation constraint.
1403    * @return the defined constraint.
1404    */
1405  def #=(that: Int) = {
1406    val c = new XeqC(this, that)
1407    getModel.constr += c
1408    c
1409  }
1410
1411  /**
1412    * Defines logical and (conjunction) constraint between two BoolVar.
1413    *
1414    * @param that a second parameter for equation constraint.
1415    * @return the defined constraint.
1416    */
1417  def /\(that: org.jacop.core.IntVar) = {
1418    val result = new BoolVar()
1419    val parameters = Array(this, that)
1420    val c = new org.jacop.constraints.AndBool(parameters, result)
1421    getModel.constr += c.decompose(store).get(0)
1422    result
1423  }
1424
1425  /**
1426    * Defines logical or (disjunction) constraint between two BoolVar.
1427    *
1428    * @param that a second parameter for equation constraint.
1429    * @return the defined constraint.
1430    */
1431  def \/(that: org.jacop.core.IntVar) = {
1432    val result = new BoolVar()
1433    val parameters = Array(this, that)
1434    val c = new org.jacop.constraints.OrBool(parameters, result)
1435    getModel.constr += c.decompose(store).get(0)
1436    result
1437  }
1438
1439  /**
1440    * Defines logical exclusive or constraint between two BoolVar.
1441    *
1442    * @param that a second parameter for equation constraint.
1443    * @return the defined constraint.
1444    */
1445  def xor(that: org.jacop.core.IntVar) = {
1446    val result = new BoolVar()
1447    val parameters = Array(this, that)
1448    val c = new org.jacop.constraints.XorBool(parameters, result)
1449    getModel.constr += c
1450    result
1451  }
1452
1453  /**
1454    * Defines logical negation constraint for BoolVar.
1455    *
1456    * @return boolean variable that is the result for this constraint.
1457    */
1458  def unary_~ = {
1459    val result = new BoolVar()
1460    val c = new XplusYeqC(this, result, 1)
1461    getModel.constr += c
1462    result
1463  }
1464
1465  /**
1466    * Defines implication constraint.
1467    *
1468    * @param thenConstr a primitive constraint that will hold if this variable is 1.
1469    * @return the defined constraint.
1470    */
1471  def ->(thenConstr: PrimitiveConstraint): Constraint = {
1472    // val c: Constraint = new IfThen(new XeqC(this, 1), thenConstr)
1473    // getModel.constr.remove(getModel.constr.length - 1)
1474    val c: Constraint = new Implies(this, thenConstr)
1475    getModel.constr.remove(getModel.constr.length - 1)
1476    getModel.constr += c
1477    c
1478  }
1479
1480  /**
1481    * Defines reified constraint.
1482    *
1483    * @param reifC a primitive constraint that is used in reification.
1484    * @return the defined constraint.
1485    */
1486  def <=>(reifC: PrimitiveConstraint): Constraint = {
1487    val c: Constraint = new Reified(reifC, this)
1488    getModel.constr.remove(getModel.constr.length - 1)
1489    getModel.constr += c
1490    c
1491  }
1492}
1493
1494//class XgtC(name: IntVar, const: Int) extends org.jacop.constraints.XgtC(name, const) {
1495//  def <=>(that: IntVar) = {
1496//    val c = new Reified(this, that)
1497//    getModel.constr.remove(getModel.constr.length - 1)
1498//    getModel.constr += c
1499//    c
1500//  }
1501//}
1502
1503/**
1504  * FSM specification for regular constraint.
1505  *
1506  * @constructor Creates a new FSM.
1507  */
1508class fsm extends org.jacop.util.fsm.FSM {
1509
1510  import scala.collection.mutable.ArrayBuffer
1511
1512  var states = ArrayBuffer[state]()
1513
1514  /**
1515    * FSM specification for regular constraint.
1516    *
1517    * @constructor Creates a new FSM.
1518    * @param n number of states in this FSM.
1519    */
1520  def this(n: Int) {
1521    this()
1522    states = ArrayBuffer.tabulate(n)(i => new state)
1523    states.foreach(s => allStates.add(s))
1524  }
1525
1526  /**
1527    * Defines initial state for this FSM.
1528    *
1529    * @param s state.
1530    */
1531  def init(s: state) : Unit = {
1532    initState = s
1533    states += s
1534    allStates.add(s)
1535  }
1536
1537  /**
1538    * Defines a list of final state for this FSM.
1539    *
1540    * @param st array of states.
1541    */
1542  def addFinalStates(st: Array[state]) : Unit = {
1543    st.foreach(s => states += s)
1544    st.foreach(s => finalStates.add(s))
1545  }
1546
1547  def +(s: state): fsm = {
1548    states += s
1549    allStates.add(s)
1550    this
1551  }
1552
1553  /**
1554    * Number of states in this FSM.
1555    *
1556    */
1557  def length = states.length
1558
1559  /**
1560    * Get state n of this FSM.
1561    *
1562    * @param n index of state.
1563    * @return n-th state
1564    */
1565  def apply(n: Int): state = {
1566    states(n)
1567  }
1568}
1569
1570/**
1571  * state specification for FSM for regular constraint.
1572  *
1573  * @constructor Creates a new state for FSM.
1574  */
1575class state extends org.jacop.util.fsm.FSMState {
1576
1577  import org.jacop.util.fsm._
1578
1579  /**
1580    * Transition of FSM.
1581    *
1582    * @param tran values for executing this transition.
1583    * @param that next state for this transition.
1584    */
1585  def ->(tran: IntSet, that: state) : Unit = {
1586    transitions.add(new FSMTransition(tran, that))
1587  }
1588
1589  /**
1590    * Transition of FSM.
1591    *
1592    * @param tran integer value for executing this transition.
1593    * @param that next state for this transition.
1594    */
1595  def ->(tran: Int, that: state) : Unit = {
1596    transitions.add(new FSMTransition(new IntSet(tran, tran), that))
1597  }
1598}
1599
1600/**
1601  * Network specification for networkflow constraint
1602  *
1603  * @constructor Creates an empty network
1604  */
1605class network extends org.jacop.constraints.netflow.NetworkBuilder {
1606
1607  //import scala.collection.mutable.HashMap
1608
1609  var nodes = mutable.HashMap[node, org.jacop.constraints.netflow.simplex.Node]()
1610
1611  /**
1612    * Adds nodes to the network
1613    *
1614    * @param n node
1615    */
1616  def +(n: node): network = {
1617    val N = addNode(n.name, n.balance)
1618    nodes += (n -> N)
1619    // println("## " + N.name + ", " + N.balance)
1620    this
1621  }
1622
1623  /**
1624    * Get a node of the network in network format
1625    *
1626    * @param n node
1627    */
1628  def apply(n: node): org.jacop.constraints.netflow.simplex.Node = {
1629    nodes(n)
1630  }
1631
1632  /**
1633    * Creates an arc between two nodes.
1634    *
1635    * @param source      start node of the arc
1636    * @param destination end node the arc
1637    * @param weight      weight of this arc for cost calculation
1638    * @param capacity    capacity for the flow on this arc
1639    */
1640  def arc(source: node, destination: node, weight: IntVar, capacity: IntVar) : Unit = {
1641    // println(source.name + " -> " + destination.name)
1642    addArc(nodes(source), nodes(destination), weight, capacity)
1643  }
1644
1645  def cost(c: IntVar) : Unit = {
1646    setCostVariable(c)
1647  }
1648}
1649
1650/**
1651  * Node definition for network for networkflow constraint
1652  */
1653case class node(var name: String, var balance: Int) { //extends org.jacop.constraints.netflow.simplex.Node(name, balance) {
1654
1655}
1656
1657
1658/**
1659  * Solution listener that does not print anything (empty).
1660  * Used to prohibit printing from search.
1661  */
1662/*
1663class EmptyListener[T <: org.jacop.core.Var] extends org.jacop.search.SimpleSolutionListener[T] {
1664
1665  override def executeAfterSolution( search: org.jacop.search.Search[T], select: org.jacop.search.SelectChoicePoint[T]) : Boolean = {
1666
1667    val returnCode = super.executeAfterSolution(search, select);
1668
1669    return returnCode;
1670  }
1671}
1672*/
1673
1674
1675/**
1676  * Solution listener that prints solutions of search
1677  * using user specified functions.
1678  */
1679class ScalaSolutionListener[T <: org.jacop.core.Var] extends org.jacop.search.SimpleSolutionListener[T] {
1680
1681  override def executeAfterSolution(search: org.jacop.search.Search[T], select: org.jacop.search.SelectChoicePoint[T]): Boolean = {
1682
1683    val returnCode = super.executeAfterSolution(search, select)
1684
1685    printFunctions.foreach(_.apply())
1686
1687    returnCode
1688  }
1689}
1690
1691class Reifier[T <: PrimitiveConstraint](reifC: T) {
1692  def <=>(b: BoolVar): Constraint = {
1693    val c: Constraint = new Reified(reifC, b)
1694    getModel.constr.remove(getModel.constr.length - 1)
1695    getModel.constr += c
1696    c
1697  }
1698}
1699
1700