Skip to content

Commit

Permalink
Add false and logical or to CTL* grammar
Browse files Browse the repository at this point in the history
  • Loading branch information
BuildTools committed Sep 28, 2023
1 parent 2874b8f commit 2046ead
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,21 @@ public CTLStarModelCheckingResult check(TransitionSystem ts, CTLStarFormula form
public Set<String> sat(TransitionSystem ts, CTLStarFormula formula) {
if (formula instanceof CTLStarTrueFormula) {
return satTrue(ts);
} else if (formula instanceof CTLStarFalseFormula) {
return satFalse(ts);
} else if (formula instanceof CTLStarIdentifierFormula identifierFormula) {
return satIdentifier(ts, identifierFormula);
} else if (formula instanceof CTLStarAndFormula andFormula) {
return satAnd(ts, andFormula);
} else if (formula instanceof CTLStarOrFormula orFormula) {
return satOr(ts, orFormula);
} else if (formula instanceof CTLStarNotFormula notFormula) {
return satNot(ts, notFormula);
} else if (formula instanceof CTLStarParenthesisFormula parenthesisFormula) {
return sat(ts, parenthesisFormula.getFormula());
} else if (formula instanceof CTLStarExistsFormula existsFormula) {
return satExists(ts, existsFormula);
} else if(formula instanceof CTLStarAllFormula allFormula) {
} else if (formula instanceof CTLStarAllFormula allFormula) {
return satAll(ts, allFormula);
}

Expand All @@ -86,6 +90,10 @@ private Set<String> satTrue(TransitionSystem ts) {
return new HashSet<>(ts.getStates());
}

private Set<String> satFalse(TransitionSystem ts) {
return new HashSet<>();
}

private Set<String> satIdentifier(TransitionSystem ts, CTLStarIdentifierFormula formula) {
String atomicProposition = formula.getIdentifier();

Expand All @@ -107,6 +115,14 @@ private Set<String> satAnd(TransitionSystem ts, CTLStarAndFormula andFormula) {
return satStates;
}

private Set<String> satOr(TransitionSystem ts, CTLStarOrFormula orFormula) {
Set<String> satStates = new HashSet<>();
for (CTLStarFormula component : orFormula.getComponents()) {
satStates.addAll(sat(ts, component));
}
return satStates;
}

private Set<String> satNot(TransitionSystem ts, CTLStarNotFormula notFormula) {
Set<String> satStates = new HashSet<>(ts.getStates());
satStates.removeAll(sat(ts, notFormula.getFormula()));
Expand All @@ -128,6 +144,7 @@ private Set<CTLStarFormula> getStateSubFormulas(CTLStarFormula formula) {
}

if (subFormula instanceof CTLStarTrueFormula
|| subFormula instanceof CTLStarFalseFormula
|| subFormula instanceof CTLStarIdentifierFormula
|| subFormula instanceof CTLStarExistsFormula
|| subFormula instanceof CTLStarAllFormula) {
Expand All @@ -147,6 +164,18 @@ private Set<CTLStarFormula> getStateSubFormulas(CTLStarFormula formula) {
if (allStateSubFormulas) {
stateSubFormulas.add(andFormula);
}
} else if (subFormula instanceof CTLStarOrFormula orFormula) { // depends
boolean allStateSubFormulas = true;
for (CTLStarFormula component : orFormula.getComponents()) {
if (!stateSubFormulas.contains(component)) {
allStateSubFormulas = false;
break;
}
}

if (allStateSubFormulas) {
stateSubFormulas.add(orFormula);
}
} else if (subFormula instanceof CTLStarNotFormula notFormula) { // depends
if (stateSubFormulas.contains(notFormula.getFormula())) {
stateSubFormulas.add(notFormula);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package me.paultristanwagner.modelchecking.ctlstar.formula;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import me.paultristanwagner.modelchecking.ltl.formula.LTLFalseFormula;
import me.paultristanwagner.modelchecking.ltl.formula.LTLFormula;

public class CTLStarFalseFormula extends CTLStarFormula {

private CTLStarFalseFormula() {

}

public static CTLStarFalseFormula FALSE() {
return new CTLStarFalseFormula();
}


@Override
public int getDepth() {
return 1;
}

@Override
public void replaceFormula(CTLStarFormula target, String freshVariable) {
// nothing to do
}

@Override
public Set<CTLStarFormula> getSubFormulas() {
Set<CTLStarFormula> subFormulas = new HashSet<>();
subFormulas.add(this);
return subFormulas;
}

@Override
public LTLFormula toLTL() {
return LTLFalseFormula.FALSE();
}

@Override
public String toString() {
return "false";
}

@Override
public boolean equals(Object obj) {
return obj instanceof CTLStarFalseFormula;
}

@Override
public int hashCode() {
return Objects.hash(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package me.paultristanwagner.modelchecking.ctlstar.formula;

import static me.paultristanwagner.modelchecking.util.Symbol.OR_SYMBOL;

import java.util.*;
import me.paultristanwagner.modelchecking.ltl.formula.LTLFormula;
import me.paultristanwagner.modelchecking.ltl.formula.LTLOrFormula;

public class CTLStarOrFormula extends CTLStarFormula {

private final List<CTLStarFormula> components;

private CTLStarOrFormula( List<CTLStarFormula> components ) {
this.components = components;
}

public static CTLStarOrFormula or( List<CTLStarFormula> components ) {
return new CTLStarOrFormula( components );
}

public static CTLStarOrFormula or( CTLStarFormula... components ) {
return new CTLStarOrFormula( List.of( components ) );
}

@Override
public int getDepth() {
int maxDepth = 0;
for (CTLStarFormula component : components) {
maxDepth = Math.max(maxDepth, component.getDepth());
}
return maxDepth + 1;
}

@Override
public void replaceFormula(CTLStarFormula target, String freshVariable) {
components.replaceAll(
component -> {
if (component.equals(target)) {
return CTLStarIdentifierFormula.identifier(freshVariable);
} else {
component.replaceFormula(target, freshVariable);
return component;
}
});
}

@Override
public Set<CTLStarFormula> getSubFormulas() {
Set<CTLStarFormula> subFormulas = new HashSet<>();
for (CTLStarFormula component : components) {
subFormulas.addAll(component.getSubFormulas());
}
subFormulas.add(this);
return subFormulas;
}

@Override
public LTLFormula toLTL() {
List<LTLFormula> ltlComponents = new ArrayList<>();
for (CTLStarFormula component : components) {
ltlComponents.add(component.toLTL());
}
return LTLOrFormula.or(ltlComponents);
}

public List<CTLStarFormula> getComponents() {
return components;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < components.size(); i++) {
builder.append(components.get(i).toString());

if (i < components.size() - 1) {
builder.append(" ");
builder.append(OR_SYMBOL);
builder.append(" ");
}
}

return builder.toString();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CTLStarOrFormula that = (CTLStarOrFormula) o;
return Objects.equals(components, that.components);
}

@Override
public int hashCode() {
return Objects.hash(components);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ public String toString() {
return "true";
}

@Override
public boolean equals(Object obj) {
return obj instanceof CTLStarTrueFormula;
}

@Override
public int hashCode() {
return Objects.hash(1);
return Objects.hash(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public class CTLStarLexer extends Lexer {
static final TokenType LPAREN = TokenType.of("(", "^\\(");
static final TokenType RPAREN = TokenType.of(")", "^\\)");
static final TokenType TRUE = TokenType.of("true", "^(true|TRUE)");
// static final TokenType FALSE = TokenType.of("false", "^(false|FALSE)");
static final TokenType FALSE = TokenType.of("false", "^(false|FALSE)");
static final TokenType NOT = TokenType.of("not", "^(" + NOT_SYMBOL + "|!|not|NOT|~)");
static final TokenType AND = TokenType.of("and", "^(" + AND_SYMBOL + "|&|and|AND)");
// static final TokenType OR = TokenType.of("or", "^(" + OR_SYMBOL + "|\\||or|OR)");
static final TokenType OR = TokenType.of("or", "^(" + OR_SYMBOL + "|\\||or|OR)");
static final TokenType NEXT = TokenType.of("next", "^(" + NEXT_SYMBOL + "|next|NEXT|O)");
static final TokenType UNTIL = TokenType.of("until", "^(" + UNTIL_SYMBOL + "|until|UNTIL)");
static final TokenType EVENTUALLY =
Expand All @@ -30,13 +30,21 @@ public class CTLStarLexer extends Lexer {
public CTLStarLexer(String input) {
super(input);

/* registerTokenTypes(
LPAREN, RPAREN, TRUE, FALSE, NOT, AND, OR,
NEXT, UNTIL, EVENTUALLY, ALWAYS, ALL, EXISTS, IDENTIFIER
); */

registerTokenTypes(
LPAREN, RPAREN, TRUE, NOT, AND, NEXT, UNTIL, EVENTUALLY, ALWAYS, ALL, EXISTS, IDENTIFIER);
LPAREN,
RPAREN,
TRUE,
FALSE,
NOT,
AND,
OR,
NEXT,
UNTIL,
EVENTUALLY,
ALWAYS,
ALL,
EXISTS,
IDENTIFIER);

this.initialize(input);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarAlwaysFormula.always;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarEventuallyFormula.eventually;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarExistsFormula.exists;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarFalseFormula.FALSE;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarIdentifierFormula.identifier;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarNextFormula.next;
import static me.paultristanwagner.modelchecking.ctlstar.formula.CTLStarNotFormula.not;
Expand All @@ -24,12 +25,16 @@
public class CTLStarParser implements Parser<CTLStarFormula> {

/*
*
* <A> ::= <B>
* | <A> AND <B>
* <B> ::= NOT <B>
* | <A> OR <B>
* <B> ::= <C>
* | <B> AND <C>
* <C> ::= NOT <C>
* | EXISTS <PATH>
* | ALL <PATH>
* | TRUE
* | FALSE
* | IDENTIFIER
* | '(' <A> ')'
*
Expand Down Expand Up @@ -67,9 +72,26 @@ private CTLStarFormula A(Lexer lexer) {
CTLStarFormula first = B(lexer);
components.add(first);

while (lexer.hasNextToken() && lexer.getLookahead().getType() == OR) {
lexer.consume(OR);
components.add(B(lexer));
}

if (components.size() == 1) {
return first;
}

return CTLStarOrFormula.or(components);
}

private CTLStarFormula B(Lexer lexer) {
List<CTLStarFormula> components = new ArrayList<>();
CTLStarFormula first = C(lexer);
components.add(first);

while (lexer.hasNextToken() && lexer.getLookahead().getType() == AND) {
lexer.consume(AND);
components.add(B(lexer));
components.add(C(lexer));
}

if (components.size() == 1) {
Expand All @@ -79,10 +101,10 @@ private CTLStarFormula A(Lexer lexer) {
return CTLStarAndFormula.and(components);
}

private CTLStarFormula B(Lexer lexer) {
private CTLStarFormula C(Lexer lexer) {
if (lexer.getLookahead().getType() == NOT) {
lexer.consume(NOT);
return not(B(lexer));
return not(C(lexer));
} else if (lexer.getLookahead().getType() == EXISTS) {
lexer.consume(EXISTS);
return exists(parsePathFormula(lexer));
Expand All @@ -92,6 +114,9 @@ private CTLStarFormula B(Lexer lexer) {
} else if (lexer.getLookahead().getType() == TRUE) {
lexer.consume(TRUE);
return TRUE();
} else if (lexer.getLookahead().getType() == FALSE) {
lexer.consume(FALSE);
return FALSE();
} else if (lexer.getLookahead().getType() == IDENTIFIER) {
String identifier = lexer.getLookahead().getValue();
lexer.consume(IDENTIFIER);
Expand Down
Loading

0 comments on commit 2046ead

Please sign in to comment.