Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
AMP/Acore Model Design
- 1 Introduction
- 2 About AMF and MetaABM
- 3 Participating
- 4 Schedule
- 5 User Experiences
- 6 Design
- 6.1 General
- 6.2 Structure
- 6.3 Behavior
- 6.4 Functions
- 7 Discussion
As part of the move to Eclipse we've been planning to transition the "metaabm" meta-model to "acore". Acore will have significant changes based on everyone's experience using MetaABM over the last couple of years. This page is for community discussion about those changes. Note that this document scope is for discussion of the core meta-model itself, not editors, generators, etc.. except as the model design directly affects those things. We could open up more pages for these if there is interest.
About AMF and MetaABM
AMF currently includes MetaABM, so if you want to explore MetaABM, it's best to install AMP, not MetaABM. Please see [Here] for a guide to installing AMP. It is not neccessary to have actually used the meta-model to participate, but it couldn't hurt!
Please see this doc for more on the MetaABM/ Acore MetaModel itself.
The AMP project is actively soliciting feedback on those changes. Even better than feedback would be active participation in the design process. Things will be moving pretty rapidly so now is the time to get involved! Design discussions will take place at the following places.
Design Feedback and Ideas
This page is an active design document.
All you have to do to edit this page is get an Eclipse bugzilla account here: https://bugs.eclipse.org/bugs/createaccount.cgi
Please feel free to add your own thoughts, and to revise or add categories, etc... And, just saying "this part didn't work really well", or "I'm not sure what you were thinking with.." is really valuable too. Think of this as brainstorming now, so you can throw ideas at the wall and we'll see what sticks.
Just a few guidelines. Please follow general wiki talk etiquette, i.e. don't erase other's comments until it is a good time to condense. We will be churning and refining the doc overtime things so things will get distilled and we can archive discussions. Please end any comments with the following sequence so that your name and the time show up on the wiki: ~~---- See [here] for more.
General Discussion and Help
That should go to newsgroup:  Again, you can get access to the newsgroups by getting a bugzilla account == easy.
Implementation and technical issues
If it is really nitty-gritty: https://dev.eclipse.org/mailman/listinfo/amp-dev
As we refine things, we'll add them to the bugzilla. If there is a change or improvement that you really want to make sure gets into the Acore release, then you should file a bug report to the AMP AMF component for it. Really, feel free, it's always nice to get reports that come from outside of the actual project! Please also add it as a dependency to https://bugs.eclipse.org/bugs/show_bug.cgi?id=291254
I'm really pushing to get this out by the end of the year. I think it's important to get on to the release train and go to 1.0 status so I don't want to delay things more than necessary. Thoughts?--Milesparker.gmail.com 00:31, 4 November 2009 (UTC)
This is a place to put any thoughts that don't fit into specific design issues.
Things We Like
Things We Don't Like
- The hierarchical editor really is kind of awkward for editing behavior. Should we try to make behavior definition more hierarchical? --Milesparker.gmail.com 21:38, 4 November 2009 (UTC)
There are a lot of dependencies, some of which (such as in gen code) aren't really obvious, so we should balance changes against that. We also need to be sure that there is a clear mapping from MetaABM to Acore constructs. There are a number of design features that are in place largely as a result of original Repast Simphony integration that we should pull out.
The overall design requirements are below. Let's try to capture anything in current model that doesn't meet them.
- Ability to construct any (cannonical, imagined..?) ABM model with an Acore model and no other artifacts.
- Modifications to one part of model have low coupling to other components. (For example, we want to be able to change the type of a space without having to change everything that refers to that space.
- Change from current class name pattern of S for structure, A for Actions, F for Functions and I for pure abstract to an "A" for everything to match with Ecore design.
- The package namespace would obviously change, from org.metaabm.** to org.eclipse.amf.acore.**
Some specific proposed changes:
- "SContext" -> ~"AEnsemble"
- "SProjection" -> "ASpace"
- "ASpace" and "AAgent" both inherit from "AScape" (not "Ascape" :))
- AAttribute would have a new "derived" flag that would specify the value as mutable but not modifiable through behavior.
- Probably some cleanup of the IID and SNamed stuff as well as taking a look at SImplementation -- that seems a bit unnecessarily complicated.
- Perhaps provide a more privileged way of specifying non-model (library) resources.
Inheritance and Composition
The most radical changes are actually to the basic composition structure. We need to figure out a general way to handle both of these in a way that supports ad hoc model composition but retains much of the elegance and simplicity of past models.
I think that there are some flaws in the Simphony Context model that I discussed in NAACSOS talk. I'm going to try to get that online. I'm proposing that we need a model that provides an ensemble structure that allows much more control over "scale", "scope" and "space". What we want to support here is the seamless meshing, composition and filtering of models from any domain, scale, methodology or granularity. A somewhat tall order! --Milesparker.gmail.com 18:33, 4 November 2009 (UTC)
There isn't any support for inheritance at all currently, as the naive approach of modeling the Java pattern doesn't fit with what we need to do. Hopefully the scoping mechanism will resolve those issues...being a bit vague here..but the idea is that we can move beyond raw inheritance to an ad hoc assembly of agent "facets" both through explicitly defining Agent Facets (like an abstract base class or a strategy pattern) that can be assembled into runtime agents through a scoping mechanism. Question: Is there a difference in kind between such a facet and simply supporting (multi!) inheritance? I think there may be, for example for the following use case:
|Model Composition Stories|
|Salim wants to build a model of bicycle sharing in Paris. He has designed a behavioral model which covers usage decisions, but needs to model the actual road movement. There is already an extensive model for vehicle travel developed at the Big Think Institute. Salim wants a simple way to incorporate that model that does't involve a lot of moving things around and that will benefit from changes in the BTI model.}}|
|Model Composition Proposals|
|Action-Based||One thing I was thinking of doing is sort of inspired by Apple's Dylan project of the mid-90s. In Dylan, there was no such thing as an actual object per se - or rather, methods did not belong to objects, but were instead inferred from the method body definitions. This gave the code a very dynamic flavor and meant no time wasted on refactoring different pieces. Just change the method signature! But I don't think that quite works in practice as we really want to be have object attributes be a high level part of a model definition.--Milesparker.gmail.com 21:26, 4 November 2009 (UTC)|
|Wild-card namespace inclusion||We don't need to go that far, but we could encourage the definition of very small fragments, say supporting movement or whatever. This could then fit in with scoping. The idea would be that instead of a single inheritance hierarchy you could actually use scoping to assemble agents. So you'd define a bunch of agent fragments, and then refer to them as an agent, where an agent is basically an identifier combined with a string defining the inclusion of all behavior. In the use case above, Salim might define a fragment for his behavior, and then specify a TransporationUser agent that had a behavior inclusion list like "". Do we need exclusion? (See below.) We'd need to manage name collision and so on, so this isn't a trivial thing to implement, but I think the benefits for composability would be really significant.Milesparker.gmail.com 19:12, 4 November 2009 (UTC)|
|List of multi-inheiritance.||Keep it simple, just allow agents to be specified as an inclusion of a bunch of Facets. This would be like a no-op class that inherits from a bunch of base classes. I think this one might be best, especially as we don't have to deal with issues of multiple levels of wild-card inclusion, which could get really messy. But it could prevent a more flexible approach to composition (across scales, say.)--Milesparker.gmail.com 21:26, 4 November 2009 (UTC)|
|Modularization (Option)||This would provide for any model a facility for arbitrarily mapping an external namespace into an external namespace.|
Scope, Scale, Type/Kind and Space
What we need is a good way to define arbitrary semantic structures with an easily grokked one-line syntax. Here is a use case (Note how similar to the one for inheritance and composition, as they are both different aspects of the same issue:
|Model Namespace Stories|
|Tim, a grad student at the University of Pennsyltucky, has built a model of the social dynamics and demographics of penguins in Antarctica. He wants to test a theory that penguins about food sharing based on rational utility optimization and so wants to integrate a notional model of economic actors that Sally made at the Big Think Institute. We'd like to define some string for each of the models that we can use with another inclusion string that will effectively search a common namespace and that will then be able to gather and integrate the two models.}}|
So here is what we know about Tim's model:
- He's at Pennsyltucky (provenance)
- He's studying marine birds (type and scale)
- His model is in Antarctica (scale and scope)
- His model has social interaction (scope)
- His model has demographics (i.e. eat, reproduce, die..)
- She's at BTI
- Her model is about economic actors
- Her model is really notional and could apply to many different scales, but maybe it makes sense to think of human scale?
- Her model is about utility optimization (methodology)
Now, at what granularity and using what mechanism do we provide scoping information across scales and types?
|Model Namespace Proposals|
|Java-like||A strict hierarchal java package name space probably doesn't work, as those end up being arbitrary and can't deal with cross-cutting concerns:
|Hierachical Wild-Card||Or we could add in wildcards, ala XPath, but that's still hierarchical.
|Tuple Wild-card||So currently I'm thinking about using some kind of tuple space to allow an arbitrary set of dimensions and then encourage the actual detailed specification to be developed by the community at large..these could then be attached to particular agent facets, spaces and scales. A model then is simply some defined region in this arbitrarily complex space.
Tim's Ensemble: institution=edu.pentk, scope="bio,social", scale="community.higher-organisms" Tim's Ensemble: institution=edu.pentk
I'm sure that there is relevant work out there. Please share it along with any ideas for the most flexible approach to this.
Graphs / Networks
Should these be called graphs, networks, or relations?
Allow Edge Data / Agents
This started out just thinking about providing weighted graph support. But it would be a lot more general and in some way's easier to implement to simply allow agents to be assigned to graph edges as well as nodes. Is this too confusing / weird an approach?
We had space construction types defined as attributes of graphs. These should really be moved out of there and into a build graph action specialization.
Because of timeline, we should try to keep scope of new features down, remembering that it is much easier to add things than to change existing features. But this would still be a good time to think through these issues, especially as we may want to drive some things into main design.
Add a "derived" rule, which allows one to create attributes that are completely derived from rules. IFF an attribute is derived can it be modified in a ADervived root action, and it cannot be changed anywhere else. This would clean up a lot of code and make it much more modular and it would also allow users to easily create statistics and other measures.
Support for Systems Dynamics
There has been a lot of discussion about this. I wonder if we're ready to implement some specific proposals, for example explicit support for sources and sinks.
Better Support for Discrete Events / Dynamic Scheduling)
It's not clear that the existing scheduling mechanism gives us the flexibility we want. Ed MacKerrow has mentioned the need for some kind of explicit schedule creation mechanism so we'll use his example.
|Ed is working on a supply chain model. He'd like to be able to schedule some event, such as the arrival of a truck at a depot, at some arbitrary time in the future.}}|
|We need a harder use case here!|
|Existing Approach|| This can be covered by simply modeling the progression of the truck from one place to another over time. For example, we could have a GIS or simply a graph structure that represents the notional distance (we don't have edge state yet for graphs (see below), but assume we do..) Then create an ARule that checks wether the truck is traveling. If it is, then we increment our existing location by our speed. We check if we've arrived at our destination, and if so we add ourselves to the at location graph for that location.
True, but.. While this is the most notionally defensible approach it might sometimes be much simpler to not explicitly model that part of the system. OTOH, if we want to model any kind of unpredictable events (a sudden snowstorm on I-90) we're going to have to build out that part of the model anyway.
True, but.. The default ABM API codegen would not be ideal in the case where we knew with certainty that the truck would arrive at a point at a given time. Why increment a value each time if you don't have to? See above though, we may end up needing to do this and our approach is more general. More importantly a modeling (just imagined at the moment) engine that could do inference could determine that a very simple equation would be able to determine arrival time in certain cases, and optimize all of the loop execution away.
|Add an ACreateSchedule Action||Here we would have an Action that adds a Root rule to a schedule for later execution. Incidentally, this provides a potential route to providing dynamic behavior and more complex call structures. (And with that a lot of potential complexity.) This is especially true we allowed a schedule to be added for the current period. I think Simphony actually allows this, but I'm (Miles) not sure that I like the potential for issues that this could introduce.|
Do we want more explicit support for state machines? (Ala AnyLogic?) Or is this really more of an editor issue? IOTW, are there things that we can't do easily now?
Support for Equation Models (ODE/PDE)
With the current model it should be possible to infer potential equation models from model contents. Is there any additional meta-data that would be helpful in that regard?
Support Loop Structures / Recursion
In declarative languages, loops are commonly achieved by admitting (some form of) recursion, but if I understood, recursion is not possible with metaABM rules. --Francesco Parisi
Please note that the issue here is not about working with collections, i.e. the ubiquitous but problematic and unnecessary "for each" construct. Actions against collections are handled transparently by the query framework.
For rest of discussion, see this web forum thread.
Yes, we should definitely try to figure out how to achieve the result without distorting the overall Acore Action design approach.
|Recursion and Loop Stories|
|Francesco (actual case) would like to: define a behaviour of the following type "do rule (activity) X until condition C is verified.}}|
|Kimi wants to represent path planning and to do that he's pretty sure that he needs to implement a recursive search across a tree structure.}}|
|Mika wants to solve a complex utility function that involves (some kind of iterative function?).|
|'We probably need other cases here. Please add any you can think of.|
|Recursion and Loop Structures Proposals|
|Existing Approach||Right now, you can do Francesco's case pretty naturally if you allow the behavior to occur over time. Here you would simply create a ARule action that has a target "Verify" AQuery which tests for condition C. That Query has a target DoSomething (say modify a value that is a component of C). The requirement that this happen over time is problematic though, right?|
|Existing Functional Approach||For Mika's case, it probably would probably typically make the most sense to call out to an external function. There are large libraries of well-implemented, high performance, and tested functions available and so even were it possible to write a complex function in Acore. Note that this is different from simply saying "we'll model it in Java" as an answer, because here we have a very well-defined functional form -- in fact we could argue that the important thing is not the Java implementation, but the equation model that that Java implementation represents. Acore code ends up in Java too. (We need to make the process of adding external java functions easier, see below.)|
|Add High-Level Actions||If we can assume that Kimi wants to do a well defined and thorough search of a space, then it is best to do that declaratively by using high-level Acore constructs. For example, let's say he wants agents to search within some knowledge space, where agents represent nuggets of information. Then he could say search for the maximum knowledge chunk size within n distance. He shouldn't know or care how this is done, as long as the potential outcomes are well defined. If OTOH, Kimi wants to say represent some kind of sub-optimal path search that doesn't happen over time, then we may have a good case for more direct recursion/loop support.|
|New AWhile Action|| Most of the examples above seem to argue against having explicit support, but I'm sure that we'll develop cases that do require it. Here's a proposal that I think fits in with the overall design. We could add an AWhile Root Action. This would execute
In practice, the second part will generally mean that the Action will be executed while any of the Queries return true, but in typical cases users would probably simply define an initial query that tests some condition. Question: Should this be a root action only, or could/should it be made a target action as well?
|New AUntil Action|| Like AWhile, but in this case any actions will fire:
|New ARepeat Action|| This would be a *non-root* action that would fire:
|Explicit Implementation||Get rid of the requirement that Actions be in a directed tree and allow loops. Also, we could allow other actions to be directly referred to. This has a lot of potential downsides, so we'd need to think through this very carefully before going down this route.|
|Use Queries!||This is a new idea. Why not use the existing selection / query structure? One could simply define a logical function that would execute something n times, or as long as the conditions held true (while) or they hold true (until)?! This one needs more thought but it has some really cool implications and I think is quite elegant. --Milesparker.gmail.com 22:49, 8 December 2009 (UTC)|
Changes to Select, Query and Logic
Currently the ASelect, AQuery and ALogic is complex and the semantics are somewhat poorly defined. In practice it has been difficult for users to understand and difficult to generate code for. On the other hand, there are subtle and important things that the design allows you to do that we'd like to keep. Here are some random thoughts..
For example, consider the following:
S1 / \ Q1 Q2 \ / & Q3
In the above case, we do a select against space and agent in S1 using Q1 and Q2 as terms. Then we check if the results of that selection meet Q3. A potentially confusing thing is that for the fowllowing case:
S1 / \ \ Q1 Q2 Q3 \ / / & / \ / | (AAll) Q4
The select is ((Q1 & Q2) | Q3) and then Q4 is applied to the result of that selection. Basically, AAll and AAny serve as search terminals. This get's even more confusing when we add in ANone (Negation). We perhaps need to make this clearer. Here are some potential approaches:
|Select and Query Change Proposals|
|Query Containment||We could bundle up AQuery with a list of query expressions. This would get rid of the trees of queries that currently proliferate. But I think we'd still want to keep ASelect and AQuery separate.|
|End Query Node||Have an explicit "end query" node. Currently the semantics of when a query ends might not be clear, because it is possible to have a query filtering the results immediately following a select construct.|
|(Option) No Explicit Conjunction||Get rid of AAny, which is effectively a logical OR and not really necessary, as multiple paths to a given node are implicitly ORs. One could get any logical statement using (implicitly) Disjunctive Normal Form. AAny is not strictly speaking necessary (I think!) because it allows a set of potential boolean conditions to be clearly gathered up in one place, but i creates a lot of confusion esp. when we get to negation. This would mean that all queries were exactly two node layers deep, but I think we'd need to add the facility to negate any of the queries. Is the potential value to end-user of being able to use any kind of logical construction outwighed by the simplicty of simply allowing some set of AND queries connected with (implicit) ORs?|
I'm thinking the best idea is to morph AAll into an AEnd node which indicates a set of conditions and just getting rid of AAny, but I'm not sure. It might be really nice and clean to just bundle them up into a set of Selects and Queries with multiple and entries. We need to make sure that any solution allows full and simple equivalence to the General Purpose Language else construct. I think we can do that with Negation but we need to be sure that will work. These are critical issues, so we really need feedback.
User Tools for Defining Functions
Right now, we're manually providing the core libraries, though it's really pretty easy to define these, it would be nice to have some more automated hooks that allowed users to suck up a Java class file with a bunch of static methods in it and use them as methods. We actually have the code, it just needs to be integrated into the UI. We should also look at some use cases of this whole process along with examples to see if there is a way to make this whole process more visible.
Start a section here for anything you want to discuss that doesn't fit in above...