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

import lombok.Getter;

@Getter
public class DependencyTerm extends EvaluatableTerm{

	private Dependency dependency;
	private EvaluatableTerm argumentTerm;
	
	public DependencyTerm(int order) {
		super(order);
	}
	
	public DependencyTerm(Dependency dependency, EvaluatableTerm argumentTerm) {
		super(dependency.getDependedVariable().getOrder() - 1);
		this.dependency = dependency;
		this.argumentTerm = argumentTerm;
		this.addChild(dependency.getDependingTerm());
		this.addChild(dependency.getDependedVariable());
		this.addChild(argumentTerm);
	}
	
	@Override
	public boolean isLinearRightNormal() {
		return isLinearRightNormal(0);
	}
	
	@Override
	public EvaluatableTerm linearRightNormalize() {
		DependencyTerm newTerm = (DependencyTerm) clone();
		newTerm.selfLinearRightNormalize();
		return newTerm;
	}
	
	@Override
	public int getOrder() {
		ResourceVariable variable = dependency.getDependedVariable();
		if(variable.getOrder() == argumentTerm.getOrder()) {
			return variable.getOrder();
		} else {
			return variable.getOrder() - 1;
		}
	}

	@Override
	public void selfLinearRightNormalize() {
		EvaluatableTerm term = (EvaluatableTerm) dependency.getDependingTerm(); //depending term. a of [a : b -> c] 
		if(term instanceof ResourceVariable || term instanceof SetEvaluatableTerm) {
			argumentTerm.selfLinearRightNormalize();
			return;
		}
		DependencyTerm dependencyTerm = (DependencyTerm) term;
		if(! dependencyTerm.isLinearRightNormal()) {
			dependencyTerm.selfLinearRightNormalize();
		}
		if(! isLinearRightNormal()) {
			Dependency childDependency = dependencyTerm.getDependency();
			EvaluatableTerm childArgumentTerm = dependencyTerm.getArgumentTerm();
			Dependency nextDependency = new Dependency(childArgumentTerm, dependency.getDependedVariable());
			DependencyTerm nextDependencyTerm = new DependencyTerm(nextDependency, argumentTerm);
			this.argumentTerm = nextDependencyTerm;
			this.dependency = childDependency;
			this.setChild(3, nextDependencyTerm);
			this.setChild(0, childDependency.getChild(0));
			this.setChild(1, childDependency.getChild(1));
		}
		argumentTerm.selfLinearRightNormalize();
		
	}
	
	private boolean isLinearRightNormal(int depth) {
		EvaluatableTerm term = (EvaluatableTerm) dependency.getDependingTerm(); //depending term. a of [a : b -> c] 
		ResourceVariable variable = dependency.getDependedVariable();
		if(term instanceof ResourceVariable || term instanceof SetEvaluatableTerm) {
			return term.getOrder() == variable.getOrder();
		}
		DependencyTerm dependencyTerm = (DependencyTerm) term;
		if(
				dependencyTerm.isLinearRightNormal(depth + 1) && 
				dependencyTerm.getDependency().getDependedVariable().getOrder() - 1 == variable.getOrder() && 
				dependencyTerm.getOrder() == variable.getOrder() &&
				argumentTerm.getOrder() <= dependencyTerm.getOrder() &&
				depth == 0
		) {
			return true;
		}
		if(
				dependencyTerm.isLinearRightNormal(depth + 1) && 
				dependencyTerm.getDependency().getDependedVariable().getOrder() - 1 == variable.getOrder() && 
				dependencyTerm.getOrder() == variable.getOrder() &&
				argumentTerm.getOrder() < dependencyTerm.getOrder()
		) {
			return true;
		}
		
		return false;
	}
	
	@Override
	public String toStr() {
		StringBuilder sb = new StringBuilder();
		sb.append('[');
		sb.append(dependency.getDependingTerm().toStr());
		sb.append(" : ");
		sb.append(dependency.getDependedVariable().toStr());
		sb.append(" -> ");
		sb.append(argumentTerm.toStr());
		sb.append(']');
		return sb.toString();
	}
	
	@Override
	public String toStrWithOrder() {
		StringBuilder sb = new StringBuilder();
		sb.append('[');
		sb.append(dependency.getDependingTerm().toStrWithOrder());
		sb.append(" : ");
		sb.append(dependency.getDependedVariable().toStrWithOrder());
		sb.append(" -> ");
		sb.append(argumentTerm.toStrWithOrder());
		sb.append(']');
		sb.append('(');
		sb.append(order);
		sb.append(')');
		return sb.toString();
	}

	@Override
	public Object clone() {
		return new DependencyTerm(
				(Dependency) dependency.clone(),
				(EvaluatableTerm) argumentTerm.clone() 
		);
	}

}