Skip to content

Commit

Permalink
CSP: Update Csp Parser and Converter and add example files
Browse files Browse the repository at this point in the history
  • Loading branch information
Apfelbeet committed Nov 6, 2024
1 parent b741aca commit eb9a244
Show file tree
Hide file tree
Showing 22 changed files with 3,257 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.booleworks.logicng.csp.io.readers;

import com.booleworks.logicng.csp.CspFactory;
import com.booleworks.logicng.csp.io.javacc.ParseException;
import com.booleworks.logicng.csp.io.javacc.SExpressionParser;
import com.booleworks.logicng.csp.io.javacc.TokenMgrError;
import com.booleworks.logicng.csp.terms.IntegerVariable;
import com.booleworks.logicng.formulas.Formula;
import com.booleworks.logicng.formulas.FormulaFactory;
import com.booleworks.logicng.formulas.Variable;
import com.booleworks.logicng.io.parsers.ParserException;
import com.booleworks.logicng.util.Pair;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class SExpressionConverter {
private static void convertFile(final SExpressionParser parser, final File src, final File dest)
throws IOException, ParserException {
final BufferedReader br = new BufferedReader(new FileReader(src));
final BufferedWriter wr = new BufferedWriter(new FileWriter(dest));
while (br.ready()) {
try {
final String l = br.readLine();
if (l.startsWith(";") || l.isBlank()) {
continue;
}
System.out.println(l);
parser.ReInit(new StringReader(l));
final Pair<Pair<Variable, IntegerVariable>, Formula> line = parser.line();
if (line.getSecond() != null) {
wr.write(line.getSecond().toString());
wr.write('\n');
} else if (line.getFirst().getSecond() != null) {
wr.write("int " + line.getFirst().getSecond().getName() + " " +
line.getFirst().getSecond().getDomain().toString());
wr.write('\n');
}
} catch (final TokenMgrError e) {
throw new ParserException("lexer error", e);
} catch (final ParseException e) {
throw new ParserException("parser error", e);
}
}
br.close();
wr.close();
}

/**
* Converts files using the common S-expression format to the LNG format for CSP.
* <p>
* This converter is not tested and does not support all features.
* It is not supposed to be used without a manual validation afterward.
* @param src the source file or dictionary
* @param dest the destination file or dictionary
* @throws IOException if IO operations fail at the src or dest
* @throws ParserException if the parser fails to parse a file
*/
public static void convertFiles(final File src, final File dest)
throws IOException, ParserException {
final SExpressionParser parser = new SExpressionParser(new StringReader(""));
if (src.isFile()) {
final FormulaFactory f = FormulaFactory.caching();
final CspFactory cf = new CspFactory(f);
parser.setFactory(cf);
final File dest_file;
if (dest.isDirectory()) {
final Path dest_path = Paths.get(dest.getAbsolutePath(), src.getName());
dest_file = new File(dest_path.toString());
} else {
dest_file = dest;
}
if (dest_file.createNewFile()) {
convertFile(parser, src, dest_file);
} else {
throw new RuntimeException("File already exists");
}
} else if (src.isDirectory()) {
if (!dest.isDirectory()) {
throw new RuntimeException("Src is a directory, but Dest is not");
}
for (final File file : Objects.requireNonNull(src.listFiles())) {
if (file.isFile() && !file.getName().startsWith(".")) {
final FormulaFactory f = FormulaFactory.caching();
final CspFactory cf = new CspFactory(f);
parser.setFactory(cf);
final Path dest_path = Paths.get(dest.getAbsolutePath(), file.getName());
final File dest_file = new File(dest_path.toString());
System.out.println(dest_file.toString());
if (dest_file.createNewFile()) {
convertFile(parser, file, dest_file);
} else {
throw new RuntimeException("File already exists");
}
}
}
} else {
throw new RuntimeException("Invalid src");
}

}
}
83 changes: 57 additions & 26 deletions csp/src/main/javacc/CspFormulaParser.jj
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,7 @@ CspPredicate prefix_predicate() throws ParseException : {
CspPredicate.Type type;
}
{
type = prefixPredicateType() <LSQBR> (args = termList())? <RSQBR> {
if(args == null) {
args = new ArrayList<>();
}
type = prefixPredicateType() <LSQBR> args = termList() <RSQBR> {
switch(type) {
case ALLDIFFERENT:
return cf.allDifferent(args);
Expand Down Expand Up @@ -328,15 +325,64 @@ CspPredicate.Type prefixPredicateType() : {
}

Term term() throws ParseException : {
Term a;
Token minus = null;
Token t1, t2, t3;
Formula cond;
Term t;
}
{
t = term2() {return t;}
}

Term term2() throws ParseException : {
List<Term> ts = new ArrayList();
Term t;
int i;
} {
t = term1() { ts.add(t); } (
(<ADD> t = term1() { ts.add(t); })+ { t = cf.add(ts); }
| (<MINUS> t = term1() { ts.add(t); })+ {
t = ts.get(0);
for(i = 1; i < ts.size(); ++i)
t = cf.sub(t, ts.get(i));
}
)? { return t; }
}

Term term1() throws ParseException : {
List<Term> ts = new ArrayList();
Term t;
int i;
}
{
t = term0() { ts.add(t); } (
(<MUL> t = term0() { ts.add(t); })+ {
t = ts.get(0);
for(i = 1; i < ts.size(); ++i)
t = cf.mul(t, ts.get(i));
}
| (<DIV> t = constant() { ts.add(t); })+ {
t = ts.get(0);
for(i = 1; i < ts.size(); ++i)
t = cf.div(t, (IntegerConstant) ts.get(i));
}
| (<MOD> t = constant() { ts.add(t); })+ {
t = ts.get(0);
for(i = 1; i < ts.size(); ++i)
t = cf.mod(t, (IntegerConstant) ts.get(i));
}
)? { return t; }
}

Term term0() throws ParseException : {
Token minus = null;
Term a;
}
{
(minus = <MINUS>)? (
a = constant()
| LOOKAHEAD(2) a = function()
| LOOKAHEAD(2) a = intVar()
| <LBR> a = inlineList() <RBR>
a = constant()
| LOOKAHEAD(2) a = function()
| LOOKAHEAD(2) a = intVar()
| <LBR> a = term() <RBR>
) { return minus == null ? a : cf.minus(a); }
}

Expand Down Expand Up @@ -397,27 +443,12 @@ Term.Type functionType() throws ParseException : {Token id;} {
}
}

Term inlineList() throws ParseException : {
Term a, b, res = null;
IntegerConstant c;
List<Term> terms = new ArrayList<>();
}
{
a = term() { terms.add(a); } (
(<ADD> b = term() { terms.add(b); })+ { res = cf.add(terms); }
| <MINUS> b = term() { res = cf.sub(a, b); }
| <MUL> b = term() { res = cf.mul(a, b); }
| <DIV> c = constant() { res = cf.div(a, c); }
| <MOD> c = constant() { res = cf.mod(a, c); }
)? {return res == null ? a : res; }
}

List<Term> termList() : {
Term a, b;
List<Term> terms = new ArrayList<>();
}
{
a = term() {terms.add(a);} (<DELIMITER> b = term() {terms.add(b);})* { return terms; }
(a = term() {terms.add(a);} (<DELIMITER> b = term() {terms.add(b);})*)? { return terms; }
}

IntegerConstant constant() : { Token c; }
Expand Down
Loading

0 comments on commit eb9a244

Please sign in to comment.