├── LICENSE ├── README.md ├── build.gradle ├── doc ├── JvCSP3v1-1.pdf ├── checkerJava1-1.pdf ├── parserJava1-2.pdf └── parserJava1-2.tex ├── instancesTest ├── AllInterval-005.xml.lzma ├── Allergy.xml.lzma ├── Bibd-sc-06-050-25-03-10.xml.lzma ├── Bibd-sum-06-050-25-03-10.xml.lzma ├── BinPacking-mdd-n1c1w4a.xml.lzma ├── BinPacking-sum-n1c1w4a.xml.lzma ├── BinPacking-tab-n1c1w4a.xml.lzma ├── Blackhole-04-3-00.xml.lzma ├── BusScheduling-cnt-t1.xml.lzma ├── CarSequencing-dingbas.xml.lzma ├── ChessboardColoration-07-07.xml.lzma ├── ColouredQueens-07.xml.lzma ├── CostasArray-12.xml.lzma ├── Crossword-lex-vg-5-6.xml.lzma ├── CryptoPuzzle-cross-roads-danger.xml.lzma ├── Cutstock-small.xml.lzma ├── DistinctVectors-30-050-02.xml.lzma ├── Domino-300-300.xml.lzma ├── Fastfood-ff10.xml.lzma ├── GolombRuler-09-a3.xml.lzma ├── GolombRuler-09-a4.xml.lzma ├── GracefulGraph-K02-P04.xml.lzma ├── GraphColoring-3-fullins-4.xml.lzma ├── GraphColoring-qwhdec-o5-h10-1.xml.lzma ├── Hanoi-05.xml.lzma ├── Kakuro-easy-000-ext.xml.lzma ├── Kakuro-easy-000-sumdiff.xml.lzma ├── Knapsack-30-100-00.xml.lzma ├── KnightTour-06-ext03.xml.lzma ├── KnightTour-06-int.xml.lzma ├── Langford-3-10.xml.lzma ├── LangfordBin-08.xml.lzma ├── LowAutocorrelation-015.xml.lzma ├── MagicSequence-008-ca.xml.lzma ├── MagicSequence-008-co.xml.lzma ├── MagicSquare-4-table.xml.lzma ├── MagicSquare-6-mdd.xml.lzma ├── MagicSquare-6-sum.xml.lzma ├── MagicSquare-9-f10-01.xml.lzma ├── Mario-easy-4.xml.lzma ├── MarketSplit-01.xml.lzma ├── MultiKnapsack-1-01.xml.lzma ├── MultiKnapsack-1-0_X2.xml.lzma ├── Nonogram-001-regular.xml.lzma ├── Nonogram-001-table.xml.lzma ├── Opd-07-007-003.xml.lzma ├── Ortholatin-005.xml.lzma ├── Pb-gr-05.xml.lzma ├── Pb-robin08.xml.lzma ├── Primes-15-20-2-1.xml.lzma ├── PrizeCollecting-15-3-5-0.xml.lzma ├── QuadraticAssignment-bur26a.xml.lzma ├── QuadraticAssignment-qap.xml.lzma ├── QuasiGroup-3-04.xml.lzma ├── QuasiGroup-7-09.xml.lzma ├── QueenAttacking-06.xml.lzma ├── Queens-0008-m1.xml.lzma ├── RadarSurveillance-8-24-3-2-00.xml.lzma ├── Ramsey-12.xml.lzma ├── RoomMate-sr0050-int.xml.lzma ├── Sat-flat200-00-clause.xml.lzma ├── SocialGolfers-4-3-4-cp.xml.lzma ├── SportsScheduling-08.xml.lzma ├── Steiner3-08.xml.lzma ├── StillLife-03-06.xml.lzma ├── StillLife-wastage-03.xml.lzma ├── StripPacking-C1P1.xml.lzma ├── Subisomorphism-A-10.xml.lzma ├── Sudoku-s01a-alldiff.xml.lzma ├── Taillard-js-015-15-0.xml.lzma ├── Taillard-os-04-04-0.xml.lzma ├── Tpp-3-3-20-1.xml.lzma ├── TravellingSalesman-20-30-00.xml.lzma ├── Vrp-A-n32-k5.xml.lzma ├── Vrp-P-n16-k8.xml.lzma ├── Warehouse-opl.xml.lzma ├── Zebra.xml.lzma ├── driverlogw-09.xml.lzma ├── qcp-15-120-00_X2.xml.lzma ├── qwh-o30-h374-01.xml.lzma ├── testExtension1.xml.lzma ├── testExtension2.xml.lzma ├── testExtension3.xml.lzma ├── testObjective1.xml.lzma └── testPrimitive.xml.lzma ├── pom.xml └── src ├── main └── java │ └── org │ └── xcsp │ ├── common │ ├── Condition.java │ ├── Constants.java │ ├── FunctionalInterfaces.java │ ├── IVar.java │ ├── Range.java │ ├── Size.java │ ├── Softening.java │ ├── Types.java │ ├── Utilities.java │ ├── domains │ │ ├── Domains.java │ │ └── Values.java │ ├── enumerations │ │ ├── EnumerationAbstract.java │ │ ├── EnumerationCartesian.java │ │ ├── EnumerationOfCombinations.java │ │ └── EnumerationOfPermutations.java │ ├── predicates │ │ ├── MatcherInterface.java │ │ ├── TreeEvaluator.java │ │ ├── XNode.java │ │ ├── XNodeLeaf.java │ │ ├── XNodeParent.java │ │ └── XNodeParentSpecial.java │ └── structures │ │ ├── AbstractTuple.java │ │ ├── Automaton.java │ │ ├── Table.java │ │ ├── TableAbstract.java │ │ ├── TableSymbolic.java │ │ ├── Transition.java │ │ └── Transitions.java │ ├── modeler │ ├── Compiler.java │ ├── api │ │ ├── ProblemAPI.java │ │ ├── ProblemAPIBase.java │ │ ├── ProblemAPIOnVals.java │ │ ├── ProblemAPIOnVars.java │ │ └── ProblemAPISymbolic.java │ ├── definitions │ │ ├── DefXCSP.java │ │ ├── ICtr.java │ │ ├── IObj.java │ │ └── IRootForCtrAndObj.java │ ├── entities │ │ ├── CtrEntities.java │ │ ├── ModelingEntity.java │ │ ├── ObjEntities.java │ │ └── VarEntities.java │ ├── implementation │ │ ├── NotData.java │ │ ├── ProblemDataHandler.java │ │ ├── ProblemIMP.java │ │ └── ProblemIMP3.java │ └── problems │ │ ├── AllInterval.java │ │ ├── Bibd.java │ │ ├── Blackhole.java │ │ ├── BoardColoration.java │ │ ├── MagicSequence.java │ │ ├── Pic.java │ │ ├── Pic2.java │ │ ├── Queens.java │ │ ├── Rack.java │ │ ├── Rack2.java │ │ ├── Riddle.java │ │ ├── Riddle2.java │ │ ├── Riddle3.java │ │ ├── Riddle4.java │ │ ├── Riddle4b.java │ │ ├── Riddle5.java │ │ ├── Sudoku.java │ │ ├── Warehouse.java │ │ └── Zebra.java │ └── parser │ ├── WrongTypeException.java │ ├── XParser.java │ ├── callbacks │ ├── CompetitionValidator.java │ ├── FeatureDisplayer.java │ ├── SolutionChecker.java │ ├── XCallbacks.java │ └── XCallbacks2.java │ ├── entries │ ├── ParsingEntry.java │ ├── XConstraints.java │ ├── XObjectives.java │ └── XVariables.java │ └── loaders │ ├── ConstraintRecognizer.java │ ├── CtrLoaderInteger.java │ └── CtrLoaderSymbolic.java └── test └── java └── TestSolutions.java /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2023, Univ. Artois and CNRS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

XCSP3-Java-Tools v2.5.1

