Newer
Older
RDLProofSystem / src / main / java / models / terms / Dependency.java
package models.terms;

import com.google.common.collect.TreeMultiset;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

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

@Getter
public class Dependency extends RDLTerm{
	
	private RDLTerm dependingTerm;
	private TreeMultiset<EvaluatableTerm> dependedTerms;
	
	public Dependency(RDLTerm dependingTerm, List<EvaluatableTerm> dependedTerms) {
		super(new Symbol(":", dependedTerms.size() + 1), dependedTerms.iterator().next().getOrder(), dependingTerm.getSize() + dependedTerms.stream().mapToInt(v -> v.size).sum());
		this.dependingTerm = dependingTerm;
		this.dependedTerms = TreeMultiset.create(dependedTerms);
		this.addChild(dependingTerm);
		if (dependingTerm.getTermOrder() > getOrder()) {
			throw new SyntaxException("dependingTerm's order must be less than " + (getOrder() + 1) + ", but " + dependingTerm + "'s order is " + dependingTerm.getOrder());
		}
		for (EvaluatableTerm dependedTerm: dependedTerms) {
			this.addChild(dependedTerm);
			if (dependedTerm.getTermOrder() != getOrder()) {
				throw new SyntaxException(dependedTerm + " order is not " + getOrder());
			}
		}
	}
	
	public Dependency(RDLTerm dependingTerm, EvaluatableTerm ...dependedTerms) {
		this(dependingTerm, Arrays.asList(dependedTerms));
	}
	
	@Override
	public int getTermOrder() {
		return getOrder() - 1;
	}
	
	public boolean isDependeingTermEvaluatable() {
		return dependingTerm instanceof EvaluatableTerm;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(dependingTerm.toTermString());
		sb.append(" : ");
		sb.append(dependedTerms.stream().map(RDLTerm::toString).collect(Collectors.joining(", ")));
		return sb.toString();
	}
	
	@Override
	public String toStringWithOrder() {
		StringBuilder sb = new StringBuilder();
		sb.append(dependingTerm.toStringWithOrder());
		sb.append(" : ");
		sb.append(dependedTerms.stream().map(RDLTerm::toStringWithOrder).collect(Collectors.joining(", ")));
		return sb.toString() + "(" + order + ")";
	}
	
	@Override
	public String toTermString() {
		return "[" + toString() + "]";
	}

	@Override
	public boolean equals(Object another) {
		if(! (another instanceof Dependency)) {
			return false;
		}
		Dependency anotherDep = (Dependency) another;
		return anotherDep.getDependingTerm().equals(dependingTerm)
				&& anotherDep.getDependedTerms().equals(dependedTerms);
	}

	@Override
	public int hashCode() {
		return ("Dep" + toString()).hashCode();
	}
	
	@Override
	public Object clone() {
		List<EvaluatableTerm> newTerms = new ArrayList<>();
		for (EvaluatableTerm term: this.dependedTerms) {
			newTerms.add((EvaluatableTerm) term.clone());
		}
		return new Dependency((RDLTerm) dependingTerm.clone(), newTerms);
	}

}