/** * Applies this dependency structure with another, adding any new dependencies * to @newResolvedDependencies */ public DependencyStructure compose( DependencyStructure other, final List<UnlabelledDependency> newResolvedDependencies) { other = other.standardizeApart(coindexation.getMaxID() + 1); final UnifyingSubstitution substitution = UnifyingSubstitution.make(coindexation.right, other.coindexation.left, false); final Set<UnresolvedDependency> newUnresolvedDependencies = new HashSet<>(); updateResolvedDependencies( other, substitution, newUnresolvedDependencies, newResolvedDependencies); final Coindexation newCoindexationLeft = substitution.applyTo(coindexation.left); final Coindexation newCoindexationRight = substitution.applyTo(other.coindexation.right); final boolean headIsLeft = !coindexation.left.idOrHead.equals(coindexation.right.idOrHead); final Coindexation.IDorHead idOrHead = substitution.applyTo(headIsLeft ? coindexation : other.coindexation).idOrHead; final Set<UnresolvedDependency> normalizedUnresolvedDependencies = new HashSet<>(newUnresolvedDependencies.size()); final Coindexation normalizedCoindexation = normalize( new Coindexation(newCoindexationLeft, newCoindexationRight, idOrHead), newUnresolvedDependencies, normalizedUnresolvedDependencies, newResolvedDependencies, 1); return new DependencyStructure(normalizedCoindexation, normalizedUnresolvedDependencies); }
/** Generalized forward composition (to degree 2) */ public DependencyStructure compose2( DependencyStructure other, final List<UnlabelledDependency> newResolvedDependencies) { // A/B (B/C)/D ---> (A/C)/D other = other.standardizeApart(coindexation.getMaxID() + 1); final UnifyingSubstitution substitution = UnifyingSubstitution.make(coindexation.right, other.coindexation.left.left, false); final Set<UnresolvedDependency> newUnresolvedDependencies = new HashSet<>(); updateResolvedDependencies( other, substitution, newUnresolvedDependencies, newResolvedDependencies); final Set<UnresolvedDependency> normalizedUnresolvedDependencies = new HashSet<>(newUnresolvedDependencies.size()); final Coindexation normalizedCoindexation; if (coindexation.isModifier()) { // X/X X/Y/Z normalizedCoindexation = normalize( substitution.applyTo(other.coindexation), newUnresolvedDependencies, normalizedUnresolvedDependencies, newResolvedDependencies, 1); } else { // S\NP/NP NP/PP/PP final Coindexation leftWithSubstitution = substitution.applyTo(coindexation); final Coindexation rightWithSubstitution = substitution.applyTo(other.coindexation); normalizedCoindexation = normalize( new Coindexation( new Coindexation( leftWithSubstitution.left, rightWithSubstitution.left.right, leftWithSubstitution.idOrHead), rightWithSubstitution.right, leftWithSubstitution.idOrHead), newUnresolvedDependencies, normalizedUnresolvedDependencies, newResolvedDependencies, 1); } return new DependencyStructure(normalizedCoindexation, normalizedUnresolvedDependencies); }
/** * Applies this dependency structure to another, adding any new dependencies * to @newResolvedDependencies */ public DependencyStructure apply( DependencyStructure other, final List<UnlabelledDependency> newResolvedDependencies) { other = other.standardizeApart(coindexation.getMaxID() + 1); final UnifyingSubstitution substitution = UnifyingSubstitution.make(coindexation.right, other.coindexation, isConjunction); final Set<UnresolvedDependency> newUnresolvedDependencies = new HashSet<>(); final Coindexation newCoindexation = substitution.applyTo(coindexation.left); updateResolvedDependencies( other, substitution, newUnresolvedDependencies, newResolvedDependencies); final Set<UnresolvedDependency> normalizedUnresolvedDependencies = new HashSet<>(newUnresolvedDependencies.size()); final Coindexation normalizedCoindexation = normalize( newCoindexation, newUnresolvedDependencies, normalizedUnresolvedDependencies, newResolvedDependencies, 1); return new DependencyStructure(normalizedCoindexation, normalizedUnresolvedDependencies); }
/** * Updates the agenda with the result of all combinators that can be applied to leftChild and * rightChild. */ private void updateAgenda( final PriorityQueue<AgendaItem> agenda, final AgendaItem left, final AgendaItem right, final Model model) { final SyntaxTreeNode leftChild = left.getParse(); final SyntaxTreeNode rightChild = right.getParse(); if (!seenRules.isSeen(leftChild.getCategory(), rightChild.getCategory())) { return; } final List<RuleProduction> rules = getRules(leftChild.getCategory(), rightChild.getCategory()); final int size = rules.size(); for (int i = 0; i < size; i++) { final RuleProduction production = rules.get(i); // Check if normal-form constraints let us add this rule. if (NormalForm.isOk( leftChild.getRuleClass(), rightChild.getRuleClass(), production.getRuleType(), leftChild.getCategory(), rightChild.getCategory(), production.getCategory(), left.getStartOfSpan() == 0)) { final SyntaxTreeNodeBinary newNode; if (usingDependencies) { // Update all the information for tracking dependencies. final List<UnlabelledDependency> resolvedDependencies = new ArrayList<>(); final DependencyStructure newDependencies = production .getCombinator() .apply( leftChild.getDependencyStructure(), rightChild.getDependencyStructure(), resolvedDependencies); final boolean headIsLeft = newDependencies.getArbitraryHead() == leftChild.getDependencyStructure().getArbitraryHead(); newNode = new SyntaxTreeNodeBinary( production.getCategory(), leftChild, rightChild, production.getRuleType(), headIsLeft, newDependencies, resolvedDependencies); } else { // If we're not modeling dependencies, we can save a lot of work. newNode = new SyntaxTreeNodeBinary( production.getCategory(), leftChild, rightChild, production.getRuleType(), production.isHeadIsLeft(), null, null); } agenda.add(model.combineNodes(left, right, newNode)); } } }