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

com.articulate.sigma.RowVars Maven / Gradle / Ivy

package com.articulate.sigma;

import java.util.*;

public class RowVars {

    public static boolean DEBUG = false;
    
    /** ***************************************************************
     * @return a HashSet, possibly empty, containing row variable
     * names, each of which will start with the row variable
     * designator '@'.
     */
    private static HashSet findRowVars(Formula f) {

        //System.out.println("Info in RowVars.findRowVars(): F: " + f);
        HashSet result = new HashSet();
        if (!StringUtil.emptyString(f.theFormula)
            && f.theFormula.contains(Formula.R_PREF)) {
            Formula fnew = new Formula();
            fnew.read(f.theFormula);
            while (fnew.listP() && !fnew.empty()) {
                String arg = fnew.getArgument(0);
                if (arg.startsWith(Formula.R_PREF))
                    result.add(arg);
                else {
                    Formula argF = new Formula();
                    argF.read(arg);
                    if (argF.listP())
                        result.addAll(findRowVars(argF));
                }
                fnew.read(fnew.cdr());
            }
        }
        return result;
    }

    /** ***************************************************************
     * given in @param ar which is a list for each variable of all the
     * predicates in which it appears as an argument, find the minimum
     * arity allowed by predicate arities, as given by 
     * @seeAlso kb.kbCache.valences
     */
    private static HashMap getRowVarMaxArities(HashMap> ar, KB kb) {
        
        HashMap arities = new HashMap();
        Iterator it = ar.keySet().iterator();
        while (it.hasNext()) {
            String rowvar = it.next();
            HashSet preds = ar.get(rowvar);
            Iterator it2 = preds.iterator();
            while (it2.hasNext()) {
                String pred = it2.next();
                //System.out.println("INFO in RowVars.getRowVarMaxArities(): " + kb.kbCache.valences);
                //System.out.println("INFO in RowVars.getRowVarMaxArities(): pred: " + pred);
                if (kb.kbCache.valences.get(pred) != null) {
                    int arity = kb.kbCache.valences.get(pred).intValue();
                    if (arities.containsKey(pred)) {
                        if (arity < arities.get(rowvar).intValue())
                            arities.put(rowvar, new Integer(arity));
                    }
                    else
                        arities.put(rowvar, new Integer(arity));
                }
            }
        }
        return arities;
    }

    /** ***************************************************************
     * given in @param ar which is a list for each variable of all the
     * predicates in which it appears as an argument, find the maximum
     * arity allowed by predicate arities, as given by
     * @seeAlso kb.kbCache.valences
     *
     * TODO: currently we only find the maximum arity allowed by predicate arities;
     *       we also need to find the minimum predicate arities;
     */
    public static HashMap getRowVarMaxAritiesWithOtherArgs(HashMap> ar, KB kb, Formula f) {

        HashMap arities = new HashMap();
        Iterator it = ar.keySet().iterator();
        while (it.hasNext()) {
            String rowvar = it.next();
            HashSet preds = ar.get(rowvar);
            Iterator it2 = preds.iterator();
            while (it2.hasNext()) {
                String pred = it2.next();

                // If row variables in an argument list with other arguments,
                // then #arguments which can be expanded = #arguments in pred - nonRowVar
                int nonRowVar = 0;
                int start = f.theFormula.indexOf("("+pred);
                int end = f.theFormula.indexOf(")", start);
                String simpleFS = f.theFormula.substring(start, end+1);
                Formula simpleF = new Formula();
                simpleF.read(simpleFS);
                for (int i = 0; i < simpleF.listLength(); i++) {
                    if(simpleF.getArgument(i).startsWith(Formula.V_PREF))
                        nonRowVar++;
                }

                if (kb.kbCache.valences.get(pred) != null) {
                    int arity = kb.kbCache.valences.get(pred).intValue();
                    if (arities.containsKey(pred)) {
                        if (arity < arities.get(rowvar).intValue())
                            arities.put(rowvar, new Integer(arity)-nonRowVar);
                    }
                    else if (arity > 0)
                        arities.put(rowvar, new Integer(arity)-nonRowVar);
                }
            }
        }
        return arities;
    }

