def testVentureScriptAbstractExample(): class EnumerableUniformOutputPSP(cont.UniformOutputPSP): def canEnumerate(self): return True def enumerateValues(self, args): (low, high) = args.operandValues() return np.arange(low, high, (high - low) / 100) r = get_ripl() r.set_mode("venture_script") r.bind_foreign_sp( "uniform_continuous", typed_nr(EnumerableUniformOutputPSP(), [t.NumberType(), t.NumberType()], t.NumberType())) r.execute_program(""" infer resample(2); assume is_funny = tag(quote(fun), 0, flip(0.3)); assume funny_mean = tag(quote(mean), 0, uniform_continuous(-10,10)); assume mean = if (is_funny) { funny_mean } else { 0 }; assume trial = proc() { normal(mean, 1) }; observe trial() = 8; observe trial() = 8; observe trial() = 8; observe trial() = 8; infer emap(default, all, 1, false); """) eq_(True, r.sample("is_funny")) assert_almost_equal(8, r.sample("funny_mean"))
def setup_likelihood_free(): class TestPSP1(LikelihoodFreePSP): def simulate(self, args): x = args.operandValues()[0] return x + stats.distributions.norm.rvs() tester1 = typed_nr(TestPSP1(), [t.NumberType()], t.NumberType()) class TestPSP2(LikelihoodFreePSP): def simulate(self, args): x = args.operandValues()[0] return x + stats.distributions.bernoulli(0.5).rvs() tester2 = typed_nr(TestPSP2(), [t.NumberType()], t.NumberType()) ripl = get_ripl() ripl.bind_foreign_sp('test1', tester1) ripl.bind_foreign_sp('test2', tester2) return ripl
def testCollectLogScore(): # In the presence of likelihood-free SP's, the calling "collect" or # "printf" should not crash the program. class TestPSP(LikelihoodFreePSP): def simulate(self, args): x = args.operandValues()[0] return x + stats.distributions.norm.rvs() tester = typed_nr(TestPSP(), [t.NumberType()], t.NumberType()) ripl = get_ripl() ripl.bind_foreign_sp('test', tester) prog = ''' [ASSUME x (test 0)] [ASSUME y (normal x 1)] [infer (collect x)]''' ripl.execute_program(prog)
def test_profiling_likelihoodfree(): # Make sure profiling doesn't break with likelihood-free SP's class TestPSP(LikelihoodFreePSP): def simulate(self, args): x = args.operandValues()[0] return x + stats.distributions.norm.rvs() tester = typed_nr(TestPSP(), [t.NumberType()], t.NumberType()) ripl = get_ripl() ripl.bind_foreign_sp('test', tester) prog = ''' [ASSUME x (test 0)] [INFER (mh default one 10)]''' ripl.profiler_enable() ripl.execute_program(prog)
def make_gp(self, ripl): ripl.assume('make_linear', VentureFunction(makeLinear, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_periodic', VentureFunction(makePeriodic, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_se',VentureFunction(makeSquaredExponential,[t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_rq', VentureFunction(makeRQ, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('a',' (tag (quote hyper ) 0 (uniform_continuous 0 8))') ripl.assume('l',' (tag (quote hyper) 1 (uniform_continuous 0 8))') ripl.assume('q',' (tag (quote hyper) 2 (uniform_continuous 0.01 8))') ripl.assume('sf1','(tag (quote hyper) 3 (uniform_continuous 0 8))') ripl.assume('theta_se_1',' (tag (quote hyper) 4 (uniform_continuous 0 8))') ripl.assume('theta_se_2',' (tag (quote hyper) 5 (uniform_continuous 0 8))') ripl.assume('theta_rq_1','(tag (quote hyper) 6 (uniform_continuous 0 8))') ripl.assume('theta_rq_2','(tag (quote hyper) 7 (uniform_continuous 0 8))') ripl.assume('theta_rq_3','(tag (quote hyper) 8 (uniform_continuous 0 8))') ripl.assume('lin', "(apply_function make_linear a 0 )") ripl.assume('per', "(apply_function make_periodic l q sf1 1 ) ") ripl.assume('se1', "(apply_function make_se theta_se_1 theta_se_2 2 )") ripl.assume('rq', "(apply_function make_rq theta_rq_1 theta_rq_2 theta_rq_3 7 )") #### GP Structure Prior ###### for simplicity, I start with the max amount of kernel per type given ripl.assume("func_times", makeLiftedMult(lambda x1, x2: np.multiply(x1,x2))) ripl.assume("func_plus", makeLiftedAdd(lambda x1, x2: x1 + x2)) ripl.assume('cov_list','(list lin per se1 rq )') ripl.bind_foreign_sp("subset",typed_nr(Subset(), [t.ListType(),t.SimplexType()], t.ListType())) number = 4 total_perms =0 perms = [] for i in range(number): perms.append((len(list(itertools.permutations([j for j in range(i+1)]))))) total_perms+=perms[i] simplex = "( simplex " for i in range(number): simplex+=str(float(perms[i])/total_perms) + " " simplex+=" )" ripl.assume('s','(tag (quote grammar) 1 (subset cov_list '+simplex + ' ))') ripl.assume('cov_compo',""" (tag (quote grammar) 0 (lambda (l ) (if (lte ( size l) 1) (first l) (if (flip) (apply_function func_plus (first l) (cov_compo (rest l))) (apply_function func_times (first l) (cov_compo (rest l))) ) ))) """) ripl.assume('cov_structure','(cov_compo s)') ripl.assume('gp','(tag (quote model) 0 (make_gp_part_der zero cov_structure))') ripl.bind_foreign_sp("covariance_string", deterministic_typed(lambda x:VentureSymbol(x.stuff['name']), [t.AnyType()], t.AnyType(), descr="returns the covariance type")) ripl.bind_foreign_sp("covariance_label", deterministic_typed(lambda x:x.stuff['label_list'], [t.AnyType()], t.ArrayType(), descr="returns the covariance label"))
def __venture_start__(ripl, *_args): np.random.seed(3) random.seed(3) ripl.assume('make_linear', VentureFunctionDiff(makeLinear, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_periodic', VentureFunction(makePeriodic, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_squaredexp', VentureFunction(makeSquaredExponential, [t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_noise', VentureFunction(makeNoise, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_rq', VentureFunction(makeRQ, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_const_func', VentureFunction(makeConstFunc, [t.NumberType()], constantType)) ripl.assume("mult_funcs", makeLiftedMult(lambda x1, x2: np.multiply(x1,x2))) ripl.assume("add_funcs", makeLiftedAdd(lambda x1, x2: x1 + x2)) ripl.bind_foreign_sp('allocate_gpmem', gpmem.allocateGPmemSP) ## pseude-uniform structure prior def uniform_structure_prior(number): total_perms =0 perms = [] for i in range(number): perms.append((len(list(itertools.permutations([j for j in range(i+1)]))))) total_perms+=perms[i] return [float(perms[i])/total_perms for i in range(number)] uniform_structure = deterministic_typed(uniform_structure_prior, [t.IntegerType()],t.SimplexType()) ripl.bind_foreign_sp('uniform_structure', uniform_structure) ripl.bind_foreign_sp("subset",typed_nr(Subset(), [t.ListType(),t.SimplexType()], t.ListType())) if ripl.evaluate("data")=="synthetic": from get_synthetic_data import make_data_function,data_xs elif ripl.evaluate("data")=="airline": from get_airline_data import make_data_function,data_xs elif ripl.evaluate("data")=="co2": from get_co2_data import make_data_function,data_xs else: raise ValueError('Data is not known, please specify synthetic, airline or co2') ripl.bind_foreign_sp('make_data_function', deterministic_typed( make_data_function, [t.StringType()], sp.SPType([t.NumberType()], t.NumberType()))) # helper SP to get the input data get_data_xs_SP = deterministic_typed( lambda: data_xs, [], t.HomogeneousArrayType(t.NumberType())) ripl.bind_foreign_sp('get_data_xs', get_data_xs_SP) # SPs to interpret covariance structure ripl.bind_foreign_sp("covariance_string", deterministic_typed(lambda x:VentureSymbol(x.stuff['name']), [t.AnyType()], t.AnyType(), descr="returns the covariance type")) # SP to output covariance label so that we only infer over the # hyper-parameters of base kernels that are actually in use ripl.bind_foreign_sp("covariance_label", deterministic_typed(lambda x:x.stuff['label_list'], [t.AnyType()], t.ArrayType(), descr="returns the covariance label"))
aux.N += 1 aux.xTotal += x aux.STotal += x * x.T def unincorporate(self, x, args): x = np.mat(x).reshape((self.d, 1)) aux = args.spaux() aux.N -= 1 aux.xTotal -= x aux.STotal -= x * x.T def logDensityOfData(self, aux): (mN, kN, vN, SN) = self.updatedParams(aux) term1 = -(aux.N * self.d * math.log(math.pi)) / 2. term2 = logGenGamma(self.d, vN / 2.) term3 = -logGenGamma(self.d, self.v0 / 2.) term4 = (self.v0 / 2.) * np.linalg.slogdet(self.S0)[1] # first is sign term5 = -(vN / 2.) * np.linalg.slogdet(SN)[1] term6 = (self.d / 2.) * math.log(float(self.k0) / kN) return term1 + term2 + term3 + term4 + term5 + term6 registerBuiltinSP( "make_niw_normal", typed_nr(MakeCMVNOutputPSP(), [ t.HomogeneousArrayType(t.NumberType()), t.NumberType(), t.NumberType(), t.MatrixType() ], SPType([], t.HomogeneousArrayType(t.NumberType()))))
return [True, False] def description(self, name): return ' {name}(p) returns true with probability p and false otherwise. '\ 'If omitted, p is taken to be 0.5. '\ 'If you are tempted to write ({name} (exp x)),'\ ' write (log_{name} x) instead. '\ 'If you are tempted to write ({name} (logistic x)),'\ ' write (log_odds_{name} x) instead.'\ .format(name=name) registerBuiltinSP( "flip", typed_nr(BernoulliOutputPSP(), [t.ProbabilityType()], t.BoolType(), min_req_args=0)) registerBuiltinSP( "bernoulli", typed_nr(BernoulliOutputPSP(), [t.ProbabilityType()], t.IntegerType(), min_req_args=0)) class LogBernoulliOutputPSP(DiscretePSP): def simulate(self, args): logp = args.operandValues()[0] return math.log(args.py_prng().random()) < logp def logDensity(self, val, args):
class DirichletOutputPSP(RandomPSP): def simulate(self, args): alpha = args.operandValues()[0] return simulateDirichlet(alpha, args.np_prng()) def logDensity(self, val, args): alpha = args.operandValues()[0] return logDensityDirichlet(val, alpha) def description(self, name): return " %s(alphas) samples a simplex point according to the given " \ "Dirichlet distribution." % name registerBuiltinSP("dirichlet", \ typed_nr(DirichletOutputPSP(), [t.HomogeneousArrayType(t.PositiveType())], t.SimplexType())) class SymmetricDirichletOutputPSP(RandomPSP): def simulate(self, args): (alpha, n) = args.operandValues() return simulateDirichlet([float(alpha) for _ in range(int(n))], args.np_prng()) def logDensity(self, val, args): (alpha, n) = args.operandValues() return logDensityDirichlet(val, [float(alpha) for _ in range(int(n))]) def description(self, name): return " %s(alpha, n) samples a simplex point according to the " \ "symmetric Dirichlet distribution on n dimensions with " \
class MakeMSPOutputPSP(DeterministicPSP): def simulate(self, args): sharedOperatorNode = args.operandNodes[0] return VentureSPRecord( SP(MSPRequestPSP(sharedOperatorNode), ESRRefOutputPSP())) def description(self, name): return "%s returns the stochastically memoized version of the input SP." % name class MSPRequestPSP(DeterministicPSP): def __init__(self, sharedOperatorNode): self.sharedOperatorNode = sharedOperatorNode def simulate(self, args): vals = args.operandValues() id = str(vals) exp = ["memoizedSP"] + [["quote", val] for val in vals] env = VentureEnvironment(None, ["memoizedSP"], [self.sharedOperatorNode]) return Request([ESR(id, exp, addr.req_frame(id), env)]) registerBuiltinSP( "mem", typed_nr(MakeMSPOutputPSP(), [SPType([t.AnyType("a")], t.AnyType("b"), variadic=True)], SPType([t.AnyType("a")], t.AnyType("b"), variadic=True)))
class NoiselessQuad(DataGenerator): def __init__(self): self.a = 0.0025 self.b = 3.0 self.c = 1.5 def f_noiseless(self): return -self.a * (x - self.b)**2 + c def generate_noise(self, xs): return np.zeros(xs.shape) def true_optimum_x(self): return self.b GENERATORS = { 'LogAbs': LogAbs(), 'NoiselessQuad': NoiselessQuad(), } class GenerateQuadDataPSP(LikelihoodFreePSP): def simulate(self, args): key = args.operandValues()[0] data_generator = GENERATORS[key] xs, ys = data_generator.generate() return [xs, ys] generateQuadDataSP = typed_nr(GenerateQuadDataPSP(), [t.SymbolType()], t.HomogeneousArrayType(t.HomogeneousArrayType(t.NumberType())))
from venture.lite.psp import DeterministicPSP from venture.lite.sp_help import typed_nr import venture.lite.types as t import venture.lite.value as v class ExcludePSP(DeterministicPSP): def simulate(self, args): A, B = args.operandValues() ans = [x for x in B if all(abs(x - y) > 1e-6 for y in A)] return ans numarray = t.HomogeneousArrayType(t.NumberType()) excludeSP = typed_nr(ExcludePSP(), [numarray, numarray], numarray) def __venture_start__(ripl): ripl.bind_foreign_inference_sp("exclude", excludeSP)
operator = vals[1] if isinstance(operator, SPRef): # XXX trace.madeSPRecordAt(operator.makerNode) operator = operator.makerNode.madeSPRecord if not isinstance(operator.sp.requestPSP, NullRequestPSP): raise VentureValueError("Cannot assess a requesting SP.") if not operator.sp.outputPSP.isRandom(): raise VentureValueError("Cannot assess a deterministic SP.") assessedArgs = ReplacingArgs(args, vals[2:], operandNodes=args.operandNodes[2:], spaux=operator.spAux) return operator.sp.outputPSP.logDensity(value, assessedArgs) def description(self, name): return " %s(val, func, arg1, arg2, ...) returns the log probability" \ " (density) of simulating val from func(arg1, arg2, ...)" % name registerBuiltinSP( "assess", typed_nr(AssessOutputPSP(), [ t.AnyType("<val>"), SPType([t.AnyType("<args>")], t.AnyType("<val>"), variadic=True), t.AnyType("<args>") ], t.NumberType(), variadic=True))
from venture.lite.psp import DeterministicPSP from venture.lite.sp_help import typed_nr import venture.lite.types as t import venture.lite.value as v class Box: def __init__(self, initial_content=0): self.content = initial_content self.changecount = 0 class MakeBoxPSP(DeterministicPSP): def simulate(self, args): initial_content = args.operandValues()[0] return v.VentureForeignBlob(Box(initial_content)) makeBoxSP = typed_nr(MakeBoxPSP(), [t.NumberType()], t.AnyType("box")) class BoxGetOutputPSP(DeterministicPSP): def simulate(self, args): box = args.operandValues()[0].getForeignBlob() return box.content boxGetSP = typed_nr(BoxGetOutputPSP(), [t.AnyType("box")], t.NumberType()) class BoxGetChangecountOutputPSP(DeterministicPSP): def simulate(self, args): box = args.operandValues()[0].getForeignBlob() return box.changecount boxGetChangecountSP = typed_nr(BoxGetChangecountOutputPSP(), [t.AnyType("box")], t.NumberType())
def simulate(self, args): return VentureSPRecord(typed_nr(MakeQuadMSPOutputPSP(), [t.AnyType()] + 5*[t.NumberType()], t.AnyType()))
def canAbsorb(self, _trace, appNode, parentNode): return parentNode != appNode.operandNodes[2] @override(DeterministicPSP) def description(self,name): return "%s returns its third argument unchanged at runtime, " \ "but tags the subexpression creating the object as being " \ "within the given scope and block." % name def isTagOutputPSP(thing): return isinstance(thing, TagOutputPSP) or \ (isinstance(thing, TypedPSP) and isTagOutputPSP(thing.psp)) registerBuiltinSP("tag", typed_nr(TagOutputPSP(), [t.AnyType("<scope>"), t.AnyType("<block>"), t.AnyType()], t.AnyType())) class TagExcludeOutputPSP(DeterministicPSP): @override(DeterministicPSP) def simulate(self,args): return args.operandValues()[1] @override(DeterministicPSP) def gradientOfSimulate(self, _args, _value, direction): return [0, direction] @override(DeterministicPSP) def canAbsorb(self, _trace, appNode, parentNode): return parentNode != appNode.operandNodes[1]
# XXX This implementation will suggest to a multi-site proposal # that there are more distinct possibilities than actually exist, # if more than one table was emptied by recent unincorporations. # This is Github issue #462: # https://github.com/probcomp/Venturecxx/issues/462 if aux.cachedTables: tables += sorted(aux.cachedTables.values()) else: tables.append(aux.nextTable) return tables registerBuiltinSP( 'make_crp', typed_nr(MakeCRPOutputPSP(), [t.NumberType(), t.NumberType()], SPType([], t.AtomType()), min_req_args=1)) def draw_crp_samples(n, alpha, np_rng=None): """Jointly draw n samples from CRP(alpha). This returns an assignment of n objects to clusters, given by a length-n list of cluster ids. """ aux = CRPSPAux() args = MockArgs([], aux, np_rng=np_rng) psp = CRPOutputPSP(alpha, 0) # No dispersion def draw_sample(): ans = psp.simulate(args)
def make_gp(self, ripl): ripl.assume('make_linear', VentureFunction(makeLinear, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_periodic', VentureFunction(makePeriodic, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_se',VentureFunction(makeSquaredExponential,[t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_noise', VentureFunction(makeNoise, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) #ripl.assume('make_rq', VentureFunction(makeRQ, [t.NumberType(), t.NumberType(), t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_const_cov', VentureFunction(makeConst, [t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('make_CP', VentureFunction(makeCP, [t.NumberType(),t.NumberType(),t.IntegerType()], t.AnyType("VentureFunction"))) ripl.assume('hyper_parameter','(mem(lambda (i j) (tag (quote i) j (uniform_continuous 0.01 100))))') ripl.assume('lin', "(apply_function make_linear (hyper_parameter 0 0) 0 )") ripl.assume('per', "(apply_function make_periodic (hyper_parameter 1 0) (hyper_parameter 1 1) (hyper_parameter 1 2) 1 ) ") ripl.assume('se', "(apply_function make_se (hyper_parameter 2 0 ) (hyper_parameter 2 1) 2 )") #ripl.assume('rq', "(apply_function make_rq (hyper_parameter 3 0) (hyper_parameter 3 1) (hyper_parameter 3 2) 3)") ripl.assume('wn', "(apply_function make_noise (hyper_parameter 3 0) 3 )") #ripl.assume('se2', "(apply_function make_se(hyper_parameter 3 0) (hyper_parameter 3 1) 3 )") #ripl.assume('rq', "(apply_function make_rq (hyper_parameter 4 0) (hyper_parameter 4 1) (hyper_parameter 4 2) 4)") ripl.assume('cp', "(apply_function make_CP (hyper_parameter 4 0) (hyper_parameter 4 1) 4)") ripl.assume('cp_inv',"(apply_function make_CP (negate (hyper_parameter 4 0)) (hyper_parameter 4 1) 4)") #ripl.assume('c',"(apply_function make_const_cov (hyper_parameter 5 0) 5 )") #### GP Structure Prior ###### for simplicity, I start with the max amount of kernel per type given ripl.assume("func_times", makeLiftedMult(lambda x1, x2: np.multiply(x1,x2))) ripl.assume("func_plus", makeLiftedAdd(lambda x1, x2: x1 + x2)) ripl.assume('cov_list','(list lin per se wn )') ripl.bind_foreign_sp("subset",typed_nr(Subset(), [t.ListType(),t.SimplexType()], t.ListType())) number = 4 total_perms =0 perms = [] for i in range(number): perms.append((len(list(itertools.permutations([j for j in range(i+1)]))))) total_perms+=perms[i] simplex = "( simplex " for i in range(number): simplex+=str(float(perms[i])/total_perms) + " " simplex+=" )" ripl.assume('s','(tag (quote grammar) 1 (subset cov_list '+simplex + ' ))') ripl.assume('cov_compo',""" (tag (quote grammar) 0 (lambda (l ) (if (lte ( size l) 1) (first l) (if (flip 0.8) (if (flip) (apply_function func_plus (first l) (cov_compo (rest l))) (apply_function func_times (first l) (cov_compo (rest l))) ) (apply_function func_plus (apply_function func_times (first l) cp) (apply_function func_times (cov_compo (rest l)) cp_inv) ) ) ))) """) ripl.assume('cov_structure','(cov_compo s)') ripl.assume('gp','(tag (quote model) 0 (make_gp_part_der zero cov_structure))') ripl.bind_foreign_sp("covariance_string", deterministic_typed(lambda x:VentureSymbol(x.stuff['name']), [t.AnyType()], t.AnyType(), descr="returns the covariance type")) ripl.bind_foreign_sp("covariance_label", deterministic_typed(lambda x:x.stuff['label_list'], [t.AnyType()], t.ArrayType(), descr="returns the covariance label"))
def logDensity(self, value, args): n = args.operandValues()[0] xs = args.spaux().xs assert len(xs) > n theta = np.dot(xs[n], self.O) return math.log(theta[value]) def incorporate(self, value, args): n = args.operandValues()[0] os = args.spaux().os if n not in os: os[n] = [] os[n].append(value) def unincorporate(self, value, args): n = args.operandValues()[0] os = args.spaux().os del os[n][os[n].index(value)] if not os[n]: del os[n] class UncollapsedHMMRequestPSP(DeterministicPSP): def simulate(self, args): return Request([], [args.operandValues()[0]]) registerBuiltinSP( "make_lazy_hmm", typed_nr(MakeUncollapsedHMMOutputPSP(), [t.SimplexType(), t.MatrixType(), t.MatrixType()], SPType([t.CountType()], t.IntegerType())))
def venture2bql(x): if isinstance(x, vv.VentureNumber): return x.getNumber() if isinstance(x, vv.VentureInteger): return x.getInteger() if isinstance(x, vv.VentureString): return unicode(x.getString(), 'UTF-8') if isinstance(x, vv.VentureBool): return x.getBool() if isinstance(x, vv.VentureNil): return None raise ValueError('Unrepresentable value for BQL: %r' % (x,)) BAYESDB_SPS = [ ('bayesdb_open', sp.typed_nr(BayesDB_PSP(), [t.StringType()], t.AnyType('population'))), ('bayesdb_sql', sp.typed_nr(SQL_PSP(), [t.AnyType('population'), t.StringType(), t.ArrayType()], t.ArrayType(), min_req_args=2)), ('bayesdb_bql', sp.typed_nr(BQL_PSP(), [t.AnyType('population'), t.StringType(), t.ArrayType()], t.ArrayType(), min_req_args=2)), ('bayesdb_mml', sp.typed_nr(MML_PSP(), [t.AnyType('population'), t.StringType(), t.ArrayType()], t.ArrayType(), min_req_args=2)),
typed_func(lambda args: env.VentureEnvironment(), [], env.EnvironmentType(), descr="get_empty_environment returns the empty environment")) registerBuiltinSP("is_environment", type_test(env.EnvironmentType())) class ExtendEnvOutputPSP(DeterministicPSP): def simulate(self,args): (en, sym, _) = args.operandValues() node = args.operandNodes[2] return env.VentureEnvironment(en,[sym],[node]) def description(self,name): return "%s returns an extension of the given environment where the given symbol is bound to the given object" % name registerBuiltinSP("extend_environment", typed_nr(ExtendEnvOutputPSP(), [env.EnvironmentType(), t.SymbolType(), t.AnyType()], env.EnvironmentType())) class EvalRequestPSP(DeterministicPSP): def simulate(self,args): (exp, en) = args.operandValues() # Point to the desugared source code location of expression. # This is not a full address, because the call stack is gone. source_loc = addr.append(addr.top_frame(args.operandNodes[0].address), 1) return Request([ESR(args.node,exp,source_loc,en)]) def description(self,name): return "%s evaluates the given expression in the given environment and returns the result. Is itself deterministic, but the given expression may involve a stochasitc computation." % name registerBuiltinSP("eval", esr_output(TypedPSP(EvalRequestPSP(), SPType([t.ExpressionType(), env.EnvironmentType()],