![JAR search and dependency download from the Maven repository](/logo.png)
org.ggp.base.util.gdl.transforms.Relationizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.util.gdl.transforms;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.ggp.base.util.gdl.GdlUtils;
import org.ggp.base.util.gdl.grammar.Gdl;
import org.ggp.base.util.gdl.grammar.GdlDistinct;
import org.ggp.base.util.gdl.grammar.GdlLiteral;
import org.ggp.base.util.gdl.grammar.GdlNot;
import org.ggp.base.util.gdl.grammar.GdlOr;
import org.ggp.base.util.gdl.grammar.GdlPool;
import org.ggp.base.util.gdl.grammar.GdlRelation;
import org.ggp.base.util.gdl.grammar.GdlRule;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlTerm;
import org.ggp.base.util.gdl.model.SentenceForm;
import org.ggp.base.util.gdl.model.SentenceFormModel;
import org.ggp.base.util.gdl.model.SentenceFormModelFactory;
public class Relationizer {
private Relationizer() {
}
/**
* Searches the description for statements that are needlessly treated as
* base propositions when they could be expressed as simple relations, and
* replaces them with these simpler forms.
*
* Some games have been written such that unchanging facts of the game
* are listed as base propositions. Often, this is so the fact can be
* accessed by a visualization. Gamers usually don't need this distinction,
* and can reduce the costs in time and memory of processing the game if
* these statements are instead transformed into sentences.
* @throws InterruptedException
*/
public static List run(List description) throws InterruptedException {
SentenceFormModel model = SentenceFormModelFactory.create(description);
List nextFormsToReplace = new ArrayList();
//Find the update rules for each "true" statement
for(SentenceForm nextForm : model.getSentenceForms()) {
if(nextForm.getName().equals(GdlPool.NEXT)) {
//See if there is exactly one update rule, and it is the persistence rule
Set rules = model.getRules(nextForm);
if(rules.size() == 1) {
GdlRule rule = rules.iterator().next();
//Persistence rule: Exactly one literal, the "true" form of the sentence
if(rule.arity() == 1) {
GdlLiteral literal = rule.get(0);
if(literal instanceof GdlRelation) {
//Check that it really is the true form
SentenceForm trueForm = nextForm.withName(GdlPool.TRUE);
if(trueForm.matches((GdlRelation) literal)) {
GdlSentence head = rule.getHead();
GdlSentence body = (GdlSentence) literal;
//Check that the tuples are the same, and that they
//consist of distinct variables
List headTuple = GdlUtils.getTupleFromSentence(head);
List bodyTuple = GdlUtils.getTupleFromSentence(body);
if(headTuple.equals(bodyTuple)) {
//Distinct variables?
Set vars = new HashSet(headTuple);
if(vars.size() == headTuple.size()) {
nextFormsToReplace.add(nextForm);
}
}
}
}
}
}
}
}
List newDescription = new ArrayList(description);
//Now, replace the next forms
for (SentenceForm nextForm : nextFormsToReplace) {
SentenceForm initForm = nextForm.withName(GdlPool.INIT);
SentenceForm trueForm = nextForm.withName(GdlPool.TRUE);
SentenceForm baseForm = nextForm.withName(GdlPool.BASE);
//Go through the rules and relations, making replacements as needed
for (int i = 0; i < newDescription.size(); i++) {
Gdl gdl = newDescription.get(i);
if (gdl instanceof GdlRelation) {
//Replace initForm
GdlRelation relation = (GdlRelation) gdl;
if (initForm.matches(relation)) {
GdlSentence newSentence = relation.get(0).toSentence();
newDescription.set(i, newSentence);
} else if (baseForm.matches(relation)) {
newDescription.remove(i);
i--;
}
} else if (gdl instanceof GdlRule) {
GdlRule rule = (GdlRule) gdl;
//Remove persistence rule (i.e. rule with next form as head)
GdlSentence head = rule.getHead();
if (nextForm.matches(head) || baseForm.matches(head)) {
newDescription.remove(i);
i--;
} else {
//Replace true in bodies of rules with relation-only form
List body = rule.getBody();
List newBody = replaceRelationInBody(body, trueForm);
GdlSentence newHead = head;
if (initForm.matches(head)) {
newHead = head.get(0).toSentence();
}
if (!body.equals(newBody) || !head.equals(newHead)) {
GdlRule newRule = GdlPool.getRule(newHead, newBody);
newDescription.set(i, newRule);
}
}
}
}
}
return newDescription;
}
private static List replaceRelationInBody(
List body, SentenceForm trueForm) {
List newBody = new ArrayList();
for(GdlLiteral literal : body) {
newBody.add(replaceRelationInLiteral(literal, trueForm));
}
return newBody;
}
private static GdlLiteral replaceRelationInLiteral(GdlLiteral literal,
SentenceForm trueForm) {
if(literal instanceof GdlSentence) {
GdlSentence sentence = (GdlSentence) literal;
if(trueForm.matches(sentence)) {
//Replace with the sentence contained in the true sentence...
return sentence.get(0).toSentence();
} else {
return literal;
}
} else if(literal instanceof GdlNot) {
GdlNot not = (GdlNot) literal;
return GdlPool.getNot(replaceRelationInLiteral(not.getBody(), trueForm));
} else if(literal instanceof GdlOr) {
GdlOr or = (GdlOr) literal;
List newOrBody = new ArrayList();
for(int i = 0; i < or.arity(); i++)
newOrBody.add(replaceRelationInLiteral(or.get(i), trueForm));
return GdlPool.getOr(newOrBody);
} else if(literal instanceof GdlDistinct) {
return literal;
} else {
throw new RuntimeException("Unanticipated GDL literal type "+literal.getClass()+" encountered in Relationizer");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy