Clover coverage report - Maven Clover report
Coverage timestamp: Tue Sep 16 2008 01:16:37 EEST
file stats: LOC: 585   Methods: 32
NCLOC: 416   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
WsmlFlightExpressionValidator.java 0% 0% 0% 0%
coverage
 1    /*
 2    wsmo4j - a WSMO API and Reference Implementation
 3    Copyright (c) 2005, University of Innsbruck, Austria
 4    This library is free software; you can redistribute it and/or modify it under
 5    the terms of the GNU Lesser General Public License as published by the Free
 6    Software Foundation; either version 2.1 of the License, or (at your option)
 7    any later version.
 8    This library is distributed in the hope that it will be useful, but WITHOUT
 9    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 10    FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 11    details.
 12    You should have received a copy of the GNU Lesser General Public License along
 13    with this library; if not, write to the Free Software Foundation, Inc.,
 14    59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 15    */
 16    package org.deri.wsmo4j.validator;
 17   
 18    import java.util.*;
 19   
 20    import org.deri.wsmo4j.io.serializer.wsml.LogExprSerializerWSML;
 21    import org.omwg.logicalexpression.*;
 22    import org.omwg.logicalexpression.terms.Term;
 23    import org.omwg.ontology.*;
 24    import org.wsmo.common.*;
 25    import org.wsmo.factory.*;
 26    import org.wsmo.validator.ValidationError;
 27   
 28    /**
 29    * Checks logical expressions for wsml-flight validity.
 30    *
 31    * @author nathalie.steinmetz@deri.org
 32    */
 33    public class WsmlFlightExpressionValidator implements Visitor {
 34   
 35    private LogExprSerializerWSML leSerializer = null;
 36   
 37    private LogicalExpressionFactory leFactory = null;
 38   
 39    private WsmlFullValidator validator = null;
 40   
 41    private Axiom axiom = null;
 42   
 43    private List <ValidationError> errors = null;
 44   
 45    private boolean body = false;
 46   
 47    private boolean found = false;
 48   
 49    private boolean builtIn = false;
 50   
 51    private boolean foundBuiltIn = false;
 52   
 53    private boolean foundNaf = false;
 54   
 55    private boolean unSafe = false;
 56   
 57    private boolean foundPos = false;
 58   
 59    private String errorMessage = "";
 60   
 61    /**
 62    * @param axiom
 63    * whose logical expression is checked
 64    * @param errors
 65    * list that will be filled with error messages of found variant
 66    * violations
 67    */
 68  0 protected WsmlFlightExpressionValidator(Axiom axiom, LogicalExpressionFactory leFactory, List <ValidationError> errors, WsmlFullValidator val) {
 69  0 this.axiom = axiom;
 70  0 this.errors = errors;
 71  0 this.validator = val;
 72  0 leSerializer = validator.leSerializer;
 73  0 this.leFactory = leFactory;
 74    }
 75   
 76  0 public void setup() {
 77  0 body = false;
 78  0 found = false;
 79  0 foundBuiltIn = false;
 80  0 builtIn = false;
 81  0 foundNaf = false;
 82  0 foundPos = false;
 83    }
 84   
 85    /**
 86    * Checks if an Atom is valid to wsml-flight.
 87    *
 88    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitAtom(org.omwg.logicalexpression.Atom)
 89    */
 90  0 public void visitAtom(Atom expr) {
 91  0 if (!body) {
 92  0 containsVariables(expr);
 93    }
 94    }
 95   
 96    /**
 97    * Checks if an AttributeConstraintMolecule is valid to wsml-flight.
 98    *
 99    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitAttributeContraintMolecule(org.omwg.logicalexpression.AttributeConstraintMolecule)
 100    */
 101  0 public void visitAttributeContraintMolecule(AttributeConstraintMolecule expr) {
 102  0 if (!body) {
 103  0 containsVariables(expr);
 104    }
 105    }
 106   
 107    /**
 108    * Checks if an AttributeInferenceMolecule is valid to wsml-flight.
 109    *
 110    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitAttributeInferenceMolecule(org.omwg.logicalexpression.AttributeInferenceMolecule)
 111    */
 112  0 public void visitAttributeInferenceMolecule(AttributeInferenceMolecule expr) {
 113  0 if (!body) {
 114  0 containsVariables(expr);
 115    }
 116    }
 117   
 118    /**
 119    * Checks if an AttributeValueMolecule is valid to wsml-flight.
 120    *
 121    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitAttributeValueMolecule(org.omwg.logicalexpression.AttributeValueMolecule)
 122    */
 123  0 public void visitAttributeValueMolecule(AttributeValueMolecule expr) {
 124  0 if (!body) {
 125  0 containsVariables(expr);
 126    }
 127    }
 128   
 129    /**
 130    * Checks if an CompoundMolecule is valid to wsml-flight.
 131    *
 132    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitCompoundMolecule(org.omwg.logicalexpression.CompoundMolecule)
 133    */
 134  0 public void visitCompoundMolecule(CompoundMolecule expr) {
 135  0 if (!body) {
 136  0 containsVariables(expr);
 137    }
 138    }
 139   
 140    /**
 141    * Checks if an MembershipMolecule is valid to wsml-flight.
 142    *
 143    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitMemberShipMolecule(org.omwg.logicalexpression.MembershipMolecule)
 144    */
 145  0 public void visitMemberShipMolecule(MembershipMolecule expr) {
 146  0 if (!body) {
 147  0 containsVariables(expr);
 148    }
 149    }
 150   
 151    /**
 152    * Checks if an SubConceptMolecule is valid to wsml-flight.
 153    *
 154    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitSubConceptMolecule(org.omwg.logicalexpression.SubConceptMolecule)
 155    */
 156  0 public void visitSubConceptMolecule(SubConceptMolecule expr) {
 157  0 if (!body) {
 158  0 containsVariables(expr);
 159    }
 160    }
 161   
 162   
 163    /**
 164    * Checks if a Negation is valid to wsml-flight.
 165    *
 166    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitNegation(org.omwg.logicalexpression.Negation)
 167    */
 168  0 public void visitNegation(Negation expr) {
 169   
 170    }
 171   
 172    /**
 173    * Checks if a NegationAsFailure is valid to wsml-flight.
 174    *
 175    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitNegationAsFailure(org.omwg.logicalexpression.NegationAsFailure)
 176    */
 177  0 public void visitNegationAsFailure(NegationAsFailure expr) {
 178  0 if (body) {
 179  0 expr.getOperand().accept(this);
 180    }
 181    }
 182   
 183    /**
 184    * Checks if a Constraint is valid to wsml-flight.
 185    *
 186    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitConstraint(org.omwg.logicalexpression.Constraint)
 187    */
 188  0 public void visitConstraint(Constraint expr) {
 189   
 190    }
 191   
 192    /**
 193    * Checks if a Conjunction is valid to wsml-flight.
 194    *
 195    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitConjunction(org.omwg.logicalexpression.Conjunction)
 196    */
 197  0 public void visitConjunction(Conjunction expr) {
 198  0 if (body) {
 199  0 expr.getLeftOperand().accept(this);
 200  0 expr.getRightOperand().accept(this);
 201    }
 202    }
 203   
 204    /**
 205    * Checks if a Disjunction is valid to wsml-flight.
 206    *
 207    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitDisjunction(org.omwg.logicalexpression.Disjunction)
 208    */
 209  0 public void visitDisjunction(Disjunction expr) {
 210  0 if (body) {
 211  0 expr.getLeftOperand().accept(this);
 212  0 expr.getRightOperand().accept(this);
 213    }
 214    }
 215   
 216    /**
 217    * Checks if an InverseImplication is valid to wsml-flight.
 218    *
 219    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitInverseImplication(org.omwg.logicalexpression.InverseImplication)
 220    */
 221  0 public void visitInverseImplication(InverseImplication expr) {
 222  0 if (body) {
 223  0 addError(expr, ValidationError.AX_BODY_ERR + ": Must not " +
 224    "contain an InverseImplication:\n" + leSerializer.serialize(expr));
 225  0 body = false;
 226    }
 227    }
 228   
 229    /**
 230    * Checks if an Implication is valid to wsml-flight.
 231    *
 232    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitImplication(org.omwg.logicalexpression.Implication)
 233    */
 234  0 public void visitImplication(Implication expr) {
 235  0 if (body) {
 236  0 addError(expr, ValidationError.AX_BODY_ERR + ": Must not " +
 237    "contain an Implication:\n" + leSerializer.serialize(expr));
 238  0 body = false;
 239    }
 240    }
 241   
 242    /**
 243    * Checks if an Equivalence is valid to wsml-flight.
 244    *
 245    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitEquivalence(org.omwg.logicalexpression.Equivalence)
 246    */
 247  0 public void visitEquivalence(Equivalence expr) {
 248  0 if (body) {
 249  0 addError(expr, ValidationError.AX_BODY_ERR + ": Must not " +
 250    "contain an Equivalence:\n" + leSerializer.serialize(expr));
 251  0 body = false;
 252    }
 253    }
 254   
 255    /**
 256    * Checks if a LogicProgrammingRule is valid to wsml-flight.
 257    *
 258    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitLogicProgrammingRule(org.omwg.logicalexpression.LogicProgrammingRule)
 259    */
 260  0 public void visitLogicProgrammingRule(LogicProgrammingRule expr) {
 261  0 body = true;
 262  0 expr.getRightOperand().accept(this);
 263  0 holdsSafetyCondition(expr);
 264    }
 265   
 266    /**
 267    * Checks if a UniversalQuantification is valid to wsml-flight.
 268    *
 269    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitUniversalQuantification(org.omwg.logicalexpression.UniversalQuantification)
 270    */
 271  0 public void visitUniversalQuantification(UniversalQuantification expr) {
 272  0 if (body) {
 273  0 addError(expr, ValidationError.AX_BODY_ERR + ": Must not " +
 274    "contain a UniversalQuantification:\n" + leSerializer.serialize(expr));
 275  0 body = false;
 276    }
 277    }
 278   
 279    /**
 280    * Checks if an ExistentialQuantification is valid to wsml-flight.
 281    *
 282    * @see org.deri.wsmo4j.validator.WsmlRuleExpressionValidator#visitExistentialQuantification(org.omwg.logicalexpression.ExistentialQuantification)
 283    */
 284  0 public void visitExistentialQuantification(ExistentialQuantification expr) {
 285  0 if (body) {
 286  0 addError(expr, ValidationError.AX_BODY_ERR + ": Must not " +
 287    "contain an ExistentialQuantification:\n" + leSerializer.serialize(expr));
 288  0 body = false;
 289    }
 290    }
 291   
 292  0 private boolean containsVariables(LogicalExpression expr) {
 293  0 boolean flag = false;
 294  0 if (expr instanceof CompoundMolecule) {
 295  0 if (!((CompoundMolecule) expr).listAttributeConstraintMolecules().isEmpty()) {
 296  0 Iterator it = ((CompoundMolecule) expr).listAttributeConstraintMolecules().iterator();
 297  0 while (it.hasNext()) {
 298  0 containsVariables((AttributeConstraintMolecule) it.next());
 299    }
 300    }
 301  0 else if (!((CompoundMolecule) expr).listAttributeInferenceMolecules().isEmpty()) {
 302  0 Iterator it = ((CompoundMolecule) expr).listAttributeInferenceMolecules().iterator();
 303  0 while (it.hasNext()) {
 304  0 containsVariables((AttributeInferenceMolecule) it.next());
 305    }
 306    }
 307  0 else if (!((CompoundMolecule) expr).listAttributeValueMolecules().isEmpty()) {
 308  0 Iterator it = ((CompoundMolecule) expr).listAttributeValueMolecules().iterator();
 309  0 while (it.hasNext()) {
 310  0 containsVariables((AttributeValueMolecule) it.next());
 311    }
 312    }
 313  0 else if (!((CompoundMolecule) expr).listMemberShipMolecules().isEmpty()) {
 314  0 Iterator it = ((CompoundMolecule) expr).listMemberShipMolecules().iterator();
 315  0 while (it.hasNext()) {
 316  0 containsVariables((MembershipMolecule) it.next());
 317    }
 318    }
 319  0 else if (!((CompoundMolecule) expr).listSubConceptMolecules().isEmpty()) {
 320  0 Iterator it = ((CompoundMolecule) expr).listSubConceptMolecules().iterator();
 321  0 while (it.hasNext()) {
 322  0 containsVariables((SubConceptMolecule) it.next());
 323    }
 324    }
 325    }
 326  0 else if (expr instanceof Molecule) {
 327  0 if (((Molecule) expr).getLeftParameter() instanceof Variable) {
 328  0 flag = true;
 329    }
 330  0 if (((Molecule) expr).getRightParameter() instanceof Variable) {
 331  0 flag = true;
 332    }
 333    }
 334  0 else if (expr instanceof Atom) {
 335  0 Iterator it = ((Atom) expr).listParameters().iterator();
 336  0 while (it.hasNext()) {
 337  0 if (it.next() instanceof Variable) {
 338  0 flag = true;
 339    }
 340    }
 341    }
 342  0 if (flag) {
 343  0 addError(expr, ValidationError.AX_HEAD_ERR + ":\n Any variable-free " +
 344    "admissible head formula is an admissible formula:\n" +
 345    leSerializer.serialize(expr));
 346  0 return false;
 347    }
 348  0 return true;
 349    }
 350   
 351  0 private void holdsSafetyCondition(LogicProgrammingRule l) {
 352  0 LogicalExpression leL = l.getLeftOperand();
 353  0 LogicalExpression leR = l.getRightOperand();
 354  0 if (leL instanceof Conjunction) {
 355  0 transformHeadConjunction(l);
 356    }
 357  0 else if (leL instanceof Equivalence) {
 358  0 transformHeadEquivalence(l);
 359    }
 360  0 else if (leL instanceof Implication) {
 361  0 transformHeadImplication(l);
 362    }
 363  0 else if (leL instanceof InverseImplication) {
 364  0 transformHeadInverseImplication(l);
 365    }
 366  0 else if (leR instanceof Disjunction) {
 367  0 transformBody(l);
 368    }
 369    else {
 370  0 isSafe(l);
 371    }
 372    }
 373   
 374  0 private void transformHeadInverseImplication(LogicProgrammingRule l) {
 375  0 LogicProgrammingRule lpr;
 376  0 Conjunction c;
 377  0 c = leFactory.createConjunction(((Binary) l.getLeftOperand()).getRightOperand(),
 378    l.getRightOperand());
 379  0 lpr = leFactory.createLogicProgrammingRule(((Binary) l.getLeftOperand()).getLeftOperand(),
 380    c);
 381  0 holdsSafetyCondition(lpr);
 382    }
 383   
 384  0 private void transformHeadImplication(LogicProgrammingRule l) {
 385  0 LogicProgrammingRule lpr;
 386  0 Conjunction c;
 387  0 c = leFactory.createConjunction(((Binary) l.getLeftOperand()).getLeftOperand(),
 388    l.getRightOperand());
 389  0 lpr = leFactory.createLogicProgrammingRule(((Binary) l.getLeftOperand()).getRightOperand(),
 390    c);
 391  0 holdsSafetyCondition(lpr);
 392    }
 393   
 394  0 private void transformHeadEquivalence(LogicProgrammingRule l) {
 395  0 LogicProgrammingRule lpr1;
 396  0 LogicProgrammingRule lpr2;
 397  0 Implication i;
 398  0 InverseImplication ini;
 399  0 i = leFactory.createImplication(((Binary) l.getLeftOperand()).getLeftOperand(),
 400    ((Binary) l.getLeftOperand()).getRightOperand());
 401  0 ini = leFactory.createInverseImplication(((Binary) l.getLeftOperand()).getLeftOperand(),
 402    ((Binary) l.getLeftOperand()).getRightOperand());
 403  0 lpr1 = leFactory.createLogicProgrammingRule(i, l.getRightOperand());
 404  0 lpr2 = leFactory.createLogicProgrammingRule(ini, l.getRightOperand());
 405  0 holdsSafetyCondition(lpr1);
 406  0 holdsSafetyCondition(lpr2);
 407    }
 408   
 409  0 private void transformHeadConjunction(LogicProgrammingRule l) {
 410  0 LogicProgrammingRule lpr1;
 411  0 LogicProgrammingRule lpr2;
 412  0 lpr1 = leFactory.createLogicProgrammingRule(((Binary) l.getLeftOperand()).getLeftOperand(),
 413    l.getRightOperand());
 414  0 lpr2 = leFactory.createLogicProgrammingRule(
 415    ((Binary) l.getLeftOperand()).getRightOperand(), l.getRightOperand());
 416  0 holdsSafetyCondition(lpr1);
 417  0 holdsSafetyCondition(lpr2);
 418    }
 419   
 420  0 private void transformBody(LogicProgrammingRule l) {
 421  0 LogicProgrammingRule lpr1;
 422  0 LogicProgrammingRule lpr2;
 423  0 lpr1 = leFactory.createLogicProgrammingRule(l.getLeftOperand(), ((Disjunction) l
 424    .getRightOperand()).getLeftOperand());
 425  0 lpr2 = leFactory.createLogicProgrammingRule(l.getLeftOperand(), ((Disjunction) l
 426    .getRightOperand()).getRightOperand());
 427  0 holdsSafetyCondition(lpr1);
 428  0 holdsSafetyCondition(lpr2);
 429    }
 430   
 431  0 private void isSafe(LogicProgrammingRule l) {
 432  0 found = false;
 433  0 foundPos = false;
 434  0 LogicalExpression ll = l.getLeftOperand();
 435  0 LogicalExpression lr = l.getRightOperand();
 436  0 HashSet <Term> leftSet = new HashSet <Term> ();
 437  0 leftSet = getSetOfHeadVariables(ll, leftSet);
 438  0 if (!leftSet.isEmpty()) {
 439  0 Iterator it = leftSet.iterator();
 440  0 while (it.hasNext()) {
 441  0 Variable v = (Variable) it.next();
 442  0 checkBodyVariables(lr, v, false);
 443  0 if (unSafe) {
 444  0 addError(l, ValidationError.AX_SAFETY_COND + ": " +
 445    "\nError: " + errorMessage + ":\n" +
 446    leSerializer.serialize(l));
 447    }
 448    }
 449    }
 450    }
 451   
 452  0 private HashSet <Term> getSetOfHeadVariables(LogicalExpression le, HashSet <Term> set) {
 453  0 if (le instanceof Atom) {
 454  0 for (int i = 0; i < ((Atom) le).getArity(); i++) {
 455  0 if (((Atom) le).getParameter(i) instanceof Variable) {
 456  0 set.add(((Atom) le).getParameter(i));
 457    }
 458    }
 459    }
 460  0 else if (le instanceof CompoundMolecule) {
 461  0 Iterator i = ((CompoundMolecule) le).listOperands().iterator();
 462  0 while (i.hasNext()) {
 463  0 getSetOfHeadVariables((Molecule) i.next(), set);
 464    }
 465    }
 466  0 else if (le instanceof Molecule) {
 467  0 if (((Molecule) le).getLeftParameter() instanceof Variable) {
 468  0 set.add(((Molecule) le).getLeftParameter());
 469    }
 470  0 if (((Molecule) le).getRightParameter() instanceof Variable) {
 471  0 set.add(((Molecule) le).getRightParameter());
 472    }
 473  0 if (le instanceof AttributeMolecule) {
 474  0 if (((AttributeMolecule) le).getAttribute() instanceof Variable) {
 475  0 set.add(((AttributeMolecule) le).getAttribute());
 476    }
 477    }
 478    }
 479  0 return set;
 480    }
 481   
 482  0 private void checkBodyVariables(LogicalExpression le, Variable v, boolean naf) {
 483  0 unSafe = false;
 484  0 if (le instanceof Conjunction) {
 485  0 LogicalExpression ll = ((Conjunction) le).getLeftOperand();
 486  0 LogicalExpression lr = ((Conjunction) le).getRightOperand();
 487  0 checkBodyVariables(ll, v, false);
 488  0 checkBodyVariables(lr, v, false);
 489    }
 490  0 else if (le instanceof NegationAsFailure) {
 491  0 LogicalExpression l = ((NegationAsFailure) le).getOperand();
 492  0 if (!foundNaf) {
 493  0 foundNaf = true;
 494  0 checkBodyVariables(l, v, true);
 495    }
 496    else {
 497  0 foundNaf = false;
 498  0 checkBodyVariables(l, v, false);
 499    }
 500   
 501    }
 502    else {
 503  0 if (le instanceof Atom) {
 504  0 if (le instanceof BuiltInAtom) {
 505  0 builtIn = true;
 506    }
 507  0 for (int i = 0; i < ((Atom) le).getArity(); i++) {
 508  0 if (((Atom) le).getParameter(i) instanceof Variable) {
 509  0 if (((Atom) le).getParameter(i).equals(v)) {
 510  0 found = true;
 511  0 if (naf) {
 512  0 foundNaf = true;
 513    }
 514    else {
 515  0 foundPos = true;
 516    }
 517  0 if (builtIn) {
 518  0 foundBuiltIn = true;
 519    }
 520    }
 521    }
 522    }
 523    }
 524  0 else if (le instanceof CompoundMolecule) {
 525  0 Iterator i = ((CompoundMolecule) le).listOperands().iterator();
 526  0 while (i.hasNext()) {
 527  0 if (findVariable((Molecule) i.next(), v)) {
 528  0 found = true;
 529  0 if (naf) {
 530  0 foundNaf = true;
 531    }
 532  0 if (builtIn) {
 533  0 foundBuiltIn = true;
 534    }
 535    }
 536    }
 537    }
 538  0 else if (le instanceof Molecule) {
 539  0 if (findVariable((Molecule) le, v)) {
 540  0 found = true;
 541  0 if (naf) {
 542  0 foundNaf = true;
 543    }
 544    else {
 545  0 foundPos = true;
 546    }
 547  0 if (builtIn) {
 548  0 foundBuiltIn = true;
 549    }
 550    }
 551    }
 552  0 if (foundNaf && !foundPos) {
 553  0 unSafe = true;
 554  0 errorMessage = "Variable " + v.toString() + " occurs in a negative body literal";
 555    }
 556  0 if (foundBuiltIn) {
 557  0 unSafe = true;
 558  0 errorMessage = "Variable " + v.toString() + " occurs in a body literal that "
 559    + "corresponds to a built-in predicate";
 560    }
 561  0 if (!found) {
 562  0 unSafe = true;
 563  0 errorMessage = "Variable " + v.toString() + " does not occur in the body literal";
 564    }
 565    }
 566    }
 567   
 568  0 private boolean findVariable(Molecule m, Variable v) {
 569  0 if (m.getLeftParameter().equals(v) || m.getRightParameter().equals(v)) {
 570  0 return true;
 571    }
 572  0 if (!(m instanceof AttributeMolecule)) {
 573  0 return false;
 574    }
 575  0 return ((AttributeMolecule) m).getAttribute().equals(v);
 576    }
 577   
 578  0 private void addError(LogicalExpression logexp, String msg) {
 579  0 LogicalExpressionErrorImpl le = new LogicalExpressionErrorImpl(
 580    axiom, logexp, msg, WSML.WSML_FLIGHT);
 581  0 if (!errors.contains(le)) {
 582  0 errors.add(le);
 583    }
 584    }
 585    }