Esempio n. 1
0
 def VisitStateVariable(self, o, **kwargs):
     new = ast.StateVariable(symbol=o.symbol)
     new.initial_value = o.initial_value
     return copy_std(
         o,
         new,
     )
Esempio n. 2
0
    def add_timederivative(self, lhs_state_name, rhs_ast):
        statevar_obj = ast.StateVariable(lhs_state_name)
        self._resolve_global_symbol(lhs_state_name, statevar_obj)

        # Create the assignment object:
        a = ast.EqnTimeDerivative(lhs=statevar_obj, rhs=rhs_ast)

        assert not statevar_obj in self.builddata.timederivatives
        self.builddata.timederivatives[statevar_obj] = a
Esempio n. 3
0
        def ensure_state_variable(symbol):

            sv = ast.StateVariable(symbol=symbol)
            self._resolve_global_symbol(symbol=sv.symbol, target=sv)
            deriv_value = ast.ConstValueZero()

            td = ast.EqnTimeDerivativeByRegime(
                lhs=sv,
                rhs_map=ast.EqnRegimeDispatchMap(
                    rhs_map={
                        self._current_rt_graph.regimes.get_single_obj_by(name=None):
                        deriv_value
                    }))
            self.builddata.timederivatives.append(td)
Esempio n. 4
0
    def finalise(self):

        # A few sanity checks....
        # ########################
        assert self.active_scope is None

        from neurounits.librarymanager import LibraryManager
        assert isinstance(self.library_manager, LibraryManager)

        # Resolve the TimeDerivatives into a single object:
        time_derivatives = SingleSetDict()
        maps_tds = defaultdict(SingleSetDict)
        for regime_td in self.builddata._time_derivatives_per_regime:
            maps_tds[regime_td.lhs][regime_td.regime] = regime_td.rhs

        for (sv, tds) in maps_tds.items():

            statevar_obj = ast.StateVariable(sv)
            self._resolve_global_symbol(sv, statevar_obj)

            mapping = dict([(reg, rhs) for (reg, rhs) in tds.items()])
            rhs = ast.EqnTimeDerivativeByRegime(
                lhs=statevar_obj, rhs_map=ast.EqnRegimeDispatchMap(mapping))
            time_derivatives[statevar_obj] = rhs

        self.builddata.timederivatives = time_derivatives.values()
        del self.builddata._time_derivatives_per_regime

        ## Resolve the Assignments into a single object:
        assignments = SingleSetDict()
        maps_asses = defaultdict(SingleSetDict)
        for reg_ass in self.builddata._assigments_per_regime:
            #print 'Processing:', reg_ass.lhs
            maps_asses[reg_ass.lhs][reg_ass.regime] = reg_ass.rhs

        for (ass_var, tds) in maps_asses.items():

            assvar_obj = ast.AssignedVariable(ass_var)
            self._resolve_global_symbol(ass_var, assvar_obj)

            mapping = dict([(reg, rhs) for (reg, rhs) in tds.items()])
            rhs = ast.EqnAssignmentByRegime(
                lhs=assvar_obj, rhs_map=ast.EqnRegimeDispatchMap(mapping))
            assignments[assvar_obj] = rhs

        self.builddata.assignments = assignments.values()
        del self.builddata._assigments_per_regime

        # Copy rt-grpahs into builddata
        self.builddata.rt_graphs = self._all_rt_graphs.values()

        # OK, perhaps we used some functions or constants from standard libraries,
        # and we didn't import them. Lets let this slide and automatically import them:
        unresolved_symbols = [(k, v)
                              for (k, v) in self.global_scope.iteritems()
                              if not v.is_resolved()]
        for (symbol, proxyobj) in unresolved_symbols:
            if not symbol.startswith('std.'):
                continue
            (lib, token) = symbol.rsplit('.', 1)
            #print 'Automatically importing: %s' % symbol
            self.do_import(srclibrary=lib, tokens=[(token, symbol)])

        ## Finish off resolving StateVariables:
        ## They might be defined on the left hand side on StateAssignments in transitions,
        def ensure_state_variable(symbol):

            sv = ast.StateVariable(symbol=symbol)
            self._resolve_global_symbol(symbol=sv.symbol, target=sv)
            deriv_value = ast.ConstValueZero()

            td = ast.EqnTimeDerivativeByRegime(
                lhs=sv,
                rhs_map=ast.EqnRegimeDispatchMap(
                    rhs_map={
                        self._current_rt_graph.regimes.get_single_obj_by(name=None):
                        deriv_value
                    }))
            self.builddata.timederivatives.append(td)

            #assert False

        # Ok, so if we have state variables with no explcity state time derivatives, then
        # lets create them:
        for tr in self.builddata.transitions_triggers + self.builddata.transitions_events:
            for action in tr.actions:
                if isinstance(action, ast.OnEventStateAssignment):

                    if isinstance(action.lhs, SymbolProxy):

                        # Follow the proxy:
                        n = action.lhs
                        while n.target and isinstance(n.target, SymbolProxy):
                            n = n.target

                        # Already points to a state_varaible?
                        if isinstance(n.target, ast.StateVariable):
                            continue

                        target_name = self.global_scope.get_proxy_targetname(n)
                        ensure_state_variable(target_name)
                        #print 'Unresolved target:'

                    else:
                        assert isinstance(action.lhs, ast.StateVariable)

        # OK, make sure that we are not setting anything other than state_varaibles:
        for (sym, initial_value) in self._default_state_variables.items():
            sv_objs = [
                td.lhs for td in self.builddata.timederivatives
                if td.lhs.symbol == sym
            ]
            assert len(sv_objs) == 1, "Can't find state variable: %s" % sym
            sv_obj = sv_objs[0]

            sv_obj.initial_value = initial_value
            #print repr(sv_obj)

        # We inspect the io_data ('<=>' lines), and use it to:
        #  - resolve the types of unresolved symbols
        #  - set the dimensionality
        # ###################################################

        # Parse the IO data lines:
        io_data = list(
            itertools.chain(
                *[parse_io_line(l) for l in self.builddata.io_data_lines]))

        # Update 'Parameter' and 'SuppliedValue' symbols from IO Data:
        param_symbols = [
            ast.Parameter(symbol=p.symbol, dimension=p.dimension)
            for p in io_data if p.iotype == IOType.Parameter
        ]
        for p in param_symbols:
            if self.library_manager.options.allow_unused_parameter_declarations:
                self._resolve_global_symbol(p.symbol,
                                            p,
                                            expect_is_unresolved=False)
            else:
                self._resolve_global_symbol(p.symbol,
                                            p,
                                            expect_is_unresolved=True)

        reduce_ports = [
            ast.AnalogReducePort(symbol=p.symbol, dimension=p.dimension)
            for p in io_data if p.iotype is IOType.AnalogReducePort
        ]
        for s in reduce_ports:
            self._resolve_global_symbol(s.symbol, s, expect_is_unresolved=True)

        supplied_symbols = [
            ast.SuppliedValue(symbol=p.symbol, dimension=p.dimension)
            for p in io_data if p.iotype is IOType.Input
        ]
        for s in supplied_symbols:
            if self.library_manager.options.allow_unused_suppliedvalue_declarations:
                self._resolve_global_symbol(s.symbol,
                                            s,
                                            expect_is_unresolved=False)
            else:
                self._resolve_global_symbol(s.symbol,
                                            s,
                                            expect_is_unresolved=True)

        # We don't need to 'do' anything for 'output' information, since they
        # are 'AssignedValues' so will be resolved already. However, it might
        # contain dimensionality information.
        output_symbols = [p for p in io_data if p.iotype == IOType.Output]
        for o in output_symbols:
            os_obj = RemoveAllSymbolProxy().followSymbolProxy(
                self.global_scope.getSymbol(o.symbol))
            assert not os_obj.is_dimensionality_known()
            if o.dimension:
                os_obj.set_dimensionality(o.dimension)

        # OK, everything in our namespace should be resoved.  If not, then
        # something has gone wrong.  Look for remaining unresolved symbols:
        # ########################################
        unresolved_symbols = [(k, v)
                              for (k, v) in self.global_scope.iteritems()
                              if not v.is_resolved()]
        # We shouldn't get here!
        if len(unresolved_symbols) != 0:
            raise ValueError('Unresolved Symbols:%s' %
                             ([s[0] for s in unresolved_symbols]))

        # Temporary Hack:
        self.builddata.funcdefs = self.builddata.funcdefs.values()
        self.builddata.symbolicconstants = self.builddata.symbolicconstants.values(
        )

        # Lets build the Block Object!
        # ################################
        #print self.block_type
        self._astobject = self.block_type(library_manager=self.library_manager,
                                          builder=self,
                                          builddata=self.builddata,
                                          name=self.builddata.eqnset_name)

        self.post_construction_finalisation(self._astobject, io_data=io_data)
        self.library_manager = None

        # The object exists, but is not complete and needs some polishing:
        # #################################################################
        self.post_construction_finalisation(self._astobject, io_data=io_data)
        #self.library_manager = None

        # Resolve the compound-connectors:

        for compoundport in self._interface_data:
            local_name, porttype, direction, wire_mapping_txts = compoundport
            self._astobject.build_interface_connector(
                local_name=local_name,
                porttype=porttype,
                direction=direction,
                wire_mapping_txts=wire_mapping_txts)