Newer
Older
RDLProofSystem / src / main / java / inference / In.java
@Sakoda2269 Sakoda2269 6 days ago 9 KB test完了
package inference;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import models.algebra.Variable;
import models.formulas.EquationFormula;
import models.formulas.Formula;
import models.formulas.meta.MetaEquationFormula;
import models.terms.EvaluatableTerm;
import models.terms.RDLTerm;
import models.terms.meta.MatchConstraint;
import models.terms.meta.MetaConstant;
import models.terms.meta.MetaDependencyTerm;
import models.terms.meta.MetaDynamicDependencyTerm;
import models.terms.meta.MetaEvaluatableTermVariable;
import models.terms.meta.MetaRDLTerm;
import models.terms.meta.MetaTermGenerator;


@RequiredArgsConstructor
@Getter
public class In extends Formula {
	
	private final EvaluatableTerm leftSideHand;
	private final EvaluatableTerm rightSideHand;
	
	static final MetaEquationFormula domainMembershipAssumption = new MetaEquationFormula(
			new MetaDynamicDependencyTerm(
					new MetaTermGenerator() {
						@Override
						public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<Object, Object> context) {
							context.put("" + curDepth, curIndex);
							if (curDepth == maxDepth - 1 && curIndex == 0) {
								return new MetaDependencyTerm(
										new MetaEvaluatableTermVariable(new Variable("se")),
										new MetaEvaluatableTermVariable(new Variable("te")),
										new MetaEvaluatableTermVariable(new Variable("ue"))
								);
							} else if (curIndex == 0) {
								return new MetaDynamicDependencyTerm(this);
							}
							curIndex -= 1;
							if (curIndex % 2 == 0) {
								return new MetaEvaluatableTermVariable(new Variable("te" + curDepth + "_" + curIndex/2));
							}
							return new MetaEvaluatableTermVariable(new Variable("ue" + curDepth + "_" + curIndex/2));
						}
					}
			),
			new MetaConstant(new Variable("c"))
	);
	
	static final MetaDependencyTerm domainMembershipConclusionLeftSideHand = new MetaDynamicDependencyTerm(
			new MetaTermGenerator() {
				@Override
				public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<Object, Object> context) {
					maxIndex = (Integer) context.get("" + curDepth);
					if (curDepth == maxDepth && curIndex == 0) {
						return new MetaEvaluatableTermVariable(new Variable("ue"));
					}
					curIndex -= 1;
					if (curIndex >= maxIndex) {
						return null;
					}
					if (curIndex % 2 == 0) {
						return new MetaEvaluatableTermVariable(new Variable("te" + curDepth + "_" + curIndex/2));
					}
					return new MetaEvaluatableTermVariable(new Variable("ue" + curDepth + "_" + curIndex/2));
				}
			}
	);
	
	static final MetaDependencyTerm domainMembershipConclusionRightSideHand = new MetaDynamicDependencyTerm(
			new MetaTermGenerator() {
				@Override
				public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<Object, Object> context) {
					maxIndex = (Integer) context.get("" + curDepth);
					if (curDepth == maxDepth && curIndex == 0) {
						return new MetaEvaluatableTermVariable(new Variable("te"));
					}
					curIndex -= 1;
					if (curIndex >= maxIndex) {
						return null;
					}
					if (curIndex % 2 == 0) {
						return new MetaEvaluatableTermVariable(new Variable("te" + curDepth + "_" + curIndex/2));
					}
					return new MetaEvaluatableTermVariable(new Variable("ue" + curDepth + "_" + curIndex/2));
				}
			}
	);
	
	
	static final MetaEvaluatableTermVariable codomainMembershipConclusionLeftSideHand = new MetaEvaluatableTermVariable(new Variable("ve"));
	static final MetaEvaluatableTermVariable codomainMembershipConclusionRightSideHand = new MetaEvaluatableTermVariable(new Variable("se"));
	
	static final MetaEquationFormula codomainMembershipAssumption = new MetaEquationFormula(
			new MetaDynamicDependencyTerm(
					new MetaTermGenerator() {
						@Override
						public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<Object, Object> context) {
							curIndex -= 1;
							if (curIndex % 2 == 0) {
								return new MetaEvaluatableTermVariable(new Variable("te" + curIndex / 2));
							}
							return new MetaEvaluatableTermVariable(new Variable("ue" + curIndex / 2));
						}
					},
					new MetaEvaluatableTermVariable(new Variable("se"))
			),
			new MetaEvaluatableTermVariable(new Variable("ve"))
	);
	
	public Set<MetaEquationFormula> deriveRule() {
		Set<MetaEquationFormula> result = new HashSet<>();
//		result.addAll(deriveByDomainMemberShip());
//		result.addAll(deriveByCodomainMemberShip());
		return result;
	}
	
	static Set<In> deriveIn(Set<EquationFormula> equationFormulas) {
		Set<In> result = new HashSet<>();
		for (EquationFormula eq : equationFormulas) {
			result.addAll(deriveByDomainMembership(eq));
			result.addAll(deriveByCodomainMembership(eq));
		}
		return result;
	}
	
	static Set<In> deriveIn(EquationFormula equationFormula) {
		return deriveIn(Set.of(equationFormula));
	}
	
	static Set<In> deriveByDomainMembership(EquationFormula equationFormula) {
		Set<In> result = new HashSet<>();
		Set<MatchConstraint> constraints = domainMembershipAssumption.isMatchedBy(equationFormula);
		for (MatchConstraint constraint : constraints) {
			constraint.getContext().put("maxDepth", equationFormula.getLeftSideHand().getMaxDepth() - 1);
			constraint.getContext().put("maxIndex", 10000);
			RDLTerm left = domainMembershipConclusionLeftSideHand.substitute(constraint.getBinding(), constraint.getContext());
			RDLTerm right = domainMembershipConclusionRightSideHand.substitute(constraint.getBinding(), constraint.getContext());
			result.add(new In((EvaluatableTerm) left, (EvaluatableTerm)right));
		}
		return result;
	}
	
	static Set<In> deriveByCodomainMembership(EquationFormula equationFormula) {
		Set<In> result = new HashSet<>();
		Set<MatchConstraint> constraints = codomainMembershipAssumption.isMatchedBy(equationFormula);
		for (MatchConstraint constraint : constraints) {
			RDLTerm left = codomainMembershipConclusionLeftSideHand.substitute(constraint.getBinding(), constraint.getContext());
			RDLTerm right = codomainMembershipConclusionRightSideHand.substitute(constraint.getBinding(), constraint.getContext());
			result.add(new In((EvaluatableTerm) left, (EvaluatableTerm)right));
		}
		return result;
	}
	
	
