Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding subcomp to child/ren #71

Open
borismarin opened this issue Jul 13, 2015 · 8 comments
Open

Binding subcomp to child/ren #71

borismarin opened this issue Jul 13, 2015 · 8 comments

Comments

@borismarin
Copy link
Contributor

According to the docs, the shorthand notation for defining components consists in using ComponentType as the xml-element name instead of <Component type=...>:

[...] Once the units are available it is possible to define a component. There are two equivalent ways of doing this: either by using the Component element and setting its type, or by using the type as a new XML element [...]

In the same example, though, we find

<HHGate id="n" power="4">          
   <Forward type="HHExpLinearRate" rate="0.1per_ms" midpoint="-55mV" scale="10mV" />          
   <Reverse type="HHExpRate" rate="0.125per_ms" midpoint="-65mV" scale="-80mV" />      
</HHGate> 

Where <Forward> and <Reverse> are not Component Types (they even have a type attribute), but the name attribute of a Child definition in the ComponentType:

<ComponentType name="HHGate">      
   <Parameter name="power" dimension="none" />       
   <Child name="Forward" type="HHRate" />      
   <Child name="Reverse" type="HHRate" />    

In this case, <HHGate> would have two <Child> of type HHRate, and the element name is being used to determine which is which.

One can always argue that <X name="aX"> is nicer to type than <Component type="X" name="aX">, but being able to bend the rules again and use <aX> (if and only if it is a <Child>) seems abusive to me. Consistence is not only good for us writing parsers/interpreters -- which will have a lot of ad-hoc checks to cope with those special cases -- but for users as well, as changing notation in "magic" places tends to be confusing and frustrating.

Keeping the discussion here in mind, I suggest (@robertcannon) to stick to the <X name="aX"> notation (even though I'd like to be radical on the consistency side and abolish the shorthand notation altogether...).

@pgleeson will probably say we have to live with it since it is used all around NeuroML2 - but actually, this seems to be the case (multiple <Child> with the same type) only for Gate opening / closing rates.

@robertcannon
Copy link
Member

Hi Boris,

I think it is fine to not support the shorthand notation internally. As long as there is an xsl transform for those who want to write it then its not a big deal to pre-process shorthand LEMS into standard LEMS.

But there is another problem here - given that component type definition, with children called Forward and Reverse, how do you specify which of the two children a particular child element is? As far as I know there isn't a "standard" LEMS variant of this and I can't think of a good solution. You could add a property on the Component - Component type="HHExpRate" role="Forward"
but that's not very nice because the role doesn't mean anything within the scope of the component - its about the role of this component within the parent.
Or you could nest it somehow - <HHGate><Child name="Forward"><HHExpRate.../></Child>
That might be OK for the more verbose standard variant.

In fact, the same problem exists when a component type declares two or more Children elements that aren't of disjoint types. Sub-elements are assigned to lists according to their type but you can't be sure this is enough information to know which list they should go in.

@borismarin
Copy link
Contributor Author

Exactly, @robertcannon. I don't see any way of keeping the "consistent" notation element name -> comptype whilst resolving child(ren) allocation at the same time, without substantial changes to Lems syntax.

The "xml-ish" way of doing it would probably go along your suggestion, i.e.

<Component type="Gate">
    <Child name="xx" >
      <Component type="Rate"/>
    </Child>
</Component>

but it then touches the point of why we don't do things like

<Componet type="X">
   <Parameter name="p0">10nS</Parameter>
   <Child name="child0">
      <Component type="typeOfChild0"/>
   </Child>
   <Child name="child1">
      <Component type="typeOfChild1"/>
   </Child>
   <Children name="children0">
      <Component type="typeOfChildren0"/>
      <Component type="typeOfChildren0"/>
   </Children>
   <ComponentRerefence name="compref">anExternalComp</ComponentReference>
</Component>

And, of course, it also brings out the semantic model behind Lems (i.e. the objects we unmarshal xml onto) into discussion - do you see models as

class Component{
   ComponentType type;
   List<Component> subcomponents;
...
}

Or (as I am automatically generating from CompType definitions is https://github.com/borismarin/org.lemsml.codegen) the "domain model"

class X extends Component{
   TypeOfChild0 child0;
   TypeOfChild1 child1;
   List<TypeOfChildren0> children0;
...
}

I guess this also touches the general issue of references in Lems: the current mechanism for "ComponentReferences" is also a way of assigning a "tag" to a subcomponent, via attributes. We have to tag stuff anyways, as you've pointed, to eliminate ambiguities. And imo we allow constructs which are not very modular / composable: using element names as a tags for the "role" of the subcomponents is compact, but suppose we want to use the same HHRate in two places: that would only be achievable by repeating the exact component definition (which would lead to two objects), changing only the element name.

Sorry about "accordioning-up" the question. Maybe we could have a meeting to discuss that - in any case I'll draft some ideas in a document.

@robertcannon
Copy link
Member

OK, a doc with ideas sounds good.

One thought from your comments about references. We could also write

<HHExpRate name="a" rate="123".../>
<HHExpRate name="b" rate="456".../>
<Gate forward="a" reverse="b"/>

Or, indeed:

<Gate forward="a" reverse="b">
     <HHExpRate name="a" rate="123".../>
     <HHExpRate name="b" rate="456".../>
</Gate>

The former rather pollutes the namespace. I quite like the latter since it is a minor change to the scoping rules for resolving references: just look at your children first when you are referring to something by name, then your siblings and then the wider world.

On the semantics, I tend to think of ComponentTypes as class definitions, so that is closer to your second version, though in the code generation I did, each Component became a class definition with actual instances for the objects in the simulation to hold the state.

@borismarin
Copy link
Contributor Author

See here

@robertcannon
Copy link
Member

That's a good summary of the problem. I like the last solution in your document. I'll try this in a branch of jLEMS to see if it raises any issues but I think it should work fine.

@borismarin borismarin changed the title Shorthand notation Binding subcomp to child/ren Jul 17, 2015
@borismarin
Copy link
Contributor Author

@robertcannon not sure how it should work for Children, though (see the updated doc).

@borismarin
Copy link
Contributor Author

@robertcannon all that might have to do with another thing I wanted to discuss, namely the use of <Structure/ChildInstance>. I have the impression that whenever we use refs to "external" components (in opposition to defined in place / nested under) as Child/ren, it doesn't make sense not to create a runtime instance to hold their state (i.e. the use of ChildInstance is redundant).

Related observations:

  • whenever a ComponentReference is used, we need to "instantiate" it under Structure, so references and explicit component defs are not 100% interchangeable.
  • Actually, is there any case where we should NOT create runtime instances? ChildInstance x Child + references.

@robertcannon
Copy link
Member

Hi @borismarin, yes, this is a bit of a fudge. The problem is that there are also other ways to instantiate a component, such as the MultiInstantiate element which says you should have n instances, where n comes from somewhere else in the model. If you have MultiInstantiate, then you don't want any other default instantiation going on, so, for consistency it means that the normal single instantiation should be made explicit.
..well,that's why it is there but I'm not sure it is the best solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants