コード例 #1
0
ファイル: requirements.py プロジェクト: t27/Scenic
    def compile(self, namespace, scenario, syntax=None):
        """Create a closure testing the requirement in the correct runtime state.

        While we're at it, determine whether the requirement implies any relations
        we can use for pruning, and gather all of its dependencies.
        """
        bindings, ego, line = self.bindings, self.egoObject, self.line
        condition = self.condition

        # Check whether requirement implies any relations used for pruning
        if self.ty.constrainsSampling and syntax:
            relations.inferRelationsFrom(syntax, bindings, ego, line)

        # Gather dependencies of the requirement
        deps = set()
        for value in bindings.values():
            if needsSampling(value):
                deps.add(value)
            if needsLazyEvaluation(value):
                raise InvalidScenarioError(
                    f'requirement on line {line} uses value {value}'
                    ' undefined outside of object definition')
        if ego is not None:
            assert isinstance(ego, Samplable)
            deps.add(ego)

        # Construct closure
        def closure(values):
            global evaluatingRequirement, currentScenario
            # rebind any names referring to sampled objects
            for name, value in bindings.items():
                if value in values:
                    namespace[name] = values[value]
            # rebind ego object, which can be referred to implicitly
            boundEgo = None if ego is None else values[ego]
            # evaluate requirement condition, reporting errors on the correct line
            import scenic.syntax.veneer as veneer
            with veneer.executeInRequirement(scenario, boundEgo):
                result = condition()
                assert not needsSampling(result)
                if needsLazyEvaluation(result):
                    raise InvalidScenarioError(
                        f'requirement on line {line} uses value'
                        ' undefined outside of object definition')
            return result

        return CompiledRequirement(self, closure, deps)
コード例 #2
0
def storeScenarioStateIn(namespace, requirementSyntax, lineMap, filename):
    """Post-process an executed Scenic module, extracting state from the veneer."""
    # Extract created Objects
    namespace['_objects'] = tuple(veneer.allObjects)
    namespace['_egoObject'] = veneer.egoObject

    # Extract global parameters
    namespace['_params'] = veneer.globalParameters
    for name, value in veneer.globalParameters.items():
        if needsLazyEvaluation(value):
            raise InvalidScenarioError(
                f'parameter {name} uses value {value}'
                ' undefined outside of object definition')

    # Extract external parameters
    namespace['_externalParams'] = tuple(veneer.externalParameters)

    # Extract requirements, scan for relations used for pruning, and create closures
    requirements = veneer.pendingRequirements
    finalReqs = veneer.inheritedReqs
    requirementDeps = set(
    )  # things needing to be sampled to evaluate the requirements
    namespace['_requirements'] = finalReqs
    namespace['_requirementDeps'] = requirementDeps

    def makeClosure(req, bindings, ego, line):
        """Create a closure testing the requirement in the correct runtime state."""
        def evaluator():
            result = req()
            assert not needsSampling(result)
            if needsLazyEvaluation(result):
                raise InvalidScenarioError(
                    f'requirement on line {line} uses value'
                    ' undefined outside of object definition')
            return result

        def closure(values):
            # rebind any names referring to sampled objects
            for name, value in bindings.items():
                if value in values:
                    namespace[name] = values[value]
            # rebind ego object, which can be referred to implicitly
            if ego is not None:
                veneer.egoObject = values[ego]
            # evaluate requirement condition, reporting errors on the correct line
            try:
                veneer.evaluatingRequirement = True
                result = executePythonFunction(evaluator, lineMap, filename)
            finally:
                veneer.evaluatingRequirement = False
            return result

        return closure

    for reqID, (req, bindings, ego, line, prob) in requirements.items():
        # Check whether requirement implies any relations used for pruning
        reqNode = requirementSyntax[reqID]
        relations.inferRelationsFrom(reqNode, bindings, ego, line, lineMap)
        # Gather dependencies of the requirement
        for value in bindings.values():
            if needsSampling(value):
                requirementDeps.add(value)
            if needsLazyEvaluation(value):
                raise InvalidScenarioError(
                    f'requirement on line {line} uses value {value}'
                    ' undefined outside of object definition')
        if ego is not None:
            assert isinstance(ego, Samplable)
            requirementDeps.add(ego)
        # Construct closure
        finalReqs.append((makeClosure(req, bindings, ego, line), prob))
コード例 #3
0
ファイル: translator.py プロジェクト: yuul/Scenic
def storeScenarioStateIn(namespace, requirementSyntax, filename):
    # extract created Objects
    namespace['_objects'] = tuple(veneer.allObjects)
    namespace['_egoObject'] = veneer.egoObject

    # extract global parameters
    namespace['_params'] = veneer.globalParameters
    for name, value in veneer.globalParameters.items():
        if needsLazyEvaluation(value):
            raise InvalidScenarioError(
                f'parameter {name} uses value {value}'
                ' undefined outside of object definition')

    # extract requirements and create proper closures
    requirements = veneer.pendingRequirements
    finalReqs = veneer.inheritedReqs
    requirementDeps = set(
    )  # things needing to be sampled to evaluate the requirements
    namespace['_requirements'] = finalReqs
    namespace['_requirementDeps'] = requirementDeps

    def makeClosure(req, bindings, ego, line):
        def closure(values):
            # rebind any names referring to sampled objects
            for name, value in bindings.items():
                if value in values:
                    namespace[name] = values[value]
            # rebind ego object, which can be referred to implicitly
            if ego is not None:
                veneer.egoObject = values[ego]
            # evaluate requirement condition, reporting errors on the correct line
            try:
                veneer.evaluatingRequirement = True
                result = req()
                assert not needsSampling(result)
                if needsLazyEvaluation(result):
                    raise RuntimeParseError(
                        f'requirement on line {line} uses value'
                        ' undefined outside of object definition')
                return result
            except RuntimeParseError as e:
                cause = e if showInternalBacktrace else None
                raise InterpreterParseError(e, line) from cause
            finally:
                veneer.evaluatingRequirement = False

        return closure

    for reqID, (req, bindings, ego, line, prob) in requirements.items():
        # Check whether requirement implies any relations used for pruning
        reqNode = requirementSyntax[reqID]
        relations.inferRelationsFrom(reqNode, bindings, ego, line)
        # Gather dependencies of the requirement
        for value in bindings.values():
            if needsSampling(value):
                requirementDeps.add(value)
            if needsLazyEvaluation(value):
                raise InvalidScenarioError(
                    f'requirement on line {line} uses value {value}'
                    ' undefined outside of object definition')
        if ego is not None:
            assert isinstance(ego, Samplable)
            requirementDeps.add(ego)
        # Construct closure
        finalReqs.append((makeClosure(req, bindings, ego, line), prob))