    /** ***************************************************************
     * Merge the key,value pairs for a multiple value ArrayList
     */
    private static HashMap> 
        mergeValueSets(HashMap> ar1, HashMap> ar2) {
        
        HashMap> result = new HashMap>();
        result.putAll(ar1);
        Iterator it = ar2.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            HashSet values = ar2.get(key);
            HashSet arg1values = ar1.get(key);
            if (arg1values == null)
                result.put(key, values);
            else {
                arg1values.addAll(values);
            }
        }
        return result;
    }
    
    /** ***************************************************************
     * Add a key,value pair for a multiple value ArrayList
     */
    private static HashMap> 
        addToValueSet(HashMap> ar, String key, String value) {
        
        HashSet val = ar.get(key);
        if (val == null) 
            val = new HashSet();
        val.add(value);
        ar.put(key, val);
        return ar;
    }
    
    /** ***************************************************************
     */
    private static HashMap> getRowVarRelLogOps(Formula f, String pred) {
    
        //System.out.println("Info in RowVars.getRowVarRelLogOps(): pred: " + pred + " F: " + f);
        HashMap> result = new HashMap>();
        if (Formula.isQuantifier(pred)) {
            Formula arg2 = new Formula(f.getArgument(2));
            if (arg2 != null)
                return getRowVarRelations(arg2);
        }
        else if (pred.equals(Formula.NOT)) {
            Formula arg1 = new Formula(f.getArgument(1));
            if (arg1 != null)
                return getRowVarRelations(arg1);
            else
                return result;
        }
        else if (pred.equals(Formula.EQUAL) || pred.equals(Formula.IFF)  || pred.equals(Formula.IF)) {
            Formula arg1 = new Formula(f.getArgument(1));
            Formula arg2 = new Formula(f.getArgument(2));
            if (arg1 != null && arg2 != null)
                return mergeValueSets(getRowVarRelations(arg1),getRowVarRelations(arg2));
            else
                return result;
        }
        else {  // AND or OR
            ArrayList args = f.complexArgumentsToArrayList(1);
            for (int i = 1; i < args.size(); i++) {
                Formula f2 = new Formula(args.get(i));
                result = mergeValueSets(result,getRowVarRelations(f2));
            }
            return result;
        }
        return result;
    }
    
    /** ***************************************************************
     * Recurse through the formula looking for row variables.  If found,
     * add it to a map that has row variables as keys and a set of 
     * predicate names as values. 
     */
    private static HashMap> getRowVarRelations(Formula f) {
        
        //System.out.println("Info in RowVars.getRowVarRelations(): f: " + f);
        HashMap> result = new HashMap>();
        if (!f.theFormula.contains("@") || f.empty() || f.atom())
            return result;
        String pred = f.getArgument(0);
        if (!f.theFormula.substring(1).contains("(")) {  // no higher order or functions
            //System.out.println("Info in RowVars.getRowVarRelations(): simple clause f: " + f);
            HashSet rowvars = findRowVars(f);
            Iterator it = rowvars.iterator();
            while (it.hasNext()) {
                String var = it.next();
                //System.out.println("Info in RowVars.getRowVarRelations(): adding var,pred: " + var + ", " + pred);
                addToValueSet(result,var,pred);
            }
            return result;
        }
        if (Formula.isLogicalOperator(pred)) {
            return getRowVarRelLogOps(f,pred);
        }
        else {  // regular predicate
            ArrayList args = f.complexArgumentsToArrayList(1);
            for (int i = 0; i < args.size(); i++) {
                Formula f2 = new Formula(args.get(i));
                if (f2.theFormula.startsWith("@")) {
                    //System.out.println("Info in RowVars.getRowVarRelations(): adding var,pred: " + f2.theFormula + ", " + pred);
                    addToValueSet(result,f2.theFormula,pred);
                }
                else if (f2.theFormula.contains("@"))
                    result = mergeValueSets(result,getRowVarRelations(f2));
            }
        }
        return result;
    }
    
    /** ***************************************************************
     * Expand row variables, keeping the information about the original
     * source formula.  Each variable is treated like a macro that
     * expands to up to seven regular variables.  For example
     *
     * (=>
     *    (and
     *       (subrelation ?REL1 ?REL2)
     *       (?REL1 @ROW))
     *    (?REL2 @ROW))
     *
     * would become
     *
     * (=>
     *    (and
     *       (subrelation ?REL1 ?REL2)
     *       (?REL1 ?ARG1))
     *    (?REL2 ?ARG1))
     *
     * (=>
     *    (and
     *       (subrelation ?REL1 ?REL2)
     *       (?REL1 ?ARG1 ?ARG2))
     *    (?REL2 ?ARG1 ?ARG2))
     * etc.
     *
     * TODO: Note that this method does not handle the case of row 
     * variables in an argument list with other arguments.  It will
     * just blindly generate all 7 variable expansions even if this
     * means that a predicate will wind up with more than 7 arguments
     * due to the existence of a non-row-variable in the argument
     * list.
     * 
     * @return an ArrayList of Formulas, or an empty ArrayList.
     */
    public static ArrayList expandRowVars(KB kb, Formula f) {
        
        ArrayList result = new ArrayList();
        ArrayList formresult = new ArrayList();
        if (!f.theFormula.contains("@")) {
            // If there are no row variables, return the original formula
            formresult.add(f);
            return formresult;
        }
        if (DEBUG)
            System.out.println("Info in RowVars.expandRowVars(): f: " +f);
        HashMap> rels = getRowVarRelations(f);   
        HashMap rowVarMaxArities = getRowVarMaxAritiesWithOtherArgs(rels, kb, f);
        result.add(f.theFormula);
        HashSet rowvars = findRowVars(f);
        Iterator it = rowvars.iterator();
        while (it.hasNext()) {
            String var = it.next();
            if (DEBUG)
                System.out.println("Info in RowVars.expandRowVars(): var: " + var);
            String replaceVar = var.replace('@', '?');
            ArrayList newresult = new ArrayList();
            StringBuffer replaceString = new StringBuffer();
            int maxArity = 7;  
            if (rowVarMaxArities.containsKey(var) && maxArity > rowVarMaxArities.get(var).intValue())
                maxArity = rowVarMaxArities.get(var).intValue();
            for (int j = 0; j < maxArity; j++) {
                if (j > 0)
                    replaceString.append(" ");
                replaceString.append(replaceVar + Integer.toString(j+1));
                if (DEBUG)
                    System.out.println("Info in RowVars.expandRowVars(): replace: " + replaceString);
                for (int i = 0; i < result.size(); i++) {
                    String form = result.get(i);
                    form = form.replaceAll("\\"+var, replaceString.toString());
                    if (DEBUG)
                        System.out.println("Info in RowVars.expandRowVars(): form: " + form);
                    newresult.add(form);
                }
            }
            result = newresult;
        }
        
        for (int i = 0; i < result.size(); i++) {
            Formula newf = new Formula(result.get(i));
            formresult.add(newf);
        }
        if (DEBUG)
            System.out.println("Info in RowVars.expandRowVars(): exiting with: " + formresult);
        return formresult;
    }

    /** ***************************************************************
     * */
    public static void main(String[] args) {
        
        //String fstring = "(=> (and (subrelation ?REL1 ?REL2) (?REL1 @ROW)) (?REL2 @ROW))";
        String fstring = "(=> (and (contraryAttribute @ROW1) (identicalListItems (ListFn @ROW1) (ListFn @ROW2))) (contraryAttribute @ROW2))"; 
        Formula f = new Formula(fstring);
        System.out.println("Info in RowVars.main(): " + findRowVars(f));
        KBmanager.getMgr().initializeOnce();
        System.out.println("Info in RowVars.main(): finished initialization");
        KB kb = KBmanager.getMgr().getKB("SUMO");
        RowVars.DEBUG = true;
        System.out.println("Info in RowVars.main(): " + getRowVarRelations(f));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy