All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aksw.sparqlify.database.ExprIndex Maven / Gradle / Ivy

The newest version!
package org.aksw.sparqlify.database;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;

import org.aksw.commons.collections.CartesianProduct;
import org.aksw.commons.collections.FlatMapView;
import org.aksw.jena_sparql_api.normal_form.Clause;
import org.aksw.jena_sparql_api.normal_form.Dnf;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.Expr;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;



class DnfIndex {
    private Multimap singleVarExpr = HashMultimap.create();
    //private Map specific


    // NOTE: Additions are conjunctive!
    public void add(Dnf dnf) {
        Collection clauses = dnf.getClauses();

        //dnf.getCommonExprs()
    }

}


/**
 *
 * TODO Clarify: Do I want disjunctive or conjunctive normal form?
 * (a and b) or (c and d) or
 * (a or b) and(c or d)   ?
 * I guess the former is better, as (a and not a) can be easily detected
 *
 * What happens if we allow conjunctions of disjunctive normal forms?
 * ((a, b) or (c, d) AND ((x) or (y)))
 * becomes
 * (abx or aby or cdx or cdy) (so the cross product of the involved clauses)
 *
 * Maybe i could do virtual clauses:
 * CrossJoinClause(Clauses ...)
 *
 *
 *
 * Hm, but with CNF it is easier to add new expressions.
 *
 * @author Claus Stadler 
 *
 */
public class ExprIndex {

    private ExprIndex parent;


    // TODO I need this method due to the lack of suppert for CNF lookups on tables right now
    public void getEffectiveDnf(Collection vars) {
    }

    /**
     * I use this method for getting constraints for finding view candidates
     *
     *
     * @param dnfs
     * @param index
     * @param dnfIndex
     * @param blacklist
     * @param depth
     * @param parentClause
     * @param result
     */
    public void calcEffectiveClauses(final List dnfs, int index, final Set blacklist, Clause parentClause, final Set result) {
        if(index >= dnfs.size()) {
            if(parentClause != null) {
                result.add(parentClause);
            }

            return;
        }

        Dnf dnf = dnfs.get(index);

        for(Clause clause : dnf.getClauses()) {
            if(blacklist.contains(clause)) {
                continue;
            }

            Clause merged;
            if(parentClause == null) {
                merged = parentClause;
            } else {
                Set exprs = new HashSet(parentClause.getExprs());
                exprs.addAll(clause.getExprs());
                merged = new Clause(exprs);


                calcEffectiveClauses(dnfs, index + 1, blacklist, merged, result);
            }
        }
    }

    /**
     * This method is an ugly hack right, but I don't know
     * where to better calculate it
     *
     * @return
     */
    public Set calcEffectiveClauses() {
        Set result = new HashSet();

        List> tmp = new ArrayList>();

        for(Dnf dnf : dnfs) {
            tmp.add(dnf.getClauses());
        }

        CartesianProduct cartesian = CartesianProduct.create(tmp);

        for(List list : cartesian) {
            Set exprs = new HashSet();

            for(Clause c : list) {
                exprs.addAll(c.getExprs());
            }

            result.add(new Clause(exprs));
        }

        return result;
    }

    public Set getEffectiveClauses() {
        return effectiveClauses;
    }


    private Set effectiveClauses;


    //private List dnfs = new ArrayList();
    // The DNFs are sorted by number of clauses
    private NavigableMap> dnfGroups = new TreeMap>();


    private Collection dnfs = new FlatMapView(dnfGroups.values());

    private Set varsMentioned = new HashSet();


    //private Map
    //private Map commonSingleVarExprs


    //private Dnf dnf = new Dnf();
    //private Map varToClauses = new HashMap();
    //private ExprList exprs = new ExprList();
    //private Multimap varToExprs = HashMultimap.create();
    //VarExprList x;
    //private Map varToPrefixes = new HashMap();
    //private Map

    public ExprIndex() {

    }


    public ExprIndex(ExprIndex parent) {
        this.parent = parent;
        /*
        for(Dnf dnf : parent.getDnf()) {
            add(dnf);
        }*/
    }

    public ExprIndex(ExprIndex parent, Iterable exprs) {
        this.parent = parent;
        addAll(exprs);
    }

    public ExprIndex(Set dnfs) {
        addAll(dnfs);
    }

    public ExprIndex getParent() {
        return parent;
    }

    public Collection getDnf() {
        return dnfs;
    }

    public Set getVarsMentioned() {
        return varsMentioned;
    }

