Package ru.bmstu.datalog.algo

Source Code of ru.bmstu.datalog.algo.Unifier

package ru.bmstu.datalog.algo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import ru.bmstu.datalog.data.Argument;
import ru.bmstu.datalog.data.Predicate;

/**
* Container for substitution with produceMGU function.
* @author art-vybor
*/
class Unifier {
  private HashMap<Argument, Argument> substitution;
 
  public Unifier() {
    substitution = new HashMap<Argument, Argument>();
  }
 
  public Unifier(Unifier unifier) {
    substitution = new HashMap<Argument, Argument>();
    addAll(unifier);
  }

  public boolean isEqual(Argument a, Argument b) {
    Argument subA = substitution.get(a);
    Argument subB = substitution.get(b);
    if (subA == null) subA = a;
    if (subB == null) subB = b;
    return subA.equals(subB);
  }

  public Argument unify(Argument key) {
    Argument value = substitution.get(key);
    if (value != null) return substitution.get(key);
    return key;
  }
 
  public Argument get(Argument key) {
    return substitution.get(key);
  }
 
  public Set<Argument> getKeySet() {
    return substitution.keySet();
  }
 
  public void add(Argument key, Argument value) {
    substitution.put(key, value);   
  }

  @Override
  public String toString() {
    StringBuilder answerBuilder = new StringBuilder();
    answerBuilder.append("{");
     
    boolean f = false;
    for (Argument key : substitution.keySet()) {
      if (f) answerBuilder.append(", ");
      else f = true;
      answerBuilder.append(key.toString());
      answerBuilder.append("/");
      answerBuilder.append(substitution.get(key).toString());
    }
   
    answerBuilder.append("}");
    return answerBuilder.toString();
  }

  public void addWithUnify(Argument key, Argument value) {
    add(unify(key), unify(value));   
  }
 
  public Predicate unifyPredicate(Predicate predicate) {
    ArrayList<Argument> args = new ArrayList<Argument>();
   
    for (int i = 0; i < predicate.size(); i++) {
      args.add(unify(predicate.get(i)));
    }
   
    return new Predicate(predicate.getName(),args);
   
  }
 
  /**
   * Proguce MGU from two predicate, if not return null.
   * @param p1
   * @param p2
   * @return {@link Unifier}
   */
  public static Unifier produceMostGeneralUnifier(Predicate p1, Predicate p2) {
    //TODO переписать по человечески, как в курсаче
    if (!p1.isSimiliar(p2)) return null;
   
    Unifier unifier = new Unifier();
    boolean unifies = true;
    int lengthOfPredicate = p1.size();
   
    for (int i = 0; i < lengthOfPredicate && unifies; ++i) {
      Argument p1Arg = p1.get(i);
      Argument p2Arg = p2.get(i);
     
      if (unifier.isEqual(p1Arg, p2Arg) == false) {       
        if (unifier.unify(p1Arg).isVariable()) {
          unifier.addWithUnify(p1Arg, p2Arg);
         
        } else if (unifier.unify(p2Arg).isVariable()) {
          unifier.addWithUnify(p2Arg, p1Arg);
         
        } else unifies = false;
      }     
    }
   
    if (unifies)   return unifier;
    else     return null;
  }

  public void addAll(Unifier unifier) {
    substitution.putAll(unifier.getSubstitution());
  }

  private Map<Argument, Argument> getSubstitution() {
    return substitution;
  }

  /**
   * Returns a new unifier obtained merge this and source/dest.
   * @param sourcePredicate
   * @param destPredicate
   * @return {@link Unifier}
   */
  public Unifier getNewUnifier(Predicate sourcePredicate, Predicate destPredicate) {
    Unifier unifier = new Unifier(this);
   
    for (int i = 0; i < sourcePredicate.size(); i++) {
      if (sourcePredicate.get(i).isVariable()) {
        unifier.add(sourcePredicate.get(i), destPredicate.get(i));
      }
    }       
   
    return unifier;
  }
}

TOP

Related Classes of ru.bmstu.datalog.algo.Unifier

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.