Newer
Older
ResourceDependencyLogic / src / inference / equivalence / MetaSemanticEquivalenceRelation.java
@Sakoda2269 Sakoda2269 on 20 Dec 5 KB 途中まで
package inference.equivalence;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import exceptions.SubstituteFailedException;
import lombok.Getter;
import models.algebra.Expression;
import models.algebra.Variable;
import models.terms.RDLTerm;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaVariable;
import models.terms.meta.OrderVariableConstraint;
import utils.Permutation;

@Getter
public class MetaSemanticEquivalenceRelation {
	
	private MetaRDLTerm leftSideHand;
	private MetaRDLTerm rightSideHand;
	private Expression order;
	
	public MetaSemanticEquivalenceRelation(MetaRDLTerm lsh, MetaRDLTerm rsh, Expression order) {
		leftSideHand = lsh;
		rightSideHand = rsh;
		this.order = order;
	}
	
	public boolean isMatchedBy(SemanticEquivalenceRelation relation) {
		Map<Variable, RDLTerm> binding = new HashMap<>();
		Map<Variable, OrderVariableConstraint> orderConstraint = new HashMap<>();
		return isMatchedBy(relation, binding, orderConstraint);
	}
	
	public boolean isMatchedBy(SemanticEquivalenceRelation relation, Map<Variable, RDLTerm> binding, Map<Variable, OrderVariableConstraint> orderConstraint) {
		return leftSideHand.isMatchedBy(relation.getLeftSideHand(), binding, orderConstraint)
					&& rightSideHand.isMatchedBy(relation.getRightSideHand(), binding, orderConstraint);
	}
	
	public Set<SemanticEquivalenceRelation> substitute(RDLTerm term, Collection<RDLTerm> existedTerms) {
		Set<SemanticEquivalenceRelation> result = new HashSet<>();
		Set<SemanticEquivalenceRelation> leftSub = leftSubstitute(term, existedTerms);
		if (leftSub != null) {
			result.addAll(leftSub);
		}
		
		Set<SemanticEquivalenceRelation> rightSub = rightSubstitute(term, existedTerms);
		if (rightSub != null) {
			result.addAll(rightSub);
		}
		return result;
	}
	
	private Set<SemanticEquivalenceRelation> leftSubstitute(RDLTerm term, Collection<RDLTerm> existedTerms) {
		Set<SemanticEquivalenceRelation> result = new HashSet<>();
		Map<Variable, RDLTerm> binding = new HashMap<>();
		Map<Variable, OrderVariableConstraint> orderConstraint = new HashMap<>();
		if (! leftSideHand.isMatchedBy(term, binding, orderConstraint)) {
			return null;
		}
		if (! orderConstraint.containsKey(order)) {
			return null;
		}
		int order = orderConstraint.get(this.order).getOrder();
		if (order == -1) {
			return null;
		}
		
		Set<Variable> allVariables = new HashSet<>(rightSideHand.getVariables().values());
		allVariables.removeAll(binding.keySet());
		List<Variable> leftVariables = new ArrayList<>(allVariables);
		for (List<RDLTerm> useVariables: Permutation.permutation(existedTerms, leftVariables.size())) {
			Map<Variable, RDLTerm> tempBinding = new HashMap<>();
			tempBinding.putAll(binding);
			for (int i = 0; i < leftVariables.size(); i++) {
				tempBinding.put(leftVariables.get(i), useVariables.get(i));
			}
			RDLTerm tempTerm = rightSideHand.substitute(tempBinding);
			if (! rightSideHand.isMatchedBy(tempTerm, binding, orderConstraint)) {
				continue;
			}
			result.add(new SemanticEquivalenceRelation(leftSideHand.substitute(binding), rightSideHand.substitute(binding), order));
			for (int i = 0; i < leftVariables.size(); i++) {
				binding.remove(leftVariables.get(i));
			}
		}
		try {
			result.add(new SemanticEquivalenceRelation(leftSideHand.substitute(binding), rightSideHand.substitute(binding), order));
		} catch (SubstituteFailedException e){}
		return result;
	}
	
	private Set<SemanticEquivalenceRelation> rightSubstitute(RDLTerm term, Collection<RDLTerm> existedTerms) {
		Set<SemanticEquivalenceRelation> result = new HashSet<>();
		Map<Variable, RDLTerm> binding = new HashMap<>();
		Map<Variable, OrderVariableConstraint> orderConstraint = new HashMap<>();
		if (! rightSideHand.isMatchedBy(term, binding, orderConstraint)) {
			return null;
		};
		if (! orderConstraint.containsKey(order)) {
			return null;
		}
		int order = orderConstraint.get(this.order).getOrder();
		if (order == -1) {
			return null;
		}
		
		Set<Variable> allVariables = new HashSet<>();
		for (MetaVariable vari : leftSideHand.getAllVariables()) {
			allVariables.add(vari.getVariableName());
		}
		allVariables.removeAll(binding.keySet());
		List<Variable> leftVariables = new ArrayList<>(allVariables);
		for (List<RDLTerm> useVariables: Permutation.permutation(existedTerms, leftVariables.size())) {
			Map<Variable, RDLTerm> tempBinding = new HashMap<>();
			tempBinding.putAll(binding);
			for (int i = 0; i < leftVariables.size(); i++) {
				tempBinding.put(leftVariables.get(i), useVariables.get(i));
			}
			RDLTerm tempTerm = leftSideHand.substitute(tempBinding);
			if (! leftSideHand.isMatchedBy(tempTerm, binding, orderConstraint)) {
				for (int i = 0; i < leftVariables.size(); i++) {
					binding.remove(leftVariables.get(i));
				}
				continue;
			}
			result.add(new SemanticEquivalenceRelation(leftSideHand.substitute(binding), rightSideHand.substitute(binding), order));
			for (int i = 0; i < leftVariables.size(); i++) {
				binding.remove(leftVariables.get(i));
			}
		}
		try {
			result.add(new SemanticEquivalenceRelation(leftSideHand.substitute(binding), rightSideHand.substitute(binding), order));
		} catch (SubstituteFailedException e){}
		return result;
		
	}
	
	
	@Override
	public String toString() {
		return leftSideHand.toString() + " ===(" + order + ") " + rightSideHand.toString();
	}
	
	@Override
	public boolean equals(Object another) {
		if (! (another instanceof SemanticEquivalenceRelation)) {
			return false;
		}
		SemanticEquivalenceRelation relation = (SemanticEquivalenceRelation) another;
		return leftSideHand.equals(relation.getLeftSideHand()) && rightSideHand.equals(relation.getRightSideHand());
	}
	
	@Override
	public int hashCode() {
		return toString().hashCode();
	}
	
}