    void add(Dnf dnf) {
        int n = dnf.getClauses().size();
        Set set = dnfGroups.get(n);
        if(set == null) {
            set = new HashSet();
            dnfGroups.put(n, set);
        }
        set.add(dnf);

        varsMentioned.addAll(dnf.getVarsMentioned());

        this.effectiveClauses = calcEffectiveClauses();
    }

    void addAll(Collection dnfs) {
        for(Dnf dnf : dnfs) {
            add(dnf);
        }
    }

    void add(Expr expr) {
        Dnf dnf = Dnf.create(expr);

        add(dnf);
        //dnfs.add(dnf);

        /*
        exprs.add(expr);
        for(Var var : exprs.getVarsMentioned()) {
            varToExprs.put(var, expr);
        }*/

        //DnfUtils.toDnf(expr);
        //varToExp
    }



    /**
     * Any clause containing a var means, that in order for the clause to evaluate
     * to true, the expression it is involved must be true.
     *
     * @param var
     * @return
     */
    public Set getAllClausesWith(Var var) {
        Set result = new HashSet();

        for(Set dnfGroup : dnfGroups.values()) {
            for(Dnf dnf : dnfGroup) {
                Collection clauses = dnf.get(var);

                result.addAll(clauses);
            }
        }

        return result;
    }

    public Set getAllSingleVarExprs(Var var) {
        Set result = new HashSet();

        for(Set dnfGroup : dnfGroups.values()) {
            for(Dnf dnf : dnfGroup) {
                Collection clauses = dnf.get(Collections.singleton(var));

                result.addAll(clauses);
            }
        }

        return result;
    }



    public void addAll(Iterable exprs) {
        for(Expr expr : exprs) {
            add(expr);
        }
    }

    @Override
    public String toString() {
        return dnfs.toString();
    }


    public ExprIndex filterByVars(Set requiredVars) {
        //List filteredDnfs = new ArrayList();
        ExprIndex result = new ExprIndex();
        for(Set dnfGroup : dnfGroups.values()) {
            for(Dnf dnf : dnfGroup) {
                Set clauses = dnf.filterByVars(requiredVars);
                Dnf filteredDnf = new Dnf(clauses);
                result.add(filteredDnf);
            }
        }

        return result;
    }
}





/*
class EffectiveClauseIterator
    extends SinglePrefetchIterator
{
    //private ExprIndex dnfIndex;
    private Set blacklist;
    private StackCartesianProductIterator it;

    public EffectiveClauseIterator(ExprIndex dnfIndex, Set blacklist) {
        Collection dnfs = dnfIndex.getDnf();

        List> clauses = new ArrayList>();
        for(Dnf dnf : dnfs) {
            clauses.add(dnf.getClauses());
        }

        //DescenderIterator it = new DescenderIterator(clauses, )
        this.it = new StackCartesianProductIterator(clauses);
    }

    @Override
    protected Clause prefetch() throws Exception {
        while(it.hasNext()) {
            List item = it.next();

            Clause newClause = item.get(item.size() - 1);

            if(blacklist.contains(newClause)) {
                continue;
            } else if(it.canDescend()) {
                it.descend();
            }
        }
    }


}
*/



/**
 * A class intended for keeping track of possible constant values of a variable.
 *
 * Do I have to work with clauses? Or is it possible to simplify?
 *
 * OK, I don't think this class makes sense right now.
 * If we map a variable to a constant, then we don't need to deal with alternatives.
 * And if we want to mess around with expressions and satisfiability, then we can just
 * work on the expression level, rather trying to destill possible constant assignments from the exprs
 * (althought it might be useable for optimization)
 *
 * @author Claus Stadler 
 *
 * @param 
 */
class ValueSet
{
    private Set> alternatives;

    /**
     * Example 1: Alternatives, or
     * (a = x || a = y)
     *  ->  ((x), (y))
     *
     * ... && (a = x || a = z)
     *  -> a = x
     *
     *
     *
     * Example 2: Negated alternatives
     * (?a != y || ?a != z) -> no constraint derivable
     * "x is either not an Animal or it is not a Person"
     *  ((!y), (!z))
     *
     *
     * Example 3: Negative alternatives
     * (?a != y && ?a != z)
     * "x is neither an Animal nor a Person"
     *     -> neg = (!y, !z)
     *
     * Example 4: Mixed
     * (?a = x || ?a = y || ?a != y || ?a != z)
     *
     *
     * Example 5: Mixed
     * (?a = v || ?a = w) && (?a != v && ?a != y)
     *     -> (?a = v && ?a != v && ?a != y) || (?a = w && ?a != v && ?a != y)
     *     -> (false) || (?a = w && ?a != v && ?a != y)
     * pos = {w}
     *
     *
     * So stating an equality
     *
     * @param values
     */
    public void stateAlternatives(Set values) {

    }




}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy