コード例 #1
0
def toTypes(thing, types, typeError='wrong type'):
    """Convert something to any of the given types, printing an error if impossible."""
    if needs_lazy_evaluation(thing):
        # cannot check the type now; create proxy object to check type after evaluation
        return TypeChecker(thing, types, typeError)
    else:
        return coerce(thing, types, typeError)
コード例 #2
0
 def dependencies(self) -> List:
     cls = self.__class__
     init_params = list(signature(cls.__init__).parameters.keys())[1:]
     current_vals = [self.__getattribute__(p) for p in init_params]
     return [
         cv for cv in current_vals
         if needs_sampling(cv) or needs_lazy_evaluation(cv)
     ]
コード例 #3
0
 def helper(self, *args, **kwargs):
     from probRobScene.core.sampling import needs_sampling
     if any(needs_sampling(arg) for arg in itertools.chain(args, kwargs.values())):
         return VectorMethodDistribution(method, self, args, kwargs)
     elif any(needs_lazy_evaluation(arg) for arg in itertools.chain(args, kwargs.values())):
         # see analogous comment in distributionFunction
         return makeDelayedFunctionCall(helper, (self,) + args, kwargs)
     else:
         return method(self, *args, **kwargs)
コード例 #4
0
 def handler2(self, *args):
     if needs_sampling(self):
         return VectorOperatorDistribution(op, self, args)
     elif any(needs_sampling(arg) for arg in args):
         return VectorMethodDistribution(method, self, args, {})
     elif any(needs_lazy_evaluation(arg) for arg in args):
         # see analogous comment in distributionFunction
         return makeDelayedFunctionCall(handler2, args, {})
     else:
         return method(self, *args)
コード例 #5
0
 def helper(self, *args, **kwargs):
     args = tuple(to_distribution(arg) for arg in args)
     kwargs = {name: to_distribution(arg) for name, arg in kwargs.items()}
     if any(
             needs_sampling(arg)
             for arg in itertools.chain(args, kwargs.values())):
         return MethodDistribution(method, self, args, kwargs)
     elif any(
             needs_lazy_evaluation(arg)
             for arg in itertools.chain(args, kwargs.values())):
         # see analogous comment in distributionFunction
         return makeDelayedFunctionCall(helper, (self, ) + args, kwargs)
     else:
         return method(self, *args, **kwargs)
コード例 #6
0
def to_distribution(val):
    """Wrap Python data types with Distributions, if necessary.

    For example, tuples containing Samplables need to be converted into TupleDistributions
    in order to keep track of dependencies properly."""
    if isinstance(val, (tuple, list)):
        coords = [to_distribution(c) for c in val]
        if any(needs_sampling(c) or needs_lazy_evaluation(c) for c in coords):
            if isinstance(val, tuple) and hasattr(val,
                                                  '_fields'):  # namedtuple
                builder = type(val)._make
            else:
                builder = type(val)
            return TupleDistribution(*coords, builder=builder)
    return val
コード例 #7
0
 def helper(*args, **kwargs):
     args = tuple(to_distribution(arg) for arg in args)
     kwargs = {name: to_distribution(arg) for name, arg in kwargs.items()}
     if any(
             needs_sampling(arg)
             for arg in itertools.chain(args, kwargs.values())):
         return FunctionDistribution(method, args, kwargs, support)
     elif any(
             needs_lazy_evaluation(arg)
             for arg in itertools.chain(args, kwargs.values())):
         # recursively call this helper (not the original function), since the delayed
         # arguments may evaluate to distributions, in which case we'll have to make a
         # FunctionDistribution
         return makeDelayedFunctionCall(helper, args, kwargs)
     else:
         return method(*args, **kwargs)
