@Override
    public MultiUnifier getMultiUnifier(ReasonerQuery p, UnifierType unifierType){
        if (p == this) return MultiUnifierImpl.trivial();
        Preconditions.checkArgument(p instanceof ReasonerAtomicQuery);

        //NB: this is a defensive check and potentially expensive
        if (unifierType.equivalence() != null && !unifierType.equivalence().equivalent(p, this)) return MultiUnifierImpl.nonExistent();

        ReasonerAtomicQuery parent = (ReasonerAtomicQuery) p;
        MultiUnifier multiUnifier = this.getAtom().getMultiUnifier(parent.getAtom(), unifierType);

        Set<TypeAtom> childTypes = this.getAtom().getTypeConstraints().collect(Collectors.toSet());
        if (multiUnifier.isEmpty() || childTypes.isEmpty()) return multiUnifier;

        //get corresponding type unifiers
        Set<TypeAtom> parentTypes = parent.getAtom().getTypeConstraints().collect(Collectors.toSet());

        Set<Unifier> unifiers = multiUnifier.unifiers().stream()
                .map(unifier -> ReasonerUtils.typeUnifier(childTypes, parentTypes, unifier, unifierType))
                .collect(Collectors.toSet());
        return new MultiUnifierImpl(unifiers);
    }
@ Override public MultiUnifier getMultiUnifier ( ReasonerQuery p , UnifierType unifierType ) { if ( p == this ) return MultiUnifierImpl . trivial ( ) ; Preconditions . checkArgument ( p instanceof ReasonerAtomicQuery ) ; if ( unifierType . equivalence ( ) != null && ! unifierType . equivalence ( ) . equivalent ( p , this ) ) return MultiUnifierImpl . nonExistent ( ) ; ReasonerAtomicQuery parent = ( ReasonerAtomicQuery ) p ; MultiUnifier multiUnifier = this . getAtom ( ) . getMultiUnifier ( parent . getAtom ( ) , unifierType ) ; Set < TypeAtom > childTypes = this . getAtom ( ) . getTypeConstraints ( ) . collect ( Collectors . toSet ( ) ) ; if ( multiUnifier . isEmpty ( ) || childTypes . isEmpty ( ) ) return multiUnifier ; Set < TypeAtom > parentTypes = parent . getAtom ( ) . getTypeConstraints ( ) . collect ( Collectors . toSet ( ) ) ; Set < Unifier > unifiers = multiUnifier . unifiers ( ) . stream ( ) . map ( unifier -> ReasonerUtils . typeUnifier ( childTypes , parentTypes , unifier , unifierType ) ) . collect ( Collectors . toSet ( ) ) ; return new MultiUnifierImpl ( unifiers ) ; }
@throws IllegalArgumentException if passed a {@link ReasonerQuery} that is not a {@link ReasonerAtomicQuery}.