Newer
Older
RDLProofSystem / src / main / java / models / terms / meta / MetaDynaimcDependencyTerm.java
@Sakoda2269 Sakoda2269 6 hours ago 3 KB dynamicTermのisMatchedByまで
package models.terms.meta;

import com.google.common.collect.TreeMultiset;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import exceptions.SyntaxException;
import models.algebra.Variable;
import models.terms.RDLTerm;

public class MetaDynaimcDependencyTerm extends MetaDependencyTerm implements MetaDynamicTerm{

	private final MetaTermGenerator generator;
	
	public MetaDynaimcDependencyTerm (MetaTermGenerator generator) {
		this.generator = generator;
	}
	
	public MetaDynaimcDependencyTerm(MetaTermGenerator generator, List<? extends RDLTerm> terms) {
		this.generator = generator;
		if (terms.size() != 0 && terms.size() % 2 != 1) {
			throw new SyntaxException("");
		}
		this.dependingTerm = terms.size() > 0 ? terms.get(0) : null;
		for (int i = 0; i < (terms.size() - 1) / 2; i++) {
			RDLTerm dependedTerm = terms.get(i * 2 + 1);
			RDLTerm argTerm = terms.get(i * 2 + 2);
			this.termPairs.computeIfAbsent(dependedTerm, k -> TreeMultiset.create()).add(argTerm);
			addChild(dependedTerm);
			addChild(argTerm);
		}
	}
	
	@Override
	public MetaRDLTerm generate(int depth, Map<Variable, Object> context) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}
	
	public MetaRDLTerm generate(int maxIndex, int maxDepth, Map<Variable, Object> context) {
		return generate(1, maxIndex, maxDepth, context);
	}

	@Override
	public MetaRDLTerm generate(int depth, int maxIndex, int maxDepth, Map<Variable, Object> context) {
		if (maxIndex % 2 == 0 && maxIndex <= 2) return null;
		RDLTerm dependingTerm;
		List<RDLTerm> termPairs = new ArrayList<>();
		if (this.dependingTerm != null) {
			dependingTerm = this.dependingTerm;
		} else {
			dependingTerm = generator.generate(0, depth, maxIndex, maxDepth, context);
		}
		while (dependingTerm instanceof MetaDynamicTerm dynamicTerm) {
			dependingTerm = dynamicTerm.generate(depth + 1, maxIndex, maxDepth, context);
		}
		int index = 1;
		for (RDLTerm dependedTerm : this.termPairs.keySet()) {
			for (RDLTerm argTerm : this.termPairs.get(dependedTerm)) {
				while (dependedTerm instanceof MetaDynamicTerm dynamicTerm) {
					dependedTerm = dynamicTerm.generate(depth + 1, maxIndex, maxDepth, context);
				}
				while (argTerm instanceof MetaDynamicTerm dynamicTerm) {
					argTerm = dynamicTerm.generate(depth + 1, maxIndex, maxDepth, context);
				}
				termPairs.add(dependedTerm);
				termPairs.add(argTerm);
				index+=2;
			}
		}
		for (int i = 0; i < (maxIndex - index)  / 2; i++) {
			RDLTerm dependedTerm = generator.generate(i * 2 + 1, depth, maxIndex, maxDepth, context);
			RDLTerm argTerm = generator.generate(i * 2 + 2, depth, maxIndex, maxDepth, context);
			while (dependedTerm instanceof MetaDynamicTerm dynamicTerm) {
				dependedTerm = dynamicTerm.generate(depth + 1, maxIndex, maxDepth, context);
			}
			while (argTerm instanceof MetaDynamicTerm dynamicTerm) {
				argTerm = dynamicTerm.generate(depth + 1, maxIndex, maxDepth, context);
			}
			termPairs.add(dependedTerm);
			termPairs.add(argTerm);
		}
		return new MetaDependencyTerm(dependingTerm, termPairs);
	}

	@Override
	protected Set<MatchConstraint> isMatchedBy(RDLTerm another, Set<MatchConstraint> constraint, int depth) {
		int maxIndex = another.getMaxIndex();
		int maxDepth = another.getMaxDepth();
		MetaRDLTerm metaTerm = generate(maxIndex, maxDepth, new HashMap<>());
		return metaTerm.isMatchedBy(another, constraint, depth);
	}
	
	@Override
	protected RDLTerm substitute(Map<Variable, RDLTerm> binding, int depth) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	
	@Override
	public String toString() {
		if (dependingTerm != null) {
			return "[" + getChild(0).toString() + " : " + IntStream.range(0, (getChildren().size() - 1) / 2)
				.mapToObj(i -> getChild(i * 2 + 1).toString() + " -> " + getChild(i * 2 + 2)).collect(Collectors.joining(", ")) + " ...? ]";
		}
		return "[ ...? ]";
	}

}