2 | 3 | 4 | 5 | This library provides: 6 | * a parser written in Java 8 for XCSP3 instances ; see [miniguide](doc/parserJava1-2.pdf) 7 | * a tool for checking solutions (and bounds) of XCSP3 instances ; see [miniguide](doc/checkerJava1-1.pdf) 8 | 9 | A C++ parser is available in its own [repository](https://github.com/xcsp3team/XCSP3-CPP-Parser). 10 | 11 | A Python library for modeling, called PyCSP3, is also independently available. 12 | For the current version of PyCSP3, note that: 13 | * a website including more than 60 Jupyter notebooks can be found at [pycsp.org](https://pycsp.org). 14 | * the code is available on [Github](https://github.com/xcsp3team/pycsp3) 15 | * a [well-documented guide](https://arxiv.org/abs/2009.00326) is available 16 | * PyCSP3 is available as a PyPi package [here](https://pypi.org/project/pycsp3/) 17 | * a GitHub repository with more than 340 models is available at [pycsp3-models](https://github.com/xcsp3team/pycsp3-models) 18 | 19 | # 1) Documentation 20 | 21 | Information about XCSP3 can be found at [xcsp.org](https://xcsp.org). 22 | 23 | For details about these tools, see the documents referenced below. 24 | 25 | ## Java Parser 26 | 27 | See the miniguide in file [`parserJava1-2.pdf`](doc/parserJava1-2.pdf). 28 | 29 | ## Solution Checker 30 | 31 | See the miniguide in file [`checkerJava1-1.pdf`](doc/checkerJava1-1.pdf). 32 | 33 | 34 | 35 | 36 | # 2) Obtaining Binary and Sources of XCSP3 Tools 37 | 38 | ## Maven Artifact 39 | 40 | You can get it at the [Central Repository](https://search.maven.org). 41 | Currently, this is: 42 | 43 | 44 | org.xcsp 45 | xcsp3-tools 46 | 2.5.1 47 | 48 | 49 | ## Directly Building a JAR with Maven 50 | 51 | 1. Clone the repository : `git clone https://github.com/xcsp3team/XCSP3-Java-Tools.git` 52 | 1. Change directory : `cd XCSP3-Java-Tools` 53 | 1. Run Maven : `mvn package -Dmaven.test.skip=true` (of course, you need Maven to be installed) 54 | 1. Test the JARs in the directory 'target'. For example, while choosing the right value for X-Y-Z, 55 | - `java -cp target/xcsp3-tools-X-Y-Z.jar org.xcsp.modeler.Compiler`. If the usage of the compiler is displayed, you are fine. 56 | 57 | You can also directly hit a main method: 58 | - `java -jar target/xcsp3-compiler-X-Y-Z.jar` 59 | - `java -jar target/xcsp3-solutionChecker-X-Y-Z.jar` 60 | - `java -jar target/xcsp3-competitionValidator-X-Y-Z.jar` 61 | 62 | ## Directly Building a JAR with Gradle 63 | 64 | 1. Clone the repository : `git clone https://github.com/xcsp3team/XCSP3-Java-Tools.git` 65 | 1. Change directory : `cd XCSP3-Java-Tools` 66 | 1. Run Gradle : `gradle build -x test` (of course, you need Gradle to be installed) 67 | 1. Test the JAR : `java -cp build/libs/xcsp3-tools-X-Y-Z.jar org.xcsp.modeler.Compiler` (choose the right values for X-Y-Z) 68 | If the usage of the compiler is displayed, you are fine. 69 | 70 | With this JAR, you can run the compiler (JvCSP3) and the solution checker. 71 | See details in the documents, referenced above. 72 | 73 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | sourceCompatibility = 1.8 4 | targetCompatibility = 1.8 5 | 6 | archivesBaseName = "xcsp3-tools" 7 | version = '2.5.1' 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | compile group: 'org.glassfish', name: 'javax.json', version: '1.1.2' 15 | //compile files('lib/javax.json-1.0.4.jar') 16 | testCompile 'junit:junit:4.12' 17 | } 18 | 19 | 20 | 21 | jar { 22 | duplicatesStrategy(DuplicatesStrategy.EXCLUDE) 23 | } 24 | 25 | -------------------------------------------------------------------------------- /doc/JvCSP3v1-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/doc/JvCSP3v1-1.pdf -------------------------------------------------------------------------------- /doc/checkerJava1-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/doc/checkerJava1-1.pdf -------------------------------------------------------------------------------- /doc/parserJava1-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/doc/parserJava1-2.pdf -------------------------------------------------------------------------------- /instancesTest/AllInterval-005.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/AllInterval-005.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Allergy.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Allergy.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Bibd-sc-06-050-25-03-10.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Bibd-sc-06-050-25-03-10.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Bibd-sum-06-050-25-03-10.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Bibd-sum-06-050-25-03-10.xml.lzma -------------------------------------------------------------------------------- /instancesTest/BinPacking-mdd-n1c1w4a.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/BinPacking-mdd-n1c1w4a.xml.lzma -------------------------------------------------------------------------------- /instancesTest/BinPacking-sum-n1c1w4a.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/BinPacking-sum-n1c1w4a.xml.lzma -------------------------------------------------------------------------------- /instancesTest/BinPacking-tab-n1c1w4a.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/BinPacking-tab-n1c1w4a.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Blackhole-04-3-00.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Blackhole-04-3-00.xml.lzma -------------------------------------------------------------------------------- /instancesTest/BusScheduling-cnt-t1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/BusScheduling-cnt-t1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/CarSequencing-dingbas.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/CarSequencing-dingbas.xml.lzma -------------------------------------------------------------------------------- /instancesTest/ChessboardColoration-07-07.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/ChessboardColoration-07-07.xml.lzma -------------------------------------------------------------------------------- /instancesTest/ColouredQueens-07.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/ColouredQueens-07.xml.lzma -------------------------------------------------------------------------------- /instancesTest/CostasArray-12.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/CostasArray-12.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Crossword-lex-vg-5-6.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Crossword-lex-vg-5-6.xml.lzma -------------------------------------------------------------------------------- /instancesTest/CryptoPuzzle-cross-roads-danger.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/CryptoPuzzle-cross-roads-danger.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Cutstock-small.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Cutstock-small.xml.lzma -------------------------------------------------------------------------------- /instancesTest/DistinctVectors-30-050-02.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/DistinctVectors-30-050-02.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Domino-300-300.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Domino-300-300.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Fastfood-ff10.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Fastfood-ff10.xml.lzma -------------------------------------------------------------------------------- /instancesTest/GolombRuler-09-a3.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/GolombRuler-09-a3.xml.lzma -------------------------------------------------------------------------------- /instancesTest/GolombRuler-09-a4.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/GolombRuler-09-a4.xml.lzma -------------------------------------------------------------------------------- /instancesTest/GracefulGraph-K02-P04.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/GracefulGraph-K02-P04.xml.lzma -------------------------------------------------------------------------------- /instancesTest/GraphColoring-3-fullins-4.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/GraphColoring-3-fullins-4.xml.lzma -------------------------------------------------------------------------------- /instancesTest/GraphColoring-qwhdec-o5-h10-1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/GraphColoring-qwhdec-o5-h10-1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Hanoi-05.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Hanoi-05.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Kakuro-easy-000-ext.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Kakuro-easy-000-ext.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Kakuro-easy-000-sumdiff.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Kakuro-easy-000-sumdiff.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Knapsack-30-100-00.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Knapsack-30-100-00.xml.lzma -------------------------------------------------------------------------------- /instancesTest/KnightTour-06-ext03.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/KnightTour-06-ext03.xml.lzma -------------------------------------------------------------------------------- /instancesTest/KnightTour-06-int.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/KnightTour-06-int.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Langford-3-10.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Langford-3-10.xml.lzma -------------------------------------------------------------------------------- /instancesTest/LangfordBin-08.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/LangfordBin-08.xml.lzma -------------------------------------------------------------------------------- /instancesTest/LowAutocorrelation-015.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/LowAutocorrelation-015.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSequence-008-ca.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSequence-008-ca.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSequence-008-co.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSequence-008-co.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSquare-4-table.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSquare-4-table.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSquare-6-mdd.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSquare-6-mdd.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSquare-6-sum.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSquare-6-sum.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MagicSquare-9-f10-01.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MagicSquare-9-f10-01.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Mario-easy-4.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Mario-easy-4.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MarketSplit-01.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MarketSplit-01.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MultiKnapsack-1-01.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MultiKnapsack-1-01.xml.lzma -------------------------------------------------------------------------------- /instancesTest/MultiKnapsack-1-0_X2.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/MultiKnapsack-1-0_X2.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Nonogram-001-regular.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Nonogram-001-regular.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Nonogram-001-table.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Nonogram-001-table.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Opd-07-007-003.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Opd-07-007-003.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Ortholatin-005.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Ortholatin-005.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Pb-gr-05.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Pb-gr-05.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Pb-robin08.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Pb-robin08.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Primes-15-20-2-1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Primes-15-20-2-1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/PrizeCollecting-15-3-5-0.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/PrizeCollecting-15-3-5-0.xml.lzma -------------------------------------------------------------------------------- /instancesTest/QuadraticAssignment-bur26a.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/QuadraticAssignment-bur26a.xml.lzma -------------------------------------------------------------------------------- /instancesTest/QuadraticAssignment-qap.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/QuadraticAssignment-qap.xml.lzma -------------------------------------------------------------------------------- /instancesTest/QuasiGroup-3-04.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/QuasiGroup-3-04.xml.lzma -------------------------------------------------------------------------------- /instancesTest/QuasiGroup-7-09.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/QuasiGroup-7-09.xml.lzma -------------------------------------------------------------------------------- /instancesTest/QueenAttacking-06.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/QueenAttacking-06.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Queens-0008-m1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Queens-0008-m1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/RadarSurveillance-8-24-3-2-00.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/RadarSurveillance-8-24-3-2-00.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Ramsey-12.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Ramsey-12.xml.lzma -------------------------------------------------------------------------------- /instancesTest/RoomMate-sr0050-int.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/RoomMate-sr0050-int.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Sat-flat200-00-clause.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Sat-flat200-00-clause.xml.lzma -------------------------------------------------------------------------------- /instancesTest/SocialGolfers-4-3-4-cp.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/SocialGolfers-4-3-4-cp.xml.lzma -------------------------------------------------------------------------------- /instancesTest/SportsScheduling-08.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/SportsScheduling-08.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Steiner3-08.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Steiner3-08.xml.lzma -------------------------------------------------------------------------------- /instancesTest/StillLife-03-06.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/StillLife-03-06.xml.lzma -------------------------------------------------------------------------------- /instancesTest/StillLife-wastage-03.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/StillLife-wastage-03.xml.lzma -------------------------------------------------------------------------------- /instancesTest/StripPacking-C1P1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/StripPacking-C1P1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Subisomorphism-A-10.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Subisomorphism-A-10.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Sudoku-s01a-alldiff.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Sudoku-s01a-alldiff.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Taillard-js-015-15-0.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Taillard-js-015-15-0.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Taillard-os-04-04-0.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Taillard-os-04-04-0.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Tpp-3-3-20-1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Tpp-3-3-20-1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/TravellingSalesman-20-30-00.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/TravellingSalesman-20-30-00.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Vrp-A-n32-k5.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Vrp-A-n32-k5.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Vrp-P-n16-k8.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Vrp-P-n16-k8.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Warehouse-opl.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Warehouse-opl.xml.lzma -------------------------------------------------------------------------------- /instancesTest/Zebra.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/Zebra.xml.lzma -------------------------------------------------------------------------------- /instancesTest/driverlogw-09.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/driverlogw-09.xml.lzma -------------------------------------------------------------------------------- /instancesTest/qcp-15-120-00_X2.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/qcp-15-120-00_X2.xml.lzma -------------------------------------------------------------------------------- /instancesTest/qwh-o30-h374-01.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/qwh-o30-h374-01.xml.lzma -------------------------------------------------------------------------------- /instancesTest/testExtension1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/testExtension1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/testExtension2.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/testExtension2.xml.lzma -------------------------------------------------------------------------------- /instancesTest/testExtension3.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/testExtension3.xml.lzma -------------------------------------------------------------------------------- /instancesTest/testObjective1.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/testObjective1.xml.lzma -------------------------------------------------------------------------------- /instancesTest/testPrimitive.xml.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xcsp3team/XCSP3-Java-Tools/e0a4321cbc75b552e6cfd854847c2f2577dc6298/instancesTest/testPrimitive.xml.lzma -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.xcsp 5 | xcsp3-tools 6 | 2.5.1 7 | jar 8 | 9 | XCSP3 Java Tools 10 | Java Tools for parsing XCSP3 instances, compiling JvCSP3 models, and checking solutions. For more information about XCSP3, follow www.xcsp.org 11 | https://www.xcsp.org 12 | 13 | 14 | 15 | MIT License 16 | http://www.opensource.org/licenses/mit-license.php 17 | 18 | 19 | 20 | 21 | Centre de Recherche en Informatique de Lens (CRIL), University of Artois 22 | https://www.cril.univ-artois.fr/ 23 | 24 | 25 | 26 | 27 | Christophe Lecoutre 28 | lecoutre@cril.fr 29 | Univ. Artois, CRIL-CNRS 30 | http://www.cril.univ-artois.fr 31 | 32 | architect 33 | developer 34 | 35 | +1 36 | 37 | 38 | Gilles Audemard 39 | audemard@cril.fr 40 | Univ. Artois, CRIL-CNRS 41 | http://www.cril.univ-artois.fr 42 | 43 | developer 44 | 45 | +1 46 | 47 | 48 | 49 | 50 | 51 | Emmanuel Lonca 52 | lonca@cril.fr 53 | Univ. Artois, CRIL-CNRS 54 | http://www.cril.fr 55 | 56 | 57 | 58 | 59 | scm:git:git://github.com/xcsp3team/XCSP3-Java-Tools.git 60 | scm:git:ssh://github.com/xcsp3team/XCSP3-Java-Tools.git 61 | https://github.com/xcsp3team/XCSP3-Java-Tools/tree/master 62 | 63 | 64 | 65 | UTF-8 66 | 67 | 68 | 69 | 70 | 71 | javax.json 72 | javax.json-api 73 | 1.1.2 74 | 75 | 76 | 77 | org.glassfish 78 | javax.json 79 | 1.1.2 80 | 81 | 82 | junit 83 | junit 84 | 4.13.1 85 | 86 | 87 | 88 | 89 | 90 | ossrh 91 | https://oss.sonatype.org/content/repositories/snapshots 92 | 93 | 94 | ossrh 95 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 96 | 97 | 98 | 99 | 100 | 101 | disable-java8-doclint 102 | 103 | [1.8,) 104 | 105 | 106 | -Xdoclint:none 107 | 108 | 109 | 110 | 111 | 112 | src/main/java 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-release-plugin 117 | 2.5.3 118 | 119 | true 120 | false 121 | release 122 | deploy 123 | 124 | 125 | 126 | org.apache.maven.plugins 127 | maven-compiler-plugin 128 | 3.6.0 129 | 130 | 1.8 131 | 1.8 132 | 133 | 134 | 135 | org.apache.maven.plugins 136 | maven-source-plugin 137 | 2.2.1 138 | 139 | 140 | attach-sources 141 | 142 | jar-no-fork 143 | 144 | 145 | 146 | 147 | 148 | org.apache.maven.plugins 149 | maven-javadoc-plugin 150 | 2.9.1 151 | 152 | 153 | attach-javadocs 154 | 155 | jar 156 | 157 | 158 | 159 | 160 | 161 | org.apache.maven.plugins 162 | maven-gpg-plugin 163 | 1.5 164 | 165 | 166 | sign-artifacts 167 | verify 168 | 169 | sign 170 | 171 | 172 | 173 | 174 | 175 | maven-assembly-plugin 176 | 2.4 177 | 178 | 179 | competition-validator 180 | 181 | false 182 | false 183 | 184 | 185 | org.xcsp.parser.callbacks.CompetitionValidator 186 | 187 | 188 | 189 | jar-with-dependencies 190 | 191 | xcsp3-competitionValidator-${project.version} 192 | 193 | package 194 | 195 | single 196 | 197 | 198 | 199 | feature-displayer 200 | 201 | false 202 | false 203 | 204 | 205 | org.xcsp.parser.callbacks.FeatureDisplayer 206 | 207 | 208 | 209 | jar-with-dependencies 210 | 211 | xcsp3-featureDisplayer-${project.version} 212 | 213 | package 214 | 215 | single 216 | 217 | 218 | 219 | solution-checker 220 | 221 | false 222 | false 223 | 224 | 225 | org.xcsp.parser.callbacks.SolutionChecker 226 | 227 | 228 | 229 | jar-with-dependencies 230 | 231 | xcsp3-solutionChecker-${project.version} 232 | 233 | package 234 | 235 | single 236 | 237 | 238 | 239 | 240 | modeler-compiler 241 | 242 | false 243 | false 244 | 245 | 246 | org.xcsp.modeler.Compiler 247 | 248 | 249 | 250 | jar-with-dependencies 251 | 252 | xcsp3-compiler-${project.version} 253 | 254 | package 255 | 256 | single 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 XCSP3 Team (contact@xcsp.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 6 | * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | * 8 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 12 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | */ 14 | package org.xcsp.common; 15 | 16 | import java.math.BigInteger; 17 | 18 | /** 19 | * @author Christophe Lecoutre 20 | */ 21 | public interface Constants { 22 | String EMPTY_STRING = ""; 23 | 24 | String REG_WS = "\\s+"; 25 | String WHITE_SPACE = " \t\n\r\f"; 26 | 27 | // For each primitive type, we can safely use all values except the extreme ones (as defined by SAFETY_MARGIN) 28 | // so as to be able to use special values (for example, for representing +infinity and -infinity) 29 | int SAFETY_MARGIN = 10; 30 | long MIN_SAFE_BYTE = Byte.MIN_VALUE + SAFETY_MARGIN, MAX_SAFE_BYTE = Byte.MAX_VALUE - SAFETY_MARGIN; 31 | long MIN_SAFE_SHORT = Short.MIN_VALUE + SAFETY_MARGIN, MAX_SAFE_SHORT = Short.MAX_VALUE - SAFETY_MARGIN; 32 | long MIN_SAFE_INT = Integer.MIN_VALUE + SAFETY_MARGIN, MAX_SAFE_INT = Integer.MAX_VALUE - SAFETY_MARGIN; 33 | long MIN_SAFE_LONG = Long.MIN_VALUE + SAFETY_MARGIN, MAX_SAFE_LONG = Long.MAX_VALUE - SAFETY_MARGIN; 34 | BigInteger BIG_MIN_SAFE_LONG = BigInteger.valueOf(MIN_SAFE_LONG), BIG_MAX_SAFE_LONG = BigInteger.valueOf(MAX_SAFE_LONG); 35 | 36 | long MINUS_INFINITY = Long.MIN_VALUE; 37 | long PLUS_INFINITY = Long.MAX_VALUE; 38 | int MINUS_INFINITY_INT = Integer.MIN_VALUE; 39 | int PLUS_INFINITY_INT = Integer.MAX_VALUE; 40 | String MINUS_INFINITY_STRING = "-infinity"; 41 | String PLUS_INFINITY_STRING = "+infinity"; 42 | 43 | int ALL = Integer.MAX_VALUE; 44 | 45 | // We use the maximum value of each primitive type, minus 1, to denote STAR (related to the concept of short tuples) 46 | String STAR_SYMBOL = "*"; 47 | 48 | byte STAR_BYTE = Byte.MAX_VALUE - 1; 49 | short STAR_SHORT = Short.MAX_VALUE - 1; 50 | int STAR_INT = Integer.MAX_VALUE - 1; 51 | long STAR_LONG = Long.MAX_VALUE - 1; 52 | int STAR = STAR_INT; 53 | 54 | public final String TIMES = "x"; 55 | 56 | /** We use the minimum long value, plus 1, to denote that a value is outside bounds (e.g., of a domain) */ 57 | long OUTSIDE_BOUNDS = Long.MIN_VALUE + 1; 58 | 59 | // Constants used for some first-level elements of the instances 60 | String INSTANCE = "instance"; 61 | String VARIABLES = "variables"; 62 | String VAR = "var"; 63 | String ARRAY = "array"; 64 | String DOMAIN = "domain"; 65 | String REQUIRED = "required"; 66 | String POSSIBLE = "possible"; 67 | String CONSTRAINTS = "constraints"; 68 | String BLOCK = "block"; 69 | String GROUP = "group"; 70 | String ARGS = "args"; 71 | String OBJECTIVES = "objectives"; 72 | String OBJECTIVE = "objective"; 73 | String MINIMIZE = "minimize"; 74 | String MAXIMIZE = "maximize"; 75 | String SOFT = "soft"; 76 | String ANNOTATIONS = "annotations"; 77 | String DECISION = "decision"; 78 | String VAL_HEURISTIC = "valHeuristic"; 79 | String STATIC = "static"; 80 | 81 | /** A regex for denoting delimiters used in lists (elements separated by commas and surrounded by parentheses) */ 82 | String DELIMITER_LISTS = "\\s*\\)\\s*\\(\\s*|\\s*\\(\\s*|\\s*\\)\\s*"; 83 | 84 | /** A regex for denoting delimiters used in sets (elements separated by a comma and surrounded by brace brackets) */ 85 | String DELIMITER_SETS = "\\s*\\}\\s*\\{\\s*|\\s*\\{\\s*|\\s*\\}\\s*"; 86 | 87 | /** A regex for denoting delimiters used in msets (elements separated by a comma and surrounded by double brace brackets) */ 88 | String DELIMITER_MSETS = "\\s*\\}\\}\\s*\\{\\{\\s*|\\s*\\{\\{\\s*|\\s*\\}\\}\\s*"; 89 | 90 | String[] KEYWORDS = { "neg", "abs", "add", "sub", "mul", "div", "mod", "sqr", "pow", "min", "max", "dist", "lt", "le", "ge", "gt", "ne", "eq", "set", "in", 91 | "not", "and", "or", "xor", "iff", "imp", "if", "card", "union", "inter", "diff", "sdiff", "hull", "djoint", "subset", "subseq", "supseq", "supset", 92 | "convex", "PI", "E", "fdiv", "fmod", "sqrt", "nroot", "exp", "ln", "log", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", 93 | "others" }; 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/IVar.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common; 2 | 3 | /** 4 | * This is the root interface of any variable, handled either in the parser or the modeler. 5 | */ 6 | public interface IVar { 7 | /** 8 | * Returns the id (unique name) of the variable. 9 | * 10 | * @return the id (unique name) of the variable 11 | */ 12 | String id(); 13 | 14 | default String idPrefix() { 15 | String id = id(); 16 | int pos = id.indexOf('['); 17 | return pos == -1 ? id : id.substring(0, pos); 18 | } 19 | 20 | /** 21 | * This is the root interface of any integer variable, handled either in the parser or the modeler. One could have expected that the name be 22 | * {@code IVarInteger}, but this would be annoying when modeling. 23 | */ 24 | interface Var extends IVar { 25 | long firstValue(); 26 | 27 | long lastValue(); 28 | 29 | Object allValues(); 30 | 31 | default boolean isZeroOne() { 32 | return false; 33 | } 34 | } 35 | 36 | /** 37 | * This is the root interface of any symbolic variable, handled either in the parser or the modeler. One could have expected that the name is 38 | * {@code IVarSymbolic}, but we prefer to keep simple names for modeling. 39 | */ 40 | interface VarSymbolic extends IVar { 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/Size.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common; 2 | 3 | /** 4 | * This is the root abstract class of all subclasses that are useful for denoting the size (i.e., length of each dimension) of 5 | * multi-dimensional arrays of variables. These classes are used as syntactic sugar. 6 | */ 7 | public abstract class Size { 8 | /** 9 | * The respective lengths of an array of dimension {@code lengths.length}. 10 | */ 11 | public int[] lengths; 12 | 13 | /** 14 | * Sets the lengths of the dimensions of an array of dimension {@code lengths.length} 15 | * 16 | * @param lengths 17 | * the lengths of the dimensions of an array 18 | * @return this object (for method chaining) 19 | */ 20 | protected Size setLengths(int... lengths) { 21 | this.lengths = lengths; 22 | return this; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return Utilities.join(lengths); 28 | } 29 | 30 | /** 31 | * A class for representing the size (length) of a 1-dimensional array. This is mainly used as syntactic sugar. 32 | */ 33 | public static class Size1D extends Size { 34 | /** 35 | * Builds an object that represents the size (length) of a 1-dimensional array. 36 | * 37 | * @param length 38 | * the size (length) of the array 39 | * @return an object that represents the size (length) of a 1-dimensional array 40 | */ 41 | public static Size1D build(int length) { 42 | return (Size1D) new Size1D().setLengths(length); 43 | } 44 | } 45 | 46 | /** 47 | * A class for representing the size (i.e., length of each dimension) a 2-dimensional array. This is mainly used as syntactic sugar. 48 | */ 49 | public static class Size2D extends Size { 50 | /** 51 | * Builds an object that represents the size (i.e., length of each dimension) of a 2-dimensional array. 52 | * 53 | * @param length0 54 | * the size (length) of the first dimension of a 2-dimensional array 55 | * @param length1 56 | * the size (length) of the second dimension of a 2-dimensional array 57 | * @return an object that represents the size (i.e., length of each dimension) of a 2-dimensional array 58 | */ 59 | public static Size2D build(int length0, int length1) { 60 | return (Size2D) new Size2D().setLengths(length0, length1); 61 | } 62 | } 63 | 64 | /** 65 | * A class for representing the size (i.e., length of each dimension) a 3-dimensional array. This is mainly used as syntactic sugar. 66 | */ 67 | public static class Size3D extends Size { 68 | /** 69 | * Builds an object that represents the size (i.e., length of each dimension) of a 3-dimensional array. 70 | * 71 | * @param length0 72 | * the size (length) of the first dimension of a 3-dimensional array 73 | * @param length1 74 | * the size (length) of the second dimension of a 3-dimensional array 75 | * @param length2 76 | * the size (length) of the third dimension of a 3-dimensional array 77 | * @return an object that represents the size (i.e., length of each dimension) of a 3-dimensional array 78 | */ 79 | public static Size3D build(int length0, int length1, int length2) { 80 | return (Size3D) new Size3D().setLengths(length0, length1, length2); 81 | } 82 | } 83 | 84 | /** 85 | * A class for representing the size (i.e., length of each dimension) a 4-dimensional array. This is mainly used as syntactic sugar. 86 | */ 87 | public static class Size4D extends Size { 88 | /** 89 | * Builds an object that represents the size (i.e., length of each dimension) of a 4-dimensional array. 90 | * 91 | * @param length0 92 | * the size (length) of the first dimension of a 4-dimensional array 93 | * @param length1 94 | * the size (length) of the second dimension of a 4-dimensional array 95 | * @param length2 96 | * the size (length) of the third dimension of a 4-dimensional array 97 | * @param length3 98 | * the size (length) of the fourth dimension of a 4-dimensional array 99 | * @return an object that represents the size (i.e., length of each dimension) of a 4-dimensional array 100 | */ 101 | public static Size4D build(int length0, int length1, int length2, int length3) { 102 | return (Size4D) new Size4D().setLengths(length0, length1, length2, length3); 103 | } 104 | } 105 | 106 | /** 107 | * A class for representing the size (i.e., length of each dimension) a 5-dimensional array. This is mainly used as syntactic sugar. 108 | */ 109 | public static class Size5D extends Size { 110 | /** 111 | * Builds an object that represents the size (i.e., length of each dimension) of a 5-dimensional array. 112 | * 113 | * @param length0 114 | * the size (length) of the first dimension of a 5-dimensional array 115 | * @param length1 116 | * the size (length) of the second dimension of a 5-dimensional array 117 | * @param length2 118 | * the size (length) of the third dimension of a 5-dimensional array 119 | * @param length3 120 | * the size (length) of the fourth dimension of a 5-dimensional array 121 | * @param length4 122 | * the size (length) of the fifth dimension of a 5-dimensional array 123 | * @return an object that represents the size (i.e., length of each dimension) of a 5-dimensional array 124 | */ 125 | public static Size5D build(int length0, int length1, int length2, int length3, int length4) { 126 | return (Size5D) new Size5D().setLengths(length0, length1, length2, length3, length4); 127 | } 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/Softening.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common; 2 | 3 | import org.xcsp.common.Types.TypeMeasure; 4 | 5 | /** The root class used for representing softening. */ 6 | public abstract class Softening { 7 | 8 | /** A pair (operator,operand) for a cost-integrated soft constraint, or null for a cost function. */ 9 | public final Condition cost; 10 | 11 | public boolean isCostFunction() { 12 | return cost == null; 13 | } 14 | 15 | public Softening(Condition cost) { 16 | this.cost = cost; 17 | } 18 | 19 | public Softening() { 20 | this(null); 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "Softening (" + this.getClass().getSimpleName() + ")" + " " + (cost == null ? "" : "cost:" + cost); 26 | } 27 | 28 | /** The class used for representing softening of simple soft constraints. */ 29 | public static final class SofteningSimple extends Softening { 30 | 31 | /** The cost to be considered when the underlying constraint is violated. */ 32 | public final int violationCost; 33 | 34 | public SofteningSimple(Condition cost, int violationCost) { 35 | super(cost); 36 | this.violationCost = violationCost; 37 | Utilities.control(violationCost > 0, "Pb with violation cost " + violationCost); 38 | } 39 | 40 | public SofteningSimple(int violationCost) { 41 | this(null, violationCost); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return super.toString() + " violationCost=" + violationCost; 47 | } 48 | } 49 | 50 | /** The class used for representing softening of intensional constraints (that are not simple soft constraints). */ 51 | public static final class SofteningIntension extends Softening { 52 | 53 | public SofteningIntension(Condition cost) { 54 | super(cost); 55 | } 56 | 57 | public SofteningIntension() { 58 | this(null); 59 | } 60 | } 61 | 62 | /** The class used for representing softening of extensional constraints (that are not simple soft constraints). */ 63 | public static final class SofteningExtension extends Softening { 64 | /** The default cost for all tuples not explicitly listed. -1 if not useful (because all tuples are explicitly listed). */ 65 | public final int defaultCost; 66 | 67 | public SofteningExtension(Condition cost, int defaultCost) { 68 | super(cost); 69 | this.defaultCost = defaultCost; 70 | Utilities.control(defaultCost >= -1, "Pb with default cost " + defaultCost); 71 | } 72 | 73 | public SofteningExtension(int defaultCost) { 74 | this(null, defaultCost); 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return super.toString() + " defaultCost=" + defaultCost; 80 | } 81 | } 82 | 83 | /** The class used for representing softening of other constraints (global constraints and some meta-constraints). */ 84 | public static final class SofteningGlobal extends Softening { 85 | public final TypeMeasure type; 86 | 87 | public final String parameters; 88 | 89 | public SofteningGlobal(Condition cost, TypeMeasure type, String parameters) { 90 | super(cost); 91 | this.type = type; 92 | this.parameters = parameters; 93 | } 94 | 95 | public SofteningGlobal(Condition cost, TypeMeasure type) { 96 | this(cost, type, null); 97 | } 98 | 99 | public SofteningGlobal(TypeMeasure type, String parameters) { 100 | this(null, type, parameters); 101 | } 102 | 103 | public SofteningGlobal(TypeMeasure type) { 104 | this(type, null); 105 | } 106 | 107 | @Override 108 | public String toString() { 109 | return super.toString() + " type=" + type + (parameters != null ? " parameters=" + parameters : ""); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/enumerations/EnumerationAbstract.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL 7 | * LIBRE CeCILL which accompanies this distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.common.enumerations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Iterator; 13 | import java.util.List; 14 | import java.util.function.Consumer; 15 | import java.util.function.Predicate; 16 | 17 | import org.xcsp.common.Utilities; 18 | 19 | /** 20 | * This class is the root class for all subclasses allowing us to iterate over combinations, permutations, ... 21 | */ 22 | public abstract class EnumerationAbstract implements Iterator { 23 | 24 | /** 25 | * Indicates if the method {@code hasNext()} has already been called. This is not the case if the value of this field is {@code null}. Otherwise, the value 26 | * of this field indicates the presence ({@code Boolean.TRUE}) or the absence ({@code Boolean.FALSE}) of another tuple already computed. 27 | */ 28 | protected Boolean nextTuple; 29 | 30 | /** 31 | * The current tuple composed of indexes (of values) 32 | */ 33 | public final int[] currTupleOfIdxs; 34 | 35 | /** 36 | * The current tuple composed of values 37 | */ 38 | private final int[] currTupleOfVals; 39 | 40 | /** 41 | * Indicates if indexes match values (i.e., if the value at index {@code i} is always {@code i}). 42 | */ 43 | protected final boolean indexesMatchValues; 44 | 45 | /** 46 | * Builds an object that can be used for enumerating tuples, each of them with the specified length. 47 | * 48 | * @param tupleLength 49 | * the length of each tuple in the enumeration 50 | * @param indexesMatchValues 51 | * {@code true} iff indexes (of values) and values match, i.e. if the value at index {@code i} is always {@code i}) 52 | */ 53 | public EnumerationAbstract(int tupleLength, boolean indexesMatchValues) { 54 | this.currTupleOfIdxs = new int[tupleLength]; 55 | this.currTupleOfVals = new int[tupleLength]; 56 | this.indexesMatchValues = indexesMatchValues; 57 | } 58 | 59 | /** 60 | * Computes the first tuple (called at reset time). 61 | */ 62 | protected abstract void computeFirstTuple(); 63 | 64 | /** 65 | * Resets the object, so as to be able to iterate again over all tuples of the enumeration. 66 | */ 67 | public void reset() { 68 | nextTuple = Boolean.TRUE; // true because the first tuple is computed just below 69 | computeFirstTuple(); 70 | } 71 | 72 | /** 73 | * Returns the value of the current tuple at the specified position. 74 | * 75 | * @param pos 76 | * the position of an integer in the tuple 77 | * @return the value of the current tuple at the specified position 78 | */ 79 | protected abstract int valAt(int pos); 80 | 81 | private int[] vals() { 82 | if (indexesMatchValues) 83 | return currTupleOfIdxs; 84 | for (int i = 0; i < currTupleOfVals.length; i++) 85 | currTupleOfVals[i] = valAt(i); 86 | return currTupleOfVals; 87 | } 88 | 89 | @Override 90 | public abstract boolean hasNext(); 91 | 92 | /** 93 | * {@inheritDoc} DO NOT MODIFY the tuple that is returned. 94 | */ 95 | @Override 96 | public int[] next() { 97 | if (nextTuple == null) 98 | hasNext(); // determine if there is another tuple by computing it 99 | int[] t = nextTuple == Boolean.FALSE ? null : vals(); 100 | nextTuple = nextTuple == Boolean.FALSE ? Boolean.FALSE : null; 101 | return t; 102 | } 103 | 104 | public void execute(Consumer c) { 105 | reset(); 106 | while (hasNext()) { 107 | int[] t = next(); 108 | c.accept(t); 109 | } 110 | } 111 | 112 | /** 113 | * Returns an array with all tuples that can be enumerated while being accepted by the specified predicate. 114 | * 115 | * @param p 116 | * a predicate used to test the tuples in the enumeration 117 | * @return an array with all tuples that can be enumerated while being accepted by the specified predicate 118 | */ 119 | public int[][] toArray(Predicate p) { 120 | reset(); 121 | List list = new ArrayList<>(); 122 | while (hasNext()) { 123 | int[] x = next(); 124 | if (p.test(x)) 125 | list.add(x.clone()); 126 | } 127 | return list.stream().toArray(int[][]::new); 128 | } 129 | 130 | /** 131 | * Returns an array with all tuples that can be enumerated. The array is lexicographically sorted. 132 | * 133 | * @return an array with all tuples that can be enumerated 134 | */ 135 | public int[][] toArray() { 136 | reset(); 137 | List list = new ArrayList<>(); 138 | while (hasNext()) 139 | list.add(next().clone()); 140 | return list.stream().sorted(Utilities.lexComparatorInt).toArray(int[][]::new); 141 | } 142 | 143 | /** 144 | * Displays all tuples of this enumeration. 145 | */ 146 | public void displayAllTuples() { 147 | reset(); 148 | int cnt = 0; 149 | while (hasNext()) { 150 | System.out.println("(" + Utilities.join(next(), ",") + ") "); 151 | cnt++; 152 | } 153 | System.out.println("\nThere are " + cnt + " tuples"); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/enumerations/EnumerationCartesian.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.common.enumerations; 10 | 11 | import java.util.ArrayList; 12 | import java.util.Arrays; 13 | import java.util.LinkedHashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | import java.util.stream.IntStream; 17 | import java.util.stream.Stream; 18 | 19 | import org.xcsp.common.Utilities; 20 | 21 | /** 22 | * This class allows iterating over all tuples of a given length from a given set of numbers (of possibilities at each position). Execute the main 23 | * method for an illustration. 24 | */ 25 | public class EnumerationCartesian extends EnumerationAbstract { 26 | 27 | private static Map cacheOfTuples; 28 | 29 | /** 30 | * Returns an array with all tuples of the specified length such that for each tuple: 31 | *
    32 | *
  • at each position, a value is between 0 (inclusive) and {@code nValues} (exclusive)
  • 33 | *
  • all values are all different
  • 34 | *
  • the sum of the values in the tuple is equal to the specified limit
  • 35 | *
36 | * 37 | * @param limit 38 | * the integer denoting the limit of the sum 39 | * @param nValues 40 | * indicates how many values are possible at each position 41 | * @param tupleLength 42 | * the length of each tuple in the enumeration 43 | * @param offset 44 | * the value that must be systematically added to each value of each tuple 45 | * @return an array with all tuples of the specified length that respect a sum equality and an allDifferent restriction 46 | */ 47 | public static int[][] tuplesWithDiffValuesSummingTo(int limit, int nValues, int tupleLength, int offset) { 48 | if (cacheOfTuples == null) 49 | cacheOfTuples = new LinkedHashMap<>(); 50 | String key = limit + "_" + nValues + "_" + tupleLength + "_" + offset; 51 | int[][] tuples = cacheOfTuples.get(key); 52 | if (tuples != null) 53 | return tuples; 54 | List list = new ArrayList<>(); 55 | int[][] combinations = new EnumerationOfCombinations(nValues, tupleLength).toArray(); 56 | int[][] permutations = new EnumerationOfPermutations(tupleLength).toArray(); 57 | for (int[] t : combinations) { 58 | if (offset != 0) 59 | for (int i = 0; i < t.length; i++) 60 | t[i] += offset; 61 | if (IntStream.of(t).sum() == limit) 62 | for (int[] perm : permutations) 63 | list.add(IntStream.range(0, t.length).map(i -> t[perm[i]]).toArray()); 64 | } 65 | tuples = list.stream().sorted(Utilities.lexComparatorInt).toArray(int[][]::new); 66 | cacheOfTuples.put(key, tuples); 67 | return tuples; 68 | } 69 | 70 | /********************************************************************************************** 71 | * End of static section 72 | *********************************************************************************************/ 73 | 74 | /** 75 | * Gives the sets of values on which the tuples will be built. {@code values[i]} is a 1-dimensional array with all possibles (ordered) values at 76 | * position {@code i} in a tuple. 77 | */ 78 | protected final int[][] values; 79 | 80 | /** 81 | * Builds an object that can be used for enumerating tuples, using the specified sets of values. If the specified Boolean is {@code true} the 82 | * specified 2-dimensional array is cloned. 83 | * 84 | * @param values 85 | * the sets of values on which the tuples will be built 86 | * @param clone 87 | * if {@code true} the specified 2-dimensional array is cloned 88 | */ 89 | public EnumerationCartesian(int[][] values, boolean clone) { 90 | super(values.length, Stream.of(values).allMatch(t -> IntStream.range(0, t.length).allMatch(i -> t[i] == i))); 91 | this.values = clone ? Stream.of(values).map(t -> t.clone()).toArray(int[][]::new) : values; 92 | Utilities.control(Stream.of(values).allMatch(t -> t.length > 0 && IntStream.range(0, t.length - 1).allMatch(i -> t[i] < t[i + 1])), 93 | "values are not correctly formed (order,...)"); 94 | reset(); 95 | } 96 | 97 | /** 98 | * Builds an object that can be used for enumerating tuples, using the specified sets of values. 99 | * 100 | * @param values 101 | * the sets of values on which the tuples will be built 102 | */ 103 | public EnumerationCartesian(int[][] values) { 104 | this(values, true); 105 | } 106 | 107 | /** 108 | * Builds an object that can be used for enumerating tuples, using the specified numbers of values. Each tuple will contain a value at position 109 | * {@code i} in the range 0 to {@code nValues[i].length-1}. 110 | * 111 | * @param nValues 112 | * indicates how many values are possible at each position 113 | */ 114 | public EnumerationCartesian(int... nValues) { 115 | this(IntStream.range(0, nValues.length).mapToObj(i -> IntStream.range(0, nValues[i]).toArray()).toArray(int[][]::new), false); 116 | } 117 | 118 | /** 119 | * Builds an object that can be used for enumerating tuples, using the specified numbers of values. Each tuple has the specified length and will 120 | * contain a value at position {@code i} in the range 0 to {@code nValues-1}. 121 | * 122 | * @param nValues 123 | * the number of values used to form tuples 124 | * @param tupleLength 125 | * the length of each tuple 126 | */ 127 | public EnumerationCartesian(int nValues, int tupleLength) { 128 | this(IntStream.range(0, tupleLength).map(i -> nValues).toArray()); 129 | } 130 | 131 | @Override 132 | protected int valAt(int i) { 133 | return values[i][currTupleOfIdxs[i]]; 134 | } 135 | 136 | @Override 137 | protected void computeFirstTuple() { 138 | Arrays.fill(currTupleOfIdxs, 0); 139 | } 140 | 141 | @Override 142 | public boolean hasNext() { 143 | if (nextTuple != null) 144 | return nextTuple == Boolean.TRUE; 145 | for (int i = values.length - 1; i >= 0; i--) 146 | if (currTupleOfIdxs[i] + 1 == values[i].length) 147 | currTupleOfIdxs[i] = 0; 148 | else { 149 | currTupleOfIdxs[i]++; 150 | nextTuple = Boolean.TRUE; 151 | return true; 152 | } 153 | nextTuple = Boolean.FALSE; 154 | return false; 155 | } 156 | 157 | public static void main(String[] args) { 158 | new EnumerationCartesian(7, 7, 7, 7).displayAllTuples(); 159 | new EnumerationCartesian(new int[][] { { 2, 3, 4 }, { 1, 5 }, { 12, 20 } }).displayAllTuples(); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/enumerations/EnumerationOfCombinations.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.common.enumerations; 10 | 11 | import java.util.stream.IntStream; 12 | 13 | import org.xcsp.common.Utilities; 14 | 15 | /** 16 | * This class allows us to iterate over all combinations of a given length from a given set of values. Execute the main method for an illustration. 17 | */ 18 | public class EnumerationOfCombinations extends EnumerationCartesian { 19 | 20 | /** 21 | * Indicates if the numbers of possible values at each position are all equal. 22 | */ 23 | private final boolean uniform; 24 | 25 | /** 26 | * Builds an object that can be used for enumerating combinations, using the specified numbers of values. 27 | * 28 | * @param nValues 29 | * the number of possible different values at each position of the tuples. These numbers must be in an increasing order (and are 30 | * usually all equal) 31 | */ 32 | public EnumerationOfCombinations(int[] nValues) { 33 | super(nValues); 34 | this.uniform = IntStream.range(1, nValues.length).allMatch(i -> nValues[i] == nValues[0]); 35 | Utilities.control(IntStream.range(0, nValues.length - 1).allMatch(i -> nValues[i] <= nValues[i + 1]), "Numbers are not in an increasing order"); 36 | } 37 | 38 | /** 39 | * Builds an object that can be used for enumerating combinations, using the specified number of values. Each tuple (combination) has the 40 | * specified length. 41 | * 42 | * @param nValues 43 | * the number of values used to form combinations 44 | * @param tupleLength 45 | * the length of each combination 46 | */ 47 | public EnumerationOfCombinations(int nValues, int tupleLength) { 48 | this(IntStream.range(0, tupleLength).map(i -> nValues).toArray()); 49 | } 50 | 51 | @Override 52 | protected void computeFirstTuple() { 53 | for (int i = 0; nextTuple == Boolean.TRUE && i < values.length; i++) 54 | if (i >= values[i].length) 55 | nextTuple = Boolean.FALSE; 56 | else 57 | currTupleOfIdxs[i] = i; 58 | } 59 | 60 | /** 61 | * Determines if it is possible to extend the current tuple from the given position 62 | */ 63 | private boolean isExtensibleFrom(int pos) { 64 | if (uniform) 65 | return (values[pos].length - currTupleOfIdxs[pos] > values.length - pos); 66 | int value = currTupleOfIdxs[pos]; 67 | for (int i = pos; i < currTupleOfIdxs.length; i++) 68 | if (++value >= values[i].length) 69 | return false; 70 | return true; 71 | } 72 | 73 | @Override 74 | public boolean hasNext() { 75 | if (nextTuple != null) 76 | return nextTuple == Boolean.TRUE; 77 | int last = values.length - 1; 78 | while (last >= 0) 79 | if (!isExtensibleFrom(last)) 80 | last--; 81 | else { 82 | currTupleOfIdxs[last] = currTupleOfIdxs[last] + 1; 83 | for (int i = last + 1; i < values.length; i++) 84 | currTupleOfIdxs[i] = currTupleOfIdxs[i - 1] + 1; 85 | nextTuple = Boolean.TRUE; 86 | return true; 87 | } 88 | nextTuple = Boolean.FALSE; 89 | return false; 90 | } 91 | 92 | public static void main(String[] args) { 93 | new EnumerationOfCombinations(7, 4).displayAllTuples(); 94 | new EnumerationOfCombinations(new int[] { 3, 4, 4, 5 }).displayAllTuples(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/enumerations/EnumerationOfPermutations.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL 7 | * LIBRE CeCILL which accompanies this distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.common.enumerations; 10 | 11 | import java.util.Arrays; 12 | import java.util.stream.IntStream; 13 | 14 | import org.xcsp.common.Utilities; 15 | 16 | /** 17 | * This class allows us to iterate over all permutations of a given set of integer values. See the Johnson-Trotter algorithm (H. F. Trotter[1962], S. 18 | * M. Johnson[1963]). Execute the main method for an illustration. 19 | */ 20 | public class EnumerationOfPermutations extends EnumerationAbstract { 21 | 22 | /** 23 | * The values used to form permutations. 24 | */ 25 | private final int[] values; 26 | 27 | private final boolean[] currDirectionOfIndexes; // false=left ; true =right 28 | 29 | /** 30 | * Builds an object that can be used for enumerating permutations, using the specified array of values. 31 | * 32 | * @param values 33 | * the values used to form permutations 34 | */ 35 | public EnumerationOfPermutations(int... values) { 36 | super(values.length, IntStream.range(0, values.length).allMatch(i -> i == values[i])); 37 | this.values = values; 38 | this.currDirectionOfIndexes = new boolean[values.length]; 39 | Utilities.control(IntStream.of(values).distinct().count() == values.length, "Values should all be different"); 40 | reset(); 41 | } 42 | 43 | /** 44 | * Builds an object that can be used for enumerating permutations, using the specified number of values. All values are taken in the range 0 to 45 | * {@code nValues-1}. 46 | * 47 | * @param nValues 48 | * the number of values used to form permutations 49 | */ 50 | public EnumerationOfPermutations(int nValues) { 51 | this(IntStream.range(0, nValues).toArray()); 52 | } 53 | 54 | @Override 55 | protected int valAt(int i) { 56 | return values[currTupleOfIdxs[i]]; 57 | } 58 | 59 | @Override 60 | protected void computeFirstTuple() { 61 | for (int i = 0; i < currTupleOfIdxs.length; i++) 62 | currTupleOfIdxs[i] = i; 63 | Arrays.fill(currDirectionOfIndexes, false); 64 | 65 | } 66 | 67 | private int findLargestMobileIndexPosition() { 68 | int best = -1; 69 | for (int p = 0; p < currTupleOfIdxs.length; p++) { 70 | int q = currDirectionOfIndexes[p] ? p + 1 : p - 1; 71 | if (q < 0 || q > currTupleOfIdxs.length - 1) 72 | continue; 73 | if (currTupleOfIdxs[p] > currTupleOfIdxs[q]) 74 | if (best == -1 || currTupleOfIdxs[p] > currTupleOfIdxs[best]) 75 | best = p; 76 | } 77 | return best; 78 | } 79 | 80 | @Override 81 | public boolean hasNext() { 82 | if (nextTuple != null) 83 | return nextTuple == Boolean.TRUE; 84 | int p = findLargestMobileIndexPosition(); 85 | if (p == -1) { 86 | nextTuple = Boolean.FALSE; 87 | return false; 88 | } 89 | int q = currDirectionOfIndexes[p] ? p + 1 : p - 1; 90 | int tmp = currTupleOfIdxs[p]; 91 | boolean tmpD = currDirectionOfIndexes[p]; 92 | currTupleOfIdxs[p] = currTupleOfIdxs[q]; 93 | currDirectionOfIndexes[p] = currDirectionOfIndexes[q]; 94 | currTupleOfIdxs[q] = tmp; 95 | currDirectionOfIndexes[q] = tmpD; 96 | for (int i = 0; i < currDirectionOfIndexes.length; i++) 97 | if (currTupleOfIdxs[i] > tmp) 98 | currDirectionOfIndexes[i] = !currDirectionOfIndexes[i]; 99 | nextTuple = Boolean.TRUE; 100 | return true; 101 | } 102 | 103 | // @Override 104 | // public int[][] toArray() { 105 | // reset(); 106 | // int nPermutations = Utilities.factorial(values.length); 107 | // int[][] m = new int[nPermutations][values.length]; 108 | // int cnt = 0; 109 | // while (hasNext()) { 110 | // m[cnt] = next().clone(); 111 | // cnt++; 112 | // } 113 | // return Stream.of(m).sorted(Utilities.lexComparatorInt).toArray(int[][]::new); 114 | // } 115 | 116 | public static void main(String[] args) { 117 | new EnumerationOfPermutations(1, 2, 3, 4, 5).displayAllTuples(); 118 | new EnumerationOfPermutations(3).displayAllTuples(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/predicates/MatcherInterface.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.predicates; 2 | 3 | import static org.xcsp.common.Types.TypeExpr.ABS; 4 | import static org.xcsp.common.Types.TypeExpr.ADD; 5 | import static org.xcsp.common.Types.TypeExpr.EQ; 6 | import static org.xcsp.common.Types.TypeExpr.GE; 7 | import static org.xcsp.common.Types.TypeExpr.GT; 8 | import static org.xcsp.common.Types.TypeExpr.IN; 9 | import static org.xcsp.common.Types.TypeExpr.LE; 10 | import static org.xcsp.common.Types.TypeExpr.LONG; 11 | import static org.xcsp.common.Types.TypeExpr.LT; 12 | import static org.xcsp.common.Types.TypeExpr.MAX; 13 | import static org.xcsp.common.Types.TypeExpr.MIN; 14 | import static org.xcsp.common.Types.TypeExpr.MUL; 15 | import static org.xcsp.common.Types.TypeExpr.NE; 16 | import static org.xcsp.common.Types.TypeExpr.NEG; 17 | import static org.xcsp.common.Types.TypeExpr.NOT; 18 | import static org.xcsp.common.Types.TypeExpr.NOTIN; 19 | import static org.xcsp.common.Types.TypeExpr.SET; 20 | import static org.xcsp.common.Types.TypeExpr.SPECIAL; 21 | import static org.xcsp.common.Types.TypeExpr.SQR; 22 | import static org.xcsp.common.Types.TypeExpr.SUB; 23 | import static org.xcsp.common.Types.TypeExpr.VAR; 24 | import static org.xcsp.common.predicates.XNode.node; 25 | import static org.xcsp.common.predicates.XNode.specialLeaf; 26 | 27 | import java.util.function.BiPredicate; 28 | import java.util.stream.IntStream; 29 | import java.util.stream.Stream; 30 | 31 | import org.xcsp.common.IVar; 32 | 33 | /** 34 | * This interface is used to test if a specified (source) tree matches a predefined target tree. Some kind of abstraction can be used by means of special nodes. 35 | * 36 | * @author Christophe Lecoutre 37 | * 38 | */ 39 | public interface MatcherInterface { 40 | 41 | enum AbstractOperation { 42 | ariop, relop, setop, unalop, symop; // logop 43 | } 44 | 45 | XNodeLeaf any = specialLeaf("any"); 46 | XNodeLeaf anyc = specialLeaf("anyc"); // any under condition 47 | XNodeLeaf var = specialLeaf("var"); 48 | XNodeLeaf val = specialLeaf("val"); 49 | XNodeLeaf varOrVal = specialLeaf("var-or-val"); 50 | XNodeLeaf any_add_val = specialLeaf("any-add-val"); 51 | XNodeLeaf var_add_val = specialLeaf("var-add-val"); 52 | XNodeLeaf add_lastval = specialLeaf("add-lastval"); 53 | XNodeLeaf sub = specialLeaf("sub"); 54 | XNodeLeaf not = specialLeaf("not"); 55 | XNodeLeaf set_vals = specialLeaf("set-vals"); 56 | XNodeLeaf min_vars = specialLeaf("min-vars"); 57 | XNodeLeaf max_vars = specialLeaf("max-vars"); 58 | XNodeLeaf logic_vars = specialLeaf("logic-vars"); 59 | XNodeLeaf add_vars = specialLeaf("add-vars"); 60 | XNodeLeaf mul_vars = specialLeaf("mul-vars"); 61 | XNodeLeaf add_varOrVals = specialLeaf("add-varOrVals"); 62 | XNodeLeaf sub_varOrVals = specialLeaf("sub-varOrVals"); 63 | XNodeLeaf addOrSub_varOrVals = specialLeaf("addOrSub-varOrVals"); 64 | XNodeLeaf add_varsOrTerms = specialLeaf("add-mul-vals"); 65 | XNodeLeaf add_mulVars = specialLeaf("add-mul-vars"); 66 | XNodeLeaf add_varsOrTerms_valEnding = specialLeaf("add-mul-vals2"); 67 | XNodeLeaf or = specialLeaf("or"); 68 | 69 | XNodeLeaf trivial0 = specialLeaf("trivial0"); 70 | XNodeLeaf trivial1 = specialLeaf("trivial1"); 71 | 72 | Matcher x_add_k = new Matcher(node(ADD, var, val)); 73 | Matcher x_sub_k = new Matcher(node(SUB, var, val)); 74 | Matcher x_mul_k = new Matcher(node(MUL, var, val)); 75 | Matcher x_mul_y = new Matcher(node(MUL, var, var)); 76 | Matcher k_mul_x = new Matcher(node(MUL, val, var)); // used in some other contexts (when non canonized forms) 77 | 78 | Matcher x_ne_k = new Matcher(node(NE, var, val)); 79 | Matcher x_eq_k = new Matcher(node(EQ, var, val)); 80 | Matcher x_lt_k = new Matcher(node(LT, var, val)); 81 | Matcher x_le_k = new Matcher(node(LE, var, val)); 82 | Matcher k_le_x = new Matcher(node(LE, val, var)); 83 | Matcher x_ge_k = new Matcher(node(GE, var, val)); 84 | Matcher x_gt_k = new Matcher(node(GT, var, val)); 85 | 86 | Matcher x_ne_y = new Matcher(node(NE, var, var)); 87 | 88 | /** 89 | * Returns the target tree, which may possibly involve some form of abstraction by means of special nodes. 90 | * 91 | * @return the target tree 92 | */ 93 | abstract XNode target(); 94 | 95 | /** 96 | * Returns {@code true} if the specified node (considered at the specified level/depth) is valid with respect to the target tree when assuming that the 97 | * corresponding node in the target tree is a special node. 98 | * 99 | * @param node 100 | * a (source) node 101 | * @param level 102 | * the level/depth associated with the node 103 | * @return {@code true} if the specified source node is valid with respect to a corresponding special node in the target tree 104 | */ 105 | abstract boolean validForSpecialTargetNode(XNode node, int level); 106 | 107 | /** 108 | * Returns {@code true} if the specified source tree matches the specified target tree (at the specified level). 109 | * 110 | * @param source 111 | * the source (sub-)tree 112 | * @param target 113 | * the target (sub-)tree 114 | * @param level 115 | * the level/depth for the comparison 116 | * @return {@code true} if the specified source tree matches the specified target tree 117 | */ 118 | default boolean matching(XNode source, XNode target, int level) { 119 | // System.out.println("matching " + source.type + " vs " + target); 120 | if (target == any) // any node (i.e., full abstract node) => everything matches 121 | return true; 122 | if (target == anyc) // any node under condition (the difference with SPECIAL only, is that sons are not considered recursively) 123 | return validForSpecialTargetNode(source, level); 124 | if (target == var) { 125 | // System.out.println("var " + (source.type == VAR)); 126 | return source.type == VAR; 127 | } 128 | if (target == val) { 129 | // System.out.println("val " + (source.type == LONG)); 130 | return source.type == LONG; 131 | } 132 | if (target == varOrVal) 133 | return source.type == VAR || source.type == LONG; 134 | if (target == any_add_val) 135 | return source.type == ADD && source.sons.length == 2 && source.sons[1].type == LONG; 136 | if (target == var_add_val) 137 | return source.type == ADD && source.sons.length == 2 && source.sons[0].type == VAR && source.sons[1].type == LONG; 138 | if (target == add_lastval) 139 | return source.type == ADD && source.sons.length > 2 && source.sons[source.sons.length - 1].type == LONG; 140 | if (target == sub) 141 | return source.type == SUB; 142 | if (target == not) 143 | return source.type == NOT; 144 | if (target == set_vals) // abstract set => we control that source is either an empty set or a set built on only longs 145 | return source.type == SET && (source instanceof XNodeLeaf || Stream.of(source.sons).allMatch(s -> s.type == LONG)); 146 | if (target == min_vars) // abstract min => we control that source is a min built on only variables 147 | return source.type == MIN && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR); 148 | if (target == max_vars) // abstract max => we control that source is a max built on only variables 149 | return source.type == MAX && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR); 150 | if (target == logic_vars) 151 | return source.type.isLogicalOperator() && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR); 152 | if (target == add_vars) 153 | return source.type == ADD && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR); 154 | if (target == mul_vars) 155 | return source.type == MUL && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR); 156 | if (target == add_varOrVals) 157 | return source.type == ADD && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR || s.type == LONG); 158 | if (target == sub_varOrVals) 159 | return source.type == SUB && source.sons.length == 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR || s.type == LONG); 160 | if (target == addOrSub_varOrVals) 161 | return (source.type == ADD || source.type == SUB) && source.sons.length >= 2 162 | && Stream.of(source.sons).allMatch(s -> s.type == VAR || s.type == LONG); 163 | if (target == add_varsOrTerms) 164 | return source.type == ADD && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> s.type == VAR || x_mul_k.matches(s)); 165 | if (target == add_mulVars) 166 | return source.type == ADD && source.sons.length >= 2 && Stream.of(source.sons).allMatch(s -> x_mul_y.matches(s)); 167 | if (target == add_varsOrTerms_valEnding) 168 | return source.type == ADD && source.sons.length > 2 && source.sons[source.sons.length - 1].type == LONG 169 | && IntStream.range(0, source.sons.length - 1).allMatch(i -> source.sons[i].type == VAR || x_mul_k.matches(source.sons[i])); 170 | 171 | if (target == trivial0) // other trivial cases equivalent to 0 (false)? 172 | return source.type.oneOf(NE, LT, GT) && source.sons.length == 2 && source.sons[0].type == VAR && source.sons[1].type == VAR 173 | && ((XNodeLeaf) source.sons[0]).value == ((XNodeLeaf) source.sons[1]).value; 174 | 175 | if (target == trivial1) // other trivial cases equivalent to 1 (true)? 176 | return source.type.oneOf(EQ, LE, GE) && source.sons.length == 2 && source.sons[0].type == VAR && source.sons[1].type == VAR 177 | && ((XNodeLeaf) source.sons[0]).value == ((XNodeLeaf) source.sons[1]).value; 178 | 179 | if (target instanceof XNodeLeaf != source instanceof XNodeLeaf) 180 | return false; 181 | if (target.type != SPECIAL && target.type != source.type) 182 | return false; 183 | if (target.type == SPECIAL) { 184 | if (target instanceof XNodeParentSpecial) { 185 | AbstractOperation ao = AbstractOperation.valueOf(((XNodeParentSpecial) target).specialName); 186 | if (ao == AbstractOperation.ariop) 187 | if (!source.type.isArithmeticOperator()) 188 | return false; 189 | if (ao == AbstractOperation.relop) 190 | if (!source.type.isRelationalOperator()) 191 | return false; 192 | if (ao == AbstractOperation.setop) 193 | if (!source.type.oneOf(IN, NOTIN)) 194 | return false; 195 | if (ao == AbstractOperation.unalop) 196 | if (!source.type.oneOf(ABS, NEG, SQR, NOT)) 197 | return false; 198 | if (ao == AbstractOperation.symop) 199 | if (!source.type.oneOf(EQ, NE)) 200 | return false; 201 | } else if (!validForSpecialTargetNode(source, level)) 202 | return false; 203 | 204 | } 205 | if (target instanceof XNodeLeaf) 206 | return true; // it seems that we have no more control to do 207 | return target.sons.length == source.sons.length 208 | && IntStream.range(0, target.sons.length).allMatch(i -> matching(source.sons[i], target.sons[i], level + 1)); 209 | } 210 | 211 | /** 212 | * Returns {@code true} if the predefined target tree matches the specified (source) tree. 213 | * 214 | * @param tree 215 | * a tree 216 | * @return {@code true} if the predefined target tree matches the specified (source) tree 217 | */ 218 | default boolean matches(XNode tree) { 219 | return matching(tree, target(), 0); 220 | } 221 | 222 | /** 223 | * This class allows us to perform matching tests between trees. 224 | */ 225 | final class Matcher implements MatcherInterface { 226 | private final XNode target; 227 | 228 | private final BiPredicate, Integer> p; 229 | 230 | @Override 231 | public XNode target() { 232 | return target; 233 | } 234 | 235 | /** 236 | * Builds a {@code Matcher} object with the specified target tree. 237 | * 238 | * @param target 239 | * the target tree 240 | * @param p 241 | * a predicate used for special nodes in some occasions 242 | */ 243 | public Matcher(XNode target, BiPredicate, Integer> p) { 244 | this.target = target; 245 | this.p = p; 246 | } 247 | 248 | /** 249 | * Builds a {@code Matcher} object with the specified target tree. 250 | * 251 | * @param target 252 | * the target tree 253 | */ 254 | public Matcher(XNode target) { 255 | this(target, null); // (node, level) -> true); // (level == 0 && node.type.isRelationalOperator()) || (level == 1 && 256 | // node.type.isArithmeticOperator())); 257 | } 258 | 259 | @Override 260 | public boolean validForSpecialTargetNode(XNode node, int level) { 261 | return p == null || p.test(node, level); 262 | } 263 | } 264 | 265 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/predicates/XNodeLeaf.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 XCSP3 Team (contact@xcsp.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 6 | * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | * 8 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 12 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | */ 14 | package org.xcsp.common.predicates; 15 | 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.function.Function; 20 | import java.util.function.Predicate; 21 | import java.util.stream.IntStream; 22 | 23 | import org.xcsp.common.IVar; 24 | import org.xcsp.common.Types.TypeExpr; 25 | import org.xcsp.common.Utilities; 26 | import org.xcsp.common.domains.Values.Decimal; 27 | 28 | /** 29 | * The class used for representing a leaf node in a syntactic tree. 30 | * 31 | * @author Christophe Lecoutre 32 | */ 33 | public final class XNodeLeaf extends XNode { 34 | 35 | @Override 36 | public boolean equals(Object obj) { 37 | if (!(obj instanceof XNodeLeaf)) 38 | return false; 39 | return type == ((XNodeLeaf) obj).type && value.equals(((XNodeLeaf) obj).value); 40 | } 41 | 42 | @Override 43 | public int compareTo(XNode obj) { 44 | if (type != obj.type) 45 | return Integer.compare(type.ordinal(), obj.type.ordinal()); 46 | XNodeLeaf leaf = (XNodeLeaf) obj; 47 | if (type == TypeExpr.VAR) 48 | return ((IVar) value).id().compareTo(((IVar) leaf.value).id()); 49 | if (type == TypeExpr.PAR || type == TypeExpr.LONG) 50 | return Long.compare((long) value, (long) leaf.value); 51 | if (type == TypeExpr.SYMBOL) 52 | return ((String) value).compareTo((String) leaf.value); 53 | if (type == TypeExpr.SET) 54 | return 0; // because two empty sets 55 | throw new RuntimeException("Currently, this statement should not be reached."); 56 | } 57 | 58 | /** The (parsed) value of the node. it may be a variable, a decimal, a long, a parameter, a symbol or null for an empty set. */ 59 | public Object value; 60 | 61 | public Object oldValue; 62 | 63 | /** Builds a leaf node for a syntactic tree, with the specified type and the specified value. */ 64 | public XNodeLeaf(TypeExpr type, Object... value) { 65 | super(type, null); 66 | this.value = value[0]; 67 | if (value.length > 1) 68 | this.oldValue = value[1]; // ugly way of saving the old value when trees are transformed 69 | Utilities.control(type.arityMin == 0 && type.arityMax == 0 || (type == TypeExpr.SET || type == TypeExpr.SPECIAL), "Pb with this node " + type); 70 | } 71 | 72 | @Override 73 | public int size() { 74 | return 1; 75 | } 76 | 77 | @Override 78 | public int maxParameterNumber() { 79 | return type == TypeExpr.PAR ? ((Long) value).intValue() : -1; // recall that %... is not possible in predicates 80 | } 81 | 82 | @Override 83 | public XNode canonization() { 84 | return new XNodeLeaf(type, value); // we return a similar object 85 | } 86 | 87 | @Override 88 | public XNode abstraction(List args, boolean abstractIntegers, boolean multiOccurrences) { 89 | if (type == TypeExpr.VAR) { 90 | int pos = multiOccurrences ? IntStream.range(0, args.size()).filter(i -> args.get(i) == value).findFirst().orElse(-1) : -1; 91 | if (pos != -1) 92 | return new XNodeLeaf(TypeExpr.PAR, (long) pos); 93 | else { 94 | args.add(value); 95 | return new XNodeLeaf(TypeExpr.PAR, (long) (args.size() - 1)); // -1 because already added 96 | } 97 | } 98 | if (type == TypeExpr.LONG && abstractIntegers) { 99 | args.add(value); 100 | return new XNodeLeaf(TypeExpr.PAR, (long) (args.size() - 1)); // -1 because already added 101 | } 102 | return new XNodeLeaf(type, value); // we return a similar object 103 | } 104 | 105 | @Override 106 | public XNode concretization(Object[] args) { 107 | if (type != TypeExpr.PAR) 108 | return new XNodeLeaf(type, value); // we return a similar object 109 | Object arg = args[((Long) value).intValue()]; // we know that the value is a Long, which is a safe int 110 | if (arg instanceof Long) 111 | return new XNodeLeaf(TypeExpr.LONG, arg); 112 | if (arg instanceof Decimal) 113 | return new XNodeLeaf(TypeExpr.DECIMAL, arg); 114 | if (arg instanceof String) 115 | return new XNodeLeaf(TypeExpr.SYMBOL, arg); 116 | if (arg instanceof XNode) 117 | return (XNode) arg; 118 | return new XNodeLeaf(TypeExpr.VAR, arg); // kept at last position because it is complicated to check if arg is instance of V 119 | } 120 | 121 | @Override 122 | public XNode replaceSymbols(Map mapOfSymbols) { 123 | return type != TypeExpr.SYMBOL ? new XNodeLeaf(type, value) : new XNodeLeaf(TypeExpr.LONG, mapOfSymbols.get(value)); 124 | } 125 | 126 | @Override 127 | public XNode replaceLeafValues(Function f) { 128 | return new XNodeLeaf(type, f.apply(value), value); 129 | } 130 | 131 | @Override 132 | public XNode replacePartiallyParameters(Object[] valueParameters) { 133 | if (type != TypeExpr.PAR) 134 | return new XNodeLeaf(type, value); // we return a similar object 135 | int i = ((Long) value).intValue(); 136 | if (valueParameters[i] == null) { 137 | long offset = IntStream.range(0, i).filter(j -> valueParameters[j] != null).count(); 138 | return new XNodeLeaf(TypeExpr.PAR, Long.valueOf(i - offset)); // we return a parameter, with possibly a different number 139 | } 140 | if (valueParameters[i] instanceof Long) 141 | return new XNodeLeaf(TypeExpr.LONG, valueParameters[i]); 142 | Utilities.control(valueParameters[i] instanceof IVar, "Bad value of parameters"); 143 | return new XNodeLeaf(TypeExpr.VAR, valueParameters[i]); 144 | } 145 | 146 | @Override 147 | public XNode firstNodeSuchThat(Predicate> p) { 148 | return p.test(this) ? this : null; 149 | } 150 | 151 | @Override 152 | public LinkedList> allNodesSuchThat(Predicate> p, LinkedList> list) { 153 | if (p.test(this)) 154 | list.add(this); 155 | return list; 156 | } 157 | 158 | @Override 159 | public String toPostfixExpression(IVar[] scopeForAbstraction) { 160 | if (type == TypeExpr.VAR && scopeForAbstraction != null) 161 | return "%" + IntStream.range(0, scopeForAbstraction.length).filter(i -> scopeForAbstraction[i] == value).findFirst().getAsInt(); 162 | return type == TypeExpr.SET ? "0set" : value.toString(); 163 | } 164 | 165 | @Override 166 | public String toFunctionalExpression(Object[] argsForConcretization) { 167 | if (type == TypeExpr.PAR) 168 | return argsForConcretization == null ? "%" + value.toString() : argsForConcretization[((Long) value).intValue()].toString(); 169 | return type == TypeExpr.SET ? "set()" : value.toString(); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/predicates/XNodeParentSpecial.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.predicates; 2 | 3 | import org.xcsp.common.IVar; 4 | import org.xcsp.common.Types.TypeExpr; 5 | 6 | public final class XNodeParentSpecial extends XNodeParent { 7 | 8 | public final String specialName; 9 | 10 | public XNodeParentSpecial(String specialName, XNode son1, XNode son2) { 11 | super(TypeExpr.SPECIAL, son1, son2); 12 | this.specialName = specialName; 13 | } 14 | 15 | public XNodeParentSpecial(String specialName, XNode son) { 16 | super(TypeExpr.SPECIAL, son); 17 | this.specialName = specialName; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/AbstractTuple.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | import java.util.stream.Collectors; 4 | import java.util.stream.IntStream; 5 | import java.util.stream.Stream; 6 | 7 | import org.xcsp.common.Condition; 8 | import org.xcsp.common.Condition.ConditionIntset; 9 | import org.xcsp.common.Condition.ConditionIntvl; 10 | import org.xcsp.common.Condition.ConditionPar; 11 | import org.xcsp.common.Condition.ConditionSet; 12 | import org.xcsp.common.Condition.ConditionVal; 13 | import org.xcsp.common.Condition.ConditionVar; 14 | import org.xcsp.common.Constants; 15 | import org.xcsp.common.Utilities; 16 | 17 | public interface AbstractTuple { 18 | 19 | boolean match(int[] tuple); 20 | 21 | public static class OrdinaryTuple implements AbstractTuple { 22 | public int[] values; 23 | 24 | public OrdinaryTuple(int[] values) { 25 | this.values = values; 26 | } 27 | 28 | @Override 29 | public boolean match(int[] t) { 30 | assert t.length == values.length; 31 | return IntStream.range(0, t.length).allMatch(i -> values[i] == Constants.STAR || t[i] == Constants.STAR || values[i] == t[i]); 32 | } 33 | 34 | public String toString() { 35 | return Utilities.join(values); 36 | } 37 | } 38 | 39 | public static class HybridTuple implements AbstractTuple { 40 | public Object[] values; // either Integer or Condition objects inside the array 41 | 42 | public HybridTuple(Object[] values) { 43 | this.values = values; 44 | for (int i = 0; i < values.length; i++) { 45 | // System.out.println("ddd " + values[i] + " " + values[i].getClass()); 46 | if (values[i] instanceof Long) 47 | values[i] = ((Long) values[i]).intValue(); 48 | } 49 | Utilities.control(Stream.of(values).allMatch(v -> v instanceof Integer || v instanceof ConditionVal || v instanceof ConditionSet 50 | || v instanceof ConditionVar || v instanceof ConditionPar), "Bad form for smart tuple " + Utilities.join(values)); 51 | } 52 | 53 | @Override 54 | public boolean match(int[] t) { 55 | assert t.length == values.length; 56 | for (int i = 0; i < t.length; i++) { 57 | if (values[i] instanceof Integer) { 58 | int v = ((Integer) values[i]); 59 | if (v != Constants.STAR && t[i] != Constants.STAR && v != t[i]) 60 | return false; 61 | } else { 62 | Condition condition = (Condition) values[i]; 63 | if (condition instanceof ConditionVal) { 64 | if (((ConditionVal) condition).operator.isValidFor(t[i], ((ConditionVal) condition).k) == false) 65 | return false; 66 | } else if (condition instanceof ConditionIntvl) { 67 | if (((ConditionIntvl) condition).operator.isValidFor(t[i], ((ConditionIntvl) condition).min, ((ConditionIntvl) condition).max) == false) 68 | return false; 69 | } else if (condition instanceof ConditionIntset) { 70 | if (((ConditionIntset) condition).operator.isValidFor(t[i], ((ConditionIntset) condition).t) == false) 71 | return false; 72 | } else 73 | throw new AssertionError("Not implemented"); 74 | } 75 | } 76 | return true; 77 | } 78 | 79 | public String toString() { 80 | return "(" + Stream.of(values).map(v -> v instanceof Integer && (Integer) v == Constants.STAR ? Constants.STAR_SYMBOL : v.toString()) 81 | .collect(Collectors.joining(",")) + ")"; 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/Automaton.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.common.structures; 10 | 11 | import java.util.LinkedHashSet; 12 | import java.util.Set; 13 | import java.util.stream.Collectors; 14 | import java.util.stream.Stream; 15 | 16 | import org.xcsp.common.Utilities; 17 | 18 | /** 19 | * This class allows us to represent finite automatons that are useful for posting {@code regular} constraints. An 20 | * automaton is composed of an initial state, a finite set of final states and a finite set of transitions. 21 | */ 22 | public final class Automaton { 23 | /** 24 | * The start (initial) state of the automaton. 25 | */ 26 | public final String startState; 27 | 28 | /** 29 | * The set (array) of transitions. Each transition is an object composed of a first state, a symbol (that may be an 30 | * integer or a string) and a second state that is reached from the first state after reading the symbol. 31 | */ 32 | public final Transition[] transitions; 33 | 34 | /** 35 | * The set (array) of final states of the automaton, i.e., accepting stated of the automaton. 36 | */ 37 | public final String[] finalStates; 38 | 39 | /** 40 | * Cache used for storing the fact that the automaton is deterministic or not 41 | */ 42 | private Boolean deterministic; 43 | 44 | /** 45 | * Constructs an automaton from the specified arguments. 46 | * 47 | * @param startState 48 | * the start state of the automaton 49 | * @param transitions 50 | * the set (array) of transitions where each transition is an object composed of a first state, a symbol 51 | * (that may be an integer or a string) and a second state that is reached from the first state after 52 | * reading the symbol 53 | * @param finalStates 54 | * the set (array) of final states of the automaton, i.e., accepting stated of the automaton 55 | */ 56 | public Automaton(String startState, Transition[] transitions, String... finalStates) { 57 | this.startState = startState; 58 | this.transitions = transitions; 59 | this.finalStates = finalStates; 60 | } 61 | 62 | /** 63 | * Constructs an automaton from the specified arguments. 64 | * 65 | * @param startState 66 | * the start state of the automaton 67 | * @param transitions 68 | * the object encapsulating the list of transitions where each transition is an object composed of a 69 | * first state, a symbol (that may be an integer or a string) and a second state that is reached from the 70 | * first state after reading the symbol 71 | * @param finalStates 72 | * the set (array) of final states of the automaton, i.e., accepting stated of the automaton 73 | */ 74 | public Automaton(String startState, Transitions transitions, String... finalStates) { 75 | this(startState, transitions.toArray(), finalStates); 76 | } 77 | 78 | /** 79 | * Constructs an automaton from the specified regular expression, given as a string. 80 | * 81 | * @param expression 82 | * the expression representing a regular expression. 83 | */ 84 | public Automaton(String expression) { 85 | Utilities.exit("Unimplemented code; converting regular expressions into an automaton"); 86 | this.startState = null; 87 | this.transitions = null; 88 | this.finalStates = null; 89 | } 90 | 91 | public boolean _isDeterministic() { 92 | Set encountered = new LinkedHashSet<>(); 93 | for (Transition tr : transitions) 94 | if (tr.value instanceof int[]) { 95 | for (int v : (int[]) tr.value) { 96 | if (encountered.contains(tr.start + " " + v)) 97 | return false; 98 | encountered.add(tr.start + " " + v); 99 | } 100 | } else { 101 | if (encountered.contains(tr.start + " " + tr.value)) 102 | return false; 103 | encountered.add(tr.start + " " + tr.value); 104 | } 105 | return true; 106 | } 107 | 108 | public boolean isDeterministic() { 109 | if (deterministic == null) 110 | deterministic = _isDeterministic(); 111 | return deterministic; 112 | } 113 | 114 | @Override 115 | public String toString() { 116 | return "startState=" + startState + " finalStates={" + Utilities.join(finalStates) + "} " + "\ntransitions={" 117 | + Stream.of(transitions).map(t -> t.toString()).collect(Collectors.joining()) + "}"; 118 | } 119 | 120 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/Table.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | import static org.xcsp.common.Constants.STAR; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.List; 9 | import java.util.Set; 10 | import java.util.TreeSet; 11 | import java.util.function.BiFunction; 12 | import java.util.function.Function; 13 | import java.util.stream.Collectors; 14 | import java.util.stream.IntStream; 15 | import java.util.stream.Stream; 16 | 17 | import org.xcsp.common.Constants; 18 | import org.xcsp.common.Range; 19 | import org.xcsp.common.Range.Rangesx2; 20 | import org.xcsp.common.Utilities; 21 | import org.xcsp.common.enumerations.EnumerationCartesian; 22 | 23 | /** 24 | * This class allows us to represent integer tables that are useful objects when defining {@code extension} constraints. 25 | */ 26 | public class Table extends TableAbstract { 27 | 28 | /** 29 | * Returns an array of tuples in lexicographic order, and without any duplicates. 30 | * 31 | * @param tuples 32 | * an array of tuples 33 | * @return an array of tuples in lexicographic order, and without any duplicates 34 | */ 35 | public static int[][] clean(int[]... tuples) { 36 | Set set = new TreeSet<>(Utilities.lexComparatorInt); 37 | for (int i = 0; i < tuples.length - 1; i++) 38 | if (set.size() > 0) 39 | set.add(tuples[i]); 40 | else if (Utilities.lexComparatorInt.compare(tuples[i], tuples[i + 1]) >= 0) 41 | for (int j = 0; j <= i; j++) 42 | set.add(tuples[j]); 43 | if (set.size() > 0) 44 | set.add(tuples[tuples.length - 1]); 45 | return set.size() == 0 ? tuples : set.stream().toArray(int[][]::new); 46 | } 47 | 48 | /** 49 | * Returns an array of tuples in lexicographic order, and without any duplicates. 50 | * 51 | * @param tuples 52 | * a list of tuples 53 | * @return an array of tuples in lexicographic order, and without any duplicates 54 | */ 55 | public static int[][] clean(List tuples) { 56 | return clean(tuples.stream().toArray(int[][]::new)); 57 | } 58 | 59 | public static int[][] toOrdinaryTable(int[][] shortTable, int[][] values) { 60 | List tuples = new ArrayList<>(); 61 | for (int[] t : shortTable) { 62 | int[] pos = IntStream.range(0, t.length).filter(i -> t[i] == STAR).toArray(); 63 | if (pos.length == 0) 64 | tuples.add(t.clone()); 65 | else { 66 | EnumerationCartesian ec = new EnumerationCartesian( 67 | IntStream.range(0, t.length).mapToObj(i -> t[i] == STAR ? values[i] : new int[] { t[i] }).toArray(int[][]::new)); 68 | while (ec.hasNext()) 69 | tuples.add(ec.next().clone()); 70 | } 71 | } 72 | return tuples.stream().sorted(Utilities.lexComparatorInt).distinct().toArray(int[][]::new); 73 | // return Kit.intArray2D(tuples); 74 | } 75 | 76 | public static int[][] toOrdinaryTable(int[][] shortTable, int... nValues) { 77 | return toOrdinaryTable(shortTable, IntStream.of(nValues).mapToObj(i -> IntStream.range(0, i).toArray()).toArray(int[][]::new)); 78 | } 79 | 80 | @Override 81 | public Table positive(Boolean positive) { 82 | this.positive = positive; 83 | return this; 84 | } 85 | 86 | private List list = new ArrayList<>(); 87 | 88 | @Override 89 | public int size() { 90 | return list.size(); 91 | } 92 | 93 | private Table addTuple(int[] tuple) { 94 | Utilities.control(tuple != null && tuple.length > 0, "The tuple has a bad length"); 95 | Utilities.control(list.size() == 0 || list.get(0).length == tuple.length, "The tuple has a different length from those already recorded"); 96 | list.add(tuple); 97 | return this; 98 | } 99 | 100 | /** 101 | * Adds an integer tuple to the table. 102 | * 103 | * @param val 104 | * the first integer of the specified tuple 105 | * @param otherVals 106 | * the orther integers of the specified tuple 107 | * @return this integer table 108 | */ 109 | public Table add(int val, int... otherVals) { 110 | return addTuple(IntStream.range(0, otherVals.length + 1).map(i -> i == 0 ? val : otherVals[i - 1]).toArray()); 111 | } 112 | 113 | // /** 114 | // * Adds an integer tuple to the table if the condition evaluates to {@code true} 115 | // * 116 | // * @param condition 117 | // * a Boolean condition 118 | // * @param tuple 119 | // * an integer tuple 120 | // * @return this integer table 121 | // */ 122 | // public Table addIf(boolean condition, int... tuple) { 123 | // return condition ? add(tuple) : this; 124 | // } 125 | 126 | /** 127 | * Adds the specified integer tuples to the table. 128 | * 129 | * @param tuples 130 | * a sequence of other tuples 131 | * @return this integer table 132 | */ 133 | public Table add(int[]... tuples) { 134 | Stream.of(tuples).forEach(t -> addTuple(t)); 135 | return this; 136 | } 137 | 138 | /** 139 | * Adds all tuples of the specified stream to the table. 140 | * 141 | * @param stream 142 | * a stream of tuples to be added to the table 143 | * @return this integer table 144 | */ 145 | public Table add(Stream stream) { 146 | return add(stream.toArray(int[][]::new)); 147 | } 148 | 149 | /** 150 | * Adds all tuples of the specified collection to the table. 151 | * 152 | * @param tuples 153 | * a collection of tuples to be added to the table 154 | * @return this integer table 155 | */ 156 | public Table add(Collection tuples) { 157 | return add(tuples.toArray(new int[0][])); 158 | } 159 | 160 | /** 161 | * Adds all tuples of the specified table to this table. 162 | * 163 | * @param table 164 | * another table 165 | * @return this integer table 166 | */ 167 | public Table add(Table table) { 168 | return add(table.toArray()); 169 | } 170 | 171 | /** 172 | * Adds the tuples obtained after parsing the specified string. The string must represent a sequence of tuples as defined in XCSP3. For example, 173 | * it could be {@code "(0,0,1)(0,2,0)(1,0,1)(1,1,2)"}. 174 | * 175 | * @param s 176 | * a string representing a sequence of integer tuples 177 | * @return this integer table 178 | */ 179 | public Table add(String s) { 180 | boolean b = controlStringRepresentationOfTuples(s); 181 | Utilities.control(b, "The specified string is not correct, as it does not correspond to a sequence of integer tuples"); 182 | int[][] tuples = Stream.of(s.split(Constants.DELIMITER_LISTS)).skip(1) 183 | .map(tok -> Stream.of(tok.split("\\s*,\\s*")).mapToInt(v -> v.equals(Constants.STAR_SYMBOL) ? STAR : Integer.parseInt(v)).toArray()) 184 | .toArray(int[][]::new); 185 | Stream.of(tuples).forEach(tuple -> addTuple(tuple)); 186 | return this; 187 | } 188 | 189 | public Table addFrom(Range r, Function f) { 190 | r.stream().mapToObj(i -> f.apply(i)).filter(t -> t != null).forEach(t -> add(t)); 191 | return this; 192 | } 193 | 194 | public Table addFrom(Rangesx2 r2, BiFunction f) { 195 | for (int i : r2.items[0]) 196 | for (int j : r2.items[1]) { 197 | int[] t = f.apply(i, j); 198 | if (t != null) 199 | add(t); 200 | } 201 | return this; 202 | } 203 | 204 | private int[] intersectionOf(int[] t1, int[] t2, int[] out) { 205 | assert t1.length == t2.length; 206 | for (int i = 0; i < t1.length; i++) { 207 | if (t1[i] == t2[i]) 208 | out[i] = t1[i]; 209 | else if (t1[i] == STAR) 210 | out[i] = t2[i]; 211 | else if (t2[i] == STAR) 212 | out[i] = t1[i]; 213 | else 214 | return null; 215 | } 216 | return out; 217 | } 218 | 219 | public Table intersectionWith(Table other) { 220 | Utilities.control(positive && other.positive, "Tables must be both positive"); 221 | int[][] m1 = this.toArray(); 222 | int[][] m2 = other.toArray(); 223 | Utilities.control(m1[0].length == m2[0].length, "Not the same arity"); 224 | if (m1.length > m2.length) { 225 | int[][] m = m1; 226 | m1 = m2; 227 | m2 = m; 228 | } 229 | int[] tmp = new int[m1[0].length]; 230 | Set setOfSupports = new TreeSet<>(Utilities.lexComparatorInt); 231 | for (int[] t1 : m1) { 232 | IntStream.range(0, tmp.length).forEach(i -> tmp[i] = t1[i] == STAR ? Integer.MIN_VALUE : t1[i]); // we compute tmp from t1 233 | int index = Arrays.binarySearch(m2, tmp, Utilities.lexComparatorInt); 234 | if (index >= 0) 235 | setOfSupports.add(t1.clone()); 236 | else { 237 | for (int i = -index - 1; i < m2.length; i++) { 238 | // if (Utilities.lexicographicInt.compare(lowerTuple(m2[i], tmp), t1) > 0) break; else 239 | if (intersectionOf(t1, m2[i], tmp) != null) 240 | setOfSupports.add(tmp.clone()); 241 | } 242 | } 243 | } 244 | return new Table().add(setOfSupports.stream()); // .toArray(new int[setOfSupports.size()][]); 245 | } 246 | 247 | public Table addColumnWithValue(int position, int value) { 248 | int[][] m = this.toArray(); 249 | Utilities.control(0 <= position && position <= m[0].length, "bad value of column position"); 250 | return new Table().add(IntStream.range(0, m.length) 251 | .mapToObj(i -> IntStream.range(0, m[0].length + 1).map(j -> j < position ? m[i][j] : j == position ? STAR : m[i][j - 1]).toArray())); 252 | } 253 | 254 | /** 255 | * Returns a 2-dimensional array corresponding to the collected tuples. Tuples are sorted and made distinct. 256 | * 257 | * @return a 2-dimensional array corresponding to the collected tuples 258 | */ 259 | public int[][] toArray() { 260 | return list.stream().sorted(Utilities.lexComparatorInt).distinct().toArray(int[][]::new); 261 | } 262 | 263 | public int[][] toOrdinaryTableArray(int[][] values) { 264 | return Table.toOrdinaryTable(toArray(), values); 265 | } 266 | 267 | public int[][] toOrdinaryTableArray(int... nValues) { 268 | return Table.toOrdinaryTable(toArray(), nValues); 269 | } 270 | 271 | @Override 272 | public String toString() { 273 | return list.stream().map(t -> "(" + Utilities.join(t, ",") + ")").collect(Collectors.joining(" ")); 274 | } 275 | 276 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/TableAbstract.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | import java.util.stream.Stream; 4 | 5 | import org.xcsp.common.Utilities; 6 | 7 | /** 8 | * This class allows us to represent tables that are useful objects when defining {@code extension} constraints. 9 | */ 10 | public abstract class TableAbstract { 11 | 12 | public final String TABLE_SYNTAX_PB = "The syntax used for listing tuples is not correct.\n" 13 | + "For example, this should be (1,2)(2,1)(2,3) for an integer table and (a,b)(b,b)(c,a) for a symbolic table"; 14 | 15 | public Boolean positive = Boolean.TRUE; 16 | 17 | /** 18 | * Sets if the table is positive (i.e, contains supports) or negative (i.e., contains conflicts) 19 | * 20 | * @param positive 21 | * a Boolean value indicating if the table is positive ({@code true}) or negative ({@code false}) 22 | * @return this table 23 | */ 24 | public TableAbstract positive(Boolean positive) { 25 | this.positive = positive; 26 | return this; 27 | } 28 | 29 | /** 30 | * Returns the number of tuples in this table 31 | * 32 | * @return the number of tuples in this table 33 | */ 34 | public abstract int size(); 35 | 36 | /** 37 | * Controls that the string is well-formed. The string must represent a sequence of tuples as defined in XCSP3. For example, it could be 38 | * {@code "(0,0,1)(0,2,0)(1,0,1)(1,1,2)"} when tuples are integer or {@code "(a,a,b)(a,c,a)(b,a,b)(b,b,c)"} when tuples are symbolic. 39 | * 40 | * @param tuples 41 | * a string representing a sequence of tuples 42 | * @return {@code true} if the tuples are integer 43 | */ 44 | protected boolean controlStringRepresentationOfTuples(String tuples) { 45 | tuples = tuples.trim(); 46 | Utilities.control(tuples.length() != 0, "The string is empty"); 47 | Utilities.control(tuples.charAt(0) == '(' && tuples.charAt(tuples.length() - 1) == ')', "Parentheses are not correct in " + tuples); 48 | String[] toks = tuples.substring(1, tuples.indexOf(")")).split("\\s*,\\s*"); 49 | Utilities.control(Stream.of(toks).anyMatch(tok -> !tok.equals("*")), "The tuple only contains *"); 50 | return Stream.of(toks).anyMatch(tok -> Utilities.isInteger(tok)); 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/TableSymbolic.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Set; 6 | import java.util.TreeSet; 7 | import java.util.stream.Stream; 8 | 9 | import org.xcsp.common.Constants; 10 | import org.xcsp.common.Utilities; 11 | 12 | public class TableSymbolic extends TableAbstract { 13 | 14 | /** 15 | * Returns an array of tuples in lexicographic order, and without any duplicates. 16 | * 17 | * @param tuples 18 | * an array of tuples 19 | * @return an array of tuples in lexicographic order, and without any duplicates 20 | */ 21 | public static String[][] clean(String[][] tuples) { 22 | Set set = new TreeSet<>(Utilities.lexComparatorString); 23 | for (int i = 0; i < tuples.length - 1; i++) 24 | if (set.size() > 0) 25 | set.add(tuples[i]); 26 | else if (Utilities.lexComparatorString.compare(tuples[i], tuples[i + 1]) >= 0) 27 | for (int j = 0; j <= i; j++) 28 | set.add(tuples[j]); 29 | if (set.size() > 0) 30 | set.add(tuples[tuples.length - 1]); 31 | return set.size() == 0 ? tuples : set.stream().toArray(String[][]::new); 32 | } 33 | 34 | public static String[][] clean(List tuples) { 35 | return clean(tuples.stream().toArray(String[][]::new)); 36 | } 37 | 38 | @Override 39 | public TableSymbolic positive(Boolean positive) { 40 | this.positive = positive; 41 | return this; 42 | } 43 | 44 | private List list = new ArrayList<>(); 45 | 46 | @Override 47 | public int size() { 48 | return list.size(); 49 | } 50 | 51 | /** 52 | * Adds the specified symbolic tuple to the table. 53 | * 54 | * @param tuple 55 | * a symbolic tuple 56 | * @return this symbolic table 57 | */ 58 | public TableSymbolic add(String... tuple) { 59 | Utilities.control(tuple.length > 0, "A tuple of length 0 has been encoutered during parsing.\n" + TABLE_SYNTAX_PB); 60 | Utilities.control(list.size() == 0 || list.get(0).length == tuple.length, "The tuple has a different length from those already recorded"); 61 | list.add(tuple); 62 | return this; 63 | } 64 | 65 | /** 66 | * Adds the specified symbolic tuples to the table. 67 | * 68 | * @param tuples 69 | * a sequence of tuples 70 | * @return this symbolic table 71 | */ 72 | public TableSymbolic add(String[]... tuples) { 73 | Stream.of(tuples).forEach(t -> add(t)); 74 | return this; 75 | } 76 | 77 | /** 78 | * Adds all tuples of the specified stream to the table. 79 | * 80 | * @param stream 81 | * a stream of tuples to be added to the table 82 | * @return this symbolic table 83 | */ 84 | public TableSymbolic add(Stream stream) { 85 | stream.forEach(t -> add(t)); 86 | return this; 87 | } 88 | 89 | /** 90 | * Adds the tuples obtained after parsing the specified string. The string must represent a sequence of tuples as defined in XCSP3. For example, 91 | * it could be {@code "(a,a,b)(a,c,a)(b,a,b)(b,b,c)"}. 92 | * 93 | * @param s 94 | * a string representing a sequence of tuples 95 | * @return this symbolic table 96 | */ 97 | public TableSymbolic addSequence(String s) { 98 | boolean b = controlStringRepresentationOfTuples(s); 99 | Utilities.control(!b, "The specified string is not correct, as it does not correspond to a sequence of symbolic tuples"); 100 | String[][] tuples = Stream.of(s.split(Constants.DELIMITER_LISTS)).skip(1).map(tok -> Stream.of(tok.split("\\s*,\\s*")).toArray(String[]::new)) 101 | .toArray(String[][]::new); 102 | Stream.of(tuples).forEach(tuple -> add(tuple)); 103 | return this; 104 | } 105 | 106 | /** 107 | * Returns a 2-dimensional array corresponding to the collected tuples. 108 | * 109 | * @return a 2-dimensional array corresponding to the collected tuples 110 | */ 111 | public String[][] toArray() { 112 | return list.stream().sorted(Utilities.lexComparatorString).distinct().toArray(String[][]::new); 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/Transition.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | /** 4 | * This class allows us to represent a transition that is a useful object when defining finite automatons. 5 | */ 6 | public class Transition { 7 | 8 | /** 9 | * The source state, where the transition begins. 10 | */ 11 | public String start; 12 | 13 | /** 14 | * The value (object) labeling the transition. 15 | */ 16 | public Object value; 17 | 18 | /** 19 | * The target state, where the transition ends. 20 | */ 21 | public String end; 22 | 23 | /** 24 | * Constructs a transition from the specified arguments. 25 | * 26 | * @param firstState 27 | * the first state, where the transition begins 28 | * @param symbol 29 | * the symbol labeling the transition 30 | * @param secondState 31 | * the second state, where the transition ends 32 | */ 33 | public Transition(String firstState, Object symbol, String secondState) { 34 | this.start = firstState; 35 | this.value = symbol; 36 | this.end = secondState; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "(" + start + "," + value.toString() + "," + end + ")"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/common/structures/Transitions.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.common.structures; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import java.util.stream.IntStream; 7 | import java.util.stream.Stream; 8 | 9 | import org.xcsp.common.Constants; 10 | import org.xcsp.common.Range; 11 | import org.xcsp.common.Utilities; 12 | 13 | /** 14 | * An object encapsulating a list of transitions. This is sometimes useful when defining finite automatons. 15 | */ 16 | public final class Transitions { 17 | 18 | /** 19 | * Parses the specified string and returns an object {@code Transitions} that contains a list of transitions. The string must represent a sequence 20 | * of transitions as defined in XCSP3. For example, it could be {@code "(q0,0,q2)(q0,1,q3)(q1,0,q3)(q2,1,q3)"} when symbols are defined by 21 | * integers or {@code "(q0,a,q2)(q0,b,q3)(q1,a,q3)(q2,b,q3)"} when symbols are defined by strings. 22 | * 23 | * @param transitions 24 | * a string representing a sequence of transitions 25 | * @return an object {@code Transitions} containing a list of transitions after parsing the specified argument 26 | */ 27 | public static Transitions parse(String transitions) { 28 | return new Transitions().add(transitions); 29 | } 30 | 31 | private List list = new ArrayList<>(); 32 | 33 | /** 34 | * Adds transitions to this object. 35 | * 36 | * @param transitions 37 | * a string representing a sequence of transitions 38 | * @return this object (for chaining) 39 | */ 40 | public Transitions add(String transitions) { 41 | Stream st = Stream.of(transitions.trim().split(Constants.DELIMITER_LISTS)).skip(1); 42 | st.forEach(tok -> { 43 | String[] t = tok.split("\\s*,\\s*"); 44 | Utilities.control(t.length == 3, "Pb with a transition, which is not formed of 3 pieces"); 45 | add(t[0], Utilities.isInteger(t[1]) ? Integer.parseInt(t[1]) : t[1], t[2]); 46 | }); 47 | return this; 48 | } 49 | 50 | /** 51 | * Adds a transition to this object. 52 | * 53 | * @param transition 54 | * a transition to be added 55 | * @return this object (for chaining) 56 | */ 57 | public Transitions add(Transition transition) { 58 | list.add(transition); 59 | return this; 60 | } 61 | 62 | /** 63 | * Adds transitions from a stream to this object. 64 | * 65 | * @param transitions 66 | * a stream of transitions 67 | * @return this object (for chaining) 68 | */ 69 | public Transitions add(Stream transitions) { 70 | transitions.forEach(t -> add(t)); 71 | return this; 72 | } 73 | 74 | /** 75 | * Adds a transition to this object. 76 | * 77 | * @param firstState 78 | * the first state, where the transition begins 79 | * @param symbol 80 | * the symbol labeling the transition 81 | * @param secondState 82 | * the second state, where the transition ends 83 | * @return this object (for chaining) 84 | */ 85 | public Transitions add(String firstState, Object symbol, String secondState) { 86 | return add(new Transition(firstState, symbol, secondState)); 87 | } 88 | 89 | /** 90 | * Adds some transitions to this object, one for each (integer) symbol. 91 | * 92 | * @param firstState 93 | * the first state, where the transition begins 94 | * @param symbols 95 | * the different symbols (here, integers) labeling the transition 96 | * @param secondState 97 | * the second state, where the transition ends 98 | * @return this object (for chaining) 99 | */ 100 | public Transitions add(String firstState, int[] symbols, String secondState) { 101 | IntStream.of(symbols).forEach(v -> add(new Transition(firstState, v, secondState))); 102 | return this; 103 | } 104 | 105 | /** 106 | * Adds some transitions to this object, one for each (integer) symbol contained in the specified range. 107 | * 108 | * @param firstState 109 | * the first state, where the transition begins 110 | * @param range 111 | * the different symbols (here, integers contained in the range) labeling the transition 112 | * @param secondState 113 | * the second state, where the transition ends 114 | * @return this object (for chaining) 115 | */ 116 | public Transitions add(String firstState, Range range, String secondState) { 117 | add(firstState, range.toArray(), secondState); 118 | return this; 119 | } 120 | 121 | /** 122 | * Returns an array with collected objects {@code Transition} 123 | * 124 | * @return an array with collected objects {@code Transition} 125 | */ 126 | public Transition[] toArray() { 127 | return list.stream().toArray(Transition[]::new); 128 | } 129 | 130 | @Override 131 | public String toString() { 132 | return list.stream().map(t -> t.toString()).collect(Collectors.joining()); 133 | } 134 | 135 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/definitions/DefXCSP.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.definitions; 2 | 3 | import java.util.AbstractMap.SimpleEntry; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.IntStream; 9 | import java.util.stream.Stream; 10 | 11 | import org.xcsp.common.Utilities; 12 | 13 | public class DefXCSP { 14 | 15 | /** 16 | * Name of the element (constraint or objective). For example, this may be {@code allDifferent}, {@code regular}, or {@code extension}. 17 | */ 18 | public String name; 19 | 20 | /** 21 | * Attributes associated with the constraint. Some of them can be useful for defining the semantics. 22 | */ 23 | public List> attributes = new ArrayList<>(); 24 | 25 | /** 26 | * Parameters of the constraint, seen as children (sons) of the constraint. 27 | */ 28 | public List sons = new ArrayList<>(); 29 | 30 | public boolean possibleSimplification; // true if simplified XCSP form is possible 31 | 32 | public Map map; 33 | 34 | private String print(List> list) { 35 | return list.size() == 0 ? "" : " (" + list.stream().map(a -> a.getKey() + "='" + a.getValue() + "'").collect(Collectors.joining(" ")) + ")"; 36 | } 37 | 38 | private boolean same(List> list1, List> list2) { 39 | return list1.size() == list2.size() && IntStream.range(0, list1.size()) 40 | .allMatch(i -> list1.get(i).getKey().equals(list2.get(i).getKey()) && list1.get(i).getValue().equals(list2.get(i).getValue())); 41 | } 42 | 43 | public class Son { 44 | public String name; 45 | public Object content; 46 | public List> attributes = new ArrayList<>(); 47 | 48 | public Son(String name, Object content) { 49 | this.name = name; 50 | this.content = content; 51 | } 52 | 53 | public Son(String name, Object content, String attName, Object attValue) { 54 | this(name, content); 55 | attributes.add(new SimpleEntry<>(attName, attValue)); 56 | } 57 | 58 | public Son(String name, Object content, String attName1, Object attValue1, String attName2, Object attValue2) { 59 | this(name, content); 60 | attributes.add(new SimpleEntry<>(attName1, attValue1)); 61 | attributes.add(new SimpleEntry<>(attName2, attValue2)); 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return name + " : " + content.toString() + print(attributes); 67 | } 68 | } 69 | 70 | public DefXCSP(String name, boolean possibleSimplification, Map map) { 71 | this.name = name; 72 | this.possibleSimplification = possibleSimplification; 73 | this.map = map; 74 | } 75 | 76 | public DefXCSP(String name, Map map) { 77 | this(name, true, map); 78 | } 79 | 80 | public DefXCSP(String name) { 81 | this(name, true, null); 82 | } 83 | 84 | public DefXCSP addSon(String name, Object content) { 85 | Utilities.control(content != null, "Pb"); 86 | sons.add(new Son(name, content)); 87 | return this; 88 | } 89 | 90 | public DefXCSP addSon(String name, Object content, String attName, Object attValue) { 91 | Utilities.control(content != null && attValue != null, "Pb"); 92 | sons.add(new Son(name, content, attName, attValue)); 93 | return this; 94 | } 95 | 96 | public DefXCSP addSon(String name, Object content, String attName1, Object attValue1, String attName2, Object attValue2) { 97 | Utilities.control(content != null && attValue1 != null && attValue2 != null, "Pb"); 98 | sons.add(new Son(name, content, attName1, attValue1, attName2, attValue2)); 99 | return this; 100 | } 101 | 102 | public DefXCSP add(String... params) { 103 | Stream.of(params).filter(param -> map.get(param) != null).forEach(param -> sons.add(new Son(param, map.get(param)))); 104 | return this; 105 | } 106 | 107 | public DefXCSP addConditional(String param) { 108 | return map.containsKey(param) ? add(param) : this; 109 | } 110 | 111 | public DefXCSP addOne(String key) { 112 | if (key.equals(ICtr.MATRIX)) { 113 | possibleSimplification = false; 114 | return add(key); 115 | } 116 | String lifted = key.equals(ICtr.LISTS) ? ICtr.LIST : key.equals(ICtr.SETS) ? ICtr.SET : key.equals(ICtr.MSETS) ? ICtr.MSET : null; 117 | if (lifted == null) 118 | return add(key); 119 | Stream.of((Object[]) map.get(lifted + "s")).forEach(o -> addSon(lifted, o)); 120 | return this; 121 | } 122 | 123 | public DefXCSP addListOrLifted() { 124 | if (map.containsKey(ICtr.MATRIX)) { 125 | possibleSimplification = false; 126 | return add(ICtr.MATRIX); 127 | } 128 | String lifted = map.containsKey(ICtr.LISTS) ? ICtr.LIST : map.containsKey(ICtr.SETS) ? ICtr.SET : map.containsKey(ICtr.MSETS) ? ICtr.MSET : null; 129 | if (lifted == null) 130 | return add(ICtr.LIST); // basic variant 131 | Stream.of((Object[]) map.get(lifted + "s")).forEach(o -> addSon(lifted, o)); 132 | return this; 133 | } 134 | 135 | public int[] differencesWith(DefXCSP def) { 136 | if (!name.equals(def.name) || attributes.size() != def.attributes.size() || sons.size() != def.sons.size() 137 | || possibleSimplification != def.possibleSimplification) 138 | return null; 139 | if (!same(attributes, def.attributes)) 140 | return null; 141 | if (IntStream.range(0, sons.size()) 142 | .anyMatch(i -> !sons.get(i).name.equals(def.sons.get(i).name) || !same(sons.get(i).attributes, def.sons.get(i).attributes))) 143 | return null; 144 | return IntStream.range(0, sons.size()).filter(i -> !sons.get(i).content.toString().equals(def.sons.get(i).content.toString())).toArray(); 145 | } 146 | 147 | @Override 148 | public String toString() { 149 | return name + " : " + sons.stream().map(c -> c.toString()).collect(Collectors.joining(" ")) + print(attributes); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/definitions/IObj.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.definitions; 2 | 3 | import static org.xcsp.modeler.definitions.IRootForCtrAndObj.map; 4 | 5 | import java.util.AbstractMap.SimpleEntry; 6 | import java.util.Map; 7 | 8 | import org.xcsp.common.IVar; 9 | import org.xcsp.common.Types.TypeObjective; 10 | import org.xcsp.common.predicates.XNode; 11 | 12 | public interface IObj extends IRootForCtrAndObj { 13 | 14 | String MINIMIZE = "minimize"; 15 | String MAXIMIZE = "maximize"; 16 | String FUNCTION = ICtr.FUNCTION; 17 | String TYPE = "type"; 18 | String LIST = ICtr.LIST; 19 | String COEFFS = ICtr.COEFFS; 20 | 21 | public interface IObjFunctional extends IObj { 22 | 23 | public static IObjFunctional buildFrom(IVar[] scope, boolean minimize, XNode tree) { 24 | return new IObjFunctional() { 25 | @Override 26 | public Map mapXCSP() { 27 | return map(SCOPE, scope, MINIMIZE, minimize, FUNCTION, tree); 28 | } 29 | }; 30 | } 31 | 32 | @Override 33 | default DefXCSP defXCSP() { 34 | Map map = mapXCSP(); 35 | DefXCSP def = def((Boolean) map.get(MINIMIZE) ? MINIMIZE : MAXIMIZE); 36 | return def.add(FUNCTION); 37 | } 38 | } 39 | 40 | public interface IObjSpecialized extends IObj { 41 | 42 | public static IObjSpecialized buildFrom(IVar[] scope, boolean minimize, TypeObjective type, String list, String coeffs) { 43 | return new IObjSpecialized() { 44 | @Override 45 | public Map mapXCSP() { 46 | return map(SCOPE, scope, MINIMIZE, minimize, TYPE, type, LIST, list, COEFFS, coeffs); 47 | } 48 | }; 49 | } 50 | 51 | @Override 52 | default DefXCSP defXCSP() { 53 | Map map = mapXCSP(); 54 | DefXCSP def = def((Boolean) map.get(MINIMIZE) ? MINIMIZE : MAXIMIZE); 55 | if (map.containsKey(TYPE)) { 56 | String t = ((TypeObjective) map.get(TYPE)).name().toLowerCase(); 57 | def.attributes.add(new SimpleEntry<>(TYPE, t.equals("nvalues") ? "nValues" : t)); 58 | } 59 | return def.add(LIST, COEFFS); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/definitions/IRootForCtrAndObj.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.definitions; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | import java.util.stream.IntStream; 6 | 7 | import org.xcsp.common.IVar; 8 | import org.xcsp.common.Utilities; 9 | 10 | public interface IRootForCtrAndObj { 11 | String SCOPE = "scope"; 12 | 13 | static Map map(String[] keys, Object... values) { 14 | Utilities.control(keys.length == values.length && keys.length > 0, "Bad form"); 15 | Map map = new LinkedHashMap<>(); 16 | IntStream.range(0, keys.length).filter(i -> values[i] != null).forEach(i -> map.put(keys[i], values[i])); 17 | return map; 18 | } 19 | 20 | static Map map(String s, Object o) { 21 | return map(new String[] { s }, o); 22 | } 23 | 24 | static Map map(String s1, Object o1, String s2, Object o2) { 25 | return map(new String[] { s1, s2 }, o1, o2); 26 | } 27 | 28 | static Map map(String s1, Object o1, String s2, Object o2, String s3, Object o3) { 29 | return map(new String[] { s1, s2, s3 }, o1, o2, o3); 30 | } 31 | 32 | static Map map(String s1, Object o1, String s2, Object o2, String s3, Object o3, String s4, Object o4) { 33 | return map(new String[] { s1, s2, s3, s4 }, o1, o2, o3, o4); 34 | } 35 | 36 | static Map map(String s1, Object o1, String s2, Object o2, String s3, Object o3, String s4, Object o4, String s5, Object o5) { 37 | return map(new String[] { s1, s2, s3, s4, s5 }, o1, o2, o3, o4, o5); 38 | } 39 | 40 | static Map map(String s1, Object o1, String s2, Object o2, String s3, Object o3, String s4, Object o4, String s5, Object o5, String s6, 41 | Object o6) { 42 | return map(new String[] { s1, s2, s3, s4, s5, s6 }, o1, o2, o3, o4, o5, o6); 43 | } 44 | 45 | default Map mapXCSP() { 46 | return null; 47 | } 48 | 49 | default DefXCSP defXCSP() { 50 | return null; 51 | } 52 | 53 | default DefXCSP def(String name) { 54 | return new DefXCSP(name, mapXCSP()); 55 | } 56 | 57 | default IVar[] scope() { 58 | return (IVar[]) mapXCSP().get(SCOPE); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/entities/CtrEntities.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.entities; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.IntStream; 9 | import java.util.stream.Stream; 10 | 11 | import org.xcsp.common.Softening; 12 | import org.xcsp.common.Types.TypeClass; 13 | import org.xcsp.common.Utilities; 14 | import org.xcsp.modeler.definitions.ICtr; 15 | import org.xcsp.modeler.entities.ModelingEntity.TagDummy; 16 | import org.xcsp.modeler.entities.VarEntities.VarEntity; 17 | 18 | public final class CtrEntities { 19 | 20 | public List allEntities = new ArrayList<>(); 21 | public Map ctrToCtrAlone = new LinkedHashMap<>(); // useful for recording specific information (id, note, classes) about constraints 22 | public Map ctrToCtrArray = new LinkedHashMap<>(); 23 | 24 | public CtrArray newCtrArrayEntity(ICtr[] ctrs, boolean dummy, TypeClass... classes) { 25 | return ctrs.length == 0 || dummy ? new CtrArrayDummy(ctrs, classes) : new CtrArray(ctrs, classes); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return allEntities.stream().map(ce -> ce.getClass().getSimpleName()).collect(Collectors.joining(" ")); 31 | } 32 | 33 | // ************************************************************************ 34 | // ***** Classes for handling stand-alone and groups of constraints 35 | // ************************************************************************ 36 | 37 | public abstract class CtrEntity extends ModelingEntity { 38 | protected CtrEntity(TypeClass... classes) { 39 | super(classes); 40 | allEntities.add(this); 41 | } 42 | 43 | public abstract CtrEntity violationCost(int violationCost); 44 | } 45 | 46 | // note a CtrAlone ca is really alone iff ctrToCtrArray.get(ca.ctr) return null; 47 | public class CtrAlone extends CtrEntity { 48 | public ICtr ctr; 49 | public Softening softening; 50 | 51 | public CtrAlone(TypeClass... classes) { 52 | super(classes); 53 | } 54 | 55 | public CtrAlone(ICtr ctr, TypeClass... classes) { 56 | this(classes); 57 | this.ctr = ctr; 58 | ctrToCtrAlone.put(ctr, this); 59 | Utilities.control(ctr != null && !(this instanceof CtrAloneDummy), "CtrAloneDummy possible only iff the specified constraint is null." 60 | + "In some implementations other than default one, it could be different."); 61 | } 62 | 63 | @Override 64 | public CtrEntity violationCost(int violationCost) { 65 | return null; // TODO still to be implemented 66 | // softening = new XSofteningSimple(null, violationCost); 67 | // ctr.pb.framework = TypeFramework.WCSP; 68 | // ctr.pb.resolution.cfg.framework = TypeFramework.WCSP; 69 | // return this; 70 | } 71 | } 72 | 73 | /** 74 | * Objects of this class correspond to extreme cases where the constraint is irrelevant (for example, a sum with 0 variable). Such constraint will 75 | * not be recorded. 76 | */ 77 | public final class CtrAloneDummy extends CtrAlone implements TagDummy { 78 | 79 | public CtrAloneDummy(String note, TypeClass... classes) { 80 | super(classes); 81 | note(note); // the note indicates why the constraint is dummy 82 | } 83 | } 84 | 85 | public class CtrArray extends CtrEntity { 86 | public ICtr[] ctrs; 87 | 88 | /** 89 | * while managing a loop (or a block), some variables and arrays of variables can be defined internally to this loop. If a tag applies to the 90 | * loop, the variables and arrays of variables must also be tagged. This list stores the concerned var entities. 91 | */ 92 | public List varEntitiessSubjectToTags; 93 | 94 | public CtrArray(ICtr[] ctrs, TypeClass... classes) { 95 | super(classes); 96 | this.ctrs = ctrs; 97 | if (!(this instanceof CtrArrayDummy)) 98 | Stream.of(ctrs).forEach(c -> ctrToCtrArray.put(c, this)); 99 | } 100 | 101 | @Override 102 | public CtrEntity violationCost(int violationCost) { 103 | System.out.println("Not possible to associate a violation cost with a group of constraints"); 104 | return null; 105 | } 106 | 107 | public CtrArray append(CtrArray ca) { 108 | Utilities.control(ca.id == null && ca.note == null && ca.classes.size() == 0, 109 | "Implementation not finished yet to take into account such situations where some information must be merged"); 110 | this.ctrs = Utilities.convert(IntStream.range(0, ctrs.length + ca.ctrs.length).mapToObj(i -> i < ctrs.length ? ctrs[i] : ca.ctrs[i - ctrs.length]) 111 | .collect(Collectors.toList())); 112 | return this; 113 | } 114 | 115 | @Override 116 | public CtrArray tag(TypeClass... classes) { 117 | super.tag(classes); 118 | varEntitiessSubjectToTags.stream().forEach(x -> x.tag(classes)); 119 | return this; 120 | } 121 | } 122 | 123 | /** 124 | * Objects of this class correspond to cases where a set of constraints will have to be merged with another one. The array is dummy, but involved 125 | * constraints are not. 126 | */ 127 | public final class CtrArrayDummy extends CtrArray implements TagDummy { 128 | 129 | protected CtrArrayDummy(ICtr[] ctrs, TypeClass... classes) { 130 | super(ctrs, classes); 131 | Stream.of(ctrs).forEach(c -> ctrToCtrAlone.get(c).tag(classes)); // because the dummy array will disappear (be merged) 132 | } 133 | 134 | @Override 135 | public CtrArrayDummy note(String note) { 136 | Stream.of(ctrs).forEach(c -> ctrToCtrAlone.get(c).note(note)); // notes are merged 137 | // we don't apply notes to objects in varsSubjectToTags 138 | return this; 139 | } 140 | 141 | @Override 142 | public CtrArrayDummy tag(TypeClass... classes) { 143 | Stream.of(ctrs).forEach(c -> ctrToCtrAlone.get(c).tag(classes)); 144 | varEntitiessSubjectToTags.stream().forEach(x -> x.tag(classes)); 145 | return this; 146 | } 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/entities/ModelingEntity.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.entities; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedHashSet; 5 | import java.util.Set; 6 | 7 | import org.xcsp.common.Types.TypeClass; 8 | import org.xcsp.common.Utilities; 9 | 10 | public abstract class ModelingEntity { 11 | public interface TagDummy { 12 | } 13 | 14 | public String id, note; 15 | public final Set classes; 16 | 17 | protected ModelingEntity(String id, String note, TypeClass... classes) { 18 | this.id = id; 19 | this.note = note; 20 | this.classes = classes == null ? new LinkedHashSet<>() : new LinkedHashSet<>(Arrays.asList(classes)); 21 | } 22 | 23 | protected ModelingEntity(TypeClass... classes) { 24 | this(null, null, classes); 25 | } 26 | 27 | public final ModelingEntity id(String id) { 28 | Utilities.control(this.id == null && id != null, "Pb with the id"); 29 | this.id = id; 30 | return this; 31 | } 32 | 33 | public ModelingEntity note(String note) { 34 | this.note = this.note == null ? note : this.note + " " + note; 35 | return this; 36 | } 37 | 38 | public ModelingEntity tag(TypeClass... classes) { 39 | this.classes.addAll(Arrays.asList(classes)); 40 | return this; 41 | } 42 | 43 | public final ModelingEntity tag(String... classes) { 44 | return tag(TypeClass.classesFor(classes)); 45 | } 46 | 47 | public final boolean nullBasicAttributes() { 48 | return (id == null || id.length() == 0) && (note == null || note.length() == 0) && classes.size() == 0; 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/entities/ObjEntities.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.entities; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import org.xcsp.common.Types.TypeClass; 8 | import org.xcsp.modeler.definitions.IObj; 9 | 10 | public class ObjEntities { 11 | 12 | public List allEntities = new ArrayList<>(); 13 | 14 | public class ObjEntity extends ModelingEntity { 15 | public IObj obj; 16 | 17 | public ObjEntity(IObj obj, TypeClass... classes) { 18 | super(classes); 19 | this.obj = obj; 20 | allEntities.add(this); 21 | } 22 | } 23 | 24 | public boolean active() { 25 | return allEntities.size() > 0; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return allEntities.stream().map(e -> e.getClass().getSimpleName()).collect(Collectors.joining(" ")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/implementation/NotData.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.implementation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface NotData { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/implementation/ProblemDataHandler.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.modeler.implementation; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileOutputStream; 5 | import java.io.FileReader; 6 | import java.io.PrintWriter; 7 | import java.lang.reflect.Array; 8 | import java.lang.reflect.Constructor; 9 | import java.lang.reflect.Field; 10 | import java.lang.reflect.Modifier; 11 | import java.lang.reflect.ParameterizedType; 12 | import java.lang.reflect.Type; 13 | import java.util.ArrayList; 14 | import java.util.LinkedHashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.Map.Entry; 18 | import java.util.stream.Collectors; 19 | import java.util.stream.IntStream; 20 | import java.util.stream.Stream; 21 | 22 | import javax.json.Json; 23 | import javax.json.JsonArray; 24 | import javax.json.JsonArrayBuilder; 25 | import javax.json.JsonNumber; 26 | import javax.json.JsonObject; 27 | import javax.json.JsonObjectBuilder; 28 | import javax.json.JsonReader; 29 | import javax.json.JsonString; 30 | import javax.json.JsonStructure; 31 | import javax.json.JsonValue; 32 | import javax.json.JsonWriter; 33 | 34 | import org.xcsp.common.Utilities; 35 | import org.xcsp.modeler.api.ProblemAPI; 36 | 37 | /** Data Handler, using JSON as format. */ 38 | public final class ProblemDataHandler { 39 | 40 | private Object handleField(Field field, JsonObject jsonObject, ProblemAPI api) { 41 | if (ProblemIMP.mustBeIgnored(field)) 42 | return null; 43 | field.setAccessible(true); 44 | String key = field.getName(); 45 | try { 46 | if (jsonObject.isNull(key)) 47 | return null; 48 | } catch (NullPointerException e) { 49 | ProblemIMP.control(false, "The field " + key + " has not been found"); 50 | } 51 | return load(jsonObject.get(key), field.getType(), field.getGenericType(), api); 52 | } 53 | 54 | private Object load(JsonValue json, Class type, Type genericType, ProblemAPI api) { 55 | if (json instanceof JsonString && ((JsonString) json).getString().equals("null") && type != String.class) 56 | return null; // is that always the good solution ? what about String and "null ? 57 | if (type == boolean.class || type == Boolean.class) 58 | return json == JsonValue.TRUE; 59 | if (type == int.class || type == Integer.class || type == byte.class || type == Byte.class || type == short.class || type == Short.class) 60 | return ((JsonNumber) json).intValue(); 61 | if (type == long.class || type == Long.class) 62 | return ((JsonNumber) json).longValue(); 63 | if (type == double.class || type == Double.class || type == float.class || type == Float.class) 64 | return ((JsonNumber) json).doubleValue(); 65 | if (type == String.class) 66 | return ((JsonString) json).getString(); 67 | if (json.toString().equals("\"null\"") || json.toString().equals("null")) // null or string "null" => null 68 | return null; 69 | if (type.isArray()) { 70 | JsonArray jsonArray = (JsonArray) json; 71 | List list = jsonArray.stream().map(v -> load(v, type.getComponentType(), null, api)).collect(Collectors.toList()); 72 | Object array = Array.newInstance(type.getComponentType(), jsonArray.size()); 73 | IntStream.range(0, jsonArray.size()).forEach(i -> Array.set(array, i, list.get(i))); 74 | return array; 75 | } 76 | if (type == List.class) { 77 | Class c = (Class) ((ParameterizedType) genericType).getActualTypeArguments()[0]; 78 | return ((JsonArray) json).stream().map(v -> load(v, c, null, api)).collect(Collectors.toList()); 79 | } 80 | if (type == Map.class) { 81 | Class c1 = (Class) ((ParameterizedType) genericType).getActualTypeArguments()[0]; 82 | Class c2 = (Class) ((ParameterizedType) genericType).getActualTypeArguments()[1]; 83 | Utilities.control(c1 == Integer.class || c1 == String.class, "Managing other types of keys ?"); 84 | return ((JsonObject) json).entrySet().stream().collect(Collectors.toMap(e -> Integer.parseInt(e.getKey()), e -> load(e.getValue(), c2, null, api))); 85 | } 86 | // below, this is the code for loading an object 87 | try { 88 | if (type.isEnum()) { 89 | Utilities.control(Stream.of(type.getEnumConstants()).anyMatch(c -> json.toString().equals("\"" + c.toString() + "\"")), ""); 90 | return Stream.of(type.getEnumConstants()).filter(c -> json.toString().equals("\"" + c.toString() + "\"")).findFirst().get(); 91 | } 92 | if (json instanceof JsonString) { 93 | Utilities.control(json.toString().equals("\"null\""), "Pb with a JSON element"); 94 | return null; 95 | } 96 | JsonObject jsonObject = (JsonObject) json; 97 | if (type == api.getClass()) { 98 | for (Field field : type.getDeclaredFields()) { 99 | Object value = handleField(field, jsonObject, api); 100 | if (value != null) 101 | field.set(api, value); 102 | } 103 | return api; 104 | } else { 105 | Utilities.control(type.getDeclaredConstructors().length == 1, "Only one constructor is allowed"); 106 | Constructor c = type.getDeclaredConstructors()[0]; 107 | c.setAccessible(true); 108 | boolean additionnalArgument = !Modifier.isStatic(type.getModifiers()) && type.getEnclosingClass() != null; 109 | boolean defaultConstructor = c.getParameterTypes().length == (additionnalArgument ? 1 : 0); 110 | if (defaultConstructor) { 111 | Object obj = additionnalArgument ? c.newInstance(api) : c.newInstance(); 112 | for (Field field : type.getDeclaredFields()) { 113 | Object value = handleField(field, jsonObject, api); 114 | if (value != null) 115 | field.set(obj, value); 116 | } 117 | return obj; 118 | } else { 119 | List list = new ArrayList<>(); 120 | if (additionnalArgument) 121 | list.add(api); // api first object of the constructor if the class is not static 122 | for (Field field : type.getDeclaredFields()) { 123 | Object value = handleField(field, jsonObject, api); 124 | if (value != null) 125 | list.add(value); 126 | } 127 | return c.newInstance(list.toArray()); 128 | } 129 | } 130 | } catch (Exception e) { 131 | e.printStackTrace(); 132 | Utilities.exit("Pb when loading "); 133 | } 134 | return null; 135 | } 136 | 137 | public void load(ProblemAPI api, String fileName) { 138 | try (JsonReader jsonReader = Json.createReader(new BufferedReader(new FileReader(fileName)))) { 139 | load(jsonReader.readObject(), api.getClass(), null, api); 140 | } catch (Exception e) { 141 | e.printStackTrace(); 142 | Utilities.exit("Pb when loading " + e); 143 | } 144 | } 145 | 146 | private JsonStructure save(Object object) throws Exception { 147 | if (object.getClass().isArray() || object instanceof List) { 148 | JsonArrayBuilder builder = Json.createArrayBuilder(); 149 | for (Object item : object instanceof List ? (List) object 150 | : IntStream.range(0, Array.getLength(object)).mapToObj(i -> Array.get(object, i)).collect(Collectors.toList())) { 151 | if (item == null) 152 | builder.addNull(); 153 | else if (item.getClass() == Boolean.class) 154 | builder.add((boolean) item); 155 | else if (item.getClass() == Integer.class || item.getClass() == Byte.class || item.getClass() == Short.class) 156 | builder.add(((Number) item).intValue()); 157 | else if (item.getClass() == Long.class) 158 | builder.add((long) item); 159 | else if (item.getClass() == Double.class || item.getClass() == Float.class) 160 | builder.add(((Number) item).doubleValue()); 161 | else if (item.getClass() == String.class) 162 | builder.add((String) item); 163 | else 164 | builder.add(save(item)); 165 | } 166 | return builder.build(); 167 | } 168 | JsonObjectBuilder builder = Json.createObjectBuilder(); 169 | Map map = null; 170 | if (object instanceof Map) 171 | map = (Map) object; 172 | else if (object instanceof ProblemAPI) { 173 | List fields = ProblemIMP.problemDataFields(new ArrayList<>(), object.getClass()); 174 | map = fields.stream().collect(Collectors.toMap(Field::getName, f -> { 175 | try { 176 | f.setAccessible(true); 177 | return f.get(object) == null ? "null" : f.get(object); // "null" because null provokes an exception when merging 178 | } catch (Exception e) { 179 | return "null"; 180 | } 181 | }, (v1, v2) -> v1, LinkedHashMap::new)); 182 | } else { 183 | map = Stream.of(object.getClass().getDeclaredFields()).filter(f -> !ProblemIMP.mustBeIgnored(f)).peek(f -> f.setAccessible(true)) 184 | .collect(Collectors.toMap(Field::getName, f -> { 185 | try { 186 | f.setAccessible(true); 187 | return f.get(object) == null ? "null" : f.get(object); // "null" because null provokes an exception when merging 188 | } catch (Exception e) { 189 | e.printStackTrace(); 190 | return null; 191 | } 192 | }, (v1, v2) -> v1, LinkedHashMap::new)); 193 | } 194 | for (Object key : map.keySet()) 195 | map.replace(key, "null", null); 196 | for (Entry e : map.entrySet()) { 197 | String key = e.getKey().toString(); 198 | Object value = e.getValue(); 199 | if (value == null) 200 | builder.addNull(key); 201 | else if (value.getClass().isArray()) 202 | builder.add(key, save(value)); 203 | else { 204 | if (value.getClass() == Boolean.class) 205 | builder.add(key, (boolean) value); 206 | else if (value.getClass() == Integer.class || value.getClass() == Byte.class || value.getClass() == Short.class) 207 | builder.add(key, ((Number) value).intValue()); 208 | else if (value.getClass() == Long.class) 209 | builder.add(key, (long) value); 210 | else if (value.getClass() == Double.class || value.getClass() == Float.class) 211 | builder.add(key, ((Number) value).doubleValue()); 212 | else if (value.getClass() == String.class) 213 | builder.add(key, (String) value); 214 | else if (value instanceof Enum) 215 | builder.add(key, value.toString()); 216 | else 217 | builder.add(key, save(value)); 218 | } 219 | } 220 | return builder.build(); 221 | } 222 | 223 | public void save(ProblemAPI api, String fileName) { 224 | fileName = fileName + ".json"; 225 | System.out.print("\n Saving Data File " + fileName + " ... "); 226 | Map properties = new LinkedHashMap<>(1); 227 | // properties.put(JsonGenerator.PRETTY_PRINTING, true); 228 | try (JsonWriter jsonWriter = Json.createWriterFactory(properties).createWriter(new PrintWriter(new FileOutputStream(fileName)));) { 229 | JsonStructure js = save(api); 230 | jsonWriter.write(js); 231 | } catch (Exception e) { 232 | e.printStackTrace(); 233 | e.getCause().getStackTrace(); 234 | } 235 | System.out.println("Finished."); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/AllInterval.java: -------------------------------------------------------------------------------- 1 | /** 2 | 1 * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | /** 15 | * Problem described at http://www.csplib.org/Problems/prob007/
16 | * For order 8, 9, 10, 11 and 12, there are respectively 40, 120, 296, 648 and 1328 solutions. 17 | * 18 | */ 19 | public class AllInterval implements ProblemAPI { 20 | 21 | int n; // order 22 | 23 | @Override 24 | public void model() { 25 | Var[] x = array("x", size(n), dom(range(n)), "x[i] is the ith value of the series"); 26 | Var[] y = array("y", size(n - 1), dom(range(1, n)), "y[i] is the distance between x[i] and x[i+1]"); 27 | 28 | allDifferent(x); 29 | allDifferent(y); 30 | forall(range(n - 1), i -> equal(y[i], dist(x[i], x[i + 1]))); 31 | 32 | block(() -> { 33 | lessThan(x[0], x[n - 1]); 34 | lessThan(y[0], y[1]); 35 | }).tag(SYMMETRY_BREAKING); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Bibd.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Bibd implements ProblemAPI { 15 | 16 | int v, b, r, k, l; // l stands for lambda 17 | 18 | @Override 19 | public void model() { 20 | b = b != 0 ? b : (l * v * (v - 1)) / (k * (k - 1)); // when b is 0, we compute it 21 | r = r != 0 ? r : (l * (v - 1)) / (k - 1); // when r is 0, we compute it 22 | 23 | Var[][] x = array("x", size(v, b), dom(0, 1), "x[i][j] is the value of the matrix at row i and col j"); 24 | 25 | forall(range(v), i -> sum(x[i], EQ, r)); 26 | forall(range(b), j -> sum(columnOf(x, j), EQ, k)); 27 | forall(range(v).range(v), (i, j) -> { 28 | if (i < j) 29 | sum(x[i], weightedBy(x[j]), EQ, l); 30 | }); 31 | lexMatrix(x, INCREASING).tag(SYMMETRY_BREAKING); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Blackhole.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Blackhole implements ProblemAPI { 15 | 16 | int nCardsPerSuit, nCardsPerPile; // todo removing redundant nCardsPerPile 17 | int[][] piles; 18 | 19 | @Override 20 | public void model() { 21 | int nCards = 4 * nCardsPerSuit, nPiles = (nCards - 1) / nCardsPerPile; 22 | 23 | Var[] x = array("x", size(nCards), dom(range(nCards)), "x[i] is the value j of the card at the ith position of the built stack."); 24 | Var[] y = array("y", size(nCards), dom(range(nCards)), "y[j] is the position i of the card whose value is j"); 25 | 26 | channel(x, y); 27 | equal(y[0], 0).note("the Ace of Spades is initially put on the stack"); 28 | 29 | forall(range(nPiles), i -> ordered(variablesFrom(piles[i], j -> y[j]), STRICTLY_INCREASING)).note("cards must be played in the order of the piles"); 30 | 31 | int[][] tuples = range(nCards).range(nCards) 32 | .select((i, j) -> i % nCardsPerSuit == (j + 1) % nCardsPerSuit || j % nCardsPerSuit == (i + 1) % nCardsPerSuit); 33 | slide(x, range(nCards - 1), i -> extension(vars(x[i], x[i + 1]), tuples)) 34 | .note("each new card put on the stack must be at a rank higher or lower than the previous one."); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/BoardColoration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | /** 15 | * All squares of a board of a specified size (specified numbers of rows and columns) must be colored with the mininum number of colors. The four 16 | * corners of any rectangle inside the board must not be assigned the same color. 17 | */ 18 | public class BoardColoration implements ProblemAPI { 19 | 20 | int nRows; 21 | int nCols; 22 | 23 | @Override 24 | public void model() { 25 | Var[][] x = array("x", size(nRows, nCols), dom(range(nRows * nCols)), "x[i][j] is the color at row i and column j"); 26 | 27 | forall(range(nRows).range(nRows).range(nCols).range(nCols), (i1, i2, j1, j2) -> { 28 | if (i1 < i2 && j1 < j2) 29 | notAllEqual(x[i1][j1], x[i1][j2], x[i2][j1], x[i2][j2]); 30 | }); 31 | lexMatrix(x, INCREASING).tag(SYMMETRY_BREAKING); 32 | 33 | minimize(MAXIMUM, x); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/MagicSequence.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class MagicSequence implements ProblemAPI { 15 | int n; 16 | 17 | @Override 18 | public void model() { 19 | Var[] x = array("x", size(n), dom(range(n)), "x[i] is the ith value of the sequence"); 20 | 21 | cardinality(x, range(n), occurExactly(x)).note("each value i occurs exactly x[i] times in the sequence"); 22 | 23 | block(() -> { 24 | sum(x, EQ, n); 25 | sum(x, range(-1, n - 1), EQ, 0); 26 | }).tag(REDUNDANT_CONSTRAINTS); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Pic.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.VarSymbolic; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Pic implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | VarSymbolic x = var("x", dom("a", "b")); 19 | VarSymbolic y = var("y", dom("a", "b")); 20 | VarSymbolic z = var("z", dom("a", "b")); 21 | 22 | extension(vars(x, y), tableSymbolic("(a,a)(b,b)")); 23 | extension(vars(x, z), tableSymbolic("(a,a)(b,b)")); 24 | extension(vars(y, z), tableSymbolic("(a,b)(b,a)")); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Pic2.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Pic2 implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x = var("x", dom(0, 1)); 19 | Var y = var("y", dom(0, 1)); 20 | Var z = var("z", dom(0, 1)); 21 | 22 | extension(vars(x, y), table("(0,0)(1,1)")); 23 | extension(vars(x, z), table("(0,0)(1,1)")); 24 | extension(vars(y, z), table("(0,1)(1,0)")); 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Queens.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Queens implements ProblemAPI { 15 | int n; // number of queens 16 | 17 | @Override 18 | public void model() { 19 | Var[] q = array("q", size(n), dom(range(n)), "q[i] is the column where is put the ith queen (at row i)"); 20 | 21 | if (modelVariant("m1")) { 22 | forall(range(n).range(n), (i, j) -> { 23 | if (i < j) 24 | conjunction(ne(q[i], q[j]), ne(dist(q[i], q[j]), dist(i, j))); 25 | }); 26 | } 27 | if (modelVariant("m2")) { 28 | allDifferent(q); 29 | forall(range(n).range(n), (i, j) -> { 30 | if (i < j) 31 | different(dist(q[i], q[j]), dist(i, j)); 32 | }); 33 | } 34 | if (modelVariant("m3")) { 35 | allDifferent(q); 36 | allDifferent(treesFrom(range(n), i -> add(q[i], i))); 37 | allDifferent(treesFrom(range(n), i -> sub(q[i], i))); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Rack.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | //java abscon.Resolution problems.acad.Rack -data=/home/lecoutre/instances/Rack/r2.json -ev -f=cop => 1100 in 40s 15 | public class Rack implements ProblemAPI { 16 | int nRacks; 17 | int[][] models; 18 | int[][] cardTypes; 19 | 20 | @Override 21 | public void model() { 22 | models = addObject(models, tuple(0, 0, 0), 0); // we add first a dummy model (0,0,0) 23 | int nModels = models.length, nTypes = cardTypes.length; 24 | int[] powers = columnOf(models, 0), connectors = columnOf(models, 1), prices = columnOf(models, 2), cardPowers = columnOf(cardTypes, 0); 25 | int maxCapacity = maxOf(connectors); 26 | 27 | Var[] r = array("r", size(nRacks), dom(range(nModels)), "r[i] is the model used for the ith rack"); 28 | Var[][] c = array("c", size(nRacks, nTypes), (i, j) -> dom(range(Math.min(maxCapacity, cardTypes[j][1]) + 1)), 29 | "c[i][j] is the number of cards of type j put in the ith rack"); 30 | Var[] rpw = array("rpw", size(nRacks), dom(powers), "rpw[i] is the power of the ith rack"); 31 | Var[] rcn = array("rcn", size(nRacks), dom(connectors), "rcn[i] is the number of connectors of the ith rack"); 32 | Var[] rpr = array("rpr", size(nRacks), dom(prices), "rpr[i] is the price of the ith rack"); 33 | 34 | forall(range(nRacks), i -> extension(vars(r[i], rpw[i]), indexing(powers))).note("linking the ith rack with its power"); 35 | forall(range(nRacks), i -> extension(vars(r[i], rcn[i]), indexing(connectors))).note("linking the ith rack with its number of connectors"); 36 | forall(range(nRacks), i -> extension(vars(r[i], rpr[i]), indexing(prices))).note("linking the ith rack with its price"); 37 | 38 | forall(range(nRacks), i -> sum(c[i], LE, rcn[i])).note("connector-capacity constraints"); 39 | forall(range(nRacks), i -> sum(c[i], weightedBy(cardPowers), LE, rpw[i])).note("power-capacity constraints"); 40 | forall(range(nTypes), i -> sum(columnOf(c, i), EQ, cardTypes[i][1])).note("demand constraints"); 41 | 42 | block(() -> { 43 | decreasing(r); 44 | disjunction(ne(r[0], r[1]), ge(c[0][0], c[1][0])); 45 | }).tag(SYMMETRY_BREAKING); 46 | 47 | minimize(SUM, rpr); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Rack2.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Rack2 implements ProblemAPI { 15 | int nRacks; 16 | RackModel[] rackModels; 17 | CardType[] cardTypes; 18 | 19 | class RackModel { 20 | int power, nConnectors, price; 21 | } 22 | 23 | class CardType { 24 | int power, demand; 25 | } 26 | 27 | @Override 28 | public void model() { 29 | rackModels = addObject(rackModels, new RackModel(), 0); // we add first a dummy model (0,0,0) 30 | int nModels = rackModels.length, nTypes = cardTypes.length; 31 | int[] powers = valuesFrom(rackModels, rackModel -> rackModel.power); 32 | int[] connectors = valuesFrom(rackModels, rackModel -> rackModel.nConnectors); 33 | int[] prices = valuesFrom(rackModels, rackModel -> rackModel.price); 34 | int[] cardPowers = valuesFrom(cardTypes, cardType -> cardType.power); 35 | int maxCapacity = maxOf(connectors); 36 | 37 | Var[] r = array("r", size(nRacks), dom(range(nModels)), "r[i] is the model used for the ith rack"); 38 | Var[][] c = array("c", size(nRacks, nTypes), (i, j) -> dom(range(Math.min(maxCapacity, cardTypes[j].demand) + 1)), 39 | "c[i][j] is the number of cards of type j put in the ith rack"); 40 | Var[] rpw = array("rpw", size(nRacks), dom(powers), "rpw[i] is the power of the ith rack"); 41 | Var[] rcn = array("rcn", size(nRacks), dom(connectors), "rcn[i] is the number of connectors of the ith rack"); 42 | Var[] rpr = array("rpr", size(nRacks), dom(prices), "rpr[i] is the price of the ith rack"); 43 | 44 | forall(range(nRacks), i -> extension(vars(r[i], rpw[i]), indexing(powers))).note("linking the ith rack with its power"); 45 | forall(range(nRacks), i -> extension(vars(r[i], rcn[i]), indexing(connectors))).note("linking the ith rack with its number of connectors"); 46 | forall(range(nRacks), i -> extension(vars(r[i], rpr[i]), indexing(prices))).note("linking the ith rack with its price"); 47 | 48 | forall(range(nRacks), i -> sum(c[i], LE, rcn[i])).note("connector-capacity constraints"); 49 | forall(range(nRacks), i -> sum(c[i], weightedBy(cardPowers), LE, rpw[i])).note("power-capacity constraints"); 50 | forall(range(nTypes), i -> sum(columnOf(c, i), EQ, cardTypes[i].demand)).note("demand constraints"); 51 | 52 | block(() -> { 53 | decreasing(r); 54 | disjunction(ne(r[0], r[1]), ge(c[0][0], c[1][0])); 55 | }).tag(SYMMETRY_BREAKING); 56 | 57 | minimize(SUM, rpr); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x1 = var("x1", dom(range(15))); 19 | Var x2 = var("x2", dom(range(15))); 20 | Var x3 = var("x3", dom(range(15))); 21 | Var x4 = var("x4", dom(range(15))); 22 | 23 | equal(add(x1, 1), x2); 24 | equal(add(x2, 1), x3); 25 | equal(add(x3, 1), x4); 26 | equal(add(x1, x2, x3, x4), 14); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle2.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle2 implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x[] = array("x", size(4), dom(range(15))); 19 | 20 | equal(add(x[0], 1), x[1]); 21 | equal(add(x[1], 1), x[2]); 22 | equal(add(x[2], 1), x[3]); 23 | equal(add(x[0], x[1], x[2], x[3]), 14); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle3.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle3 implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x[] = array("x", size(4), i -> dom(range(i < 2 ? 6 : 9))); 19 | 20 | equal(add(x[0], 1), x[1]); 21 | equal(add(x[1], 1), x[2]); 22 | equal(add(x[2], 1), x[3]); 23 | equal(add(x[0], x[1], x[2], x[3]), 14); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle4.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle4 implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x[] = array("x", size(4), dom(range(15))); 19 | 20 | forall(range(3), i -> equal(add(x[i], 1), x[i + 1])); 21 | equal(add(x[0], x[1], x[2], x[3]), 14); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle4b.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle4b implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x[] = array("x", size(4), dom(range(15))); 19 | for (int i = 0; i < 3; i++) 20 | equal(add(x[i], 1), x[i + 1]); 21 | equal(add(x[0], x[1], x[2], x[3]), 14); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Riddle5.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | class Riddle5 implements ProblemAPI { 15 | 16 | @Override 17 | public void model() { 18 | Var x[] = array("x", size(4), i -> dom(range(15))); 19 | 20 | forall(range(3), i -> equal(add(x[i], 1), x[i + 1])); 21 | sum(x, EQ, 14); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Sudoku.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | public class Sudoku implements ProblemAPI { 15 | 16 | int n; // order of the grid (typically, 9) 17 | int[][] clues; // if not 0, clues[i][j] is a value imposed at row i and col j 18 | 19 | @Override 20 | public void model() { 21 | int base = (int) Math.sqrt(n); 22 | 23 | Var[][] x = array("x", size(n, n), dom(rangeClosed(1, n)), "x[i][j] is the value in cell at row i and col j."); 24 | 25 | allDifferentMatrix(x); 26 | forall(range(0, n, base).range(0, n, base), (i, j) -> allDifferent(select(x, range(i, i + base).range(j, j + base)))).tag(BLOCKS); 27 | instantiation(x, clues, onlyOn((i, j) -> clues[i][j] != 0)).tag(CLUES); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Warehouse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | // Problem defined at http://csplib.org/Problems/prob034/ 15 | public class Warehouse implements ProblemAPI { 16 | int fixedCost; 17 | int[] warehouseCapacities; 18 | int[][] storeSupplyCosts; 19 | 20 | @Override 21 | public void model() { 22 | int nWarehouses = warehouseCapacities.length, nStores = storeSupplyCosts.length; 23 | 24 | Var[] sw = array("sw", size(nStores), dom(range(nWarehouses)), "sw[i] is the supplying warehouse for the ith store"); 25 | Var[] sc = array("sc", size(nStores), i -> dom(storeSupplyCosts[i]), "sc[i] is the supplying cost for the ith store"); 26 | Var[] open = array("open", size(nWarehouses), dom(0, 1), "open[i] is 1 if the ith warehouse is open"); 27 | 28 | forall(range(nWarehouses), i -> atMost(sw, takingValue(i), warehouseCapacities[i])).note("Capacities of warehouses must not be exceeded."); 29 | forall(range(nStores), i -> element(open, at(sw[i]), condition(EQ, 1))).note("The warehouse supplier of the ith store must be open."); 30 | forall(range(nStores), i -> element(storeSupplyCosts[i], at(sw[i]), condition(EQ, sc[i]))).note("Computing the cost of supplying the ith store."); 31 | 32 | int[] coeffs = vals(repeat(1, nStores), repeat(fixedCost, nWarehouses)); 33 | minimize(SUM, vars(sc, open), weightedBy(coeffs)).note("minimizing the overall cost"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/modeler/problems/Zebra.java: -------------------------------------------------------------------------------- 1 | /** 2 | * AbsCon - Copyright (c) 2017, CRIL-CNRS - lecoutre@cril.fr 3 | * 4 | * All rights reserved. 5 | * 6 | * This program and the accompanying materials are made available under the terms of the CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL which accompanies this 7 | * distribution, and is available at http://www.cecill.info 8 | */ 9 | package org.xcsp.modeler.problems; 10 | 11 | import org.xcsp.common.IVar.Var; 12 | import org.xcsp.modeler.api.ProblemAPI; 13 | 14 | // 48 solutions 15 | public class Zebra implements ProblemAPI { 16 | 17 | @Override 18 | public void model() { 19 | Var yellow = var("yellow", dom(rangeClosed(1, 5))); 20 | Var green = var("green", dom(rangeClosed(1, 5))); 21 | Var red = var("red", dom(rangeClosed(1, 5))); 22 | Var white = var("white", dom(rangeClosed(1, 5))); 23 | Var blue = var("blue", dom(rangeClosed(1, 5))); 24 | 25 | Var italy = var("italy", dom(rangeClosed(1, 5))); 26 | Var spain = var("spain", dom(rangeClosed(1, 5))); 27 | Var japan = var("japan", dom(rangeClosed(1, 5))); 28 | Var england = var("england", dom(rangeClosed(1, 5))); 29 | Var norway = var("norway", dom(rangeClosed(1, 5))); 30 | 31 | Var painter = var("painter", dom(rangeClosed(1, 5))); 32 | Var sculptor = var("sculptor", dom(rangeClosed(1, 5))); 33 | Var diplomat = var("diplomat", dom(rangeClosed(1, 5))); 34 | Var pianist = var("pianist", dom(rangeClosed(1, 5))); 35 | Var doctor = var("doctor", dom(rangeClosed(1, 5))); 36 | 37 | Var cat = var("cat", dom(rangeClosed(1, 5))); 38 | Var zebra = var("zebra", dom(rangeClosed(1, 5))); 39 | Var bear = var("bear", dom(rangeClosed(1, 5))); 40 | Var snails = var("snails", dom(rangeClosed(1, 5))); 41 | Var horse = var("horse", dom(rangeClosed(1, 5))); 42 | 43 | Var milk = var("milk", dom(rangeClosed(1, 5))); 44 | Var water = var("water", dom(rangeClosed(1, 5))); 45 | Var tea = var("tea", dom(rangeClosed(1, 5))); 46 | Var coffee = var("coffee", dom(rangeClosed(1, 5))); 47 | Var juice = var("juice", dom(rangeClosed(1, 5))); 48 | 49 | allDifferent(yellow, green, red, white, blue); 50 | allDifferent(italy, spain, japan, england, norway); 51 | allDifferent(painter, sculptor, diplomat, pianist, doctor); 52 | allDifferent(cat, zebra, bear, snails, horse); 53 | allDifferent(milk, water, tea, coffee, juice); 54 | 55 | equal(painter, horse); 56 | equal(diplomat, coffee); 57 | equal(white, milk); 58 | equal(spain, painter); 59 | equal(england, red); 60 | equal(snails, sculptor); 61 | equal(add(green, 1), red); 62 | equal(add(blue, 1), norway); 63 | equal(doctor, milk); 64 | equal(japan, diplomat); 65 | equal(norway, zebra); 66 | equal(dist(green, white), 1); 67 | belong(horse, set(sub(diplomat, 1), add(diplomat, 1))); 68 | belong(italy, set(red, white, green)); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/WrongTypeException.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.parser; 2 | 3 | /** 4 | * An exception thrown when a constraint parameter has not the expected type. 5 | * 6 | * This exception was created after the first version of the parser was written. 7 | * It extends {@link RuntimeException} to minimize the changes to be made elsewhere in the code; a refactoring may be useful here. 8 | * 9 | * @author Emmanuel Lonca - lonca@cril.fr 10 | */ 11 | public class WrongTypeException extends RuntimeException { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | /** 16 | * Builds a new {@link WrongTypeException} given the reason it was thrown. 17 | * 18 | * @param reason the reason 19 | */ 20 | public WrongTypeException(final String reason) { 21 | super(reason); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/callbacks/FeatureDisplayer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 XCSP3 Team (contact@xcsp.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 6 | * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | * 8 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 12 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | */ 14 | package org.xcsp.parser.callbacks; 15 | 16 | import static java.util.stream.Collectors.joining; 17 | import static java.util.stream.Collectors.toList; 18 | 19 | import java.io.File; 20 | import java.util.ArrayList; 21 | import java.util.Arrays; 22 | import java.util.Collections; 23 | import java.util.LinkedHashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.stream.IntStream; 27 | import java.util.stream.Stream; 28 | 29 | import org.xcsp.common.Types.TypeCtr; 30 | import org.xcsp.common.Types.TypeExpr; 31 | import org.xcsp.common.Types.TypeObjective; 32 | import org.xcsp.common.Utilities; 33 | import org.xcsp.parser.entries.XConstraints.XCtr; 34 | import org.xcsp.parser.entries.XObjectives.OObjectiveExpr; 35 | import org.xcsp.parser.entries.XObjectives.XObj; 36 | import org.xcsp.parser.entries.XVariables.XVar; 37 | import org.xcsp.parser.entries.XVariables.XVarInteger; 38 | import org.xcsp.parser.entries.XVariables.XVarSymbolic; 39 | 40 | /** 41 | * This class allows us to display some general information about XCSP3 instances, such the number of variables, the 42 | * number of constraints, the distribution of constraints, etc. 43 | * 44 | * @author Christophe Lecoutre 45 | */ 46 | public class FeatureDisplayer implements XCallbacks2 { 47 | 48 | // ************************************************************************ 49 | // ***** Main (and other static stuff) 50 | // ************************************************************************ 51 | 52 | private static final String INVALID = "invalid"; 53 | 54 | public static void main(String[] args) throws Exception { 55 | boolean competitionMode = args.length > 0 && args[0].equals("-cm"); 56 | args = competitionMode ? Arrays.copyOfRange(args, 1, args.length) : args; 57 | if (args.length != 1) { 58 | System.out.println("Usage: " + FeatureDisplayer.class.getName() + " [-cm] "); 59 | System.out.println("\tcm stands for competition mode"); 60 | } else 61 | new FeatureDisplayer(competitionMode, args[0]); 62 | } 63 | 64 | // ************************************************************************ 65 | // ***** Implementation object (bridge pattern) 66 | // ************************************************************************ 67 | 68 | private Implem implem = new Implem(this); 69 | 70 | @Override 71 | public Implem implem() { 72 | return implem; 73 | } 74 | 75 | // ************************************************************************ 76 | // ***** Intern class 77 | // ************************************************************************ 78 | 79 | /** 80 | * This class allows us to count the number of occurrences of various keys. 81 | * 82 | * @param 83 | * The type of keys 84 | */ 85 | private static class Repartitioner> { 86 | 87 | private static final int FULL_DISPLAY_LIMIT = Integer.MAX_VALUE; 88 | 89 | /** For each key, the number of occurrences is recorded (as value). */ 90 | private final Map repartition = new LinkedHashMap<>(); 91 | 92 | /** Sorted keys, when the repartition has been frozen. */ 93 | private List sortedKeys; 94 | 95 | private String name; 96 | 97 | private Repartitioner(String name) { 98 | this.name = name; 99 | } 100 | 101 | private void clear() { 102 | repartition.clear(); 103 | sortedKeys = null; 104 | } 105 | 106 | private void add(T value) { 107 | Integer nb = repartition.get(value); 108 | repartition.put(value, nb == null ? 1 : nb + 1); 109 | } 110 | 111 | private void freeze() { 112 | Collections.sort(sortedKeys = new ArrayList(repartition.keySet())); 113 | } 114 | 115 | private T first() { 116 | if (sortedKeys == null) 117 | freeze(); 118 | return sortedKeys.size() == 0 ? null : sortedKeys.get(0); 119 | } 120 | 121 | private T last() { 122 | if (sortedKeys == null) 123 | freeze(); 124 | return sortedKeys.size() == 0 ? null : sortedKeys.get(sortedKeys.size() - 1); 125 | } 126 | 127 | private String pair(T k) { 128 | return "{\"" + name + "\":" + (k instanceof Integer ? k.toString() : "\"" + k + "\"") + ",\"count\":" + repartition.get(k) + "}"; 129 | } 130 | 131 | @Override 132 | public String toString() { 133 | if (sortedKeys == null) 134 | freeze(); 135 | if (sortedKeys.size() <= FULL_DISPLAY_LIMIT) 136 | return "[" + sortedKeys.stream().map(k -> pair(k)).collect(joining(",")) + "]"; 137 | String s1 = IntStream.range(0, FULL_DISPLAY_LIMIT / 2).mapToObj(i -> pair(sortedKeys.get(i))).collect(joining(",")); 138 | String s2 = IntStream.range(sortedKeys.size() - FULL_DISPLAY_LIMIT / 2, sortedKeys.size()).mapToObj(i -> pair(sortedKeys.get(i))) 139 | .collect(joining(", ")); 140 | return "[" + s1 + ",\"...\"," + s2 + "]"; 141 | } 142 | } 143 | 144 | // ************************************************************************ 145 | // ***** Fields and Constructors 146 | // ************************************************************************ 147 | 148 | private boolean competitionMode; 149 | 150 | private int n, e; 151 | private Repartitioner sizes = new Repartitioner<>("size"); 152 | private Repartitioner degrees = new Repartitioner<>("degree"); 153 | private Repartitioner arities = new Repartitioner<>("arity"); 154 | private Repartitioner constraints = new Repartitioner<>("type"); 155 | private XObj obj; 156 | 157 | private int cnt; 158 | 159 | private List ignoredFiles = new ArrayList<>(); 160 | 161 | private void reset() { 162 | n = e = 0; 163 | sizes.clear(); 164 | degrees.clear(); 165 | arities.clear(); 166 | constraints.clear(); 167 | obj = null; 168 | } 169 | 170 | private String field(String key, Object value) { 171 | return ", " + "\"" + key + "\": " 172 | + (value instanceof Number || value instanceof Repartitioner || value instanceof Boolean ? value.toString() : "\"" + value.toString() + "\""); 173 | } 174 | 175 | @Override 176 | public void loadInstance(String fileName, String... discardedClasses) throws Exception { 177 | try { 178 | cnt++; 179 | if (cnt > 1) 180 | System.out.print(","); 181 | reset(); 182 | System.out.print("\n{\"instance\": \"" + fileName + "\""); 183 | XCallbacks2.super.loadInstance(fileName, discardedClasses); 184 | if (competitionMode) { 185 | System.out.print(field("n", n) + field("e", e) + field("nDomainTypes", implem().cache4DomObject.size())); 186 | System.out.print(field("domainSizes", sizes) + field("minDomSize", sizes.first()) + field("maxDomSize", sizes.last())); 187 | System.out.print(field("variableDegrees", degrees) + field("minDegree", degrees.first()) + field("maxDegree", degrees.last())); 188 | System.out.print(field("constraintArities", arities) + field("minConstrArity", arities.first()) + field("maxConstrArity", arities.last())); 189 | int nIntension = constraints.repartition.getOrDefault(TypeCtr.intension, 0); 190 | int nExtension = constraints.repartition.getOrDefault(TypeCtr.extension, 0); 191 | System.out.print(field("globalConstraints", constraints) + field("nIntension", nIntension) + field("nExtension", nExtension)); 192 | boolean objVar = obj == null ? false : (obj.type == TypeObjective.EXPRESSION && ((OObjectiveExpr) obj).rootNode.getType() == TypeExpr.VAR); 193 | System.out.print(field("hasObjective", (obj != null)) 194 | + (obj != null ? field("objectiveType", (obj.minimize ? "min" : "max") + ' ' + (objVar ? "VAR" : obj.type)) : "")); 195 | System.out.print("}"); 196 | } 197 | } catch (Throwable e) { 198 | if (e.getMessage().equals(INVALID)) 199 | System.out.print("\"pb\": \"Instance with some unimplemented method(s)\""); 200 | else 201 | System.out.print("\"pb\": \"Unable to be (totally) parsed\""); 202 | // e.printStackTrace(); 203 | } 204 | } 205 | 206 | private void recursiveHandling(File file) throws Exception { 207 | if (!file.exists()) 208 | Utilities.exit("The file " + file.getName() + " does not exist (or has not been found)"); 209 | if (file.isFile()) { 210 | if (file.getName().endsWith(".xml") || file.getName().endsWith(".lzma")) 211 | loadInstance(file.getAbsolutePath()); 212 | else 213 | ignoredFiles.add(file.getName()); 214 | } else 215 | for (File f : Stream.of(file.listFiles(f -> f.getName().endsWith(".xml") || f.getName().endsWith(".lzma") || file.isDirectory())).sorted() 216 | .collect(toList())) 217 | recursiveHandling(f); 218 | } 219 | 220 | /** 221 | * Builds an object {@code InstanceInformation} that directly parses the XCSP3 file(s) from the specified name that 222 | * denotes a file or a directory. 223 | * 224 | * @param competitionMode 225 | * {@code true} if information is displayed to be used by tools of XCSP3 competitions 226 | * @param name 227 | * the name of a file or directory 228 | * @throws Exception 229 | */ 230 | public FeatureDisplayer(boolean competitionMode, String name) throws Exception { 231 | this.competitionMode = competitionMode; 232 | Utilities.control(competitionMode, "For the moment, the competition mode is the only implemented mode"); 233 | ignoredFiles.clear(); 234 | implem().rawParameters(); // to keep initial formulations (no reformation being processed) 235 | System.out.print("["); 236 | recursiveHandling(new File(name)); 237 | System.out.println("\n]"); 238 | if (ignoredFiles.size() > 0) 239 | System.err.print("Number of ignore files : " + ignoredFiles.size()); 240 | } 241 | 242 | // ************************************************************************ 243 | // ***** Overridden Callback Functions 244 | // ************************************************************************ 245 | 246 | @Override 247 | public Object unimplementedCase(Object... objects) { 248 | throw new RuntimeException(INVALID); 249 | } 250 | 251 | @Override 252 | public void buildVarInteger(XVarInteger x, int minValue, int maxValue) { 253 | sizes.add(maxValue - minValue + 1); 254 | } 255 | 256 | @Override 257 | public void buildVarInteger(XVarInteger x, int[] values) { 258 | sizes.add(values.length); 259 | } 260 | 261 | @Override 262 | public void buildVarSymbolic(XVarSymbolic x, String[] values) { 263 | // TODO : manage some specific information about symbolic variables 264 | sizes.add(values.length); 265 | } 266 | 267 | @Override 268 | public void loadVar(XVar v) { 269 | n++; 270 | degrees.add(v.degree); 271 | XCallbacks2.super.loadVar(v); 272 | } 273 | 274 | @Override 275 | public void loadCtr(XCtr c) { 276 | e++; 277 | arities.add(c.vars().length); 278 | constraints.add(c.getType()); 279 | } 280 | 281 | @Override 282 | public void loadObj(XObj o) { 283 | obj = o; 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/entries/ParsingEntry.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.parser.entries; 2 | 3 | import static org.xcsp.common.Utilities.safeLong; 4 | 5 | import java.util.LinkedHashMap; 6 | import java.util.LinkedHashSet; 7 | import java.util.Map; 8 | import java.util.Set; 9 | import java.util.stream.IntStream; 10 | 11 | import org.w3c.dom.Element; 12 | import org.w3c.dom.NamedNodeMap; 13 | import org.xcsp.common.Types; 14 | import org.xcsp.common.Types.TypeAtt; 15 | import org.xcsp.common.Types.TypeClass; 16 | import org.xcsp.common.Types.TypeFlag; 17 | import org.xcsp.common.Types.TypeObjective; 18 | import org.xcsp.common.Types.TypeVar; 19 | import org.xcsp.common.Utilities; 20 | import org.xcsp.parser.entries.XConstraints.XCtr; 21 | import org.xcsp.parser.entries.XVariables.XVar; 22 | 23 | /** The class root of any entry in variables, constraints and objectives. The basic attributes id, class and note are managed here. */ 24 | public abstract class ParsingEntry { 25 | /** The id (unique identifier) of the entry. */ 26 | public String id; 27 | 28 | /** The classes associated with the entry. */ 29 | public TypeClass[] classes; 30 | 31 | /** The note (short comment) associated with the entry. */ 32 | public String note; 33 | 34 | /** 35 | * The attributes that are associated with the element. Useful for storing all attributes by a simple copy. It is mainly used when dealing with special 36 | * parameters of constraints (startIndex, circular, ...). 37 | */ 38 | public final Map attributes = new LinkedHashMap<>(); 39 | 40 | /** The flags associated with the entry. Currently, used only for table constraints. */ 41 | public final Set flags = new LinkedHashSet<>(); 42 | 43 | /** Returns the Boolean value of the specified attribute, if it exists, the specified default value otherwise. */ 44 | public final boolean getAttributeValue(TypeAtt att, boolean defaultValue) { 45 | return attributes.get(att) == null ? defaultValue : attributes.get(att).toLowerCase().equals("true"); 46 | } 47 | 48 | /** Returns the int value of the specified attribute, if it exists, the specified default value otherwise. */ 49 | public final int getAttributeValue(TypeAtt att, int defaultValue) { 50 | return attributes.get(att) == null ? defaultValue : Utilities.safeInt(safeLong(attributes.get(att))); 51 | } 52 | 53 | /** Returns the value of the specified attribute, if it exists, the specified default value otherwise. */ 54 | public final > T getAttributeValue(TypeAtt att, Class clazz, T defaultValue) { 55 | return attributes.get(att) == null ? defaultValue : Types.valueOf(clazz, attributes.get(att)); 56 | } 57 | 58 | /** Collect the XMl attributes of the specified element into a map (using an enum type for keys, and String for values). */ 59 | public void copyAttributesOf(Element elt) { 60 | NamedNodeMap al = elt.getAttributes(); 61 | IntStream.range(0, al.getLength()).forEach(i -> attributes.put(TypeAtt.valOf(al.item(i).getNodeName()), al.item(i).getNodeValue())); 62 | if (id == null && attributes.containsKey(TypeAtt.id)) 63 | id = attributes.get(TypeAtt.id); 64 | if (attributes.containsKey(TypeAtt.CLASS)) 65 | classes = TypeClass.classesFor(attributes.get(TypeAtt.CLASS).split("\\s+")); 66 | if (attributes.containsKey(TypeAtt.note)) 67 | note = attributes.get(TypeAtt.note); 68 | } 69 | 70 | protected ParsingEntry() { 71 | } 72 | 73 | protected ParsingEntry(String id) { 74 | this.id = id; 75 | Utilities.control(id.matches("[a-zA-Z][_a-zA-Z0-9\\[\\]]*"), "Badly formed id : " + id + ". This does not match [a-zA-Z][_a-zA-Z0-9\\\\[\\\\]]* \n"); 76 | } 77 | 78 | /** The root class used for Var and Array objects. */ 79 | public static abstract class VEntry extends ParsingEntry { 80 | /** The type of the entry. */ 81 | public final TypeVar type; 82 | 83 | /** Returns the type of the entry. We need an accessor for Scala. */ 84 | public final TypeVar getType() { 85 | return type; 86 | } 87 | 88 | /** Builds an entry with the specified id and type. */ 89 | protected VEntry(String id, TypeVar type) { 90 | super(id); 91 | this.type = type; 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | return id + ":" + type; 97 | } 98 | } 99 | 100 | /** 101 | * The root class of any element that is a (direct or indirect) entry in . Also used for child elements of constraints (and constraint 102 | * templates). 103 | */ 104 | public static abstract class CEntry extends ParsingEntry { 105 | 106 | /** The set of variables involved in this element. This is used as a cache (lazy initialization, as seen in method vars()). */ 107 | private XVar[] vars; 108 | 109 | /** Returns the set of variables involved in this element. */ 110 | public XVar[] vars() { 111 | if (this instanceof XCtr && ((XCtr) this).abstraction != null) 112 | return collectVars(new LinkedHashSet<>()).toArray(new XVar[0]); 113 | return vars != null ? vars : (vars = collectVars(new LinkedHashSet<>()).toArray(new XVar[0])); 114 | } 115 | 116 | /** Collect the set of variables involved in this element, and add them to the specified set. */ 117 | public abstract LinkedHashSet collectVars(LinkedHashSet set); 118 | 119 | /** Returns true iff this element is subject to abstraction, i.e., contains parameters (tokens of the form %i or %...). */ 120 | public abstract boolean subjectToAbstraction(); 121 | 122 | @Override 123 | public String toString() { 124 | return "(" + (attributes == null ? "" : Utilities.join(attributes, ":", " ")) + ")"; 125 | } 126 | } 127 | 128 | /** The root class for representing objectives. */ 129 | public static abstract class OEntry extends ParsingEntry { 130 | 131 | /** Indicates whether the objective must be minimized or maximized. */ 132 | public final boolean minimize; 133 | 134 | /** The type (expression, sum, minimum, ...) of the objective. */ 135 | public final TypeObjective type; 136 | 137 | public abstract XVar[] vars(); 138 | 139 | /** Returns The type (expression, sum, minimum, ...) of the objective. We need an accessor for Scala. */ 140 | public final TypeObjective getType() { 141 | return type; 142 | } 143 | 144 | /** Builds an objective with the specified minimize value and type. */ 145 | public OEntry(boolean minimize, TypeObjective type) { 146 | this.minimize = minimize; 147 | this.type = type; 148 | } 149 | 150 | @Override 151 | public String toString() { 152 | return (id != null ? id + " " : "") + (minimize ? "minimize" : "maximize") + " " + type; 153 | } 154 | } 155 | 156 | /** The root class for representing annotations. */ 157 | public static class AEntry extends ParsingEntry { 158 | 159 | public final String name; 160 | 161 | public final Object value; 162 | 163 | /** Builds an annotation with the specified arguments. */ 164 | public AEntry(String name, Object value) { 165 | this.name = name; 166 | this.value = value; 167 | } 168 | 169 | @Override 170 | public String toString() { 171 | return name + " " + value; 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/entries/XObjectives.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 XCSP3 Team (contact@xcsp.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 6 | * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | * 8 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 12 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | */ 14 | package org.xcsp.parser.entries; 15 | 16 | import java.util.LinkedHashSet; 17 | 18 | import org.xcsp.common.IVar; 19 | import org.xcsp.common.Types.TypeObjective; 20 | import org.xcsp.common.Utilities; 21 | import org.xcsp.common.predicates.XNode; 22 | import org.xcsp.parser.entries.ParsingEntry.OEntry; 23 | import org.xcsp.parser.entries.XVariables.XVar; 24 | 25 | /** 26 | * @author Christophe Lecoutre 27 | */ 28 | public class XObjectives { 29 | 30 | /** Intermediate class introduced only for clarity reasons. */ 31 | public static abstract class XObj extends OEntry { 32 | public XObj(boolean minimize, TypeObjective type) { 33 | super(minimize, type); 34 | } 35 | } 36 | 37 | /** The class for representing objectives defined from functional expressions (can just be a variable). */ 38 | public static final class OObjectiveExpr extends XObj { 39 | public final XNode rootNode; 40 | 41 | /** Builds an objective from the specified functional expression (given by the root of a syntactic tree). */ 42 | public OObjectiveExpr(boolean minimize, TypeObjective type, XNode rootNode) { 43 | super(minimize, type); 44 | this.rootNode = rootNode; 45 | } 46 | 47 | @Override 48 | public XVar[] vars() { 49 | return rootNode.vars(); 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return super.toString() + " " + rootNode.toString(); 55 | } 56 | } 57 | 58 | /** The class for representing objectives defined from a list of variables, and possibly a list of coefficients. */ 59 | public static final class OObjectiveSpecial extends XObj { 60 | /** The list of variables or trees of the objective. */ 61 | public final Object[] terms; 62 | 63 | /** The list of coefficients. Either this field is null, or there are as many coefficients as variables. */ 64 | public final Object[] coeffs; 65 | 66 | /** Builds an objective from the specified arrays of variables and coefficients. */ 67 | public OObjectiveSpecial(boolean minimize, TypeObjective type, Object[] terms, Object[] coeffs) { 68 | super(minimize, type); 69 | this.terms = terms; 70 | this.coeffs = coeffs; 71 | // TODO adding a control on vars 72 | } 73 | 74 | @Override 75 | public XVar[] vars() { 76 | // if (terms[0] instanceof IVar) 77 | // return (XVar[]) terms; 78 | LinkedHashSet set = new LinkedHashSet<>(); 79 | for (Object term : terms) { 80 | if (term instanceof IVar) 81 | set.add((IVar) term); 82 | else { 83 | assert term instanceof XNode; 84 | ((XNode) term).listOfVars().stream().forEach(x -> set.add(x)); 85 | } 86 | } 87 | if (coeffs != null) 88 | for (Object coeff : coeffs) { 89 | if (coeff instanceof IVar) 90 | set.add((IVar) coeff); 91 | else if (coeff instanceof XNode) 92 | ((XNode) coeff).listOfVars().stream().forEach(x -> set.add(x)); 93 | else 94 | assert coeff instanceof Long; 95 | } 96 | return set.size() == 0 ? null : set.stream().toArray(s -> Utilities.buildArray(set.iterator().next().getClass(), s)); 97 | } 98 | 99 | @Override 100 | public String toString() { 101 | return super.toString() + "\n\tTerms: " + Utilities.join(terms) + (coeffs != null ? "\n\tCoeffs: " + Utilities.join(coeffs) : ""); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/entries/XVariables.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 XCSP3 Team (contact@xcsp.org) 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 6 | * the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | * 8 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 12 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | */ 14 | package org.xcsp.parser.entries; 15 | 16 | import java.util.ArrayList; 17 | import java.util.Arrays; 18 | import java.util.List; 19 | import java.util.stream.LongStream; 20 | import java.util.stream.Stream; 21 | 22 | import org.xcsp.common.IVar; 23 | import org.xcsp.common.IVar.Var; 24 | import org.xcsp.common.IVar.VarSymbolic; 25 | import org.xcsp.common.Types.TypeVar; 26 | import org.xcsp.common.Utilities; 27 | import org.xcsp.common.domains.Domains.Dom; 28 | import org.xcsp.common.domains.Domains.IDom; 29 | import org.xcsp.common.domains.Values.IntegerEntity; 30 | import org.xcsp.common.domains.Values.IntegerInterval; 31 | import org.xcsp.parser.XParser.TypePrimitive; 32 | import org.xcsp.parser.entries.ParsingEntry.VEntry; 33 | 34 | /** 35 | * In this class, we find intern classes for managing variables and arrays of variables. 36 | * 37 | * @author Christophe Lecoutre 38 | */ 39 | public class XVariables { 40 | 41 | public static final String OTHERS = "others"; 42 | 43 | /** The class used to represent variables. */ 44 | public static abstract class XVar extends VEntry implements IVar { 45 | 46 | /** Builds a variable with the specified id, type and domain. */ 47 | public static final XVar build(String id, TypeVar type, IDom dom) { 48 | switch (type) { 49 | case integer: 50 | return new XVarInteger(id, type, dom); 51 | case symbolic: 52 | return new XVarSymbolic(id, type, dom); 53 | case stochastic: 54 | return new XVarStochastic(id, type, dom); 55 | case real: 56 | return new XVarReal(id, type, dom); 57 | case set: 58 | return new XVarSet(id, type, dom); 59 | default: 60 | throw new RuntimeException("Unimplemented case "); 61 | } 62 | } 63 | 64 | /** Builds a variable from an array with the specified id (combined with the specified indexes), type and domain. */ 65 | public static final XVar build(String idArray, TypeVar type, IDom dom, int[] indexes) { 66 | return build(idArray + "[" + Utilities.join(indexes, "][") + "]", type, dom); 67 | } 68 | 69 | /** The domain of the variable. It is null if the variable is qualitative. */ 70 | public final IDom dom; 71 | 72 | /** The degree of the variable. This is automatically computed after all constraints have been parsed. */ 73 | public int degree; 74 | 75 | /** Builds a variable with the specified id, type and domain. */ 76 | protected XVar(String id, TypeVar type, IDom dom) { 77 | super(id, type); 78 | this.dom = dom; 79 | } 80 | 81 | // /** Builds a variable from an array with the specified id (combined with the specified indexes), type and domain. */ 82 | // protected VVar(String idArray, TypeVar type, DDom dom, int[] indexes) { 83 | // this(idArray + "[" + XUtility.join(indexes, "][") + "]", type, dom); 84 | // } 85 | 86 | @Override 87 | public String id() { 88 | return id; 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return id; // + " :" + type + " of " + dom; 94 | } 95 | } 96 | 97 | /** The following classes are introduced, only for being able to have types for variables in the parser interface */ 98 | public static final class XVarInteger extends XVar implements Var { 99 | 100 | /** 101 | * Returns the size of the Cartesian product for the domains of the specified variables. Importantly, if this value does not fit within a {@code long}, 102 | * -1 is returned. 103 | */ 104 | public static long domainCartesianProductSize(XVarInteger[] scp) { 105 | long[] domSizes = Stream.of(scp).mapToLong(x -> IntegerEntity.nValues((IntegerEntity[]) ((Dom) x.dom).values)).toArray(); 106 | if (LongStream.of(domSizes).anyMatch(l -> l == -1L)) 107 | return -1L; 108 | long cnt = 1; 109 | try { 110 | for (long size : domSizes) 111 | cnt = Math.multiplyExact(cnt, size); 112 | } catch (ArithmeticException e) { 113 | return -1L; 114 | } 115 | return cnt; 116 | } 117 | 118 | public TypePrimitive whichPrimitive() { 119 | return TypePrimitive.whichPrimitiveFor(firstValue(), lastValue()); 120 | } 121 | 122 | /** Builds an integer variable with the specified id, type and domain. */ 123 | protected XVarInteger(String id, TypeVar type, IDom dom) { 124 | super(id, type, dom); 125 | } 126 | 127 | @Override 128 | public long firstValue() { 129 | return ((Dom) dom).firstValue(); 130 | } 131 | 132 | @Override 133 | public long lastValue() { 134 | return ((Dom) dom).lastValue(); 135 | } 136 | 137 | @Override 138 | public Object allValues() { 139 | return ((Dom) dom).allValues(); 140 | } 141 | 142 | @Override 143 | public boolean isZeroOne() { 144 | return firstValue() == 0 && lastValue() == 1; 145 | } 146 | } 147 | 148 | public static final class XVarSymbolic extends XVar implements VarSymbolic { 149 | /** Builds a symbolic variable with the specified id, type and domain. */ 150 | protected XVarSymbolic(String id, TypeVar type, IDom dom) { 151 | super(id, type, dom); 152 | } 153 | } 154 | 155 | public static final class XVarStochastic extends XVar { 156 | /** Builds a stochastic variable with the specified id, type and domain. */ 157 | protected XVarStochastic(String id, TypeVar type, IDom dom) { 158 | super(id, type, dom); 159 | } 160 | } 161 | 162 | public static final class XVarReal extends XVar { 163 | /** Builds a real variable with the specified id, type and domain. */ 164 | protected XVarReal(String id, TypeVar type, IDom dom) { 165 | super(id, type, dom); 166 | } 167 | } 168 | 169 | public static final class XVarSet extends XVar { 170 | /** Builds a set variable with the specified id, type and domain. */ 171 | protected XVarSet(String id, TypeVar type, IDom dom) { 172 | super(id, type, dom); 173 | } 174 | } 175 | 176 | /** The class used to represent arrays of variables. */ 177 | public static final class XArray extends VEntry { 178 | /** The size of the array, as defined in XCSP3. */ 179 | public final int[] size; 180 | 181 | /** 182 | * The flat (one-dimensional) array composed of all variables contained in the (multi-dimensional) array. This way, we can easily deal with arrays of 183 | * any dimensions. 184 | */ 185 | public final XVar[] vars; 186 | 187 | /** Builds an array of variables with the specified id, type and size. */ 188 | public XArray(String id, TypeVar type, int[] size) { 189 | super(id, type); 190 | this.size = size; 191 | this.vars = new XVar[Arrays.stream(size).reduce(1, (s, t) -> s * t)]; 192 | } 193 | 194 | /** Builds a variable with the specified domain for each unoccupied cell of the flat array. */ 195 | private void buildVarsWith(IDom dom) { 196 | int[] indexes = new int[size.length]; 197 | for (int i = 0; i < vars.length; i++) { 198 | if (vars[i] == null) 199 | vars[i] = XVar.build(id, type, dom, indexes); 200 | for (int j = indexes.length - 1; j >= 0; j--) 201 | if (++indexes[j] == size[j]) 202 | indexes[j] = 0; 203 | else 204 | break; 205 | } 206 | } 207 | 208 | /** 209 | * Builds an array of variables with the specified id, type and size. All variables are directly defined with the specified domain. 210 | */ 211 | public XArray(String id, TypeVar type, int[] sizes, IDom dom) { 212 | this(id, type, sizes); 213 | buildVarsWith(dom); 214 | } 215 | 216 | /** Transforms a flat index into a multi-dimensional index. */ 217 | protected int[] indexesFor(int flatIndex) { 218 | int[] t = new int[size.length]; 219 | for (int i = t.length - 1; i > 0; i--) { 220 | t[i] = flatIndex % size[i]; 221 | flatIndex = flatIndex / size[i]; 222 | } 223 | t[0] = flatIndex; 224 | return t; 225 | } 226 | 227 | /** Transforms a multi-dimensional index into a flat index. */ 228 | private int flatIndexFor(int... indexes) { 229 | int sum = 0; 230 | for (int i = indexes.length - 1, nb = 1; i >= 0; i--) { 231 | sum += indexes[i] * nb; 232 | nb *= size[i]; 233 | } 234 | return sum; 235 | } 236 | 237 | /** Returns the variable at the position given by the multi-dimensional index. */ 238 | public XVar varAt(int... indexes) { 239 | return vars[flatIndexFor(indexes)]; 240 | } 241 | 242 | public Dom domAt(boolean discardZeroDegreeVariables, int... indexes) { 243 | XVar x = vars[flatIndexFor(indexes)]; 244 | return x == null ? null : (x.degree == 0 && discardZeroDegreeVariables) ? null : (Dom) x.dom; 245 | } 246 | 247 | /** 248 | * Returns the domain of the variable at the position given by the multi-dimensional index. However, if this variable does not exist or if its degree is 249 | * 0, null is returned. 250 | */ 251 | public Dom domAt(int... indexes) { 252 | return domAt(true, indexes); 253 | } 254 | 255 | /** 256 | * Builds an array of IntegerEnity objects for representing the ranges of indexes that are computed with respect to the specified compact form. 257 | */ 258 | public IntegerEntity[] buildIndexRanges(String compactForm) { 259 | IntegerEntity[] t = new IntegerEntity[size.length]; 260 | String suffix = compactForm.substring(compactForm.indexOf("[")); 261 | for (int i = 0; i < t.length; i++) { 262 | int pos = suffix.indexOf("]"); 263 | String tok = suffix.substring(1, pos); 264 | t[i] = tok.length() == 0 ? new IntegerInterval(0, size[i] - 1) : IntegerEntity.parse(tok); 265 | suffix = suffix.substring(pos + 1); 266 | } 267 | return t; 268 | } 269 | 270 | /** Computes the next multi-dimensional index with respect to specified ranges. Returns false if non exists. */ 271 | private boolean incrementIndexes(int[] indexes, IntegerEntity[] indexRanges) { 272 | int j = indexes.length - 1; 273 | for (; j >= 0; j--) 274 | if (indexRanges[j].isSingleton()) 275 | continue; 276 | else if (++indexes[j] > ((IntegerInterval) indexRanges[j]).sup) 277 | indexes[j] = (int) ((IntegerInterval) indexRanges[j]).inf; 278 | else 279 | break; 280 | return j >= 0; 281 | } 282 | 283 | /** Any variable that matches one compact form present in the specified string is built with the specified domain. */ 284 | public void setDom(String s, IDom dom) { 285 | if (s.trim().equals(OTHERS)) 286 | buildVarsWith(dom); 287 | else 288 | for (String tok : s.split("\\s+")) { 289 | Utilities.control(tok.substring(0, tok.indexOf("[")).equals(id), "One value of attribute 'for' incorrect in array " + id); 290 | IntegerEntity[] indexRanges = buildIndexRanges(tok); 291 | int[] indexes = Stream.of(indexRanges).mapToInt(it -> (int) it.smallest()).toArray(); // first index 292 | do { 293 | int flatIndex = flatIndexFor(indexes); 294 | Utilities.control(vars[flatIndex] == null, "Problem with two domain definitions for the same variable"); 295 | vars[flatIndex] = XVar.build(id, type, dom, indexes); 296 | } while (incrementIndexes(indexes, indexRanges)); 297 | } 298 | } 299 | 300 | /** 301 | * Returns the list of variables that match the specified compact form. For example, for x[1..3], the list will contain x[1] x[2] and x[3]. 302 | */ 303 | public List getVarsFor(String compactForm) { 304 | List list = new ArrayList<>(); 305 | IntegerEntity[] indexRanges = buildIndexRanges(compactForm); 306 | int[] indexes = Stream.of(indexRanges).mapToInt(it -> (int) it.smallest()).toArray(); // first index 307 | do { 308 | list.add(vars[flatIndexFor(indexes)]); 309 | } while (incrementIndexes(indexes, indexRanges)); 310 | return list; 311 | } 312 | 313 | @Override 314 | public String toString() { 315 | return super.toString() + " [" + Utilities.join(size, "][") + "] " + Utilities.join(vars, " "); 316 | } 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /src/main/java/org/xcsp/parser/loaders/CtrLoaderSymbolic.java: -------------------------------------------------------------------------------- 1 | package org.xcsp.parser.loaders; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.stream.Stream; 5 | 6 | import org.xcsp.common.Types.TypeChild; 7 | import org.xcsp.common.predicates.XNodeParent; 8 | import org.xcsp.parser.callbacks.XCallbacks; 9 | import org.xcsp.parser.entries.XConstraints.CChild; 10 | import org.xcsp.parser.entries.XConstraints.XCtr; 11 | import org.xcsp.parser.entries.XVariables.XVarSymbolic; 12 | 13 | public class CtrLoaderSymbolic { 14 | private XCallbacks xc; 15 | 16 | public CtrLoaderSymbolic(XCallbacks xc) { 17 | this.xc = xc; 18 | } 19 | 20 | public void load(XCtr c) { 21 | switch (c.getType()) { 22 | case intension: 23 | intension(c); 24 | break; 25 | case extension: 26 | extension(c); 27 | break; 28 | case allDifferent: 29 | allDifferent(c); 30 | break; 31 | default: 32 | xc.unimplementedCase(c); 33 | } 34 | } 35 | 36 | private void intension(XCtr c) { 37 | xc.buildCtrIntension(c.id, Stream.of(c.vars()).toArray(XVarSymbolic[]::new), (XNodeParent) c.childs[0].value); 38 | } 39 | 40 | private void extension(XCtr c) { 41 | CChild c1 = c.childs[1]; 42 | boolean positive = c1.type == TypeChild.supports; 43 | if (c1.value == null || Array.getLength(c1.value) == 0) { // 0 tuple 44 | if (positive) 45 | xc.buildCtrFalse(c.id, c.vars()); 46 | else 47 | xc.buildCtrTrue(c.id, c.vars()); 48 | } else { 49 | XVarSymbolic[] list = (XVarSymbolic[]) c.childs[0].value; 50 | if (list.length == 1) // unary constraint 51 | xc.buildCtrExtension(c.id, list[0], (String[]) c1.value, positive, c1.flags); 52 | else 53 | xc.buildCtrExtension(c.id, list, (String[][]) c1.value, positive, c1.flags); 54 | } 55 | } 56 | 57 | private void allDifferent(XCtr c) { 58 | if (c.childs.length == 1 && c.childs[0].type == TypeChild.list) 59 | xc.buildCtrAllDifferent(c.id, (XVarSymbolic[]) (c.childs[0].value)); 60 | else 61 | xc.unimplementedCase(c); 62 | } 63 | 64 | } --------------------------------------------------------------------------------