Newer
Older
ResourceDependencyLogic / src / models / DependencyTerm.java
package models;

import lombok.Getter;
import models.algebra.Symbol;

@Getter
public class DependencyTerm extends EvaluatableTerm{

	private EvaluatableTerm dependingTerm;
	private ResourceVariable dependedVariable;
	private EvaluatableTerm argumentTerm;
	
	public DependencyTerm(int order) {
		super(new Symbol(":", 3), order);
	}
	
	public DependencyTerm(EvaluatableTerm dependingTerm, ResourceVariable dependedVariable, EvaluatableTerm argumentTerm) {
		super(new Symbol(":", 3), dependedVariable.getOrder() == argumentTerm.getOrder() ? dependedVariable.getOrder() : dependedVariable.getOrder() - 1);
		this.dependingTerm = dependingTerm;
		this.dependedVariable = dependedVariable;
		this.argumentTerm = argumentTerm;
		addChild(dependingTerm);
		addChild(dependedVariable);
		addChild(argumentTerm);
	}
	
	@Override
	public boolean isLinearRightNormal() {
		return isLinearRightNormal(0);
	}
	
	@Override
	public EvaluatableTerm linearRightNormalize() {
		DependencyTerm newTerm = (DependencyTerm) clone();
		newTerm.selfLinearRightNormalize();
		return newTerm;
	}
	
	@Override
	public void selfLinearRightNormalize() {
		if(dependingTerm instanceof ResourceVariable || dependingTerm instanceof SetEvaluatableTerm) {
			argumentTerm.selfLinearRightNormalize();
			return;
		}
		DependencyTerm dependencyTerm = (DependencyTerm) dependingTerm;
		if(! dependencyTerm.isLinearRightNormal()) {
			dependencyTerm.selfLinearRightNormalize();
		}
		if(! isLinearRightNormal()) {
			EvaluatableTerm childArgumentTerm = dependencyTerm.getArgumentTerm();
			DependencyTerm nextDependencyTerm = new DependencyTerm(childArgumentTerm, dependedVariable, argumentTerm);
			this.dependingTerm = dependencyTerm.getDependingTerm();
			this.dependedVariable = dependencyTerm.getDependedVariable();
			this.argumentTerm = nextDependencyTerm;
			this.setChild(3, nextDependencyTerm);
			this.setChild(0, dependencyTerm.getDependingTerm());
			this.setChild(1, dependencyTerm.getDependedVariable());
		}
		argumentTerm.selfLinearRightNormalize();
		
	}
	
	private boolean isLinearRightNormal(int depth) {
		if(dependingTerm instanceof ResourceVariable || dependingTerm instanceof SetEvaluatableTerm) {
			return dependingTerm.getOrder() == dependedVariable.getOrder();
		}
		DependencyTerm dependencyTerm = (DependencyTerm) dependingTerm;
		if(
				dependencyTerm.isLinearRightNormal(depth + 1) && 
				dependencyTerm.getDependedVariable().getOrder() - 1 == dependedVariable.getOrder() && 
				dependencyTerm.getOrder() == dependedVariable.getOrder() &&
				argumentTerm.getOrder() <= dependencyTerm.getOrder() &&
				depth == 0
		) {
			return true;
		}
		if(
				dependencyTerm.isLinearRightNormal(depth + 1) && 
				dependencyTerm.getDependedVariable().getOrder() - 1 == dependedVariable.getOrder() && 
				dependencyTerm.getOrder() == dependedVariable.getOrder() &&
				argumentTerm.getOrder() < dependencyTerm.getOrder()
		) {
			return true;
		}
		
		return false;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append('[');
		sb.append(getDependingTerm().toString());
		sb.append(" : ");
		sb.append(getDependedVariable().toString());
		sb.append(" -> ");
		sb.append(argumentTerm.toString());
		sb.append(']');
		return sb.toString();
	}
	
	@Override
	public String toStringWithOrder() {
		StringBuilder sb = new StringBuilder();
		sb.append('[');
		sb.append(getDependingTerm().toStringWithOrder());
		sb.append(" : ");
		sb.append(getDependedVariable().toStringWithOrder());
		sb.append(" -> ");
		sb.append(argumentTerm.toStringWithOrder());
		sb.append(']');
		sb.append('(');
		sb.append(order);
		sb.append(')');
		return sb.toString();
	}
	
	@Override
	public boolean equals(Object another) {
		if(! (another instanceof DependencyTerm)) {
			return false;
		}
		DependencyTerm term = (DependencyTerm) another;
		return dependingTerm.equals(term.getDependingTerm()) && 
				dependedVariable.equals(term.getDependedVariable()) && 
				argumentTerm.equals(term.getArgumentTerm());
	}

	@Override
	public int hashCode() {
		return ("DT" + toString()).hashCode();
	}

	@Override
	public Object clone() {
		return new DependencyTerm(
				(EvaluatableTerm) dependingTerm.clone(),
				(ResourceVariable) dependedVariable.clone(),
				(EvaluatableTerm) argumentTerm.clone() 
		);
	}


}