コード例 #8
0
    def generate(self, max_iterations=2000, verbosity=0, feedback=None):
        active_reqs = [
            req for req, prob in self.requirements if random.random() <= prob
        ]

        sample, iterations = rejection_sample(self.objects, self.dependencies,
                                              self.workspace, active_reqs,
                                              max_iterations, verbosity)

        # obtained a valid sample; assemble a scene from it
        sampled_objects = tuple(sample[obj] for obj in self.objects)
        sampled_params = {}
        for param, value in self.params.items():
            sampled_value = sample[value] if isinstance(value,
                                                        Samplable) else value
            assert not needs_lazy_evaluation(sampled_value)
            sampled_params[param] = sampled_value
        scene = Scene(self.workspace, sampled_objects, sampled_params)
        return scene, iterations
コード例 #9
0
 def dependencies(self) -> List:
     return [x for x in (self.obj, *self.args, *self.kwargs.values()) if needs_sampling(x) or needs_lazy_evaluation(x)]
コード例 #10
0
    def __init__(self, *args, **kwargs):
        self._conditioned = self
        # Validate specifiers
        name = type(self).__name__
        defs = self.defaults()

        specifiers = list(args) + [Specifier(p, v) for p, v in kwargs.items()]

        properties = group_by(specifiers, lambda s: s.property)
        for p, specs in properties.items():
            if len(specs) == 1:
                properties[p] = specs[0]
            else:
                spec_vals = [s.value for s in specs]
                regs = [sv.region for sv in spec_vals]
                # r1 = spec_vals[0].region
                # r2 = spec_vals[1].region
                delayed_intersection = makeDelayedFunctionCall(
                    intersect_distribution, regs, {})
                intersect_spec = Specifier(p, delayed_intersection)
                properties[p] = intersect_spec
                specifiers.append(intersect_spec)
                for s in specs:
                    specifiers.remove(s)
            # else:
            #     raise RuntimeParseError(f'property "{p}" of {name} specified twice (non combinable)')

        # TODO: dealing with duplicates part using intersections

        optionals = collections.defaultdict(list)
        for s in specifiers:
            relevant_opts = [o for o in s.optionals if o in defs]
            for opt in relevant_opts:
                optionals[opt].append(s)

        # Decide which optionals to use
        optionals_for_spec = collections.defaultdict(set)
        for opt, specs in optionals.items():
            if opt in properties:
                continue  # optionals do not override a primary specification
            if len(specs) > 1:
                raise RuntimeParseError(
                    f'property "{opt}" of {name} specified twice (optionally)')
            assert len(specs) == 1
            spec = specs[0]
            properties[opt] = spec
            optionals_for_spec[spec].add(opt)

        # Add any default specifiers needed
        for prop in filter(lambda x: x not in properties, defs):
            specifiers.append(defs[prop])
            properties[prop] = defs[prop]

        # Topologically sort specifiers
        order = []
        seen, done = set(), set()

        def dfs(spec: Specifier):
            if spec in done:
                return
            elif spec in seen:
                raise RuntimeParseError(
                    f'specifier for property {spec.property} '
                    'depends on itself')
            seen.add(spec)
            for dep in spec.requiredProperties:
                child = properties.get(dep)
                if child is None:
                    raise RuntimeParseError(
                        f'property {dep} required by '
                        f'specifier {spec} is not specified')
                else:
                    dfs(child)
            order.append(spec)
            done.add(spec)

        for spec in specifiers:
            dfs(spec)
        assert len(order) == len(specifiers)

        # Evaluate and apply specifiers
        for spec in order:
            v = probRobScene.core.distributions.to_distribution(
                evaluate_in(spec.value, self))
            assert not needs_lazy_evaluation(v)
            setattr(self, spec.property, v)
            for opt in optionals_for_spec[spec]:
                assert opt in spec.optionals
                setattr(self, opt, getattr(v, opt))

        # Set up dependencies
        self.properties = set(properties)
コード例 #11
0
 def withProperties(cls, props):
     assert all(reqProp in props for reqProp in cls.defaults())
     assert all(not needs_lazy_evaluation(val) for val in props.values())
     specs = (Specifier(prop, val) for prop, val in props.items())
     return cls(*specs)