//	private Set<MetaEquationFormula> deriveByDomainMemberShip() {
//		Set<MetaEquationFormula> result = new HashSet<>();
//		Set<MatchConstraint> leftMatchResult = domainMembershipConclusionLeftSideHand.isMatchedBy(leftSideHand);
//		Set<MatchConstraint> rightMatchResult = domainMembershipConclusionRightSideHand.isMatchedBy(rightSideHand, leftMatchResult);
//		for (MatchConstraint constraint: rightMatchResult) {
//			int used1 = (Integer) constraint.getContext().getOrDefault("used1", 1);
//			int used2 = (Integer) constraint.getContext().getOrDefault("used2", 1);
//			int depth1 = (Integer) constraint.getContext().get("depth1");
//			int depth2 = (Integer) constraint.getContext().get("depth2");
//			if (used1 != used2) {
//				continue;
//			}
//			if (depth1 != depth2) {
//				continue;
//			}
//			boolean flg = false;
//			for (int i = 1; i < depth1; i++) {
//				int d1 = (Integer) constraint.getContext().get("1-" + i);
//				int d2 = (Integer) constraint.getContext().get("2-" + i);
//				if (d1 != d2) {
//					flg = true;
//					break;
//				}
//			}
//			if (flg) continue;
//			Map<MetaRDLTerm, RDLTerm> mapping = new HashMap<>();
//			for (Variable variable: constraint.getBinding().keySet()) {
//				mapping.put(new MetaEvaluatableTermVariable(variable), constraint.getBinding().get(variable));
//			}
//			MetaRDLTerm left = (MetaRDLTerm)domainMembershipAssumptionLeftSideHand.generate(10000, depth1, constraint.cloneContext()).replace(mapping);
//			MetaResource right = new MetaResource(new Variable("c"), new Constant("0"));
//			result.add(new MetaEquationFormula(left, right));
//		}
//		return result;
//	}
//	
//	private Set<MetaEquationFormula> deriveByCodomainMemberShip() {
//		Set<MetaEquationFormula> result = new HashSet<>();
//		Set<MatchConstraint> leftMatchResult = codomainMembershipConclusionLeftSideHand.isMatchedBy(leftSideHand);
//		Set<MatchConstraint> rightMatchResult = codomainMembershipConclusionRightSideHand.isMatchedBy(rightSideHand, leftMatchResult);
//		for (MatchConstraint constraint : rightMatchResult) {
//			Map<MetaRDLTerm, RDLTerm> mapping = new HashMap<>();
//			for (Variable variable: constraint.getBinding().keySet()) {
//				mapping.put(new MetaEvaluatableTermVariable(variable), constraint.getBinding().get(variable));
//			}
//			MetaRDLTerm left = new MetaDynamicDependencyTerm(
//					new MetaTermGenerator() {
//						@Override
//						public MetaRDLTerm generate(int curIndex, int curDepth, int maxIndex, int maxDepth, Map<String, Object> context) {
//							curIndex -= 1;
//							if (curIndex % 2 == 0) {
//								return new MetaEvaluatableTermVariable(new Variable("te" + curIndex / 2));
//							}
//							return new MetaEvaluatableTermVariable(new Variable("ue" + curIndex / 2));
//						}
//					},
//					constraint.getBinding().get(codomainMembershipConclusionRightSideHand.getVariableName())
//			);
//			result.add(new MetaEquationFormula(left, constraint.getBinding().get(codomainMembershipConclusionLeftSideHand.getVariableName())));
//		}
//		return result;
//	}
	
	
	
	@Override
	public String toString() {
		return leftSideHand.toString() + " in " + rightSideHand.toString();
	}
	
	@Override
	public boolean equals(Object another) {
		if (another instanceof In in) {
			return this.leftSideHand.equals(in.getLeftSideHand()) && this.rightSideHand.equals(in.getRightSideHand());
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return toString().hashCode();
	}
	
}