def VisitStateVariable(self, o, **kwargs): new = ast.StateVariable(symbol=o.symbol) new.initial_value = o.initial_value return copy_std( o, new, )
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
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)
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)