private void addNumberVars(POP pop, Type newObjType, Collection newObjs) { for (Iterator iter = getAddedTupleIterator(Arrays.asList(pop.getArgTypes()), newObjType, newObjs); iter.hasNext(); ) { List genObjs = (List) iter.next(); NumberVar v = new NumberVar(pop, genObjs); if (Util.verbose()) { System.out.println("Adding uninstantiated var: " + v); } addNumberVar(v); } }
private void addObjects(Type newObjType, Collection newObjs) { if (newObjs.isEmpty()) { return; } List objs = (List) objectsByType.get(newObjType); if (objs != null) { // if type serves as an argument to some basic RV // Add function app vars with these objects as argument for (Iterator fIter = model.getFunctions().iterator(); fIter.hasNext(); ) { Function f = (Function) fIter.next(); if (f instanceof RandomFunction) { RandomFunction rf = (RandomFunction) f; if (Arrays.asList(f.getArgTypes()).contains(newObjType)) { addFuncAppVars(rf, newObjType, newObjs); } } } // Add number vars with these object as arguments for (Iterator typeIter = model.getTypes().iterator(); typeIter.hasNext(); ) { Type generatedType = (Type) typeIter.next(); for (Iterator popIter = generatedType.getPOPs().iterator(); popIter.hasNext(); ) { POP pop = (POP) popIter.next(); if (Arrays.asList(pop.getArgTypes()).contains(newObjType)) { addNumberVars(pop, newObjType, newObjs); } } } // Don't need to worry about skolem constant vars because // they don't have arguments objs.addAll(newObjs); } }
/** * compute the feasible region based on the evidence, the method will only use the v2 if 1. v1 is * a direct parent of v2, or 2. v1 and v2 are the same, i.e. corresponding to evidence variable * * @param v1 the variable to sample * @param v2 the variable corresponding to evidence * @return */ private Region computeRegionFromEvidence(BayesNetVar v1, BayesNetVar v2) { if (v1.equals(v2)) { // the variable is in the evidence, it should be directly set to evidence // value return new SingletonRegion(evidence.getObservedValue(v2)); } if (v2 instanceof DerivedVar) { ArgSpec as = ((DerivedVar) v2).getArgSpec(); if (as instanceof CardinalitySpec) { // child is cardinality of a set ImplicitSetSpec iss = ((CardinalitySpec) as).getSetSpec(); Type childType = iss.getType(); if (v1 instanceof NumberVar) { // parent is number variable, potential match NumberVar numv1 = (NumberVar) v1; POP parentPOP = numv1.pop(); Type parentType = parentPOP.type(); if (!parentType.equals(childType)) { return null; } else { // potential match, if Object[] objs = numv1.args(); // generating objects for parent // variable if (objs.length == 0) { // no any constraint return Region.FULL_REGION; } else { // v1 is parent of v2 Formula cond = iss.getCond(); if (cond.isDetermined(this) && cond.isTrue(this)) { int value = ((Number) evidence.getObservedValue(v2)).intValue(); // get all previously satisfied var Set<BayesNetVar> pvars = getAlreadySampledParentVars(v2); for (BayesNetVar pv : pvars) { // eliminate the already sampled ones int a = ((Number) this.getValue(pv)).intValue(); value -= a; } // v1 is parent of v2, and will be sampled immediately pvars.add(v1); if ((value > 0) && anyMoreNumberVar(childType, cond)) { return new IntRegion(0, value); } else { return new SingletonRegion(value); } } } } } /* TODO check other cases of v1 that can be potential parent of this */ } else { // other cases of argspec in v1 } } else { // other variables // might be parent // TODO check whether the condition has v1 as parent } return null; }
/** add all random variables without parents into the uninstantiated variables */ protected void init() { // added number variables for those number statement without origin // functions for (Type generatedType : model.getTypes()) { Collection<POP> pops = generatedType.getPOPs(); // set initial size of unused number statements for each type restPOPs.put(generatedType, new HashSet<POP>(pops)); for (POP pop : pops) { for (int i = 0; i < pop.getArgTypes().length; ++i) { objectsByType.put(pop.getArgTypes()[i], new ArrayList()); } if (pop.getArgTypes().length == 0) { addNumberVar(new NumberVar(pop, Collections.EMPTY_LIST)); } } } // Determine what types serve as arguments to basic RVs. Initialize // their object lists to be empty. As we're doing this, add any // random variables with empty arg lists to the list of uninstantiated // RVs. for (Function f : model.getFunctions()) { if (f instanceof RandomFunction) { for (int i = 0; i < f.getArgTypes().length; ++i) { objectsByType.put(f.getArgTypes()[i], new ArrayList()); } if (f.getArgTypes().length == 0) { uninstVars.add(new RandFuncAppVar((RandomFunction) f, Collections.EMPTY_LIST)); } } } // add skolem constants defined in symbol evidence // already added in step 1 // for (SkolemConstant c : evidence.getSkolemConstants()) { // uninstVars.add(new RandFuncAppVar(c, Collections.EMPTY_LIST)); // } // Create initial object lists for those types. While doing so, // add uninstantiated variables that have these objects as arguments. for (Type type : objectsByType.keySet()) { if (type.isSubtypeOf(BuiltInTypes.INTEGER)) { addObjects(type, Collections.singleton(new Integer(0))); intsAreArgs = true; } else if (type == BuiltInTypes.BOOLEAN) { addObjects(type, type.getGuaranteedObjects()); } else if (type.isBuiltIn()) { Util.fatalError("Illegal argument type for random function: " + type, false); } else { // user-defined type addObjects(type, type.getGuaranteedObjects()); } } // set the iterator lastIter = uninstVars.iterator(); }