From: <an...@us...> - 2009-01-21 15:37:39
|
Revision: 7277 http://smartfrog.svn.sourceforge.net/smartfrog/?rev=7277&view=rev Author: anfarr Date: 2009-01-21 15:37:35 +0000 (Wed, 21 Jan 2009) Log Message: ----------- SFOS-1025: Constraint enhancements Modified Paths: -------------- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Aggregator.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Array.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/BaseFunction.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Constraint.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/sfcomponentdescription/SFComponentDescriptionImpl.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/sfreference/SFApplyReference.java trunk/core/smartfrog/src/org/smartfrog/sfcore/reference/ApplyReference.java trunk/core/smartfrog/src/org/smartfrog/sfcore/reference/Function.java Added Paths: ----------- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/DynamicPolicyEvaluation.java trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/PrettyPrint.java Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Aggregator.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Aggregator.java 2009-01-20 16:46:51 UTC (rev 7276) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Aggregator.java 2009-01-21 15:37:35 UTC (rev 7277) @@ -21,21 +21,23 @@ package org.smartfrog.sfcore.languages.sf.functions; import java.util.Enumeration; +import java.util.HashMap; import java.util.Vector; import org.smartfrog.sfcore.common.Context; import org.smartfrog.sfcore.common.MessageKeys; import org.smartfrog.sfcore.common.SmartFrogFunctionResolutionException; -import org.smartfrog.sfcore.common.SmartFrogResolutionException; import org.smartfrog.sfcore.componentdescription.ComponentDescription; import org.smartfrog.sfcore.languages.sf.DefaultParser; +import org.smartfrog.sfcore.languages.sf.constraints.ConstraintConstants; import org.smartfrog.sfcore.languages.sf.constraints.CoreSolver; import org.smartfrog.sfcore.languages.sf.constraints.FreeVar; +import org.smartfrog.sfcore.languages.sf.functions.Constraint.CompositeSource; import org.smartfrog.sfcore.languages.sf.sfreference.SFApplyReference; import org.smartfrog.sfcore.reference.Reference; /** - * Defines the Constraint function. + * Does aggregation, pasting aggregated output into contained apply references */ public class Aggregator extends BaseFunction implements MessageKeys { @@ -45,109 +47,47 @@ * @return an Object representing the answer * @throws SmartFrogFunctionResolutionException if any of the parameters are not there or of the wrong type * */ - protected Object doFunction() throws SmartFrogFunctionResolutionException { - ComponentDescription comp = context.getOriginatingDescr(); - Context orgContext = comp.sfContext(); - ComponentDescription source_cd; - Object source_obj; - Reference src_ref; - String path_s; - - //Hybrid attribute? - Object arraypath = orgContext.get("sfAggregatorPath"); - if (arraypath!=null){ - //then it should be valid - if (!(arraypath instanceof String)) throw new SmartFrogFunctionResolutionException("AggregatorPath in Aggregator: "+comp+" should be a String"); - String arraypath_s = (String) arraypath; - int src_idx = arraypath_s.indexOf(":"); - if (src_idx<0) throw new SmartFrogFunctionResolutionException("AggregatorPath in Aggregator: "+comp+" is incorrectly formatted"); - String src_s = arraypath_s.substring(0, src_idx); - try { - src_ref = Reference.fromString(src_s); - } catch (SmartFrogResolutionException e){ throw new SmartFrogFunctionResolutionException("Cannot construct reference for source array from AggregatorPath in Aggregator: "+comp); } - path_s = arraypath_s.substring(src_idx); - - //System.out.println("Source:"+src_s+", Path:"+path_s); - } else { - //otherwise we look for split version... - //Source - Object arraysource = orgContext.get("sfAggregatorArraySource"); - if (arraysource==null || !(arraysource instanceof Reference)) throw new SmartFrogFunctionResolutionException("ArraySource in Aggregator: "+comp+" should be a REFERENCE to a ComponentDescription"); - src_ref = (Reference) arraysource; - - //Attr Path - Object attrpath = orgContext.get("sfAggregatorAttributePath"); - if (attrpath==null || !(attrpath instanceof String)) throw new SmartFrogFunctionResolutionException("AttributePath in Aggregator: "+comp+" should be a String"); - path_s = ":"+attrpath; - } + protected Object doFunction() throws SmartFrogFunctionResolutionException { + java.util.Vector<CompositeSource> css = new java.util.Vector<CompositeSource>(); + HashMap<Object, Object> others = new HashMap<Object, Object>(); + + //System.out.println("Getting sources..."); + + Constraint.getCompositeSources(comp, css, null, true); + + //System.out.println("Got sources..."); + + CoreSolver.getInstance().setShouldUndo(true); - try { - source_obj = comp.sfResolve(src_ref); - } catch (Exception e){ throw new SmartFrogFunctionResolutionException(e); } - if (source_obj==null || !(source_obj instanceof ComponentDescription)) throw new SmartFrogFunctionResolutionException("ArraySource in Aggregator: "+comp+" should resolve to a COMPONENT DESCRIPTION"); - source_cd = (ComponentDescription) source_obj; - - - Vector arguments = new Vector(); - extractArgumentsFromSource(comp, source_cd, path_s, arguments); - - CoreSolver.getInstance().setShouldUndo(true); - - //Attach arguments to contained function types... - Enumeration el_enum = orgContext.keys(); - while (el_enum.hasMoreElements()){ - String key = (String) el_enum.nextElement(); - - if (key.indexOf("sf")==0) continue; //ignore sf attributes... - - Object val = orgContext.get(key); - if (val instanceof SFApplyReference){ - ComponentDescription val_comp = ((SFApplyReference) val).getComponentDescription(); - insertArguments(arguments, val_comp); - } - } + for (int i=0; i<css.size(); i++){ + CompositeSource cs = css.get(i); + + //System.out.println("****"+cs); + + Constraint.extractArgumentsFromSource(cs); + + //Attach arguments to contained function types... + Enumeration el_enum = orgContext.keys(); + while (el_enum.hasMoreElements()){ + String key = (String) el_enum.nextElement(); + + if (key.indexOf("sf")==0) continue; //ignore sf attributes... + + Object val = orgContext.get(key); + if (val instanceof SFApplyReference){ + ComponentDescription val_comp = ((SFApplyReference) val).getComponentDescription(); + insertArguments(cs.arguments.getArgs(), val_comp); + } + } - orgContext.put("sfFunctionClassStatus", "done"); + } + + orgContext.put(ConstraintConstants.FunctionClassStatus, ConstraintConstants.FCS_DONE); CoreSolver.getInstance().setShouldUndo(false); - return null; + return comp; } - static boolean extractArgumentsFromSource(ComponentDescription comp, ComponentDescription source_cd, String path_s, Vector arguments) throws SmartFrogFunctionResolutionException { - Object sourceClass = source_cd.sfContext().get("sfFunctionClass"); - if (!sourceClass.equals("org.smartfrog.sfcore.languages.sf.functions.Array")) throw new SmartFrogFunctionResolutionException("Source in Aggregator: "+comp+" must have orginated as an Array type"); - - //Extent - Object extent = source_cd.sfContext().get("sfArrayExtent"); - - //Prefix - String prefix_s = (String) source_cd.sfContext().get("sfArrayPrefix"); - - boolean freevar=false; - - if (extent instanceof Integer){ - int ext_int = ((Integer)extent).intValue(); - for (int i=0; i<ext_int; i++){ - String el = prefix_s+i; - Object arg = resolve(source_cd, el+path_s); - if (freevar==false && isFreeVar(arg)) freevar=true; - if (arg!=null) arguments.add(arg); - } - } else if (extent instanceof Vector){ - Vector ext_vec = (Vector)extent; - for (int i=0; i<ext_vec.size(); i++){ - Object suff = ext_vec.get(i); - if (!(suff instanceof String)) throw new SmartFrogFunctionResolutionException("Vector extent in Array: "+source_cd+" should be comprised of Strings"); - String el=prefix_s+suff; - Object arg = resolve(source_cd, el+path_s); - if (freevar==false && isFreeVar(arg)) freevar=true; - if (arg!=null) arguments.add(arg); - } - } - - return freevar; - } - static boolean isFreeVar(Object arg){ if (arg instanceof FreeVar) return true; else if (arg instanceof Vector){ Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Array.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Array.java 2009-01-20 16:46:51 UTC (rev 7276) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Array.java 2009-01-21 15:37:35 UTC (rev 7277) @@ -25,17 +25,24 @@ import org.smartfrog.sfcore.common.Context; import org.smartfrog.sfcore.common.MessageKeys; +import org.smartfrog.sfcore.common.SFNull; +import org.smartfrog.sfcore.common.SmartFrogContextException; import org.smartfrog.sfcore.common.SmartFrogFunctionResolutionException; +import org.smartfrog.sfcore.common.SmartFrogResolutionException; import org.smartfrog.sfcore.componentdescription.ComponentDescription; +import org.smartfrog.sfcore.languages.sf.constraints.ConstraintConstants; import org.smartfrog.sfcore.languages.sf.constraints.CoreSolver; +import org.smartfrog.sfcore.languages.sf.functions.Constraint.ComponentResolution; import org.smartfrog.sfcore.languages.sf.sfreference.SFApplyReference; +import org.smartfrog.sfcore.prim.Prim; import org.smartfrog.sfcore.reference.Reference; /** * Defines the Constraint function. */ -public class Array extends BaseFunction implements MessageKeys { - +public class Array extends BaseFunction implements MessageKeys { + + private int idx=0; /** * The method to implement the functionality of the if-then-else function. * @@ -43,109 +50,260 @@ * @throws SmartFrogFunctionResolutionException if any of the parameters are not there or of the wrong type * */ protected Object doFunction() throws SmartFrogFunctionResolutionException { - ComponentDescription comp = context.getOriginatingDescr(); - Context orgContext = comp.sfContext(); - - int idx=0; - Vector vec_extent = new Vector(); + Object result=null; + try {result=doFunctionWkr();} catch (SmartFrogContextException e){/*Shouldn't happen*/} + return result; + } + + /** + * Internal worker method for doFunction + * @return result of applying function + * @throws SmartFrogFunctionResolutionException + * @throws SmartFrogContextException + */ + private Object doFunctionWkr() throws SmartFrogFunctionResolutionException, SmartFrogContextException { + Object dest = comp; CoreSolver.getInstance().setShouldUndo(true); - Object prefix = orgContext.get("sfArrayPrefix"); - if (prefix==null || !(prefix instanceof String)) throw new SmartFrogFunctionResolutionException("Prefix in Array: "+comp+" should be a String"); - String prefix_s = (String)prefix; - + //Now do the tagged versions... + Enumeration key_enum = orgContext.keys(); + Object key = key_enum.nextElement(); - Object generator = orgContext.get("sfArrayGenerator"); - Object extent = orgContext.get("sfArrayExtent"); + Object path=null; + Object prefix=null; + String prefix_s=null; - if (generator!=null || extent!=null){ + //Get the prefix... + prefix = orgContext.get(ConstraintConstants.PREFIX); - if (extent instanceof Vector) { - Vector extent_v = (Vector) extent; - for (int i=0;i<extent_v.size();i++) vec_extent.add(extent_v.get(i)); + if (prefix==null){ + while (true){ //Get first attribute of note + key = key_enum.nextElement(); + if (orgContext.sfContainsTag(key, ConstraintConstants.PREFIX_TAG)){ + prefix = orgContext.get(key); + + break; + } } - - //Do the standard generator and extent - idx = processExtentGenerator(idx, comp, prefix_s, generator, extent); - - generator = extent = null; + } + if (prefix==null) throw new SmartFrogFunctionResolutionException("Array: "+comp+" has no prefix"); + + if (prefix instanceof String) prefix_s= (String) prefix; + else throw new SmartFrogFunctionResolutionException("In Array: "+comp+", prefix must be a String..."); + + /* PATH's are not currently offered for Arrays for simplicity. Additional measures for link resolution would need to be taken otherwise which I feel complicate matters + path = orgContext.get(ConstraintConstants.PATH); + + + boolean spare_key=false; + if (path==null){ + //Is there a path? + if (key_enum.hasMoreElements()) { + key = key_enum.nextElement(); + if (orgContext.sfContainsTag(key, ConstraintConstants.PATH_TAG)) path = orgContext.get(key); + else spare_key=true; + } } - //Now do the tagged versions... - Enumeration attr_enum = orgContext.keys(); - while (attr_enum.hasMoreElements()){ - Object attr = attr_enum.nextElement(); - try { - if (orgContext.sfContainsTag(attr, "sfArrayExtentGenerator")){ - Object val = orgContext.get(attr); - if (!(val instanceof Vector)) throw new SmartFrogFunctionResolutionException("sfArrayExtentGenerator-tagged attributes in Array: "+comp+" must have Vector values."); - Vector val_vec = (Vector) val; - if (val_vec.size()!=2) throw new SmartFrogFunctionResolutionException("sfArrayExtentGenerator-tagged attributes in Array: "+comp+" must have Vector values with 2 members."); - extent = val_vec.get(0); - generator = val_vec.get(1); - if (!(generator instanceof String)) throw new SmartFrogFunctionResolutionException("sfArrayExtentGenerator-tagged attributes in Array: "+comp+" generator: "+ generator+" must be a String"); - Reference gen_ref = Reference.fromString((String)generator); - generator = comp.sfResolve(gen_ref); - - if (extent instanceof Vector) { - Vector extent_v = (Vector) extent; - for (int i=0;i<extent_v.size();i++) vec_extent.add(extent_v.get(i)); - } - idx = processExtentGenerator(idx, comp, prefix_s, generator, extent); - generator = extent = null; - } - } catch (Exception e){/*shouldn't happen*/} + //Resolve path... + if (path!=null && path instanceof Reference) { + try{dest = comp.sfResolve(((Reference)path).copyandRemoveLazy());}catch(SmartFrogResolutionException sfre){/*Shouldn't happen} + }*/ + + Object extent = orgContext.get(ConstraintConstants.EXTENT); + Object generator = orgContext.get(ConstraintConstants.GENERATOR); + + if (extent!=null){ + process_array_members(dest,prefix_s,extent,generator); + } else { + + boolean first=true; + + //Now for the extents and generators... + while (true){ + + if (key_enum.hasMoreElements()) { //even if spare_key, there must be a generator... + //if (spare_key) spare_key=false; + /*else*/ key = key_enum.nextElement(); + if (!orgContext.sfContainsTag(key, ConstraintConstants.EXTENT_TAG)) { + if (first) throw new SmartFrogFunctionResolutionException("In Array: "+comp+", extent must follow prefix..."); + else break; //from while... + } + extent = orgContext.get(key); + if (key_enum.hasMoreElements()) { + key = key_enum.nextElement(); + if (!orgContext.sfContainsTag(key, ConstraintConstants.GENERATOR_TAG)) throw new SmartFrogFunctionResolutionException("In Array: "+comp+", generator must follow extent..."); + generator = orgContext.get(key); + boolean md = process_array_members(dest,prefix_s,extent,generator); + if (md && !first) throw new SmartFrogFunctionResolutionException("In Array: "+comp+", multi-dimensional arrays can not define multiple extents..."); + first=false; + } else throw new SmartFrogFunctionResolutionException("In Array: "+comp+", generator must follow extent..."); + } else if (first) throw new SmartFrogFunctionResolutionException("Array: "+comp+" has no extent"); + else break; + } } - //Write aggregated extent - if (idx>0) orgContext.put("sfArrayExtent", new Integer(idx)); - else if (vec_extent.size()>0) orgContext.put("sfArrayExtent", vec_extent); - //Set sfFunctionClass to "done" orgContext.put("sfFunctionClassStatus", "done"); CoreSolver.getInstance().setShouldUndo(false); - - return null; + return comp; } - - int processExtentGenerator(int idx, ComponentDescription comp, String prefix_s, - Object generator, Object extent) throws SmartFrogFunctionResolutionException { - if (extent!=null){ - if (extent instanceof Integer){ - int ext_int = ((Integer)extent).intValue() + idx; - for (int i=idx; i<ext_int; i++) putArrayEntry(comp, prefix_s+i, generator, new Integer(i)); - idx=ext_int; - } else if (extent instanceof Vector){ - Vector ext_vec = (Vector)extent; - for (int i=0; i<ext_vec.size(); i++) { + + /** + * Adds individual array members + * @param dest destination for array members + * @param prefix_s prefix of array members + * @param extent size of array + * @param generator template for array members + * @return whether it is a multi-dimensional array + * @throws SmartFrogFunctionResolutionException + */ + private boolean process_array_members(Object dest, String prefix_s, Object extent, Object generator) throws SmartFrogFunctionResolutionException { + boolean md=false; + if (extent instanceof Integer){ + int ext_int = ((Integer)extent).intValue() + idx; + for (int i=idx; i<ext_int; i++) putArrayEntry(dest, prefix_s+i, generator, new Integer(i)); + idx=ext_int; + } else if (extent instanceof Vector){ + Vector ext_vec = (Vector)extent; + + //Is it a multi-dimensional array? + if (ext_vec.get(0) instanceof String){ + //no... + for (int i=0; i<ext_vec.size(); i++) { Object suff = ext_vec.get(i); if (!(suff instanceof String)) throw new SmartFrogFunctionResolutionException("Vector extent in Array: "+comp+" should be comprised of Strings"); - putArrayEntry(comp, prefix_s+suff, generator, (String) suff); + putArrayEntry(dest, prefix_s+suff, generator, (String) suff); } - } else throw new SmartFrogFunctionResolutionException("Extent in Array: "+comp+" should be an Integer or a Vector"); + } else { + md=true; + //yes... + //Compose initial index... + Vector el_idx = null; + while ((el_idx=next_el_idx(el_idx,ext_vec))!=null){ + putArrayEntry(dest, prefix_s, generator, el_idx); + } + } + } else throw new SmartFrogFunctionResolutionException("Extent in Array: "+dest+" should be an Integer or a Vector"); + return md; + } + + /** + * Gets first index of array, given extent vector + * @param ref_vec extent vector + * @return first index + * @throws SmartFrogFunctionResolutionException + */ + private Vector get_first_el_idx(Vector ref_vec) throws SmartFrogFunctionResolutionException{ + Vector el_idx = new Vector(); + for (int i=0; i<ref_vec.size(); i++){ + Object ref = ref_vec.get(i); + if (ref instanceof Integer){ + el_idx.add(new Integer(0)); + } else if (ref instanceof Vector){ + el_idx.add(((Vector)ref).get(0)); + } else throw new SmartFrogFunctionResolutionException("In Array: "+comp+" badly formed multi-dimensional extent"); } - return idx; + return el_idx; } - void putArrayEntry(ComponentDescription orgComp, String el, Object generator, Object el_idx) throws SmartFrogFunctionResolutionException{ + /** + * Gets next index of extent vector + * @param el_idx previous index + * @param ref_vec extent vector + * @return next index + * @throws SmartFrogFunctionResolutionException + */ + + private Vector next_el_idx(Vector el_idx, Vector ref_vec) throws SmartFrogFunctionResolutionException { + if (el_idx==null) return get_first_el_idx(ref_vec); - ComponentDescription generator_cd=null; + Vector next_idx = new Vector(); + boolean next=false; + + for (idx=0;idx<ref_vec.size();idx++){ + Object ref = ref_vec.get(idx); + Object el = el_idx.get(idx); + if (next){ //already found a next element, so suffix stays the same... + next_idx.add(el); + } else { + if (ref instanceof Integer){ + int ref_int = ((Integer)ref).intValue(); + int next_int = ((Integer)el_idx.get(idx)).intValue() + 1; + + if (ref_int>next_int) { + next=true; //found... + next_idx.add(new Integer(next_int)); + } else { + next_idx.add(new Integer(0)); + } + + + } else if (ref instanceof Vector){ + Vector ref_v = (Vector) ref; + int ref_size = ref_v.size(); + Object prev = el_idx.get(idx); + int next_entry = ref_v.indexOf(prev)+1; + + + if (next_entry!=ref_size){ + next=true; //found... + next_idx.add(ref_v.get(next_entry)); + } else { + next_idx.add(ref_v.get(0)); + } + + + } else throw new SmartFrogFunctionResolutionException("In Array: "+comp+" badly formed multi-dimensional extent"); + } + } + if (next) return next_idx; + else return null; + } + + /** + * Puts a member entry into array + * @param dest destination of member put + * @param el prefix of name of member attribute to put + * @param generator member template to put + * @param el_idx index of member in array + */ + private void putArrayEntry(Object dest, String el, Object generator, Object el_idx) { + ComponentDescription generator_cd=null; Object generator_copy=null; + if (generator instanceof ComponentDescription) { generator_copy = generator_cd = (ComponentDescription) ((ComponentDescription) generator).copy(); } else if (generator instanceof SFApplyReference) { generator_copy = ((SFApplyReference) generator).copy(); generator_cd = ((SFApplyReference)generator_copy).getComponentDescription(); - } + } - generator_cd.sfContext().put("sfArrayIndex", el_idx); - generator_cd.sfContext().put("sfArrayTag", el); - generator_cd.sfContext().remove("sfIsGenerator"); - orgComp.sfContext().put(el, generator_copy); + + if (el_idx instanceof Vector) { //Multi-dimensional... + Vector el_vec = (Vector) el_idx; + for (int i=0; i<el_vec.size(); i++) { + Object suff = el_vec.get(i); + el+="_"+suff; + generator_cd.sfContext().put(ConstraintConstants.INDEX+i, suff); + } + } else generator_cd.sfContext().put(ConstraintConstants.INDEX, el_idx); + + generator_cd.sfContext().put(ConstraintConstants.TAG, el); + generator_cd.sfContext().remove("sfIsArrayGenerator"); + + if (dest instanceof ComponentDescription){ + generator_cd.setParent((ComponentDescription) dest); + try{((ComponentDescription) dest).sfAddAttribute(el, generator_copy);} catch (Exception e){/*Shouldn't happen*/} + } /*COMMENTED OUT FOR NOW AS FOR TIME BEING ARRAYS ARE STRICTLY PARSE TIME CREATURES + else /*Assume Prim* { + generator_cd.setPrimParent((Prim) dest); + try {((Prim)dest).sfAddAttribute(el, generator_copy);} catch (Exception e){/*Shouldn't happen*} + } */ } - + } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/BaseFunction.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/BaseFunction.java 2009-01-20 16:46:51 UTC (rev 7276) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/BaseFunction.java 2009-01-21 15:37:35 UTC (rev 7277) @@ -20,13 +20,14 @@ package org.smartfrog.sfcore.languages.sf.functions; +import org.smartfrog.sfcore.common.Context; +import org.smartfrog.sfcore.common.SmartFrogFunctionResolutionException; +import org.smartfrog.sfcore.componentdescription.ComponentDescription; +import org.smartfrog.sfcore.languages.sf.sfreference.SFApplyReference; import org.smartfrog.sfcore.reference.Function; +import org.smartfrog.sfcore.reference.Reference; import org.smartfrog.sfcore.reference.ReferenceResolver; import org.smartfrog.sfcore.reference.RemoteReferenceResolver; -import org.smartfrog.sfcore.reference.Reference; -import org.smartfrog.sfcore.common.SmartFrogFunctionResolutionException; -import org.smartfrog.sfcore.common.Context; -import org.smartfrog.sfcore.componentdescription.ComponentDescription; /** * Defines the base function for all the functions. @@ -43,9 +44,32 @@ protected Context context = null; protected ReferenceResolver rr = null; protected RemoteReferenceResolver rrr = null; - + protected ComponentDescription comp; + protected Context orgContext; protected Reference name = null; - + protected Reference ar= null; + protected Object arkey = null; + + private void extras(Reference ar, Object key){ + this.ar = ar; + this.arkey = key; + } + + private Object doit(Context ctx, Reference unused) throws SmartFrogFunctionResolutionException { + this.context = ctx; + if (this.context!=null) this.comp = context.getOriginatingDescr(); + if (this.comp!=null) this.orgContext = comp.sfContext(); + + Object result = doFunction(); + + if (result instanceof ComponentDescription) { + ((ComponentDescription)result).setParent(null); + ((ComponentDescription)result).setPrimParent(null); + } + return result; + } + + /** * base implementation of a function method. * Calls the (abstract) method doFunction. @@ -55,35 +79,48 @@ * @throws SmartFrogFunctionResolutionException if the doFunction method does. */ public Object doit(Context ctx, Reference unused, ReferenceResolver resolver) throws SmartFrogFunctionResolutionException { - this.context = ctx; this.rr = resolver; - - Object result = doFunction(); - if (result instanceof ComponentDescription) { - ((ComponentDescription)result).setParent(null); - ((ComponentDescription)result).setPrimParent(null); - } - - return result; + return doit(ctx, unused); } - + /** * base implementation of a function method. * Calls the (abstract) method doFunction. * Note that it makes sure that the result has no parent if it is a component description - this will * cause it to be patched into whereever it is returned. + * + * @throws SmartFrogFunctionResolutionException if the doFunction method does. + */ + public Object doit(Context ctx, Reference unused, ReferenceResolver resolver, Reference ar, Object key) throws SmartFrogFunctionResolutionException { + extras(ar,key); + return doit(ctx, unused, resolver); + } + + /** + * base implementation of a function method. + * Calls the (abstract) method doFunction. + * Note that it makes sure that the result has no parent if it is a component description - this will + * cause it to be patched into whereever it is returned. * * @throws SmartFrogFunctionResolutionException if the doFunction method does. */ public Object doit(Context ctx, Reference unused, RemoteReferenceResolver resolver) throws SmartFrogFunctionResolutionException { - this.context = ctx; - this.rrr = resolver; + this.rrr = resolver; + return doit(ctx, unused); + } + + /** + * base implementation of a function method. + * Calls the (abstract) method doFunction. + * Note that it makes sure that the result has no parent if it is a component description - this will + * cause it to be patched into whereever it is returned. + * + * @throws SmartFrogFunctionResolutionException if the doFunction method does. + */ + public Object doit(Context ctx, Reference unused, RemoteReferenceResolver resolver, Reference ar, Object key) throws SmartFrogFunctionResolutionException { + extras(ar,key); + return doit(ctx, unused, resolver); + } - Object result = doFunction(); - if (result instanceof ComponentDescription) { - ((ComponentDescription)result).setParent(null); - ((ComponentDescription)result).setPrimParent(null); - } - return result; - } + } Modified: trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Constraint.java =================================================================== --- trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Constraint.java 2009-01-20 16:46:51 UTC (rev 7276) +++ trunk/core/smartfrog/src/org/smartfrog/sfcore/languages/sf/functions/Constraint.java 2009-01-21 15:37:35 UTC (rev 7277) @@ -22,23 +22,115 @@ import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Iterator; import java.util.Vector; import org.smartfrog.sfcore.common.Context; import org.smartfrog.sfcore.common.MessageKeys; +import org.smartfrog.sfcore.common.SFNull; +import org.smartfrog.sfcore.common.SmartFrogCompilationException; +import org.smartfrog.sfcore.common.SmartFrogContextException; +import org.smartfrog.sfcore.common.SmartFrogException; import org.smartfrog.sfcore.common.SmartFrogFunctionResolutionException; import org.smartfrog.sfcore.common.SmartFrogResolutionException; import org.smartfrog.sfcore.componentdescription.ComponentDescription; +import org.smartfrog.sfcore.languages.sf.constraints.ConstraintConstants; import org.smartfrog.sfcore.languages.sf.constraints.CoreSolver; import org.smartfrog.sfcore.languages.sf.constraints.FreeVar; +import org.smartfrog.sfcore.languages.sf.constraints.ConstraintResolutionState.ConstraintContext; +import org.smartfrog.sfcore.languages.sf.constraints.propositions.Proposition; +import org.smartfrog.sfcore.languages.sf.sfreference.SFReference; +import org.smartfrog.sfcore.prim.Prim; +import org.smartfrog.sfcore.reference.HereReferencePart; import org.smartfrog.sfcore.reference.Reference; +import org.smartfrog.sfcore.reference.ReferencePart; /** * Defines the Constraint function. */ public class Constraint extends BaseFunction implements MessageKeys { + + static class Argument { + Object loc; + Object arg; + Argument(Object loc, Object arg){ + this.loc=loc; this.arg=arg; + } + } + + static class Arguments { + HashMap<String, Object> args = new HashMap<String, Object>(); + Vector<Argument> argsa = new Vector<Argument>(); + Vector<Object> argsv = new Vector<Object>(); + void put(Object loc, Object arg){ + args.put(loc.toString(), arg); + argsa.add(new Argument(loc, arg)); + argsv.add(arg); + } + + Object get(Object loc){ + return args.get(loc.toString()); + } + + public String toString(){ + String ret="["; + for (int i=0;i<argsv.size();i++){ + if (i>0) ret+=", "; + ret+= argsv.get(i).toString(); + } + return ret+"]"; + } + + public String toFullString(){ + return toFullVector().toString(); + } + + public Vector toFullVector(){ + Vector args= new Vector(); + for (int i=0;i<argsv.size();i++){ + Vector arg = new Vector(); + args.add(arg); + arg.add(argsa.get(i).loc); + arg.add(argsa.get(i).arg); + } + return args; + } + + Vector getArgs(){ + return argsv; + } + } + + static public class CompositeSource { + HashMap context; + Object source; + Reference path; + Object update; + String prefix; + Reference pred; + Object key; + Object retval; + Arguments arguments=new Arguments(); + boolean freevars=false; + int idx=-1; + + CompositeSource(HashMap context, Object source, String prefix, Reference path, Reference pred, Object key, Object update){ + this.context=context; + this.source=source; + this.prefix=prefix; + this.update=update; + this.key=key; + this.path=path; + this.pred=pred; + } + + public String toString(){ + return ""+context+":"+source+":"+prefix+":"+path+":"+pred+":"+key+":"+update+":"+arguments+":"+freevars+":"+idx; + } + } + /** * The method to implement the functionality of the if-then-else function. * @@ -47,8 +139,7 @@ * */ protected Object doFunction() throws SmartFrogFunctionResolutionException { //If constraint resolution is not pertinent or possible return - if (!CoreSolver.getInstance().getConstraintsPossible()) return null; - + /** * Records the attributes used for consraint goal preds */ @@ -73,82 +164,63 @@ * Automatic variables... */ Vector autos = new Vector(); - + /** - * The description pertaining to the Constraint - */ - ComponentDescription comp = context.getOriginatingDescr(); - - /** - * The context pertaining to the Constraint - */ - Context orgContext = comp.sfContext(); - - /** * User variables present? */ boolean isuservars=false; + HashMap<FreeVar, Object> assigns = new HashMap<FreeVar, Object>(); + + //System.out.println("In constraint..."); + + if (!CoreSolver.getInstance().getConstraintsPossible()) return comp; + CoreSolver.getInstance().setShouldUndo(true); - Enumeration attr_enum = orgContext.keys(); + + Vector<CompositeSource> aggs=new Vector<CompositeSource>(); + getCompositeSources(comp, aggs, null, true); - while (attr_enum.hasMoreElements()){ - Object attr = attr_enum.nextElement(); + for (int i=0;i<aggs.size();i++){ + CompositeSource cs = aggs.get(i); + + //System.out.println("%%%%%%%%%%%%%%%%%%%%%%"+cs+orgContext.get(cs.key)); + + extractArgumentsFromSource(cs); + + //System.out.println("+++++++++++++++++++++"+cs.key+":"+cs.arguments); + + //Unify arguments... + Object value = orgContext.get(cs.key); + unify(cs.arguments, value, assigns); + String csargs = cs.arguments.toString(); + //System.out.println("CSARGS!!!"+cs.key+":"+csargs); + orgContext.put(cs.key, cs.arguments.getArgs()); + + try { + if (cs.freevars) orgContext.sfAddTag(cs.key, "sfFreeVars"); + } catch (SmartFrogContextException context){/*Shouldn't happen*/} + } + + //System.out.println("111"); - try { - if (orgContext.sfContainsTag(attr, "sfAggregatedConstraintSource")){ - - Object val = orgContext.get(attr); - if (!(val instanceof Vector)) throw new SmartFrogFunctionResolutionException("sfAggregatedConstraintSource-tagged attributes in AggregatedConstraint: "+comp+" must have Vector values."); - Vector val_vec = (Vector) val; - if (val_vec.size()!=3) throw new SmartFrogFunctionResolutionException("sfAggregatedConstraintSource-tagged attributes in AggregatedConstraint: "+comp+" must have Vector values with 2 members."); - Object arraysource = val_vec.get(0); - - if (arraysource==null || !(arraysource instanceof String)) throw new SmartFrogFunctionResolutionException("First argument of an sfAggregatedConstraintSource tagged attribute in: "+comp+" should be a STRING which resolves to a Component Description"); - Object _arraysource = comp.sfResolve(Reference.fromString((String)arraysource)); - if (_arraysource==null || !(_arraysource instanceof ComponentDescription)) throw new SmartFrogFunctionResolutionException("First argument of an sfAggregatedConstraintSource tagged attribute in: "+comp+" should be a String which resolves to a COMPONENT DESCRIPTION"); - - - ComponentDescription source_cd = (ComponentDescription) _arraysource; - - Object sourceClass = source_cd.sfContext().get("sfFunctionClass"); - if (!sourceClass.equals("org.smartfrog.sfcore.languages.sf.functions.Array")) throw new SmartFrogFunctionResolutionException("First argument of an sfAggregatedConstraintSource tagged attribute in: "+comp+" must have orginated as an Array type"); - - Object attrpath = val_vec.get(1); - if (attrpath==null || !(attrpath instanceof String)) throw new SmartFrogFunctionResolutionException("Second argument of an sfAggregatedConstraintSource tagged attribute in: "+comp+" should be a STRING"); - String path_s = ":"+attrpath; - - Object newattr = val_vec.get(2); - if (newattr==null || !(newattr instanceof String)) throw new SmartFrogFunctionResolutionException("Third argument of an sfAggregatedConstraintSource tagged attribute in: "+comp+" should be a STRING"); - String newattr_s = (String)newattr; - - Vector ac_values = new Vector(); - - boolean freevars = Aggregator.extractArgumentsFromSource(comp, source_cd, path_s, ac_values); - - comp.sfContext().put(newattr_s, ac_values); - if (freevars) comp.sfContext().sfAddTag(newattr_s, "sfAggregatedConstraintFreeVars"); - - } - } catch (Exception e){/*shouldn't happen, so will ignore*/} - - } - CoreSolver.getInstance().setShouldUndo(false); + + Object ret_key=null; //Process attributes, either constraint goals or other... - attr_enum = orgContext.keys(); + Enumeration attr_enum = orgContext.keys(); while (attr_enum.hasMoreElements()){ Object key = attr_enum.nextElement(); Object val = orgContext.get(key); try { + + if (orgContext.sfContainsTag(key, "sfReturn")) ret_key=key; + if (orgContext.sfContainsTag(key, "sfConstraint")) goal_attrs.add(key); else { - if (val instanceof String && !isLegal((String)val)) continue; - - attrs.add(key); - values.add(val); + if (val instanceof String && !isLegal((String)val)) continue; //Set the attribute name originating this FreeVar if (val instanceof FreeVar) { @@ -156,15 +228,107 @@ if (fv.getConsEvalKey()==null) fv.setConsEvalKey(key); //Make sure range is appropriated in free var - fv.setRange(comp); + fv.constructRange(comp); - } - if (orgContext.sfContainsTag(key, "sfConstraintAutoVar")) autos.add(key); - else if (!isuservars && orgContext.sfContainsTag(key, "sfConstraintUserVar")) isuservars=true; + if (orgContext.sfContainsTag(key, "sfConstraintAutoVar")) autos.add(key); + else if (orgContext.sfContainsTag(key, "sfConstraintUserVar")) isuservars=true; + + } else if (val instanceof ComponentDescription){ + + ComponentDescription cd = (ComponentDescription) val; + + if (cd.sfContext().get("IsConstraintVar")!=null){ + + FreeVar fv = new FreeVar(); + + //System.out.println("cd:"+cd); + + //range + Object range = null; + if ((range=cd.sfContext().get(ConstraintConstants.RANGE))!=null) fv.setRange(range); + else if ((range=cd.sfContext().get(ConstraintConstants.RANGEREF))!=null) fv.setRangeRef(range); + else if (cd.sfContext().get(ConstraintConstants.IRANGE)!=null) fv.setRange(new Integer(0)); + else if (cd.sfContext().get(ConstraintConstants.BRANGE)!=null) fv.setRange(new Boolean(true)); + + //System.out.println("22222"); + + //qualification + Object qual_val=null; + if ((qual_val=cd.sfContext().get(ConstraintConstants.AUTOVAR))!=null){ + //System.out.println("Yes we have an autovar!"); + if (qual_val instanceof SFNull) { + //System.out.println("Yes we are null..."); + autos.add(key); + } else if (qual_val instanceof SFReference){ + Reference auto_ref=null; + try { + auto_ref=((SFReference) qual_val).sfAsReference(); + } catch (SmartFrogCompilationException sfce){ throw new SmartFrogFunctionResolutionException(sfce);} + Object label = cd.sfResolve(auto_ref); + //System.out.println("label:"+(label==null)); + + ComponentDescription label_cd = null; + try { + label_cd = (ComponentDescription) label; + } catch (ClassCastException cce){ + throw new SmartFrogFunctionResolutionException("Reference for autovar does not resolve to a Labelling CD, ref:"+qual_val+" in var dec: "+cd+", in constraint: "+comp); + } + + Object label_key = label_cd.sfParent().sfAttributeKeyFor(label); + CoreSolver.getInstance().addAutoVar(label_key, fv); + } + } else if ((qual_val=cd.sfContext().get(ConstraintConstants.DEFVAR))!=null){ + fv.setDefVal(qual_val); + } else if (cd.sfContext().get(ConstraintConstants.USERVAR)!=null){ + isuservars=true; + orgContext.sfAddTag(key, "sfConstraintUserVar"); + } + + + //System.out.println("AUTOEFFECTCDPARENT"+cd); + + //effects + ComponentDescription autoEffectsCD=null; + try {autoEffectsCD = (ComponentDescription) cd.sfContext().get(ConstraintConstants.AUTOEFFECTS); } + catch (ClassCastException cce){/**do**/} + + if (autoEffectsCD!=null){ + //System.out.println("AUTOEFFECTCD"+autoEffectsCD); + + Enumeration ae_enum = autoEffectsCD.sfContext().keys(); + + Vector<Reference> autoEffects = new Vector<Reference>(); + while (ae_enum.hasMoreElements()){ + try { autoEffects.add(((SFReference) autoEffectsCD.sfContext().get(ae_enum.nextElement())).sfAsReference()); } + catch (ClassCastException cce){ throw new SmartFrogFunctionResolutionException("Policy for autovar is not Reference in var dec: "+cd+", in constraint: "+comp); } + } + fv.setAutoEffectCD(autoEffectsCD); + fv.setAutoEffects(autoEffects); + } + + fv.constructRange(cd); + fv.setConsEvalKey(key); + + + val=fv; //so that freevar gets added instead... + //Insert this new FreeVar... + orgContext.put(key, fv); + + + //System.out.println("In In In4"+key+":"+val+":"+orgContext); + + } + } + + attrs.add(key); + values.add(val); + //System.out.println("Just Added"+key+":"+val); } - } catch (Exception e){/**Shouldn't happen**/} + } catch (Exception e){/**Shouldn't happen*/} } - + + //System.out.println("222"); + //Sort the goal in lex order Collections.sort(goal_attrs); @@ -175,100 +339,661 @@ } //Add empty goal if no goal... - if (goal_attrs.size()==0) goal.add("true"); + if (goal_attrs.size()==0) goal.add("nil"); + //Construct constraint context... + ConstraintContext cc = new ConstraintContext((ComponentDescription)rr, comp, arkey, ar, ret_key); + + //System.out.println("333"); + //Solve goal try { - CoreSolver.getInstance().solve(comp, attrs, values, goal, autos, isuservars); + CoreSolver.getInstance().solve(cc, attrs, values, goal, autos, isuservars, assigns); } catch (Exception e){ e.printStackTrace(); - throw new SmartFrogFunctionResolutionException("Error in solving constraints in: "+context); + ////System.out.println("WE ARE IN ERROR!!!"); + throw new Error("Error in solving constraints:"+e+" in: "+orgContext); } + //VAR effects... + try { + //System.out.println("Applying freevar effects..."+cc.getFVs()); + + Vector<FreeVar> fvs = cc.getFVs(); + for (FreeVar fv: fvs){ + fv.applyAutoEffects(); + } + } catch (SmartFrogResolutionException sfre){ throw new SmartFrogFunctionResolutionException(sfre);} - //Have we done backtracking, need to throw! - Context backtracked = CoreSolver.getInstance().hasBacktrackedTo(); - if (backtracked!=null) orgContext = backtracked; - + ConstraintContext cc_new = CoreSolver.getInstance().hasBacktrackedTo(); + if (cc_new!=null) { + cc=cc_new; + assignContext(cc); + } + boolean hasBacktracked = (cc_new!=null); + //System.out.println("�1"); + + ////System.out.println("HAS BACKTRACKED!!!"+hasBacktracked); + //Mark (poss. backtracked) constraint as done... CoreSolver.getInstance().setShouldUndo(true); + + //File preliminary results... + //fileAggregates(comp); + + //Do propositions + //Speculatively, write the constraint in to its future home, to assess propositions... + ////System.out.println("KEYKEY:"+arkey+":"+comp+":"+orgContext); + + //System.out.println("�2"); + + + if (!Proposition.getResult()) { + ////System.out.println("WE ARE EVALLING PRPS!"); + if (arkey!=null) ((ComponentDescription)rr).sfContext().put(arkey, comp); //this will be undone if backtracking occurs... + + + boolean backtracked=Proposition.evaluatePropositions(false); //to backtrack? rename + ////System.out.println("Post backtracking"+backtracked); + while (backtracked){ + ////System.out.println("Failing..."); + try {CoreSolver.getInstance().fail();} catch (Exception e){/***/} + ////System.out.println("Reevaling props..."); + + cc_new = CoreSolver.getInstance().hasBacktrackedTo(); + if (cc_new!=null) { + cc=cc_new; + assignContext(cc); + } + hasBacktracked = (cc_new!=null); + + //fileAggregates(comp); + if (arkey!=null) ((ComponentDescription)rr).sfContext().put(arkey, comp); + backtracked=Proposition.evaluatePropositions(true); + } + + //Write back apply reference for now... + ////System.out.println("Writing back..."); + if (arkey!=null) ((ComponentDescription)rr).sfContext().put(arkey, ar); + } + + //We're done... orgContext.put("sfFunctionClassStatus", "done"); + + //System.out.println("�3"); + + CoreSolver.getInstance().setShouldUndo(false); + + //System.out.println("�4"); - //Finally, am I an aggregated constraint? If so, map values back... - CoreSolver.getInstance().setShouldUndo(true); + if (hasBacktracked) { + CoreSolver.getInstance().resetDoneBacktracking(); + throw new SmartFrogConstraintBacktrackError(); + } + + ret_key=cc.getRetKey(); + + //System.out.println("�5"+ret_key); + + + + Object ret_val = (ret_key!=null?orgContext.get(ret_key):comp); + //System.out.println("RETURNING!!!"+ret_val); + + return ret_val; + } - attr_enum = orgContext.keys(); + void unify(Arguments arguments, Object val, HashMap<FreeVar, Object> assigns) throws SmartFrogFunctionResolutionException { + //System.out.println("Pre-specified value:"+val); + + String error_s = "aggregated value attribute has illegal pre-specfied value:"+val; + if (val instanceof SFNull) return; //Nothing to do... + if (!(val instanceof Vector)) throw new SmartFrogFunctionResolutionException(error_s+", not a Vector!"); + + Vector val_vec = (Vector) val; + for (int i=0; i<val_vec.size();i++){ + Object vitem = val_vec.get(i); + ////System.out.println("VITEM!!!"+vitem); + + if (!(vitem instanceof Vector)) { + ////System.out.println("Thrown VITEM!!!"+vitem); + throw new SmartFrogFunctionResolutionException(error_s+", should be a vector of [loc,value] pairs"); //items should be a vec of [loc, value], we ignore val... + } + Vector vitem_vec = (Vector) vitem; + + if (vitem_vec.size()!=2) { + ////System.out.println("Thrown VITEM!!!"+vitem); + throw new SmartFrogFunctionResolutionException(error_s+", should be a vector of [loc,value] pairs"); //wrong size, so ignore val... + } + + Object loc = vitem_vec.get(0); + Object vvalue = vitem_vec.get(1); + Object avalue = arguments.get(loc); + + if (avalue instanceof FreeVar){ + //if (vvalue instanceof SFNull) vvalue=new FreeVar(); + ////System.out.println("Location:"+loc+":"+avalue.toString()+":"+vvalue.toString()); + assigns.put((FreeVar)avalue, vvalue); + } else if (!avalue.equals(vvalue)) throw new SmartFrogFunctionResolutionException(error_s+", ununifiable values"); + } + } + + + //The next two methods are not currently used, but may be at some point and are left in as such... + void unify_(Vector arguments, Object val, Vector goal){ + + if (!(val instanceof Vector)) return; //Not unifiable on type + + String goal_s=unify_vec(arguments, (Vector)val); + + if (goal_s!=null) goal.add(goal_s); + } + + String unify_vec(Vector arguments, Vector val_vec){ + String goal_s=null; + if (val_vec.size()!=arguments.size()) return null; //Not unifiable on size + + for (int i=0; i<val_vec.size();i++){ + Object vitem = val_vec.get(i); + Object aitem = arguments.get(i); + if (vitem instanceof Vector && aitem instanceof Vector) { + String goal_s1 = unify_vec((Vector) aitem, (Vector) vitem); + if (goal_s1==null) return null; + if (goal_s!=null) goal_s += ", "+goal_s1; + else goal_s=goal_s1; + } else if (aitem instanceof FreeVar) { + String goal_s1 = aitem.toString()+"="+vitem.toString(); + if (goal_s!=null) goal_s += ", "+goal_s1; + else goal_s=goal_s1; + } else if (!(aitem.equals(vitem))) return null; + } + if (goal_s!=null) return goal_s; + else return ""; + } + + void assignContext(ConstraintContext cc){ + if (cc!=null){ + ar=cc.getAR(); + comp=cc.getCD(); + rr=cc.getParent(); + arkey=cc.getKey(); + orgContext=comp.sfContext(); + } + } + + void fileAggregates(ComponentDescription comp) throws SmartFrogFunctionResolutionException { + Vector<CompositeSource> aggs=new Vector<CompositeSource>(); + getCompositeSources(comp, aggs, null, true); - while (attr_enum.hasMoreElements()){ - Object attr = attr_enum.nextElement(); + for (int i=0;i<aggs.size();i++){ + CompositeSource cs = aggs.get(i); + try { + if (orgContext.sfContainsTag(cs.key, "sfFreeVars")){ + ////System.out.println("UPDATE UPDATE:"+cs.key+":"+cs.update); + if (cs.prefix==null) updateValue(cs); + else updateArrayOfValues(cs); + } + } catch (SmartFrogContextException context){/*Shouldn't happen*/} + } + } + + public static void getCompositeSources(ComponentDescription comp, Vector<CompositeSource> cs, java.util.Vector<Object> other, boolean mpred) throws SmartFrogFunctionResolutionException{ + Context context = comp.sfContext(); + Enumeration en = context.keys(); + Object key=null; + + ////System.out.println("Comp"+comp); + + while ((key=getNextKey(en,comp))!=null){ + //Context information firstly... + HashMap contextInfo_hm = new HashMap(); + Object contextInfo = getTaggedValue("sfContext", key, comp); + while (contextInfo!=null){ + contextInfo_hm.put(key, contextInfo); + contextInfo = getTaggedValue("sfContext", getNextKey(en,comp), comp); + } - try { - - if (orgContext.sfContainsTag(attr, "sfAggregatedConstraintSource")){ - Vector val = (Vector) orgContext.get(attr); - Object arraysource = val.get(0); - ComponentDescription source_cd = (ComponentDescription) comp.sfResolve(Reference.fromString((String)arraysource)); - String path_s = (String) val.get(1); - Object newattr = val.get(2); + Object source = getTaggedValue("sfSource", getNextKey(en,comp), comp, false); + + //System.out.println("Source"+source); + + if (source==null) { + /*Object val = getTaggedValue("sfReturn", key, comp); + if (val!=null){ + //sort ret val! + g_retval=val; + } else*/ if (other!=null) other.add(key); + leftover=null; + continue; //round while... + } + + //"Hand" resolve + if (!(source instanceof Reference)) throw new SmartFrogFunctionResolutionException("Tagged source: "+source+" in comp: "+comp+" should be a reference"); + Reference source_ref=null; + if (source instanceof SFReference) { + try {source_ref=((SFReference)source).sfAsReference();} + catch (SmartFrogCompilationException sfce){throw new SmartFrogFunctionResolutionException(sfce);} + } + else source_ref= (Reference) source; + + //System.out.println("SourceRef"+source_ref); + + Object prefix = getTaggedValue("sfPrefix", getNextKey(en,comp), comp); + Object path = getTaggedValue("sfPath", getNextKey(en,comp), comp, false); + + if (prefix!=null || path!=null) { + try { source = resolve(comp, source_ref); } catch (Exception e) {throw new SmartFrogFunctionResolutionException("Can not resolve source ref:"+source_ref+" in: "+comp);} + if (!(source instanceof ComponentDescription) && !(source instanceof Prim)) throw new SmartFrogFunctionResolutionException("Source ref:"+source_ref+" in: "+comp+" does not resolve to a Prim/ComponentDescription"); + } else { + path=source; + source=comp; + } + + Object pred = null; + Object update = null; + + //System.out.println("PREFIX:PATH"+prefix+path); + + if (path!=null && (!(path instanceof Reference))) throw new SmartFrogFunctionResolutionException("Tagged path in comp: "+comp+" must be a Reference"); + + boolean first=true; + + if (mpred){ + while (true){ + pred = getTaggedValue("sfPred", getNextKey(en,comp), comp, false); + update = getTaggedValue("sfUpdate", getNextKey(en,comp), comp); - //Manipulate path to get inter_path - int idx = path_s.lastIndexOf(":"); - String interpath_s = ""; - if (idx!=-1){ - interpath_s = ":"+path_s.substring(0, idx); - path_s = path_s.substring(idx+1); - } + //System.out.println("PRED:UPDATE"+pred+update); - if (orgContext.sfContainsTag(newattr, "sfAggregatedConstraintFreeVars")){ + if (pred!=null && !(pred instanceof Reference)){ + if ((pred instanceof Boolean && ((Boolean)pred).booleanValue()) || pred instanceof SFNull) pred=null; + else throw new SmartFrogFunctionResolutionException("Tagged pred: "+pred+" in comp: "+comp+" is not Reference or Boolean true"); + } - Vector ac_values = (Vector) orgContext.get(newattr); - - //Extent - Object extent = source_cd.sfContext().get("sfArrayExtent"); - - //Prefix - String prefix_s = (String) source_cd.sfContext().get("sfArrayPrefix"); - - if (extent instanceof Integer){ - int ext_int = ((Integer)extent).intValue(); - for (int i=0; i<ext_int; i++){ - String el = prefix_s+i; - Object ac_val = ac_values.get(i); - if (!(ac_val instanceof FreeVar)) replace(source_cd, el+interpath_s, path_s, ac_val); - } - } else if (extent instanceof Vector){ - Vector ext_vec = (Vector)extent; - for (int i=0; i<ext_vec.size(); i++){ - String suff_s = (String) ext_vec.get(i); - String el=prefix_s+suff_s; - Object ac_val = ac_values.get(i); - if (!(ac_val instanceof FreeVar)) replace(source_cd, el+interpath_s, path_s, ac_val); - } - } - } + if (pred!=null && update==null) throw new SmartFrogFunctionResolutionException("Tagged source in comp: "+comp+" with no update"); + + if (pred==null && update==null){ + if (first) { + //System.out.println("1Adding"); + CompositeSource comp_src = new CompositeSource(contextInfo_hm, source, (String)prefix, (Reference)path, null, null, null); + cs.add(comp_src); + } + break; + } + + first=false; + + //System.out.println("2Adding"); + CompositeSource comp_src = new CompositeSource(contextInfo_hm, source, (String)prefix, (Reference)path, (Reference)pred, lastKey, update); + cs.add(comp_src); + } + } else { + //System.out.println("nextup..."); + + pred = getTaggedValue("sfPred", getNextKey(en,comp), comp, false); + update = getTaggedValue("sfUpdate", getNextKey(en,comp), comp); + + //System.out.println("PRED:UPDATE"+pred+update); + + if (pred!=null && !(pred instanceof Reference)){ + if ((pred instanceof Boolean && ((Boolean)pred).booleanValue()) || pred instanceof SFNull) pred=null; + else throw new SmartFrogFunctionResolutionException("Tagged pred: "+pred+" in comp: "+comp+" is not Reference or Boolean true"); + } + + if (update==null) throw new SmartFrogFunctionResolutionException("Tagged source in comp: "+comp+" with no update"); + CompositeSource comp_src = new CompositeSource(contextInfo_hm, source, (String)prefix, (Reference)path, (Reference)pred, lastKey, update); + cs.add(comp_src); + } + } + + //System.out.println("Leaving getCS"); + + } + + static private abstract class AggregationOp { + CompositeSource cs; + AggregationOp(CompositeSource cs){ + this.cs=cs; + } + abstract void doIt(Object loc) throws SmartFrogFunctionResolutionException; + } + + static private class ExtractOp extends AggregationOp{ + ExtractOp(CompositeSource cs){ super(cs); } + void doIt(Object loc) throws SmartFrogFunctionResolutionException { + ComponentResolution cr = getComponentResolution(cs.source,cs.path); + cs.arguments.put(loc, cr.val); + if (cr.val instanceof FreeVar) cs.freevars=true; + } + } + + static private class UpdateOp extends AggregationOp{ + UpdateOp(CompositeSource cs){ super(cs); cs.idx=0;} + void doIt(Object loc) throws SmartFrogFunctionResolutionException{ + updateValue(cs); + cs.idx++; + } + } + + static void doAggregationUpdate(AggregationOp ao) throws SmartFrogFunctionResolutionException { + CompositeSource cs = ao.cs; + Object cssource = cs.source; + Prim p = (cssource instanceof Prim?(Prim)cssource:null); + ComponentDescription c = (cssource instanceof ComponentDescription?(ComponentDescription)cssource:null); + + ... [truncated message content] |