Package lupos.rif.visitor

Source Code of lupos.rif.visitor.SubstituteFunctionCallsVisitor

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.rif.visitor;

import java.util.ArrayList;
import java.util.List;

import lupos.rif.IExpression;
import lupos.rif.IRuleNode;
import lupos.rif.IRuleVisitor;
import lupos.rif.IVariableScope;
import lupos.rif.RIFException;
import lupos.rif.SimpleRuleVisitor;
import lupos.rif.model.Conjunction;
import lupos.rif.model.Constant;
import lupos.rif.model.Disjunction;
import lupos.rif.model.Document;
import lupos.rif.model.Equality;
import lupos.rif.model.ExistExpression;
import lupos.rif.model.External;
import lupos.rif.model.Rule;
import lupos.rif.model.RuleList;
import lupos.rif.model.RulePredicate;
import lupos.rif.model.RuleVariable;

public class SubstituteFunctionCallsVisitor implements
    IRuleVisitor<IRuleNode, Object> {
  private String aliasString = "ALIASVAR_";
  private int aliasCtr = 0;
  private IVariableScope currentVariableScope = null;

  public IRuleNode visit(Document obj, Object arg) throws RIFException {
    for (Rule rule : obj.getRules())
      if (rule.isImplication())
        rule.accept(this, arg);
    return obj;
  }

  public IRuleNode visit(Conjunction obj, Object arg) throws RIFException {
    // Conjunction koennen Rueckgabe sein, neu berechen
    List<IExpression> exprs = new ArrayList<IExpression>(obj.exprs);
    obj.exprs.clear();
    for (IExpression expr : exprs)
      // keine einzelnen Externals
      if (expr instanceof External)
        obj.addExpr(expr);
      else
        obj.addExpr((IExpression) expr.accept(this, obj));
    return obj;
  }

  public IRuleNode visit(Disjunction obj, Object arg) throws RIFException {
    // Conjunction koennen Rueckgabe sein, neu berechen
    List<IExpression> exprs = new ArrayList<IExpression>(obj.exprs);
    obj.exprs.clear();
    for (IExpression expr : exprs)
      // keine einzelnen Externals
      if (expr instanceof External)
        obj.addExpr(expr);
      else
        obj.addExpr((IExpression) expr.accept(this, obj));
    return obj;
  }

  public IRuleNode visit(ExistExpression obj, Object arg) throws RIFException {
    IVariableScope temp = currentVariableScope;
    currentVariableScope = obj;
    if (!(obj.expr instanceof External))
      obj.expr = (IExpression) obj.expr.accept(this, obj);
    currentVariableScope = temp;
    return obj;
  }

  public IRuleNode visit(Rule obj, Object arg) throws RIFException {
    currentVariableScope = obj;
    aliasCtr = 0;
    obj.setHead((IExpression) obj.getHead().accept(this, obj));

    // Equalities (mit Aliasvariablen) aus Head entfernen
    final List<Equality> equalities = new ArrayList<Equality>();
    final SimpleRuleVisitor extractEquality = new SimpleRuleVisitor() {
      @Override
      public IRuleNode visit(Equality obj, IRuleNode arg)
          throws RIFException {
        if (obj.isPossibleAssignment()
            && obj.leftExpr instanceof RuleVariable
            && ((RuleVariable) obj.leftExpr).getVariable()
                .getName().contains(aliasString)) {
          ((Conjunction) obj.getParent()).exprs.remove(obj);
          equalities.add(obj);
        }
        return null;
      }
    };
    obj.getHead().accept(extractEquality, null);

    if (!(obj.getBody() instanceof External))
      obj.setBody((IExpression) obj.getBody().accept(this, obj));

    // dem Body hinzufuegen
    if (!equalities.isEmpty()) {
      Conjunction conj = new Conjunction();
      conj.setParent(obj);
      for (Equality eq : equalities)
        conj.addExpr(eq);
      conj.addExpr(obj.getBody());
      obj.setBody(conj);
    }
    return obj;
  }

  public IRuleNode visit(External obj, Object arg) throws RIFException {
    final Conjunction conjunction = new Conjunction();
    conjunction.setParent((IRuleNode) arg);

    RuleVariable alias = new RuleVariable(aliasString + aliasCtr++);
    conjunction.addExpr(alias);

    Equality comp = new Equality();
    comp.leftExpr = new RuleVariable(alias.getName());
    comp.leftExpr.setParent(comp);
    comp.rightExpr = obj;
    obj.setParent(comp);
    conjunction.addExpr(comp);

    currentVariableScope.addVariable(new RuleVariable(alias.getName()));
    return conjunction;
  }

  public IRuleNode visit(RulePredicate obj, Object arg) throws RIFException {
    Conjunction conjunction = null;
    // Funktionsaufrufe mit Variable ersetzen
    ArrayList<IExpression> params = new ArrayList<IExpression>(
        obj.termParams);
    // Relationen koennen keine Externals sein.
    for (IExpression expr : obj.termParams) {
      final IRuleNode result = expr.accept(this, obj);
      if (result instanceof Conjunction) {
        conjunction = conjunction == null ? new Conjunction()
            : conjunction;
        for (IExpression item : ((Conjunction) result).exprs)
          if (item instanceof Equality)
            conjunction.addExpr(item);
          else
            params.set(params.indexOf(expr), item);
      }
    }
    obj.termParams = params;
    if (conjunction != null)
      conjunction.addExpr(obj);
    return conjunction == null ? obj : conjunction;
  }

  public IRuleNode visit(RuleList obj, Object arg) throws RIFException {
    Conjunction conjunction = null;
    ArrayList<IExpression> items = new ArrayList<IExpression>(
        obj.getItems());
    for (IExpression expr : obj.getItems()) {
      final IRuleNode result = expr.accept(this, obj);
      if (result instanceof Conjunction) {
        conjunction = conjunction == null ? new Conjunction()
            : conjunction;
        for (IExpression item : ((Conjunction) result).exprs)
          if (item instanceof Equality)
            conjunction.addExpr(item);
          else
            items.set(items.indexOf(expr), item);
      }
    }
    obj.getItems().clear();
    obj.getItems().addAll(items);
    if (conjunction != null)
      conjunction.addExpr(obj);
    return conjunction != null ? conjunction : obj;
  }

  public IRuleNode visit(Equality obj, Object arg) throws RIFException {
    return obj;
  }

  public IRuleNode visit(Constant obj, Object arg) throws RIFException {
    return obj;
  }

  public IRuleNode visit(RuleVariable obj, Object arg) throws RIFException {
    return obj;
  }
}
TOP

Related Classes of lupos.rif.visitor.SubstituteFunctionCallsVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.