-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b3d89fb
commit 82d61a2
Showing
26 changed files
with
3,390 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/main/java/me/paultristanwagner/satchecking/parse/ComparisonLexer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package me.paultristanwagner.satchecking.parse; | ||
|
||
import static me.paultristanwagner.satchecking.parse.TokenType.*; | ||
|
||
public class ComparisonLexer extends Lexer { | ||
|
||
public ComparisonLexer(String input) { | ||
super(input); | ||
|
||
registerTokenTypes( | ||
EQUALS, | ||
NOT_EQUALS, | ||
GREATER_EQUALS, | ||
LOWER_EQUALS, | ||
LESS_THAN, | ||
GREATER_THAN | ||
); | ||
|
||
initialize(input); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
...n/java/me/paultristanwagner/satchecking/parse/MultivariatePolynomialConstraintParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package me.paultristanwagner.satchecking.parse; | ||
|
||
import me.paultristanwagner.satchecking.sat.Result; | ||
import me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomial; | ||
import me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint; | ||
|
||
import static me.paultristanwagner.satchecking.parse.TokenType.*; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.Comparison.GREATER_THAN; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.Comparison.GREATER_THAN_OR_EQUALS; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.Comparison.LESS_THAN; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.Comparison.LESS_THAN_OR_EQUALS; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.Comparison.NOT_EQUALS; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomialConstraint.multivariatePolynomialConstraint; | ||
|
||
public class MultivariatePolynomialConstraintParser implements Parser<MultivariatePolynomialConstraint> { | ||
|
||
@Override | ||
public MultivariatePolynomialConstraint parse(String string) { | ||
ParseResult<MultivariatePolynomialConstraint> result = parseWithRemaining(string); | ||
if(!result.complete()) { | ||
throw new SyntaxError("Expected end of input", string, result.charsRead()); | ||
} | ||
|
||
return result.result(); | ||
} | ||
|
||
@Override | ||
public ParseResult<MultivariatePolynomialConstraint> parseWithRemaining(String string) { | ||
Parser<MultivariatePolynomial> parser = new PolynomialParser(); | ||
|
||
ParseResult<MultivariatePolynomial> pResult = parser.parseWithRemaining(string); | ||
MultivariatePolynomial p = pResult.result(); | ||
|
||
Lexer lexer = new ComparisonLexer(string.substring(pResult.charsRead())); | ||
MultivariatePolynomialConstraint.Comparison comparison = parseComparison(lexer); | ||
|
||
ParseResult<MultivariatePolynomial> qResult = parser.parseWithRemaining(lexer.getRemaining()); | ||
MultivariatePolynomial q = qResult.result(); | ||
|
||
MultivariatePolynomial d = p.subtract(q); | ||
MultivariatePolynomialConstraint constraint = multivariatePolynomialConstraint(d, comparison); | ||
|
||
int charsRead = pResult.charsRead() + lexer.getCursor() + qResult.charsRead(); | ||
return new ParseResult<>(constraint, charsRead, qResult.complete()); | ||
} | ||
|
||
private MultivariatePolynomialConstraint.Comparison parseComparison(Lexer lexer) { | ||
if(lexer.canConsume(TokenType.EQUALS)) { | ||
lexer.consume(TokenType.EQUALS); | ||
return MultivariatePolynomialConstraint.Comparison.EQUALS; | ||
} else if(lexer.canConsume(TokenType.NOT_EQUALS)) { | ||
lexer.consume(TokenType.NOT_EQUALS); | ||
return NOT_EQUALS; | ||
} else if(lexer.canConsume(TokenType.LESS_THAN)) { | ||
lexer.consume(TokenType.LESS_THAN); | ||
return LESS_THAN; | ||
} else if(lexer.canConsume(TokenType.GREATER_THAN)) { | ||
lexer.consume(TokenType.GREATER_THAN); | ||
return GREATER_THAN; | ||
} else if(lexer.canConsume(LOWER_EQUALS)) { | ||
lexer.consume(LOWER_EQUALS); | ||
return LESS_THAN_OR_EQUALS; | ||
} else if(lexer.canConsume(GREATER_EQUALS)) { | ||
lexer.consume(GREATER_EQUALS); | ||
return GREATER_THAN_OR_EQUALS; | ||
} else { | ||
throw new SyntaxError("Expected comparison operator", lexer.getInput(), lexer.getCursor()); | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/me/paultristanwagner/satchecking/parse/PolynomialLexer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package me.paultristanwagner.satchecking.parse; | ||
|
||
import static me.paultristanwagner.satchecking.parse.TokenType.*; | ||
|
||
public class PolynomialLexer extends Lexer { | ||
|
||
public PolynomialLexer(String input) { | ||
super(input); | ||
|
||
registerTokenTypes( | ||
PLUS, | ||
MINUS, | ||
FRACTION, | ||
DECIMAL, | ||
IDENTIFIER, | ||
TIMES, | ||
POWER); | ||
|
||
initialize(input); | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
src/main/java/me/paultristanwagner/satchecking/parse/PolynomialParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package me.paultristanwagner.satchecking.parse; | ||
|
||
import me.paultristanwagner.satchecking.theory.arithmetic.Number; | ||
import me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomial; | ||
|
||
import java.util.Scanner; | ||
|
||
import static me.paultristanwagner.satchecking.parse.TokenType.*; | ||
import static me.paultristanwagner.satchecking.theory.arithmetic.Number.number; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomial.constant; | ||
import static me.paultristanwagner.satchecking.theory.nonlinear.MultivariatePolynomial.variable; | ||
|
||
public class PolynomialParser implements Parser<MultivariatePolynomial> { | ||
|
||
public static void main(String[] args){ | ||
Scanner scanner = new Scanner(System.in); | ||
PolynomialParser parser = new PolynomialParser(); | ||
|
||
String line; | ||
while ((line = scanner.nextLine()) != null) { | ||
MultivariatePolynomial polynomial = parser.parse(line); | ||
System.out.println(polynomial); | ||
} | ||
} | ||
|
||
/* | ||
* Grammar for polynomial constraints: | ||
* <S> ::= <TERM> EQUALS 0 | ||
* | ||
* <TERM> ::= <MONOMIAL> PLUS <MONOMIAL> | ||
* | <MONOMIAL> MINUS <MONOMIAL> | ||
* | <MONOMIAL> | ||
* | ||
* <MONOMIAL> ::= <FACTOR> TIMES <FACTOR> | ||
* | <FACTOR> | ||
* | ||
* <FACTOR> ::= FRACTION | ||
* | DECIMAL | ||
* | IDENTIFIER | ||
* | IDENTIFIER POWER INTEGER | ||
*/ | ||
|
||
public MultivariatePolynomial parse(String string) { | ||
ParseResult<MultivariatePolynomial> result = parseWithRemaining(string); | ||
|
||
if (!result.complete()) { | ||
throw new SyntaxError("Expected end of input", string, result.charsRead()); | ||
} | ||
|
||
return result.result(); | ||
} | ||
|
||
@Override | ||
public ParseResult<MultivariatePolynomial> parseWithRemaining(String string) { | ||
Lexer lexer = new PolynomialLexer(string); | ||
|
||
lexer.requireNextToken(); | ||
|
||
MultivariatePolynomial polynomial = parseTerm(lexer); | ||
|
||
return new ParseResult<>(polynomial, lexer.getCursor(), lexer.getCursor() == string.length()); | ||
} | ||
|
||
private MultivariatePolynomial parseTerm(Lexer lexer) { | ||
MultivariatePolynomial term1 = parseMonomial(lexer); | ||
|
||
while(lexer.canConsume(PLUS) || lexer.canConsume(MINUS)){ | ||
if (lexer.canConsume(PLUS)) { | ||
lexer.consume(PLUS); | ||
MultivariatePolynomial term2 = parseMonomial(lexer); | ||
term1 = term1.add(term2); | ||
} else if (lexer.canConsume(MINUS)) { | ||
lexer.consume(MINUS); | ||
MultivariatePolynomial term2 = parseMonomial(lexer); | ||
term1 = term1.subtract(term2); | ||
} | ||
} | ||
|
||
return term1; | ||
} | ||
|
||
private MultivariatePolynomial parseMonomial(Lexer lexer) { | ||
MultivariatePolynomial monomial1 = parseFactor(lexer); | ||
|
||
while (lexer.canConsumeEither(TIMES, IDENTIFIER)) { | ||
if(lexer.canConsume(TIMES)) { | ||
lexer.consume(TIMES); | ||
} | ||
MultivariatePolynomial monomial2 = parseFactor(lexer); | ||
monomial1 = monomial1.multiply(monomial2); | ||
} | ||
|
||
return monomial1; | ||
} | ||
|
||
private int parseSign(Lexer lexer) { | ||
int sign = 1; | ||
while(lexer.canConsumeEither(PLUS, MINUS)){ | ||
if (lexer.canConsume(PLUS)) { | ||
lexer.consume(PLUS); | ||
} else if (lexer.canConsume(MINUS)) { | ||
lexer.consume(MINUS); | ||
sign *= -1; | ||
} | ||
} | ||
|
||
return sign; | ||
} | ||
|
||
private MultivariatePolynomial parseFactor(Lexer lexer) { | ||
int sign = parseSign(lexer); | ||
|
||
if (lexer.canConsumeEither(DECIMAL, FRACTION)) { | ||
String value = lexer.getLookahead().getValue(); | ||
lexer.consumeEither(DECIMAL, FRACTION); | ||
Number number = Number.parse(value); | ||
|
||
if(sign == -1) { | ||
number = number.negate(); | ||
} | ||
|
||
return constant(number); | ||
} | ||
|
||
if (lexer.canConsume(IDENTIFIER)) { | ||
String variable = lexer.getLookahead().getValue(); | ||
lexer.consume(IDENTIFIER); | ||
|
||
if (lexer.canConsume(POWER)) { | ||
lexer.consume(POWER); | ||
lexer.require(DECIMAL); | ||
String exponent = lexer.getLookahead().getValue(); | ||
lexer.consume(DECIMAL); | ||
|
||
MultivariatePolynomial monomial = variable(variable).pow(Integer.parseInt(exponent)); | ||
|
||
return monomial.multiply(constant(number(sign))); | ||
} | ||
|
||
return variable(variable).multiply(constant(number(sign))); | ||
} | ||
|
||
throw new SyntaxError("Expected either a decimal or an identifier", lexer.getInput(), lexer.getCursor()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.