/**
*
*/
package agg.xt_basis;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import agg.attribute.AttrConditionTuple;
import agg.attribute.AttrContext;
import agg.cons.Evaluable;
import agg.cons.Formula;
import agg.util.XMLHelper;
/**
* @author olga
*
*/
public class NestedApplCond extends OrdinaryMorphism implements Evaluable {
NestedApplCond itsParent;
String varTag = "";
// private boolean valid;
// private int old_tick;
// private boolean old_val;
private boolean evaluable=true;
final List<NestedApplCond> itsACs = new Vector<NestedApplCond>(0, 1);
String formulaStr = "true";
Formula itsFormula = new Formula(true);
OrdinaryMorphism relatedMorph;
public boolean forall, exist;
public NestedApplCond(final Graph orig, final Graph img, final AttrContext ac) {
super(orig, img, ac);
}
public void setParent(NestedApplCond ac) {
this.itsParent = ac;
}
public NestedApplCond getParent() {
return this.itsParent;
}
public void setName(String n) {
this.itsName = n;
this.itsFormula.setName(n.concat(".formula"));
}
public String getName() {
return this.itsName;
}
public void clear() {
for (int i=0; i<this.itsACs.size(); i++) {
this.itsACs.get(i).clear();
}
super.clear();
}
public void dispose() {
this.clear();
this.itsACs.clear();
super.dispose();
}
/**
* Checks dangling edges of this and its nested application conditions.
* Returns true if no dangling edge exists, otherwise false.
*/
public boolean isValid() {
if (this.isEnabled()) {
final Iterator<Node> objects = this.itsOrig.getNodesSet().iterator();
while (objects.hasNext()) {
final Node x = objects.next();
if (this.getImage(x) == null) {
final Node y = (Node) this.getImage(x);
if (y != null
&& x.getNumberOfArcs() != y.getNumberOfArcs()) {
this.setErrorMsg(this.getName()+" - General AC failed (dangling edge)");
// this.setErrorMsg(this.getName()+" - General AC failed (dangling edge)");
return false;
}
}
}
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (!ac.isValid()) {
// this.setErrorMsg(this.getName()+": "+ac.getName()+" - General AC failed (dangling edge)");
return false;
}
}
}
return true;
}
/**
* Destroys validation results of this general application condition.
* The validation results correspond to its rule and the current match.
* They are temporary and should be destroyed after the current match is checked.
*/
public void disposeResults() {
this.relatedMorph = null;
for (int i=0; i<this.itsACs.size(); i++) {
this.itsACs.get(i).disposeResults();
}
if (this.itsCoMorph != null) {
this.itsCoMorph.dispose();
this.itsCoMorph = null;
}
}
/**
* Creates and adds a new (nested) application condition.
* Note, because a new morphism is empty and the this.target graph is not,
* it is not a morphism in terms of theory,
* which demands an application condition to be a total morphism.
*
* @return an empty morphism <code>ac</code> with
* <code>ac.getOriginal() == this.getTarget()</code>.
*/
public NestedApplCond createNestedAC() {
final NestedApplCond ac = new NestedApplCond(
this.itsImag,
BaseFactory.theFactory().createGraph(this.itsImag.getTypeSet()),
this.itsImag.getAttrContext());
ac.setParent(this);
this.itsACs.add(ac);
AttrContext acContext = ac.getAttrContext();
ac.getImage().setAttrContext(acContext);
ac.getImage().setKind(GraphKind.AC);
return ac;
}
public boolean addNestedAC(final NestedApplCond cond) {
if (cond.getSource() == this.itsImag
&& !this.itsACs.contains(cond)) {
this.itsACs.add(cond);
cond.setParent(this);
return true;
}
return false;
}
public boolean addNestedAC(int indx, final NestedApplCond ac) {
if (ac.getSource() == this.itsImag
&& !this.itsACs.contains(ac)) {
ac.getTarget().setKind(GraphKind.AC);
if (indx >= 0 && indx < this.itsACs.size())
this.itsACs.add(indx, ac);
else
this.itsACs.add(ac);
ac.setParent(this);
return true;
}
return false;
}
public void removeNestedAC(final NestedApplCond ac) {
if (this.itsACs.remove(ac)) {
this.itsFormula.patchOutEvaluable(ac, true);
this.refreshFormula(new Vector<Evaluable>(this.getEnabledACs()));
// ac.getImage().dispose();
}
}
public int getSizeOfNestedAC() {
return this.itsACs.size();
}
public List<NestedApplCond> getNestedACs() {
return this.itsACs;
}
public List<Evaluable> getEnabledGeneralACsAsEvaluable() {
List<Evaluable> list = new Vector<Evaluable>(this.itsACs.size());
for (int i = 0; i < this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled())
list.add(ac);
}
return list;
}
public NestedApplCond getNestedACAt(int indx) {
if (indx >= 0 && indx < this.itsACs.size())
return this.itsACs.get(indx);
return null;
}
public boolean setDefaultFormulaTrue() {
final List<Evaluable> vars = new Vector<Evaluable>(this.itsACs.size());
if (this.itsACs.size() == 0) {
this.formulaStr = "true";
return true;
}
String tmp = "";
int indx = -1;
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled()) {
indx++;
vars.add(ac);
if (indx == 0)
tmp = tmp.concat(String.valueOf(indx+1));
else
tmp = tmp.concat("&").concat(String.valueOf(indx+1));
// ac.setVarTagInFormula(String.valueOf(indx+1));
}
}
if ("".equals(tmp)) {
this.formulaStr = "true";
return true;
}
if (this.itsFormula.setFormula(vars, tmp)) {
this.formulaStr = this.itsFormula.getAsString(vars);
// System.out.println("NestedApplCond: "+this.getName()+" default formula: "+this.formulaStr);
return true;
}
return false;
}
public boolean setDefaultFormulaFalse() {
final List<Evaluable> vars = new Vector<Evaluable>(this.itsACs.size());
if (this.itsACs.size() == 0) {
this.formulaStr = "true";
return true;
}
String tmp = "";
int indx = -1;
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled()) {
indx++;
vars.add(ac);
if (indx == 0)
tmp = tmp.concat(String.valueOf(indx+1));
else
tmp = tmp.concat("&").concat(String.valueOf(indx+1));
// ac.setVarTagInFormula(String.valueOf(indx+1));
}
}
if ("".equals(tmp)) {
this.formulaStr = "true";
return true;
} else {
tmp ="!(".concat(tmp).concat(")");
}
if (this.itsFormula.setFormula(vars, tmp)) {
this.formulaStr = this.itsFormula.getAsString(vars);
// System.out.println("NestedApplCond: "+this.getName()+" default formula: "+this.formulaStr);
return true;
}
return false;
}
public boolean refreshFormula(final List<Evaluable> vars) {
String bnf = this.formulaStr;
if (this.itsFormula.setFormula(vars, bnf)) {
this.formulaStr = this.itsFormula.getAsString(vars);
this.setTextualComment("Formula: ".concat(this.formulaStr));
return true;
} else {
this.formulaStr = "true";
}
return false;
}
public boolean setFormula(String formStr) {
// return this.setFormula(formStr, this.itsACs);
return this.setFormula(formStr, this.getEnabledACs());
}
/**
* Set a boolean formula represented by the specified string <code>formStr</code>
* above the nested application conditions of the <code>list</code>.
* @return <code>true</code> if successful, otherwise - <code>false</code>
*/
public boolean setFormula(String formStr, final List<NestedApplCond> list) {
if (formStr.equals("true")) {
this.formulaStr = formStr;
return true;
}
else if (formStr.equals("false")) {
return this.setDefaultFormulaFalse();
}
int n = 0;
final List<Evaluable> vars = new Vector<Evaluable>(n);
for (int i=0; i<list.size(); i++) {
NestedApplCond ac = list.get(i);
if (ac.isEnabled()) {
vars.add(ac);
n++;
}
}
if (n == 0) {
this.formulaStr = "true";
return true;
}
if (this.itsFormula.setFormula(vars, formStr)) {
this.formulaStr = this.itsFormula.getAsString(vars);
this.setTextualComment("Formula: ".concat(this.formulaStr));
interpretForallOperator();
// System.out.println("NestedApplCond: "+this.getName()+" formula: "+this.formulaStr);
return true;
} else
return false;
}
public void setFormula(Formula f) {
this.itsFormula = f;
this.formulaStr = this.itsFormula.getAsString(this.getEnabledGeneralACsAsEvaluable());
this.setTextualComment("Formula: ".concat(this.formulaStr));
}
private void interpretForallOperator() {
if (this.formulaStr.contains("A"))
this.forall = true;
else
this.forall = false;
}
public void setRelatedMorphism(final OrdinaryMorphism morph) {
this.relatedMorph = morph;
}
public OrdinaryMorphism getRelatedMorphism() {
return this.relatedMorph;
}
public boolean evaluate(final Graph g) {
if (!this.enabled) {
return true;
} else if (this.relatedMorph == null || this.relatedMorph.getTarget() != g) {
return false;
}
PACStarMorphism comorph = MatchHelper.createNestedACstar(this, this.relatedMorph);
boolean result =
(MatchHelper.checkGACStar(comorph, this, this.relatedMorph, false) != null);
this.disposeResults();
return result;
}
public void setCoMorphism(final OrdinaryMorphism aCoMorph) {
this.itsCoMorph = aCoMorph;
}
public boolean eval(Object o) {
// return eval(o, -1);
return evaluate((Graph) o);
}
public boolean eval(Object o, int tick) {
return evaluate((Graph) o);
// if (tick != -1 && tick == old_tick) {
// return old_val;
// }
// old_tick = tick;
// old_val = evaluate((Graph) o);
// return old_val;
}
public boolean eval(Object o, boolean negation) {
// return eval(o);
return evaluate((Graph) o);
}
public boolean eval(Object o, int tick, boolean negation) {
// return eval(o);
return evaluate((Graph) o);
}
public boolean isEvaluable() {
return this.evaluable;
}
// not used now!
/*
private void setEvaluable(OrdinaryMorphism m, Graph g) {
this.evaluable = true;
VarTuple vars = (VarTuple) m.getAttrContext().getVariables();
Vector<String> varnames = g.getVariableNamesOfAttributes();
CondTuple conds = (CondTuple) m.getAttrContext().getConditions();
for (int i = 0; i < conds.getSize() && this.evaluable; i++) {
CondMember cond = conds.getCondMemberAt(i);
if (!cond.isEvaluable(vars)) {
Vector<String> condVars = cond.getAllVariables();
for (int j = 0; j < condVars.size(); j++) {
String n = condVars.elementAt(j);
VarMember var = vars.getVarMemberAt(n);
if ((!var.isSet() && varnames.contains(n))
// || (!var.isSet() && !varnames.contains(n))
)
this.evaluable = false;
}
}
}
// check constants
if (this.evaluable)
doCheckConstantOfImage(m, g.getNodesSet().iterator());
if (this.evaluable)
doCheckConstantOfImage(m, g.getArcsSet().iterator());
}
private void doCheckConstantOfImage(
final OrdinaryMorphism m,
final Iterator<?> elems) {
while (elems.hasNext()) {
GraphObject o = (GraphObject) elems.next();
if (o.getAttribute() == null)
continue;
GraphObject img = m.getImage(o);
ValueTuple val = (ValueTuple) o.getAttribute();
for (int i = 0; i < val.getSize(); i++) {
ValueMember valm = val.getValueMemberAt(i);
if (valm.isSet() && valm.getExpr().isConstant()) {
if (img != null) {
ValueTuple valImg = (ValueTuple) img.getAttribute();
ValueMember valmImg = valImg.getValueMemberAt(i);
if (!(valmImg.isSet() && valmImg.getExpr().equals(
valm.getExpr()))) {
this.evaluable = false;
}
}
}
}
}
}
*/
public String getFormulaStr() {
return this.formulaStr;
}
public String getFormulaText() {
return this.formulaStr;
}
public Formula getFormula() {
return this.itsFormula;
}
public boolean evalFormulaAtGraph(final Object g) {
return evalFormula((Graph ) g);
}
public boolean evalFormula(final Graph g) {
if (this.itsACs.size() != 0) {
if (this.itsCoMorph != null) {
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
ac.setRelatedMorphism(this.itsCoMorph);
}
if (this.formulaStr.equals("true"))
this.setDefaultFormulaTrue();
else if (this.formulaStr.equals("false"))
this.setDefaultFormulaFalse();
return this.itsFormula.eval(g);
}
return false;
}
return true;
}
public List<NestedApplCond> getEnabledNestedACs() {
final List<NestedApplCond> vars = new Vector<NestedApplCond>();
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled())
vars.add(ac);
vars.addAll(ac.getEnabledNestedACs());
}
return vars;
}
public List<NestedApplCond> getEnabledACs() {
final List<NestedApplCond> vars = new Vector<NestedApplCond>();
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled())
vars.add(ac);
}
return vars;
}
public List<String> getNameOfEnabledACs() {
final List<String> vars = new Vector<String>();
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled())
vars.add(ac.getName());
}
return vars;
}
public List<String> getNameOfEnabledNestedACs() {
final List<String> vars = new Vector<String>();
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
if (ac.isEnabled())
vars.add(ac.getName());
vars.addAll(ac.getNameOfEnabledNestedACs());
}
return vars;
}
public List<String> getNameOfNestedACs() {
final List<String> vars = new Vector<String>();
for (int i=0; i<this.itsACs.size(); i++) {
NestedApplCond ac = this.itsACs.get(i);
vars.add(ac.getName());
vars.addAll(ac.getNameOfEnabledNestedACs());
}
return vars;
}
public void setVarTagInFormula(String n) {
this.varTag = n;
}
public String getVarTagInFormula() {
return this.varTag;
}
/* (non-Javadoc)
* @see agg.util.XMLObject#XreadObject(agg.util.XMLHelper)
*/
public void readNestedApplConds(XMLHelper h) {
if (h.readSubTag("ApplCondition")) {
while (h.readSubTag("NestedAC")) {
String attrStr = h.readAttr("formula");
if (!"".equals(attrStr))
this.formulaStr = attrStr;
else
this.formulaStr = "true";
this.setTextualComment("Formula: ".concat(this.formulaStr));
boolean acEnabled = true;
Object acattr_enabled = h.readAttr("enabled");
if ((acattr_enabled != null)
&& ((String) acattr_enabled).equals("false"))
acEnabled = false;
NestedApplCond ac = createNestedAC();
ac.getTarget().setHelpInfo(this.getName());
ac.getTarget().xyAttr = this.getTarget().xyAttr;
h.getObject("", ac.getTarget(), true);
ac.readMorphism(h);
ac.readNestedApplConds(h);
h.close();
ac.setEnabled(acEnabled);
ac.getTarget().setHelpInfo("");
}
if (h.readSubTag("AttrCondition")) {
AttrConditionTuple condt = getAttrContext().getConditions();
if (condt != null)
h.enrichObject(condt);
h.close();
}
h.close();
this.setFormula(this.formulaStr);
}
}
/* (non-Javadoc)
* @see agg.util.XMLObject#XwriteObject(agg.util.XMLHelper)
*/
public void writeNestedApplConds(XMLHelper h) {
// Attr context conditions
AttrConditionTuple condt = this.getAttrContext().getConditions();
int num = condt.getNumberOfEntries();
// nested ACs
Enumeration<OrdinaryMorphism> nested = (new Vector<OrdinaryMorphism>(this.itsACs)).elements();
if (nested.hasMoreElements()) {
h.openSubTag("ApplCondition");
while (nested.hasMoreElements()) {
OrdinaryMorphism m = nested.nextElement();
m.getTarget().setKind(GraphKind.AC);
h.openSubTag("NestedAC");
if (!"".equals(this.formulaStr))
h.addAttr("formula", this.formulaStr);
if (!m.isEnabled())
h.addAttr("enabled", "false");
h.addObject("", m.getTarget(), true);
m.writeMorphism(h);
((NestedApplCond) m).writeNestedApplConds(h);
h.close();
}
// Attr context conditions
if (num > 0) {
h.openSubTag("AttrCondition");
h.addObject("", condt, true);
h.close();
}
h.close();
}
}
/* (non-Javadoc)
* @see agg.cons.Evaluable#evalForall(java.lang.Object, int, boolean)
*/
public boolean evalForall(Object o, int tick) {
// TODO Auto-generated method stub
return false;
}
}