<commit_before>package it.unibz.inf.ontop.owlrefplatform.core.optimization;

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import it.unibz.inf.ontop.model.ImmutableExpression;
import it.unibz.inf.ontop.model.Variable;
import it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.NextNodeAndQuery;
import it.unibz.inf.ontop.pivotalrepr.*;
import it.unibz.inf.ontop.pivotalrepr.impl.IllegalTreeException;
import it.unibz.inf.ontop.pivotalrepr.impl.IllegalTreeUpdateException;
import it.unibz.inf.ontop.pivotalrepr.proposal.NodeCentricOptimizationResults;
import it.unibz.inf.ontop.pivotalrepr.proposal.PushDownBooleanExpressionProposal;
import it.unibz.inf.ontop.pivotalrepr.proposal.impl.PushDownBooleanExpressionProposalImpl;
import it.unibz.inf.ontop.utils.ImmutableCollectors;

import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

import static it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.getDepthFirstNextNode;
import static it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.getNextNodeAndQuery;
import static it.unibz.inf.ontop.pivotalrepr.BinaryOrderedOperatorNode.ArgumentPosition.RIGHT;

/**
 * Extensible through hooks
 */
public class PushDownBooleanExpressionOptimizerImpl implements PushDownBooleanExpressionOptimizer {

    /**
     * A recipient node n receives a boolean expression e being propagated down,
     * only if all variables of e are projected out by the subtree rooted in n.
     * n may be either:
     * - a direct recipient of e, if it natively supports boolean expressions (JoinOrFilterNode)
     * - an indirect recipient of e,
     * and a parent filter node for n will be created as the direct recipient of e.
     *
     * Note that a lefJoinNode may be either a direct recipient node (if it is also the provider node),
     * or an indirect one
     */
    protected static class Recipient {
        public final Optional<JoinOrFilterNode> directRecipientNode;
        public final Optional<QueryNode> indirectRecipientNode;

        private Recipient(LeftJoinNode root, boolean isDirectRecipient) {
            if(isDirectRecipient){
                directRecipientNode = Optional.of(root);
                indirectRecipientNode = Optional.empty();
            }else{
                directRecipientNode = Optional.empty();
                indirectRecipientNode = Optional.of(root);
            }
        }

        private Recipient(QueryNode root) {
            if(root instanceof LeftJoinNode) {
                throw new IllegalStateException("For LeftJoin recipient nodes, use the other constructor");
            }
            if(root instanceof CommutativeJoinOrFilterNode){
                directRecipientNode = Optional.of((JoinOrFilterNode) root);
                indirectRecipientNode = Optional.empty();
            }else{
                directRecipientNode = Optional.empty();
                indirectRecipientNode = Optional.of(root);
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Recipient recipient = (Recipient) o;

            if (!indirectRecipientNode.equals(recipient.indirectRecipientNode)) return false;
            return directRecipientNode.equals(recipient.directRecipientNode);

        }<commit_msg>extended access privilege for overloading PushDownExpression optimizer<commit_after>package it.unibz.inf.ontop.owlrefplatform.core.optimization;

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import it.unibz.inf.ontop.model.ImmutableExpression;
import it.unibz.inf.ontop.model.Variable;
import it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.NextNodeAndQuery;
import it.unibz.inf.ontop.pivotalrepr.*;
import it.unibz.inf.ontop.pivotalrepr.impl.IllegalTreeException;
import it.unibz.inf.ontop.pivotalrepr.impl.IllegalTreeUpdateException;
import it.unibz.inf.ontop.pivotalrepr.proposal.NodeCentricOptimizationResults;
import it.unibz.inf.ontop.pivotalrepr.proposal.PushDownBooleanExpressionProposal;
import it.unibz.inf.ontop.pivotalrepr.proposal.impl.PushDownBooleanExpressionProposalImpl;
import it.unibz.inf.ontop.utils.ImmutableCollectors;

import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

import static it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.getDepthFirstNextNode;
import static it.unibz.inf.ontop.owlrefplatform.core.optimization.QueryNodeNavigationTools.getNextNodeAndQuery;
import static it.unibz.inf.ontop.pivotalrepr.BinaryOrderedOperatorNode.ArgumentPosition.RIGHT;

/**
 * Extensible through hooks
 */
public class PushDownBooleanExpressionOptimizerImpl implements PushDownBooleanExpressionOptimizer {

    /**
     * A recipient node n receives a boolean expression e being propagated down,
     * only if all variables of e are projected out by the subtree rooted in n.
     * n may be either:
     * - a direct recipient of e, if it natively supports boolean expressions (JoinOrFilterNode)
     * - an indirect recipient of e,
     * and a parent filter node for n will be created as the direct recipient of e.
     *
     * Note that a lefJoinNode may be either a direct recipient node (if it is also the provider node),
     * or an indirect one
     */
    protected static class Recipient {
        public final Optional<JoinOrFilterNode> directRecipientNode;
        public final Optional<QueryNode> indirectRecipientNode;

        private Recipient(LeftJoinNode root, boolean isDirectRecipient) {
            if(isDirectRecipient){
                directRecipientNode = Optional.of(root);
                indirectRecipientNode = Optional.empty();
            }else{
                directRecipientNode = Optional.empty();
                indirectRecipientNode = Optional.of(root);
            }
        }

        public Recipient(QueryNode root) {
            if(root instanceof LeftJoinNode) {
                throw new IllegalStateException("For LeftJoin recipient nodes, use the other constructor");
            }
            if(root instanceof CommutativeJoinOrFilterNode){
                directRecipientNode = Optional.of((JoinOrFilterNode) root);
                indirectRecipientNode = Optional.empty();
            }else{
                directRecipientNode = Optional.empty();
                indirectRecipientNode = Optional.of(root);
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Recipient recipient = (Recipient) o;

            if (!indirectRecipientNode.equals(recipient.indirectRecipientNode)) return false;
            return directRecipientNode.equals(recipient.directRecipientNode);

        }
{'fraction_non_alphanumeric': 0.08067135896047645, 'fraction_numerical': 0.0, 'mean_word_length': 3.3490288404944084, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1380264', 'n_tokens_mistral': 2117, 'n_tokens_neox': 2031, 'n_words': 458}