ADDED mttroot/ntt/COPYING Index: mttroot/ntt/COPYING ================================================================== --- /dev/null +++ mttroot/ntt/COPYING @@ -0,0 +1,358 @@ + + ntt: new transformation tools for using bond graphs with Matlab + Copyright (C) 2003 Dr. Dominic J. Diston + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +^L + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. ADDED mttroot/ntt/bin/make_abg.m Index: mttroot/ntt/bin/make_abg.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_abg.m @@ -0,0 +1,57 @@ +function abg = make_abg(system) +global mtt_environment + +start_time = mttGetTime ; + +input = [] ; +abg = [] ; + + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "abg" representation') ; + mttWriteNewLine ; + + if isempty(mtt_environment) + mttNotify('...WARNING: No "env" definition => all domain references will be ignored') ; + mttWriteNewLine ; + mttNotify(' => paths will not be recognised') ; + mttWriteNewLine ; + end + + abg = mttCreateAcausalBondgraph(system) ; + input = 'abg' ; +end + +mttAssert(strcmp(input,'abg'),'Input representation not recognised') ; + +if isempty(abg) + mttWriteNewLine ; + mttNotify('Copying "abg" representation') ; + mttWriteNewLine ; + + mttNotify('...INFO: Input already defined as a "abg": copying to Output') ; + mttWriteNewLine ; + mttWriteNewLine ; + abg = system ; +end + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; ADDED mttroot/ntt/bin/make_cbg.m Index: mttroot/ntt/bin/make_cbg.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_cbg.m @@ -0,0 +1,70 @@ +function cbg = make_cbg(system) +global mtt_environment + +start_time = mttGetTime ; + +input = [] ; +abg = [] ; +cbg = [] ; + + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "abg" representation') ; + mttWriteNewLine ; + + if isempty(mtt_environment) + mttNotify('...WARNING: No "env" definition => all domain references will be ignored') ; + mttWriteNewLine ; + mttNotify(' => paths will not be recognised') ; + mttWriteNewLine ; + end + + abg = mttCreateAcausalBondgraph(system) ; + input = 'abg' ; +end + +if strcmp(input,'abg') + if isempty(abg) + abg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "abg" to "cbg"') ; + mttWriteNewLine ; + cbg = mttCreateCausalBondgraph(abg) ; + input = 'cbg' ; +end + +mttAssert(strcmp(input,'cbg'),'Input representation not recognised') ; + +if isempty(cbg) + mttWriteNewLine ; + mttNotify('Copying "cbg" representation') ; + mttWriteNewLine ; + + mttNotify('...INFO: Input already defined as a "cbg": copying to Output') ; + mttWriteNewLine ; + mttWriteNewLine ; + cbg = system ; +end + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; ADDED mttroot/ntt/bin/make_env.m Index: mttroot/ntt/bin/make_env.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_env.m @@ -0,0 +1,52 @@ +function make_env(system) +global mtt_environment + +start_time = mttGetTime ; + +input = [] ; +env = [] ; + + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "env" representation') ; + mttWriteNewLine ; + + env = mttCreateEnvironment(system) ; + input = 'env' ; +end + +mttAssert(strcmp(input,'env'),'Input representation not recognised') ; + +if isempty(env) + mttWriteNewLine ; + mttNotify('Copying "env" representation') ; + mttWriteNewLine ; + + mttNotify('...INFO: Input already defined as a "env": copying to Output') ; + mttWriteNewLine ; + mttWriteNewLine ; + env = system ; +end + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; + + +mtt_environment = env ; ADDED mttroot/ntt/bin/make_ese.m Index: mttroot/ntt/bin/make_ese.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_ese.m @@ -0,0 +1,84 @@ +function ese = make_ese(system,sorter_on) +global mtt_environment + +if nargin<2 + sorter_on = 1 ; +end + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + +start_time = mttGetTime ; + +abg = [] ; +cbg = [] ; +ese = [] ; + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "abg" representation') ; + mttWriteNewLine ; + + if isempty(mtt_environment) + mttNotify('...WARNING: No "env" definition => all domain references will be ignored') ; + mttWriteNewLine ; + mttNotify(' => paths will not be recognised') ; + mttWriteNewLine ; + end + + abg = mttCreateAcausalBondgraph(system) ; + input = 'abg' ; +end + +if strcmp(input,'abg') + if isempty(abg) + abg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "abg" to "cbg"') ; + mttWriteNewLine ; + cbg = mttCreateCausalBondgraph(abg) ; + input = 'cbg' ; +end + +if strcmp(input,'cbg') + if isempty(cbg) + cbg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "cbg" to "ese"') ; + mttWriteNewLine ; + ese = mttCreateElementaryEquations(cbg,sorter_on) ; + input = 'ese' ; +end + +mttAssert(strcmp(input,'ese'),'Input representation not recognised') ; + +if isempty(ese) + mttWriteNewLine ; + mttNotify('Making "ese" representation') ; + mttWriteNewLine ; + + mttNotify('Input already defined as a "ese": copying to Output') ; + mttWriteNewLine ; + mttWriteNewLine ; + ese = system ; +end + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; ADDED mttroot/ntt/bin/make_mdl.m Index: mttroot/ntt/bin/make_mdl.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_mdl.m @@ -0,0 +1,78 @@ +function make_sfun(system,sorter_on) +global mtt_environment + +if nargin<2 + sorter_on = 1 ; +end + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + +start_time = mttGetTime ; + +abg = [] ; +cbg = [] ; +ese = [] ; + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "abg" representation') ; + mttWriteNewLine ; + + if isempty(mtt_environment) + mttNotify('...WARNING: No "env" definition => all domain references will be ignored') ; + mttWriteNewLine ; + mttNotify(' => paths will not be recognised') ; + mttWriteNewLine ; + end + + abg = mttCreateAcausalBondgraph(system) ; + input = 'abg' ; +end + +if strcmp(input,'abg') + if isempty(abg) + abg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "abg" to "cbg"') ; + mttWriteNewLine ; + cbg = mttCreateCausalBondgraph(abg) ; + input = 'cbg' ; +end + +if strcmp(input,'cbg') + if isempty(cbg) + cbg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "cbg" to "ese"') ; + mttWriteNewLine ; + ese = mttCreateElementaryEquations(cbg,sorter_on) ; + input = 'ese' ; +end + +mttAssert(strcmp(input,'ese'),'Input representation not recognised') ; + +if isempty(ese) + ese = system ; +end +mttCreateSystemMdl(ese) ; + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; ADDED mttroot/ntt/bin/make_sfun.m Index: mttroot/ntt/bin/make_sfun.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/make_sfun.m @@ -0,0 +1,85 @@ +function make_sfun(system,sorter_on) +global mtt_environment + +if nargin<2 + sorter_on = 1 ; +end + +switch class(system) +case 'char', + input = 'spec' ; +case 'struct', + if isfield(system,'representation') + input = system.representation ; + end +end + +start_time = mttGetTime ; + +abg = [] ; +cbg = [] ; +ese = [] ; + +if strcmp(input,'spec') + mttWriteNewLine ; + mttNotify('Making "abg" representation') ; + mttWriteNewLine ; + + if isempty(mtt_environment) + mttNotify('...WARNING: No "env" definition => all domain references will be ignored') ; + mttWriteNewLine ; + mttNotify(' => paths will not be recognised') ; + mttWriteNewLine ; + end + + abg = mttCreateAcausalBondgraph(system) ; + input = 'abg' ; +end + +if strcmp(input,'abg') + if isempty(abg) + abg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "abg" to "cbg"') ; + mttWriteNewLine ; + cbg = mttCreateCausalBondgraph(abg) ; + input = 'cbg' ; +end + +if strcmp(input,'cbg') + if isempty(cbg) + cbg = system ; + end + + mttWriteNewLine ; + mttNotify('Transforming from "cbg" to "ese"') ; + mttWriteNewLine ; + ese = mttCreateElementaryEquations(cbg,sorter_on) ; + input = 'ese' ; +end + +mttAssert(strcmp(input,'ese'),'Input representation not recognised') ; + +if isempty(ese) + ese = system ; +end +mttWriteSystemEquations(ese) ; +mttWriteSystemDefinitions(ese) ; +mttWriteSystemInitialisation(ese) ; +mttWriteSystemMapping(ese) ; + +ese = mttCreateApps(ese) ; +mttWriteSystemApps(ese) ; +mttWriteSystemSfun(ese) ; + + +elapsed_time = mttElapseTime(start_time) ; +cpu_utilisation = round(100*elapsed_time.cpu/elapsed_time.clock) ; + +mttWriteNewLine ; +mttNotify(['Completed in ',num2str(elapsed_time.clock),' seconds']) ; +mttNotify([' (',num2str(cpu_utilisation),'%% cpu)']) ; +mttWriteNewLine ; +mttWriteNewLine ; ADDED mttroot/ntt/bin/trans/m/mttApplyInterfaceCausality.m Index: mttroot/ntt/bin/trans/m/mttApplyInterfaceCausality.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttApplyInterfaceCausality.m @@ -0,0 +1,200 @@ +function model = mttApplyInterfaceCausality(model,specified_rule,branch) ; + is_root_model = (nargin==2) ; + + objects = mttGetFieldNames(model,'obj') ; + + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if isfield(object,'obj') + if is_root_model + branch = object_name ; + else + branch = [branch,'/',object_name] ; + end + + object = mttApplyInterfaceCausality(object,specified_rule,branch) ; + model = setfield(model,'obj',object_name,object) ; + + else + if ~isempty(object.cr) + if is_root_model + branch = mttDetachText(model.source,'/') ; + end + here = [branch,':',object_name] ; + + port_names = mttGetFieldNames(object.cr.interface,'port') ; + + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(object.cr.interface,'port',port_name) ; + + inbond = port.in ; + outbond = port.out ; + + for k = 1:mttGetFieldLength(port,'causality') + rule = port.causality(k).rule ; + definition = port.causality(k).def ; + association = port.causality(k).with ; + not_applied = ~port.causality(k).applied ; + + switch rule + case 'assert', is_assertion = 1 ; + case 'prefer', is_assertion = 0 ; + otherwise + error(['Unrecognised rule "',port_causality.rule,'" in ',here]) ; + end + + apply_rule = strcmp(specified_rule,rule) & not_applied ; + if apply_rule + + switch definition +% case 'effort_state', +% mttAssert(mttIsEqual(port.is_flow_state,0),... +% ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ; +% port.is_effort_state = 1 ; + +% case 'flow_state', +% mttAssert(mttIsEqual(port.is_effort_state,0),... +% ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ; +% port.is_flow_state = 1 ; + + case {'effort_in_flow_out','flow_in_effort_out','flow_out_effort_in','effort_out_flow_in'} + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + switch definition + case {'effort_in_flow_out','flow_out_effort_in'}, + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,1,1,1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,0,0,1) ; + case {'flow_in_effort_out','effort_out_flow_in'}, + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,0,0,1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,1,1,1) ; + end + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case 'effort_in' + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,1,[],1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,0,[],1) ; + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case 'effort_out' + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,0,[],1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,1,[],1) ; + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case 'flow_in' + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],0,1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],1,1) ; + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case 'flow_out' + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],1,1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],0,1) ; + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case 'unicausal', + mttAssert(isempty(association),... + ['Over-constraint at port "',port_name,'" in ',here]) ; + + [model,inbond_ok] = mttUpdateBondCausality(model,inbond,[],[],1) ; + [model,outbond_ok] = mttUpdateBondCausality(model,outbond,[],[],1) ; + + ok = inbond_ok & outbond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict at port "',port_name,'" in ',here]) ; + end + + case {'equicausal','anticausal'} + mttAssert(length(association)==1,... + ['Incorrect constraint at port "',port_name,'" in ',here]) ; + + associated_port_name = association{1} ; + associated_port = getfield(cr.interface,'port',associated_port_name) ; + + associated_inbond = associated_port.in ; + associated_outbond = associated_port.out ; + + mttAsert(xor(isempty(inbond),isempty(outbond)),... + ['Causal rule expects unique bond at port "',port_name,'" in ',here]) ; + mttAsert(xor(isempty(associated_inbond),isempty(associated_outbond)),... + ['Causal rule expects unique bond at port "',associated_port_name,'" in ',here]) ; + + if isempty(associated_inbond) + a = associated_outbond ; + else + a = associated_inbond ; + end + + if isempty(inbond) + b = outbond ; + else + b = inbond ; + end + + switch definition + case 'equicausal', + [model,bond_ok] = mttUpdateBondCausality(model,b,... + model.bond(a).effort,model.bond(a).flow,model.bond(a).unicausal) ; + [model,associated_bond_ok] = mttUpdateBondCausality(model,a,... + model.bond(b).effort,~model.bond(b).flow,model.bond(b).unicausal) ; + case 'anticausal', + [model,bond_ok] = mttUpdateBondCausality(model,b,... + ~model.bond(a).effort,model.bond(a).flow,model.bond(a).unicausal) ; + [model,associated_bond_ok] = mttUpdateBondCausality(model,a,... + ~model.bond(b).effort,~model.bond(b).flow,model.bond(b).unicausal) ; + end + + ok = bond_ok & associated_bond_ok ; + if is_assertion + mttAssert(ok,['Causal conflict between ports "',port_name,... + 'and',associated_port_name,'" in ',here]) ; + end + + otherwise, + error(['Unrecognised constraint "',definition,'" in ',here]) ; + end + + port.causality(k).applied = 1 ; + object = setfield(object,'cr','interface','port',port_name,port) ; + model = setfield(model,'obj',object_name,object) ; + end + end + end + end + end + end + ADDED mttroot/ntt/bin/trans/m/mttApplyInterfaceDomains.m Index: mttroot/ntt/bin/trans/m/mttApplyInterfaceDomains.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttApplyInterfaceDomains.m @@ -0,0 +1,52 @@ +function model = mttApplyInterfaceDomains(model,branch) ; + is_root_model = (nargin==1) ; + + objects = mttGetFieldNames(model,'obj') ; + + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if isfield(object,'obj') + if is_root_model + branch = object_name ; + else + branch = [branch,'/',object_name] ; + end + + object = mttApplyInterfaceDomains(object,branch) ; + model = setfield(model,'obj',object_name,object) ; + + else + if ~isempty(object.cr) + if is_root_model + branch = mttDetachText(model.source,'/') ; + end + here = [branch,':',object_name] ; + + port_names = mttGetFieldNames(object.cr.interface,'port') ; + + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(object.cr.interface,'port',port_name) ; + + predefined_domain = port.domain ; + predefined_domain_item = port.domain_item ; + + inbond = port.in ; + outbond = port.out ; + + if isempty(inbond) + bond_number = outbond ; + else + bond_number = inbond ; + end + + [model,ok] = mttUpdateBondDomain(model,bond_number,predefined_domain,predefined_domain_item) ; + + mttAssert(ok,['Domain conflict at port "',port_name,'" in ',here]) ; + end + end + end + end + ADDED mttroot/ntt/bin/trans/m/mttCreateAcausalBondgraph.m Index: mttroot/ntt/bin/trans/m/mttCreateAcausalBondgraph.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateAcausalBondgraph.m @@ -0,0 +1,131 @@ +function model = mttCreateAcausalBondgraph(system,root) +global mtt_environment + + +switch nargin +case 0, + model = [] ; return ; +case 1, + root = [] ; + is_root_model = 1 ; +otherwise, + is_root_model = 0 ; +end + +if is_root_model + model = intialise_model(system) ; + + directory_name = identify_directory_name(system) ; + source_name = identify_source_name(system,directory_name) ; + + mttNotify('...acquiring "abg" source definitions') ; + mttWriteNewLine ; +else + model = propagate_root_data(root) ; + source_name = system ; +end + +specification_filename = [source_name,'_abg.txt'] ; +specification = mttFetchSpecification(specification_filename) ; +specification = mttSetFieldDefault(specification,'bondgraph',system) ; + +[local_system_name,rubbish] = mttDetachText(system,'/') ; +if isempty(local_system_name) + local_system_name = system ; +end + + +if is_root_model + source_name = identify_source_name(specification.bondgraph,directory_name) ; +else + source_name = specification.bondgraph ; +end +source_name = mttCutText(source_name,'_abg.fig') ; + +bondgraph_filename = [source_name,'_abg.fig'] ; +bondgraph = mttFetchBondgraph(bondgraph_filename) ; + +model = mttCreateUnifiedModel(model,bondgraph,specification) ; +model = mttDeleteField(model,'branch') ; +model = mttDeleteField(model,'leaf') ; + + +if is_root_model + mttWriteNewLine ; + mttNotify('...acquiring "cr" source definitions') ; + mttWriteNewLine ; + + for n = 1:length(model.crs) + source_name = model.crs{n} ; + cr_filename = [source_name,'_cr.txt'] ; + + if ~mttFileExists(cr_filename) + cr_short_name = mttDetachText(source_name,'/') ; + + mttNotify([' ...ERROR: "',cr_short_name,'_cr" source does not exist']) ; + mttWriteNewLine ; + mttNotify([' ...finding dependencies for ',source_name,':']) ; + mttWriteNewLine ; + + prefix = mttDetachText(system,'/') ; + if isempty(prefix) + prefix = system ; + end + + cr_user = model.cr_usage(n).obj ; + for i = 1:length(cr_user) + mttNotify([' ',prefix,'/',cr_user{i}]) ; + mttWriteNewLine ; + end + end + + model.cr(n) = mttFetchInterfaceDefinition(cr_filename) ; + end + + model = mttDeleteField(model,'cr_usage') ; + model = mttDeleteField(model,'crs') ; + model = mttDeleteField(model,'abgs') ; +end + +model.env = mtt_environment ; + + + +function model = intialise_model(system) + model.representation = 'abg' ; + model.abgs = [] ; + model.crs = [] ; + model.cr_usage = [] ; + model.branch = [] ; + model.leaf = [] ; + +function model = propagate_root_data(root) + model.abgs = root.abgs ; + model.crs = root.crs ; + model.cr_usage = root.cr_usage ; + model.branch = root.branch ; + model.leaf = root.leaf ; + +function directory = identify_directory_name(system) + mttAssert(ischar(system),'System must be specified by name') ; + working_directory = pwd ; + working_directory = strrep(working_directory,'\','/') ; + + [system_name,local_directory] = mttDetachText(system,'/') ; + if isempty(system_name) + local_directory = [] ; + end + + if isempty(local_directory) + directory = working_directory ; + else + directory = mttLocateDirectory(working_directory,local_directory) ; + end + +function source = identify_source_name(system,directory) + [system_name,local_directory] = mttDetachText(system,'/') ; + if isempty(system_name) + system_name = system ; + local_directory = [] ; + end + source = [directory,'/',system_name] ; ADDED mttroot/ntt/bin/trans/m/mttCreateApps.m Index: mttroot/ntt/bin/trans/m/mttCreateApps.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateApps.m @@ -0,0 +1,72 @@ +function model = mttCreateApps(model) + +apps_filename = [model.source,'_apps.txt'] ; +apps = mttFetchApps(apps_filename) ; + +if isempty(apps) + return ; +end + +for i = 1:length(apps.app) + app_source = apps.app{i} ; + + [rubbish,working_directory] = mttDetachText(model.source,'/') ; + [name,path_spec] = mttDetachText(app_source,'/') ; + + if isempty(name) + source_name = [working_directory,'/',domain_source] ; + else + directory = identify_directory(working_directory,path_spec,model) ; + source_name = [directory,'/',name] ; + end + + app_filename = [source_name,'_app.h'] ; + model.app{i} = app_filename ; +end + + +function directory = identify_directory(working_directory,path_spec,model) + path_names = mttGetFieldNames(model.env,'path') ; + + if isempty(path_spec) + directory = [] ; + else + if path_spec(1)=='$' + [path_alias,path_branch] = mttCutText(path_spec,'/') ; + path_alias(1) = [] ; + + mttAssert(ismember(path_alias,path_names),... + ['Path "',path_alias,'" not recognised']) ; + + path_root = getfield(model.env,'path',path_alias) ; + + if isempty(path_branch) + directory = path_root ; + else + directory = [path_root,'/',path_branch] ; + end + else + [name,local_directory] = mttDetachText(path_spec,'/') ; + + directory_located = 0 ; + if strcmp(local_directory,'.') + if isempty(name) + directory = working_directory ; + directory_located = 1 ; + else + local_directory = name ; + end + else + local_directory = path_spec ; + end + + if ~directory_located + directory = mttLocateDirectory(working_directory,local_directory) ; + end + end + end + + + + + ADDED mttroot/ntt/bin/trans/m/mttCreateCausalBondgraph.m Index: mttroot/ntt/bin/trans/m/mttCreateCausalBondgraph.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateCausalBondgraph.m @@ -0,0 +1,452 @@ +function model = mttCreateCausalBondgraph(model) + +model.representation = 'cbg' ; + +model = incorporate_interface_definitions(model) ; +model = establish_abg_dependencies(model) ; +model = create_object_hierarchy(model) ; +model = assign_sympar_values(model) ; +model = complete_causal_assignment(model) ; +model = complete_domain_assignment(model) ; +model = overwrite_implicit_domains(model) ; + + +function model = incorporate_interface_definitions(model) + mttNotify('...incorporating "cr" definitions') ; + mttWriteNewLine ; + + mttNotify([' ...processing ',model.source]) ; + mttWriteNewLine ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if ~mttIsFoundationClass(object.class) + mttAssert(xor(isempty(object.abg),isempty(object.cr)),... + ['"',object_name,'" must exclusively have a "cr" or an "abg" representation']) ; + end + + if isempty(object.cr) + object = mttDeleteField(object,'cr_item') ; + model = setfield(model,'obj',object_name,object) ; + else + model = mttEmbedInterfaceDefinition(model,object_name) ; + end + end + + for i = 1:mttGetFieldLength(model,'abg') + component_type = mttDetachText(model.abg(i).source,'/') ; + mttNotify([' ...processing "#',num2str(i),':',component_type,'" ',model.abg(i).source]) ; + mttWriteNewLine ; + + objects = mttGetFieldNames(model.abg(i),'obj') ; + for j = 1:length(objects) + object_name = objects{j} ; + object = getfield(model,'abg',{i},'obj',object_name) ; + + if ~mttIsFoundationClass(object.class) + mttAssert(xor(isempty(object.abg),isempty(object.cr)),... + ['abg[',num2str(i),']: "',object_name,'" must exclusively have a "cr" or an "abg" representation']) ; + end + + if isempty(object.cr) + object = mttDeleteField(object,'cr_item') ; + model = setfield(model,'abg',{i},'obj',object_name,object) ; + else + model.abg(i) = mttEmbedInterfaceDefinition(model.abg(i),object_name,model) ; + end + end + model.abg(i).invokes = [] ; + model.abg(i).invoked_by = [] ; + end + model = mttDeleteField(model,'cr') ; + + +function model = establish_abg_dependencies(model) + mttNotify('...establishing "abg" dependencies') ; + mttWriteNewLine ; + + for i = 1:mttGetFieldLength(model,'abg') + objects = mttGetFieldNames(model.abg(i),'obj') ; + for j = 1:length(objects) + object_name = objects{j} ; + object = getfield(model.abg(i).obj,object_name) ; + + if isempty(object.cr) %... still within object hierarchy + if ~mttIsFoundationClass(object.class) + existing_dependencies = model.abg(i).invokes ; + + if isempty(existing_dependencies) + new_dependency = 1 ; + else + new_dependency = isempty(find(existing_dependencies==object.abg)) ; + end + + if new_dependency + model.abg(i).invokes = [existing_dependencies,object.abg] ; + end + + existing_dependencies = model.abg(object.abg).invoked_by ; + if isempty(existing_dependencies) + new_dependency = 1 ; + else + new_dependency = isempty(find(existing_dependencies==i)) ; + end + + if new_dependency + model.abg(object.abg).invoked_by = [existing_dependencies,i] ; + end + end + end + end + end + + model.invokes = [] ; + + objects = mttGetFieldNames(model,'obj') ; + for j = 1:length(objects) + object_name = objects{j} ; + object = getfield(model.obj,object_name) ; + + if ~isempty(object.abg) + if ~mttIsFoundationClass(object.class) + existing_dependencies = model.invokes ; + + if isempty(existing_dependencies) + new_dependency = 1 ; + else + new_dependency = isempty(find(existing_dependencies==object.abg)) ; + end + + if new_dependency + model.invokes = [existing_dependencies,object.abg] ; + end + end + end + end + + +function model = create_object_hierarchy(model) ; + mttNotify('...creating object hierarchy') ; + mttWriteNewLine ; + + top_level_model = mttDetachText(model.source,'/') ; + + if isfield(model,'abg') + is_embedded = zeros(1,length(model.abg)) ; + embedding = 1 ; + else + embedding = 0 ; + end + + component = 0 ; + + embedding = isfield(model,'abg') ; + while embedding + component = 1 + mod(component,length(model.abg)) ; + if ~is_embedded(component) + if isempty(model.abg(component).invokes) + number_of_systems = length(model.abg(component).invoked_by) ; + + for n = 1:number_of_systems + system = model.abg(component).invoked_by(n) ; + component_type = mttDetachText(model.abg(component).source,'/') ; + system_type = mttDetachText(model.abg(system).source,'/') ; + mttNotify([' ...embedding "#',num2str(component),':',component_type,... + '" definition within "#',num2str(system),':',system_type,'" objects']) ; + mttWriteNewLine ; + + model = mttEmbedAcausalBondgraph(model,component,system) ; + end + model.abg(component).invoked_by = [] ; + + if ~isempty(find(model.invokes==component)) + component_type = mttDetachText(model.abg(component).source,'/') ; + mttNotify([' ...embedding "#',num2str(component),':',component_type,... + '" definition within "',top_level_model,'"']) ; + mttWriteNewLine ; + + model = mttEmbedAcausalBondgraph(model,component) ; + end + is_embedded(component) = 1 ; + end + end + embedding = any(~is_embedded) ; + end + + model = mttDeleteField(model,'abg') ; + model = mttDeleteField(model,'invokes') ; + + +function model = assign_sympar_values(model) + mttNotify('...assigning "sympar" values') ; + mttWriteNewLine ; + + model_name = mttDetachText(model.source,'/') ; + current_branch = model_name ; + + sympars = model.sympar ; + defaults = model.sympar_default ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if ~mttIsPassiveClass(object.class) + for j = 1:length(object.parameter) + object_parameter = object.parameter{j} ; + if ischar(object_parameter) + index = strmatch(object_parameter,sympars,'exact') ; + + new_parameter = 0 ; + + if isempty(index) + new_parameter = 1 ; + else + default_value = defaults{index} ; + if isempty(default_value) + new_parameter = 1 ; + else + object.parameter{j} = default_value ; + end + end + + if new_parameter + object.parameter{j} = [current_branch,'___',object_parameter] ; + end + end + end + + branch = [model_name,'__',object_name] ; + object = assign_object_sympar_values(object,branch) ; + + model = setfield(model,'obj',object_name,object) ; + end + end + + +function model = assign_object_sympar_values(model,branch) + current_branch = branch ; + + sympars = model.sympar ; + parameters = model.parameter ; + + if ~isempty(model.abg) + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if ~mttIsPassiveClass(object.class) + for j = 1:length(object.parameter) + object_parameter = object.parameter{j} ; + if ischar(object_parameter) + index = strmatch(object_parameter,sympars,'exact') ; + if isempty(index) + object.parameter{j} = [current_branch,'___',object_parameter] ; + else + object.parameter{j} = parameters{index} ; + end + end + end + + branch = [current_branch,'__',object_name] ; + object = assign_object_sympar_values(object,branch) ; + + model = setfield(model,'obj',object_name,object) ; + end + end + elseif ~isempty(model.cr) + model.cr.parameter = model.parameter ; + end + + +function model = complete_causal_assignment(model) + mttWriteNewLine ; + mttNotify('...summarising model content') ; + mttWriteNewLine ; + + model = mttCountObjects(model) ; + mttNotifyNumberOfObjects(model) ; + mttWriteNewLine ; + model = mttDeleteField(model,'count') ; + + model = mttMeasureCausalCompletion(model) ; + mttNotifyNumberOfBonds(model) ; + mttWriteNewLine ; + + mttWriteNewLine ; + mttNotify('...analysing predefined causality') ; + mttWriteNewLine ; + + mttNotifyCausalCompletion(model) ; + mttWriteNewLine ; + + if model.causal_completion.is_causal + mttNotify('...applying CR constraints') ; + mttWriteNewLine ; + model = incorporate_cr_rules(model,'assert') ; + else + mttNotify('...completing causality') ; + mttWriteNewLine ; + + iterations = 0 ; + + propagating = 1 ; + while propagating + iterations = iterations + 1 ; + previous_causal_completion = model.causal_completion ; + + model = mttApplyInterfaceCausality(model,'assert') ; + model = mttPropagateCausality(model) ; + model = mttApplyInterfaceCausality(model,'prefer') ; + model = mttPropagateCausality(model) ; + model = mttMeasureCausalCompletion(model) ; + + is_stable = mttCompareCausalCompletion(model.causal_completion,previous_causal_completion) ; + propagating = (~is_stable) ; + + if propagating + mttNotify(['...iteration ',num2str(iterations)]) ; + mttWriteNewLine ; + mttNotifyCausalCompletion(model) ; + end + + propagating = propagating & (~model.causal_completion.is_causal) ; + end + end + + + if ~model.causal_completion.is_causal + mttWriteNewLine ; + mttNotify('...causality not complete') ; + mttWriteNewLine ; + mttWriteNewLine ; + + mttIdentifyUndercausalBonds(model) ; + end + + model = mttDeleteField(model,'causal_completion') ; + + +function model = complete_domain_assignment(model) + mttWriteNewLine ; + mttNotify('...allocating domain definitions') ; + mttWriteNewLine ; + + model = mttMeasureDomainCompletion(model) ; + + iterations = 0 ; + + propagating = 1 ; + while propagating + iterations = iterations + 1 ; + previous_domain_completion = model.domain_completion ; + + model = mttApplyInterfaceDomains(model) ; + model = mttPropagateDomains(model) ; + model = mttMeasureDomainCompletion(model) ; + + is_stable = mttCompareDomainCompletion(model.domain_completion,previous_domain_completion) ; + propagating = (~is_stable) ; + + if propagating + mttNotify(['...iteration ',num2str(iterations)]) ; + mttWriteNewLine ; + mttNotifyDomainCompletion(model) ; + end + + propagating = propagating & (~model.domain_completion.is_done) ; + end + + model = mttDeleteField(model,'domain_completion') ; + + +function model = overwrite_implicit_domains(model) + mttWriteNewLine ; + mttNotify('...overwriting implicit domain definitions') ; + mttWriteNewLine ; + + model = mttOverwriteImplicitDomains(model) ; + + +function model = mttOverwriteImplicitDomains(root,model,env) + is_root_model = nargin==1 ; + + if is_root_model + model = root ; + env = root.env ; + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if ~isempty(object.abg) + object = mttOverwriteImplicitDomains(model,object,env) ; + end + + if ~isempty(object.cr) + interface_ports = mttGetFieldNames(object.cr.interface,'port') ; + for j = 1:length(interface_ports) + port_name = interface_ports{j} ; + port = getfield(object.cr.interface,'port',port_name) ; + + if isempty(port.domain) + if isempty(port.in) + bond_number = port.out ; + else + bond_number = port.in ; + end + + actual_domain = model.bond(bond_number).domain ; + actual_domain_item = model.bond(bond_number).domain_item ; + + port.domain = actual_domain ; + port.domain_item = actual_domain_item ; + object.cr.interface = setfield(object.cr.interface,'port',port_name,port) ; + + number_of_operators = mttGetFieldLength(object.cr,'operator') ; + for op_counter = 1:number_of_operators + operator = object.cr.operator(op_counter) ; + + matching_links = strmatch(port_name,{operator.link.name},'exact') ; + + number_of_equations = mttGetFieldLength(operator,'equation') ; + + for eq_counter = 1:number_of_equations + equation = operator.equation(eq_counter) ; +% if isempty(equation.domain) + + number_of_chunks = mttGetFieldLength(equation,'chunk') ; + for chunk_counter = 1:number_of_chunks + chunk = equation.chunk{chunk_counter} ; + + if iscell(chunk) + if strcmp(chunk{1},'link') + link = chunk{2} ; + + if any(link==matching_links) + covar = chunk{3} ; + chunk{3} = ['generic___',covar] ; + end + end + equation.chunk{chunk_counter} = chunk ; + end + end + operator.equation(eq_counter) = equation ; +% end + end + object.cr.operator(op_counter) = operator ; + end + end + end + end + + model = setfield(model,'obj',object_name,object) ; + end + ADDED mttroot/ntt/bin/trans/m/mttCreateElementaryEquations.m Index: mttroot/ntt/bin/trans/m/mttCreateElementaryEquations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateElementaryEquations.m @@ -0,0 +1,960 @@ +function model = mttCreateElementaryEquations(model,sorter_on) + +model.representation = 'ese' ; + +[model,ese,namelist] = specify_equations(model) ; +if sorter_on + [sse,counter] = sort_equations(ese,model,namelist) ; +else + sse = ese ; + counter = 0 ; +end + +model.equation = sse ; +model.sorted_equations = counter ; +model.namelist = namelist ; + + + +function [model,ese,namelist] = specify_equations(model,branch,root_namelist) + is_root_model = (nargin==1) ; + + if is_root_model + mttNotify('...specifying equations') ; + mttWriteNewLine ; + + branch = mttDetachText(model.source,'/') ; + + name_counter = 1 ; + namelist(name_counter).var = '0' ; + namelist(name_counter).domain = [] ; + namelist(name_counter).domain_item = [] ; + else + namelist = root_namelist ; + name_counter = length(namelist) ; + end + + mttNotify([' ...processing ',branch]) ; + mttWriteNewLine ; + + objects = mttGetFieldNames(model,'obj') ; + + line = 0 ; + + for n = 1:length(objects) + object_name = objects{n} ; + object = getfield(model,'obj',object_name) ; + + here = [branch,':',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'}, + + for j = 1:mttGetFieldLength(object,'interface') + flow_equation = [] ; + effort_equation = [] ; + + terminal = [branch,'__',object_name] ; + + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + + if ~isempty(inbond) + bond = model.bond(inbond) ; + [specified_domain,specified_domain_item] = mttGetBondDomain(model,inbond) ; + + new_name = 0 ; + + line = line + 1 ; + if bond.flow + if strcmp(object.class,'De') + ese(line) = specify_ese(branch,[2*inbond],branch,{1},[]) ; + else + ese(line) = specify_ese(branch,[2*inbond],branch,{name_counter+1},[]) ; + new_name = 1 ; + end + else + ese(line) = specify_ese(branch,{name_counter+1},branch,[2*inbond],[]) ; + new_name = 1 ; + end + + if new_name + name_counter = name_counter + 1 ; + namelist(name_counter).var = [terminal,'.flow'] ; + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + end + + new_name = 0 ; + + line = line + 1 ; + if bond.effort + ese(line) = specify_ese(branch,{name_counter+1},branch,[2*inbond-1],[]) ; + new_name = 1 ; + else + if strcmp(object.class,'Df') + ese(line) = specify_ese(branch,[2*inbond-1],branch,{1},[]) ; + else + ese(line) = specify_ese(branch,[2*inbond-1],branch,{name_counter+1},[]) ; + new_name = 1 ; + end + end + + if new_name + name_counter = name_counter + 1 ; + namelist(name_counter).var = [terminal,'.effort'] ; + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + end + end + + if ~isempty(outbond) + bond = model.bond(outbond) ; + [specified_domain,specified_domain_item] = mttGetBondDomain(model,outbond) ; + + new_name = 0 ; + + if bond.flow + if ~strcmp(object.class,'Se') + line = line + 1 ; + ese(line) = specify_ese(branch,{name_counter+1},branch,[2*outbond],[]) ; + new_name = 1 ; + end + else + line = line + 1 ; + ese(line) = specify_ese(branch,[2*outbond],branch,{name_counter+1},[]) ; + new_name = 1 ; + end + + if new_name + name_counter = name_counter + 1 ; + namelist(name_counter).var = [terminal,'.flow'] ; + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + end + + new_name = 0 ; + + if bond.effort + line = line + 1 ; + ese(line) = specify_ese(branch,[2*outbond-1],branch,{name_counter+1},[]) ; + new_name = 1 ; + else + if ~strcmp(object.class,'Sf') + line = line + 1 ; + ese(line) = specify_ese(branch,{name_counter+1},branch,[2*outbond-1],[]) ; + new_name = 1 ; + end + end + + if new_name + name_counter = name_counter + 1 ; + namelist(name_counter).var = [terminal,'.effort'] ; + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + end + end + end + + case '0', + + imposed_effort = [] ; + resultant_flow = [] ; + + for i = 1:mttGetFieldLength(object,'interface') + inbond = object.interface(i).in ; + outbond = object.interface(i).out ; + + if isempty(inbond) + bond_number(i) = outbond ; + orientation(i) = 0 ; + else + bond_number(i) = inbond ; + orientation(i) = 1 ; + end + + [effort,flow] = mttGetBondCausality(model,bond_number(i)) ; + + if effort==orientation(i) + imposed_effort = 2*bond_number(i)-1 ; + end + if flow==orientation(i) + resultant_flow = 2*bond_number(i) ; + resultant_orientation = orientation(i) ; + end + end + + for i = 1:mttGetFieldLength(object,'interface') + effort = 2*bond_number(i)-1 ; + if effort~=imposed_effort + derived_effort = effort ; + + line = line + 1 ; + ese(line) = specify_ese(branch,derived_effort,branch,imposed_effort,[]) ; + end + end + + flow_summation = [] ; + for i = 1:mttGetFieldLength(object,'interface') + flow = 2*bond_number(i) ; + + if flow~=resultant_flow + impinging_flow = flow ; + + if orientation(i) + if resultant_orientation + flow_summation = [ flow_summation, -impinging_flow ] ; + else + flow_summation = [ flow_summation, impinging_flow ] ; + end + else + if resultant_orientation + flow_summation = [ flow_summation, impinging_flow ] ; + else + flow_summation = [ flow_summation, -impinging_flow ] ; + end + end + end + end + + line = line + 1 ; + ese(line) = specify_ese(branch,resultant_flow,branch,flow_summation,[]) ; + + case '1', + + imposed_flow = [] ; + resultant_effort = [] ; + + for i = 1:mttGetFieldLength(object,'interface') + inbond = object.interface(i).in ; + outbond = object.interface(i).out ; + + if isempty(inbond) + bond_number(i) = outbond ; + orientation(i) = 0 ; + else + bond_number(i) = inbond ; + orientation(i) = 1 ; + end + + [effort,flow] = mttGetBondCausality(model,bond_number(i)) ; + + if flow~=orientation(i) + imposed_flow = 2*bond_number(i) ; + end + if effort~=orientation(i) + resultant_effort = 2*bond_number(i)-1 ; + resultant_orientation = orientation(i) ; + end + end + + for i = 1:mttGetFieldLength(object,'interface') + flow = 2*bond_number(i) ; + if flow~=imposed_flow + derived_flow = flow ; + + line = line + 1 ; + ese(line) = specify_ese(branch,derived_flow,branch,imposed_flow,[]) ; + end + end + + effort_summation = [] ; + for i = 1:mttGetFieldLength(object,'interface') + effort = 2*bond_number(i)-1 ; + + if effort~=resultant_effort + impinging_effort = effort ; + + if orientation(i) + if resultant_orientation + effort_summation = [ effort_summation, -impinging_effort ] ; + else + effort_summation = [ effort_summation, impinging_effort ] ; + end + else + if resultant_orientation + effort_summation = [ effort_summation, impinging_effort ] ; + else + effort_summation = [ effort_summation, -impinging_effort ] ; + end + end + end + end + + line = line + 1 ; + ese(line) = specify_ese(branch,resultant_effort,branch,effort_summation,[]) ; + + otherwise, + + if ~isempty(object.cr) + interface = object.cr.interface ; + port_names = mttGetFieldNames(interface,'port') ; + number_of_ports = length(port_names) ; + + link_counter = 0 ; + + for i = 1:number_of_ports + port_name = port_names{i} ; + port = getfield(interface,'port',port_name) ; + terminal = [branch,'__',object_name,'___',port_name] ; + + inbond = port.in ; + outbond = port.out ; + + if ~isempty(inbond) + bond = model.bond(inbond) ; + [specified_domain,specified_domain_item] = mttGetBondDomain(model,inbond) ; + + name_counter = name_counter + 1 ; + if port.is_flow_state + namelist(name_counter).var = [terminal,'.flow_state'] ; + else + namelist(name_counter).var = [terminal,'.flow'] ; + end + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + + line = line + 1 ; + link_counter = link_counter + 1 ; + if bond.flow + ese(line) = specify_ese(branch,[2*inbond],branch,{name_counter},[]) ; + link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ; + else + ese(line) = specify_ese(branch,{name_counter},branch,[2*inbond],[]) ; + link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ; + end + + name_counter = name_counter + 1 ; + if port.is_effort_state + namelist(name_counter).var = [terminal,'.effort_state'] ; + else + namelist(name_counter).var = [terminal,'.effort'] ; + end + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + + line = line + 1 ; + link_counter = link_counter + 1 ; + if bond.effort + ese(line) = specify_ese(branch,{name_counter},branch,[2*inbond-1],[]) ; + link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ; + else + ese(line) = specify_ese(branch,[2*inbond-1],branch,{name_counter},[]) ; + link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ; + end + end + + if ~isempty(outbond) + bond = model.bond(outbond) ; + [specified_domain,specified_domain_item] = mttGetBondDomain(model,outbond) ; + + name_counter = name_counter + 1 ; + if port.is_flow_state + namelist(name_counter).var = [terminal,'.flow_state'] ; + else + namelist(name_counter).var = [terminal,'.flow'] ; + end + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + + line = line + 1 ; + link_counter = link_counter + 1 ; + if bond.flow + ese(line) = specify_ese(branch,{name_counter},branch,[2*outbond],[]) ; + link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ; + else + ese(line) = specify_ese(branch,[2*outbond],branch,{name_counter},[]) ; + link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ; + end + + name_counter = name_counter + 1 ; + if port.is_effort_state + namelist(name_counter).var = [terminal,'.effort_state'] ; + else + namelist(name_counter).var = [terminal,'.effort'] ; + end + namelist(name_counter).domain = specified_domain ; + namelist(name_counter).domain_item = specified_domain_item ; + + line = line + 1 ; + link_counter = link_counter + 1 ; + if bond.effort + ese(line) = specify_ese(branch,[2*outbond-1],branch,{name_counter},[]) ; + link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ; + else + ese(line) = specify_ese(branch,{name_counter},branch,[2*outbond-1],[]) ; + link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ; + end + end + end + + + input_mask = zeros(number_of_ports,1) ; + output_mask = zeros(number_of_ports,1) ; + + number_of_links = link_counter ; + linked = zeros(number_of_links,1) ; + + operators = object.cr.operator ; + number_of_operators = length(operators) ; + + object.cr.used_operator = zeros(1,number_of_operators) ; + + op_counter = 0 ; + + matching = 1 ; + while matching + op_counter = op_counter + 1 ; + operator = operators(op_counter) ; + + full_operator_name = [branch,'__',object_name,'___',operator.name] ; + + number_of_op_links = length(operator.link) ; + op_linked = zeros(number_of_op_links,1) ; + + for j = 1:number_of_op_links + k = 0 ; + comparing = 1 ; + while comparing + k = k + 1 ; + if compare_links(link(k),operator.link(j)) + op_linked(j) = k ; + comparing = 0 ; + end + comparing = comparing & (k0 + for i = 1:number_of_domains + model.public_domain(i).representation = model.dom(i).representation ; + model.public_domain(i).source = model.dom(i).source ; + + domain = model.dom(i) ; + item_names = mttGetFieldNames(domain,'item') ; + for j = 1:length(item_names) + item_name = item_names{j} ; + item = getfield(domain,'item',item_name) ; + + compound_item = mttIdentifyDomainCovariables(item,domain,model) ; + model = setfield(model,'public_domain',{i},'item',item_name,compound_item) ; + end + end + model = hide_private_domains(model) ; +end + +model = mttDeleteField(model,'dom') ; + + +mttWriteNewLine ; +mttNotify('...acquiring "struct" source definitions') ; +mttWriteNewLine ; + +model = establish_user_structs(model) ; + +number_of_structs = mttGetFieldLength(model,'str') ; +if number_of_structs>0 + for i = 1:number_of_structs + model.public_struct(i).representation = model.str(i).representation ; + model.public_struct(i).source = model.str(i).source ; + + struct = model.str(i) ; + item_names = mttGetFieldNames(struct,'item') ; + for j = 1:length(item_names) + item_name = item_names{j} ; + item = getfield(struct,'item',item_name) ; + + compound_item = mttIdentifyStructVariables(item,struct,model) ; + model = setfield(model,'public_struct',{i},'item',item_name,compound_item) ; + end + end + model = hide_private_structs(model) ; +end + +model = mttDeleteField(model,'str') ; + + + +function directory = identify_directory_name(context) + mttAssert(ischar(context),'Context must be specified by name') ; + working_directory = pwd ; + working_directory = strrep(working_directory,'\','/') ; + + [system_name,local_directory] = mttDetachText(context,'/') ; + if isempty(system_name) + local_directory = [] ; + end + + if isempty(local_directory) + directory = working_directory ; + else + directory = mttLocateDirectory(working_directory,local_directory) ; + end + + +function source = identify_source_name(context,directory) + [context_name,local_directory] = mttDetachText(context,'/') ; + if isempty(context_name) + context_name = context ; + local_directory = [] ; + end + source = [directory,'/',context_name] ; + + +function model = establish_path_names(model) + path_names = mttGetFieldNames(model,'path') ; + + for n = 1:length(path_names) + path_name = path_names{n} ; + path_spec = getfield(model,'path',path_name) ; + + [rubbish,working_directory] = mttDetachText(model.source,'/') ; + + directory = identify_directory(working_directory,path_spec,model) ; + + mttAssert(~isempty(directory),... + ['Undefined path "',path_name,'"']) ; + + model = setfield(model,'path',path_name,directory) ; + end + + +function directory = identify_directory(working_directory,path_spec,model) + path_names = mttGetFieldNames(model,'path') ; + + if isempty(path_spec) + directory = [] ; + else + if path_spec(1)=='$' + [path_alias,path_branch] = mttCutText(path_spec,'/') ; + path_alias(1) = [] ; + + mttAssert(ismember(path_alias,path_names),... + ['Path "',path_alias,'" not recognised']) ; + + path_root = getfield(model,'path',path_alias) ; + + if isempty(path_branch) + directory = path_root ; + else + directory = [path_root,'/',path_branch] ; + end + else + [local_directory,name] = mttCutText(path_spec,'/') ; + + directory_located = 0 ; + if strcmp(local_directory,'.') + if isempty(name) + directory = working_directory ; + directory_located = 1 ; + else + local_directory = name ; + end + else + local_directory = path_spec ; + end + + if ~directory_located + directory = mttLocateDirectory(working_directory,local_directory) ; + end + end + end + + +function model = establish_user_domains(model) + path_names = mttGetFieldNames(model,'path') ; + domain_names = mttGetFieldNames(model,'domain') ; + + counter = 0 ; + + for n = 1:length(domain_names) + domain_name = domain_names{n} ; + domain_spec = getfield(model,'domain',domain_name) ; + + [rubbish,working_directory] = mttDetachText(model.source,'/') ; + [domain_source,domain_item] = mttCutText(domain_spec,'::') ; + [name,path_spec] = mttDetachText(domain_source,'/') ; + + if isempty(name) + source_name = [working_directory,'/',domain_source] ; + else + directory = identify_directory(working_directory,path_spec,model) ; + source_name = [directory,'/',name] ; + end + + domain_filename = [source_name,'_domain.txt'] ; + + domain_index = [] ; + if isfield(model,'dom') + existing_doms = {model.dom.source} ; + domain_index = strmatch(source_name,existing_doms,'exact') ; + end + + if isempty(domain_index) + counter = counter + 1 ; + model.dom(counter) = mttFetchDomain(domain_filename) ; + domain_index = counter ; + end + + domain_spec.dom = domain_index ; + domain_spec.item = domain_item ; + model = setfield(model,'domain',domain_name,domain_spec) ; + end + +function model = hide_private_domains(model) + for n = 1:mttGetFieldLength(model,'public_domain') + dom = model.dom(n) ; + dom_items = dom.item ; + + domain = model.public_domain(n) ; + domain_items = domain.item ; + + item_names = mttGetFieldNames(domain,'item') ; + + for j = 1:length(item_names) + item_name = item_names{j} ; + is_private(j) = getfield(dom_items,item_name,'is_private') ; + + if is_private(j) + domain_items = mttDeleteField(domain_items,item_name) ; + + mttAssert(~isempty(domain_items),... + ['No public domains in ',dom.source]) ; + end + end + + model = setfield(model,'public_domain',{n},'item',domain_items) ; + end + + user_domain_names = mttGetFieldNames(model,'domain') ; + for i = 1:length(user_domain_names) + user_domain_name = user_domain_names{i} ; + user_domain = getfield(model,'domain',user_domain_name) ; + + dom = model.dom(user_domain.dom) ; + if ~isempty(user_domain.item) + is_private = getfield(dom,'item',user_domain.item,'is_private') ; + mttAssert(~is_private,... + ['User-defined domain "',user_domain_name,'" is declared as private']) ; + end + end + + +function model = establish_user_structs(model) + path_names = mttGetFieldNames(model,'path') ; + struct_names = mttGetFieldNames(model,'struct') ; + + counter = 0 ; + + for n = 1:length(struct_names) + struct_name = struct_names{n} ; + struct_spec = getfield(model,'struct',struct_name) ; + + [rubbish,working_directory] = mttDetachText(model.source,'/') ; + [struct_source,struct_item] = mttCutText(struct_spec,'::') ; + [name,path_spec] = mttDetachText(struct_source,'/') ; + + if isempty(name) + source_name = [working_directory,'/',struct_source] ; + else + directory = identify_directory(working_directory,path_spec,model) ; + source_name = [directory,'/',name] ; + end + + struct_filename = [source_name,'_struct.txt'] ; + + struct_index = [] ; + if isfield(model,'str') + existing_strs = {model.str.source} ; + struct_index = strmatch(source_name,existing_strs,'exact') ; + end + + if isempty(struct_index) + counter = counter + 1 ; + model.str(counter) = mttFetchStruct(struct_filename) ; + struct_index = counter ; + end + + struct_spec.str = struct_index ; + struct_spec.item = struct_item ; + model = setfield(model,'struct',struct_name,struct_spec) ; + end + +function model = hide_private_structs(model) + for n = 1:mttGetFieldLength(model,'public_struct') + str = model.str(n) ; + str_items = str.item ; + + struct = model.public_struct(n) ; + struct_items = struct.item ; + + item_names = mttGetFieldNames(struct,'item') ; + + for j = 1:length(item_names) + item_name = item_names{j} ; + is_private(j) = getfield(str_items,item_name,'is_private') ; + + if is_private(j) + struct_items = mttDeleteField(struct_items,item_name) ; + + mttAssert(~isempty(struct_items),... + ['No public structs in ',str.source]) ; + end + end + + model = setfield(model,'public_struct',{n},'item',struct_items) ; + end + + user_struct_names = mttGetFieldNames(model,'struct') ; + for i = 1:length(user_struct_names) + user_struct_name = user_struct_names{i} ; + user_struct = getfield(model,'struct',user_struct_name) ; + + str = model.str(user_struct.str) ; + if ~isempty(user_struct.item) + is_private = getfield(str,'item',user_struct.item,'is_private') ; + mttAssert(~is_private,... + ['User-defined struct "',user_struct_name,'" is declared as private']) ; + end + end + ADDED mttroot/ntt/bin/trans/m/mttCreateSystemMdl.m Index: mttroot/ntt/bin/trans/m/mttCreateSystemMdl.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateSystemMdl.m @@ -0,0 +1,170 @@ +function mttCreateSystemMdl(model) + +model_name = mttDetachText(model.source,'/') ; +icd = mttCreateSystemMdl_ICD(model) ; + +NumInputs = length(icd.input_namelist) ; +NumOutputs = length(icd.output_namelist) ; +MaxInterfaces = max(NumInputs,NumOutputs) ; + +new_system(model_name) ; +open_system(model_name) ; +set_param(model_name,'Location',[50 100 850 250+20*MaxInterfaces]) ; + +left = 100 ; +top = 25 ; +width = 600 ; +height = 25*(5+MaxInterfaces) ; + +position_vector = [left,top,left+width,top+height] ; + +ModelHndl = add_block(... + 'simulink3/Subsystems/Subsystem',... + [model_name,'/Model'],... + 'Position',position_vector,... + 'BackgroundColor','yellow',... + 'FontName','Helvetica',... + 'FontSize',num2str(16)) ; + + +system = [model_name,'/Model'] ; + +set_param(system,'Location',[200 250 1050 285+30*MaxInterfaces]) ; + +Line = get_param(system,'Lines') ; +for i = 1:length(Line) + SrcBlock = get_param(Line(i).SrcBlock,'Name') ; + DstBlock = get_param(Line(i).DstBlock,'Name') ; + SrcPort = num2str(Line(i).SrcPort) ; + DstPort = num2str(Line(i).DstPort) ; + + delete_line(system,[SrcBlock,'/',SrcPort],[DstBlock,'/',DstPort]) ; +end + +Block = get_param(system,'Blocks') ; +for i = 1:length(Block) + delete_block([system,'/',Block{i}]) ; +end + + +left = 125 ; +centre_left = 250 ; +centre = 350 ; +centre_right = 580 ; +right = 670 ; + +top = 20 ; +down = 30 ; + +port_width = 40 ; +port_height = 15 ; +port_spacing = down ; + +mux_width = 5 ; +mux_height = NumInputs*port_spacing ; + +demux_width = 5 ; +demux_height = NumOutputs*port_spacing ; + +sfun_width = 150 ; +sfun_height = 30 ; + +left_vertical_offset = (NumInputs*port_spacing - sfun_height)/2 ; +right_vertical_offset = (NumOutputs*port_spacing - sfun_height)/2 ; + +vertical_offset = max(left_vertical_offset,right_vertical_offset) ; +datum = top + vertical_offset ; + + + +top = datum - left_vertical_offset ; + +for i = 1:NumInputs + position_vector = [... + left,... + top + (i-1)*port_spacing,... + left + port_width,... + top + (i-1)*port_spacing + port_height] ; + + InHndl(i) = add_block(... + 'simulink3/Sources/In1',... + [system,'/',icd.input_namelist{i}],... + 'Position',position_vector) ; +end + +position_vector = [... + centre_left,... + top-port_height/3,... + centre_left+mux_width,... + top+mux_height-port_height/3] ; + +MuxHndl = add_block(... + 'simulink3/Signals & Systems/Mux',... + [system,'/InputMapping'],... + 'Position',position_vector,... + 'Inputs',num2str(NumInputs)) ; + +position_vector = [... + centre,... + top+left_vertical_offset-sfun_height/2,... + centre+sfun_width,... + top+left_vertical_offset+sfun_height] ; + +SfunHndl = add_block(... + 'simulink3/Functions & Tables/S-Function',... + [system,'/sfun'],... + 'Position',position_vector,... + 'FunctionName',[model_name,'_sfun'],... + 'BackgroundColor','yellow',... + 'FontName','Helvetica',... + 'FontSize',num2str(16)) ; + + + +top = datum - right_vertical_offset ; + +position_vector = [... + centre_right,... + top-port_height/3,... + centre_right+demux_width,... + top+demux_height-port_height/3] ; + +DemuxHndl = add_block(... + 'simulink3/Signals & Systems/Demux',... + [system,'/OutputMapping'],... + 'Position',position_vector,... + 'Outputs',num2str(NumOutputs)) ; + +for i = 1:NumOutputs + position_vector = [... + right,... + top + (i-1)*port_spacing,... + right + port_width,... + top + (i-1)*port_spacing + port_height] ; + + OutHndl(i) = add_block(... + 'simulink3/Sinks/Out1',... + [system,'/',icd.output_namelist{i}],... + 'Position',position_vector) ; +end + + + +for i = 1:NumInputs + port = num2str(i) ; + InLineHndl(i) = add_line(system,... + [icd.input_namelist{i},'/1'],['InputMapping/',port]) ; +end + +SfunInLineHndl = add_line(system,'InputMapping/1','sfun/1') ; +set_param(SfunInLineHndl,'Name','_Input') ; + +SfunOutLineHndl = add_line(system,'sfun/1','OutputMapping/1') ; +set_param(SfunOutLineHndl,'Name','_Output') ; + +for i = 1:NumOutputs + port = num2str(i) ; + OutLineHndl(i) = add_line(system,... + ['OutputMapping/',port],[icd.output_namelist{i},'/1']) ; +end + ADDED mttroot/ntt/bin/trans/m/mttCreateSystemMdl_ICD.m Index: mttroot/ntt/bin/trans/m/mttCreateSystemMdl_ICD.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateSystemMdl_ICD.m @@ -0,0 +1,274 @@ +function icd = mttCreateSystemMdl_ICD(model) + +sympar = map_system_sympars(model) ; +input = map_system_inputs(model) ; +invar = map_system_invars(model) ; +outvar = map_system_outvars(model) ; + +icd.output_namelist = outvar ; +icd.input_namelist = invar ; +if ~isempty(input) + icd.input_namelist = [icd.input_namelist,input] ; +end +if ~isempty(sympar) + icd.input_namelist = [icd.input_namelist,sympar] ; +end + +icd.output_namelist = sort(icd.output_namelist) ; +icd.input_namelist = sort(icd.input_namelist) ; + + + +function map = map_system_sympars(model) + mttNotify('...mapping system inputs (symbolic parameters)') ; + mttWriteNewLine ; + + map = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'sympar') ; + + model_name = mttDetachText(model.source,'/') ; + + for i = 1:number_of_variables + variable_name = model.sympar{i} ; + default_value = model.sympar_default{i} ; + + if isempty(default_value) + line = line + 1 ; + map{line} = [model_name,'___',variable_name] ; + end + end + + +function map = map_system_inputs(model,root,branch) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system inputs (input variables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'input') ; + + for i = 1:number_of_variables + variable_name = model.input{i} ; + + line = line + 1 ; + map{line} = [current_branch,'___',variable_name] ; + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_inputs(object,root,next_branch) ; + elseif ~isempty(object.cr) + additional_map = map_system_inputs(object.cr,root,next_branch) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function map = map_system_invars(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system inputs (input covariables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if ~inbond.effort + if ~strcmp(object.class,'Df') + covar = covariables.effort ; + end + elseif inbond.flow + if ~strcmp(object.class,'De') + covar = covariables.flow ; + end + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + map{line} = [current_branch,'__',object_name,'(',covariable,')'] ; + end + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + + if outbond.effort + covar = covariables.effort ; + elseif ~outbond.flow + covar = covariables.flow ; + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + map{line} = [current_branch,'__',object_name,'(',covariable,')'] ; + end + end + end + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_invars(object,root,next_branch,env) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function map = map_system_outvars(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system outputs (output covariables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if inbond.effort + covar = covariables.effort ; + elseif ~inbond.flow + covar = covariables.flow ; + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + map{line} = [current_branch,'__',object_name,'(',covariable,')'] ; + end + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + covar = [] ; + + if ~outbond.effort + if ~strcmp(object.class,'Sf') + covar = covariables.effort ; + end + elseif outbond.flow + if ~strcmp(object.class,'Se') + covar = covariables.flow ; + end + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + map{line} = [current_branch,'__',object_name,'(',covariable,')'] ; + end + end + end + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_outvars(object,root,next_branch,env) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + ADDED mttroot/ntt/bin/trans/m/mttCreateUnifiedModel.m Index: mttroot/ntt/bin/trans/m/mttCreateUnifiedModel.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttCreateUnifiedModel.m @@ -0,0 +1,182 @@ +function model = mttCreateUnifiedModel(model,bondgraph,specification) + + model.source = mttCutText(specification.specification,'_abg.txt') ; + model.bondgraph = mttCutText(bondgraph.bondgraph,'_abg.fig') ; + + model.obj = bondgraph.obj ; + model.bond = bondgraph.bond ; + + object_names = mttGetFieldNames(model,'obj') ; + specified_object_names = mttGetFieldNames(specification,'obj') ; + + for n = 1:length(object_names) + object_name = object_names{n} ; + object = getfield(model,'obj',object_name) ; + + if ~mttIsPassiveClass(object.class) + mttAssert(ismember(object_name,specified_object_names),... + ['Object name "',object_name,'" does not appear in specification']) ; + end + end + + for n = 1:length(specified_object_names) + specified_object_name = specified_object_names{n} ; + mttAssert(ismember(specified_object_name,object_names),... + ['Specified object name "',specified_object_name,... + '" does not appear in bond graph']) ; + + specified_object = getfield(specification,'obj',specified_object_name) ; + object = getfield(model,'obj',specified_object_name) ; + + if strcmp(specified_object.name.class,object.class) + mttAssert(~mttIsFoundationClass(object.class),... + 'Cannot redefine MTT foundation class') ; + is_abg = 1 ; + else + mttAssert(~mttIsPassiveClass(object.class),... + 'Cannot modify MTT junctions or ports') ; + is_abg = 0 ; + end + + object.is_abg = is_abg ; + object.name = specified_object.name ; + object.parameter = specified_object.parameter ; + + model = setfield(model,'obj',specified_object_name,object) ; + end + + model.sympar = specification.sympar ; + model.numpar = specification.numpar ; + model.input = specification.input ; + + model.sympar_default = specification.sympar_default ; + model.numpar_default = specification.numpar_default ; + model.input_default = specification.input_default ; + + for n = 1:length(object_names) + object_name = object_names{n} ; + object = getfield(model,'obj',object_name) ; + + if mttIsPortClass(object.class) + mttAssert(mttGetFieldLength(object,'interface')==1,... + ['Port components must have one and only one interface']) ; + + switch object.class + case {'Se','Sf'}, + mttAssert(~isempty(object.interface.out),... + 'Each source port must have an outward bond') ; + case {'De','Df'}, + mttAssert(~isempty(object.interface.in),... + 'Each detector port must have an inward bond') ; + end + end + + if ~ismember(object_name,specified_object_names) + object.name.item = [] ; + object.name.class = object.class ; + object.name.path = [] ; + object.parameter = [] ; + object.is_abg = 1 ; + end + + [rubbish,working_directory] = mttDetachText(model.source,'/') ; + local_directory = object.name.path ; + directory = mttLocateDirectory(working_directory,local_directory) ; + + source = [directory,'/',object.name.class] ; + + current_leaf = model.leaf ; + + if object.is_abg + if mttIsPassiveClass(object.name.class) + object.abg = [] ; + else + current_branch = model.branch ; + mttAssert(~ismember(source,current_branch),... + ['Recursive definition of "',source,'"']) ; + + if isempty(model.abgs) + existing_abg = [] ; + else + existing_abg = strmatch(source,model.abgs,'exact') ; + end + + if isempty(existing_abg) + if isempty(current_branch) + next_branch = {source} ; + next_leaf = object_name ; + else + next_branch = [current_branch,{source}] ; + next_leaf = [current_leaf,'/',object_name] ; + end + model.branch = next_branch ; + model.leaf = next_leaf ; + + class_model = mttCreateAcausalBondgraph(source,model) ; + + model.leaf = current_leaf ; + model.branch = current_branch ; + + next_abg = 1 + mttGetFieldLength(model,'abg') ; + for i = 1:mttGetFieldLength(class_model,'abg') + model.abg(next_abg) = class_model.abg(i) ; + model.abgs = class_model.abgs ; + next_abg = next_abg + 1 ; + end + class_model = mttDeleteField(class_model,'abg') ; + + model.crs = class_model.crs ; + class_model = mttDeleteField(class_model,'crs') ; + + model.cr_usage = class_model.cr_usage ; + class_model = mttDeleteField(class_model,'cr_usage') ; + + model.abg(next_abg) = class_model ; + model = mttAppend(model,'abgs',{source}) ; + + index = length(model.abgs) ; + mttNotify([' ...made "#',num2str(index),':',object.name.class,'" definition']) ; + mttWriteNewLine ; + end + object.abg = strmatch(source,model.abgs,'exact') ; + end + object.cr = [] ; + object.cr_item = [] ; + else + if isempty(model.crs) + existing_cr = [] ; + else + existing_cr = strmatch(source,model.crs,'exact') ; + end + + if isempty(current_leaf) + cr_user = object_name ; + else + cr_user = [current_leaf,'/',object_name] ; + end + + if isempty(existing_cr) + model = mttAppend(model,'crs',{source}) ; + + N = length(model.crs) ; + model.cr_usage(N).obj{1} = cr_user ; + else + N = 1+length(model.cr_usage(existing_cr).obj) ; + model.cr_usage(existing_cr).obj{N} = cr_user ; + end + + object.abg = [] ; + object.cr = strmatch(source,model.crs,'exact') ; + + if isempty(object.name.item) + object.cr_item = mttDetachText(model.crs{object.cr},'/') ; + else + object.cr_item = object.name.item ; + end + end + + object = mttDeleteField(object,'name') ; + object = mttDeleteField(object,'is_abg') ; + + model = setfield(model,'obj',object_name,object) ; + end ADDED mttroot/ntt/bin/trans/m/mttEmbedAcausalBondgraph.m Index: mttroot/ntt/bin/trans/m/mttEmbedAcausalBondgraph.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttEmbedAcausalBondgraph.m @@ -0,0 +1,159 @@ +function model = mttEmbedAcausalBondgraph(model,component,system) + source = model.abg(component) ; + + if nargin==2 + is_root_model = 1 ; + target = model ; + else + is_root_model = 0 ; + target = model.abg(system) ; + end + + source_objects = mttGetFieldNames(source,'obj') ; + target_objects = mttGetFieldNames(target,'obj') ; + + for n = 1:length(target_objects) + target_object_name = target_objects{n} ; + target_object = getfield(target,'obj',target_object_name) ; + + here = [mttDetachText(target.source,'/'),'/',target_object_name] ; + + is_abg_instance = 0 ; + if ~isempty(target_object.abg) + is_abg_instance = target_object.abg==component ; + end + + if is_abg_instance + target_object.sympar = source.sympar ; + target_object.numpar = source.numpar ; + target_object.input = source.input ; + + target_object.sympar_default = source.sympar_default ; + target_object.numpar_default = source.numpar_default ; + target_object.input_default = source.input_default ; + + declarations = length(target_object.sympar) ; + values = length(target_object.parameter) ; + + mttAssert(declarations==values,['Mismatched parameters in object ',here]) ; + + + number_of_target_ports = mttGetFieldLength(target_object,'interface') ; + + found_target_port = [] ; + target_ports_found = [] ; + + for i = 1:number_of_target_ports + + target_port_name = target_object.interface(i).name ; + target_inbond = target_object.interface(i).in ; + target_outbond = target_object.interface(i).out ; + + is_inline = (~isempty(target_inbond) & ~isempty(target_outbond)) ; + + next = 0 ; + found_target_port(i) = 0 ; + + matching = 1 ; + while matching + next = next + 1 ; + source_object_name = source_objects{next} ; + source_object = getfield(source,'obj',source_object_name) ; + + if ismember(source_object.class,{'SS','Se','Sf','De','Df'}) + source_port_name = source_object_name ; + + if is_inline + source_interface = getfield(source,'obj',source_port_name,'interface') ; + + inport_found = 0 ; + if ~isempty(source_interface.in) + inport_found = strcmp(source_port_name,[target_port_name,'_in']) ; + end + + outport_found = 0 ; + if ~isempty(source_interface.out) + outport_found = strcmp(source_port_name,[target_port_name,'_out']) ; + end + + found_target_port(i) = inport_found | outport_found ; + else + found_target_port(i) = strcmp(source_port_name,target_port_name) ; + end + end + + if found_target_port(i) + if isempty(target_ports_found) + target_ports_found = {target_port_name} ; + else + target_ports_found = [target_ports_found, {target_port_name}] ; + end + matching = 0 ; + else + matching = (next2 + model = create_bond(model,coordinates) ; + end + else + jump = jump + forward_arrow + reverse_arrow ; + end + end + end + else + [last_word,first_part] = mttDetachText(line,' ') ; + + if mttIsNumericText(first_part) + numbers = round(str2num(first_part)) ; % only interested in integer values + if numbers(1)==4 % ... text definition + depth = numbers(4) ; + is_visible = rem(depth,10)==0 ; + + if is_visible + coordinates = numbers(12:13) ; + text = mttCompressText(mttCutText(last_word,'\001')) ; + + identifier = mttCutText(text,'[') ; + qualifier = mttExtractText(text,'[',']') ; + + name.label = [] ; + name.domain = [] ; + name.domain_item = [] ; + name.class = [] ; + name.object = [] ; + + if isempty(identifier) + name.label = qualifier ; + model = create_label(model,name,coordinates) ; + else + [name.domain,name.domain_item] = mttCutText(qualifier,'::') ; + [name.class,name.object] = mttCutText(identifier,':') ; + model = create_object(model,name,coordinates) ; + end + end + end + end + end + end + + N = N + jump ; + processing = (N<=L) ; +end + +model = incorporate_anonymous_objects(model) ; +model = identify_causal_assignments(model) ; +model = identify_object_binding(model) ; +model = identify_object_interfaces(model) ; +model = associate_external_domains(model) ; +model = tidy_up(model) ; + + + +function model = create_line(model,coordinates) + next = 1 + mttGetFieldLength(model,'line') ; + model.line(next).xy1 = coordinates(1:2) ; + model.line(next).xy2 = coordinates(3:4) ; + model.line(next).mid = (coordinates(1:2)+coordinates(3:4))/2 ; + +function model = create_bond(model,coordinates) + next = 1 + mttGetFieldLength(model,'bond') ; + + N = length(coordinates) ; + + q1 = coordinates(N-1:N) ; p1 = coordinates(1:2) ; + p2 = coordinates(3:4) ; q2 = coordinates(N-3:N-2) ; + p3 = coordinates(5:6) ; q3 = coordinates(N-5:N-4) ; + ps = norm(p2-p1) ; qs = norm(q2-q1) ; + + orientation = sign(ps-qs) ; + + switch orientation + case 1, % harpoon points forward + xy1 = p1 ; xy2 = q2 ; v1 = p2-p1 ; v2 = q2-q3 ; harpoon = q1-q2 ; + case -1, % harpoon points backward + xy1 = p2 ; xy2 = q1 ; v1 = q2-q1 ; v2 = p2-p3 ; harpoon = p1-p2 ; + end + + harpoon_side = sign_cross_product(v2,harpoon) ; + + mttAssert(~(orientation==0 | harpoon_side==0),... + ['Ambiguous bond orientation between[',num2str(xy1),'] and [',num2str(xy2),']']) ; + + model.bond(next).xy1 = xy1 ; + model.bond(next).xy2 = xy2 ; + model.bond(next).v1 = v1 ; + model.bond(next).v2 = v2 ; + model.bond(next).harpoon = harpoon ; + model.bond(next).harpoon_side = harpoon_side ; + + model.bond(next).from.obj = [] ; + model.bond(next).from.interface = [] ; + model.bond(next).to.obj = [] ; + model.bond(next).to.interface = [] ; + model.bond(next).flow = [] ; + model.bond(next).effort = [] ; + model.bond(next).unicausal = [] ; + model.bond(next).domain = [] ; + model.bond(next).domain_item = [] ; + +function model = create_label(model,name,coordinates) + inner_name = mttExtractText(name.label,'<','>') ; + if isempty(inner_name) + label_name = name.label ; + is_inline = 0 ; + else + label_name = inner_name ; + is_inline = 1 ; + end + mttValidateName(label_name) ; + + next = 1 + mttGetFieldLength(model,'label') ; + model.label(next).name = label_name ; + model.label(next).is_inline = is_inline ; + model.label(next).xy = coordinates ; + +function model = create_object(model,name,coordinates) +global mtt_environment + + domain_names = mttGetFieldNames(mtt_environment,'domain') ; + + is_anonymous = 0 ; + if isempty(name.object) + switch name.class + case {'0','1'}, + is_anonymous = 1 ; + case 'SS', + mttAssert(~isempty(name.object),... + 'Anonymous "SS" object') ; + otherwise, + name.object = name.class ; + end + end + + if is_anonymous + next = 1 + mttGetFieldLength(model,'anonymous') ; + model.anonymous(next).class = name.class ; + model.anonymous(next).xy = coordinates ; + else + object_names = mttGetFieldNames(model,'obj') ; + if ~isempty(object_names) + mttAssert(~ismember(name.object,object_names),... + ['Repeated object: "',name.object,'"']) ; + end + + switch name.class + case {'0','1'}, + mttValidateName(name.object) ; + mttAssert(~ismember(name.object,{'in','out'}),... + 'Junctions cannot use reserved port names') ; + + case {'SS','Se','Sf','De','Df'}, + mttValidateName(name.object) ; + + if isempty(name.domain) | isempty(mtt_environment) + model = setfield(model,'obj',name.object,'domain',[]) ; + model = setfield(model,'obj',name.object,'domain_item',[]) ; + else + mttAssert(ismember(name.domain,domain_names),... + ['Unrecognised domain "',name.domain,'"']) ; + dom = getfield(mtt_environment,'domain',name.domain,'dom') ; + item = getfield(mtt_environment,'domain',name.domain,'item') ; + + if isempty(item) + public_domain = getfield(mtt_environment,'public_domain',{dom}) ; + item_names = mttGetFieldNames(public_domain,'item') ; + + mttAssert(ismember(name.domain_item,item_names),... + ['Item "',name.domain_item,'" not found in public domain "',name.domain,'"']) ; + item_name = name.domain_item ; + else + mttAssert(isempty(name.domain_item),... + ['Item unspecified in public domain "',name.domain,'"']) ; + item_name = item ; + end + + model = setfield(model,'obj',name.object,'domain',dom) ; + model = setfield(model,'obj',name.object,'domain_item',item_name) ; + end + + otherwise, + mttValidateName(name.class) ; + mttValidateName(name.object) ; + + mttAssert(~ismember(name.object,{'in','out'}),... + 'Objects cannot use reserved port names') ; + end + model = setfield(model,'obj',name.object,'class',name.class) ; + model = setfield(model,'obj',name.object,'xy',coordinates) ; + end + +function model = incorporate_anonymous_objects(model) + number_of_objects = mttGetFieldLength(model,'anonymous') ; + + last = length(num2str(number_of_objects)) ; + for i = 1:last + object_number(i) = '0' ; + end + + for i = 1:number_of_objects + anonymous_object = getfield(model,'anonymous',{i}) ; + + current_number = num2str(i) ; + width = length(current_number) ; + first = last-width+1 ; + object_number(first:last) = current_number ; + + object_name = ['mtt_obj',object_number] ; + model = setfield(model,'obj',object_name,model.anonymous(i)) ; + end + +function r = sign_cross_product(v1,v2) + r = sign(v1(1)*v2(2) - v1(2)*v2(1)) ; + +function model = identify_causal_assignments(model) + L = mttGetFieldLength(model,'line') ; + + if L>0 + N = mttGetFieldLength(model,'bond') ; + + for j = 1:L + for i = 1:N + s(i,j) = norm(model.line(j).mid - model.bond(i).xy1) ; + f(i,j) = norm(model.line(j).mid - model.bond(i).xy2) ; + end + end + + [min_range_start,nearest_bond_start] = min(s) ; + [min_range_finish,nearest_bond_finish] = min(f) ; + + equidistant = min_range_start==min_range_finish ; + at_harpoon = min_range_start>min_range_finish ; + + for j = 1:L + fulcrum = num2str(model.line(j).mid) ; + + mttAssert(~equidistant(j),... + ['Ambiguous causal line at [',num2str(model.line(j).mid),']']) ; + + if at_harpoon(j) + index = nearest_bond_finish(j) ; + bond = model.bond(index) ; + terminal = bond.xy2 ; + terminal_vector = bond.v2 ; + else + index = nearest_bond_start(j) ; + bond = model.bond(index) ; + terminal = bond.xy1 ; + terminal_vector = bond.v1 ; + end + + to_lhs = norm(model.line(j).xy1 - terminal) ; + to_mid = norm(model.line(j).mid - terminal) ; + to_rhs = norm(model.line(j).xy2 - terminal) ; + + mttAssert(to_midto_left) ; + causal_assignment = sign_cross_product(terminal_vector,causal_vector) ; + mttAssert(causal_assignment~=0,... + ['Cannot determine causality near [',num2str(fulcrum),']']) ; + + if causal_assignment==bond.harpoon_side + [bond.flow,causality_ok] = mttAssign(bond.flow,at_harpoon(j)) ; + else + [bond.effort,causality_ok] = mttAssign(bond.effort,at_harpoon(j)) ; + end + end + mttAssert(causality_ok,... + ['Ambiguous causal assignment near [',num2str(fulcrum),']']) ; + + bond.unicausal = mttCompare(bond.flow,bond.effort) ; + + model.bond(index) = bond ; + end + end + + +function model = identify_object_binding(model) + object_names = mttGetFieldNames(model,'obj') ; + number_of_objects = length(object_names) ; + number_of_bonds = mttGetFieldLength(model,'bond') ; + + for j = 1:number_of_bonds + bond = model.bond(j) ; + for i = 1:number_of_objects + object = getfield(model,'obj',object_names{i}) ; + origin_proximity(i) = norm(object.xy - bond.xy1) ; + target_proximity(i) = norm(object.xy - bond.xy2) ; + end + + [range,index] = min(origin_proximity) ; + origin_name = object_names{index} ; + bond.from.obj = origin_name ; + bond.from.interface = [] ; + + [range,index] = min(target_proximity) ; + target_name = object_names{index} ; + bond.to.obj = target_name ; + bond.to.interface = [] ; + + model = setfield(model,'bond',{j},bond) ; + + origin = getfield(model,'obj',origin_name) ; + next = 1 + mttGetFieldLength(origin,'bond') ; + origin.bond(next).number = j ; + origin.bond(next).is_inbond = 0 ; + model = setfield(model,'obj',origin_name,origin) ; + + target = getfield(model,'obj',target_name) ; + next = 1 + mttGetFieldLength(target,'bond') ; + target.bond(next).number = j ; + target.bond(next).is_inbond = 1 ; + model = setfield(model,'obj',target_name,target) ; + end + + +function model = identify_object_interfaces(model) + object_names = mttGetFieldNames(model,'obj') ; + number_of_objects = length(object_names) ; + number_of_labels = mttGetFieldLength(model,'label') ; + number_of_bonds = mttGetFieldLength(model,'bond') ; + + for j = 1:number_of_labels + label = model.label(j) ; + for i = 1:number_of_objects + object_name = object_names{i} ; + object = getfield(model,'obj',object_names{i}) ; + proximity(i) = norm(object.xy - label.xy) ; + end + [range,index] = min(proximity) ; + associated_object = object_names{index} ; + object = getfield(model,'obj',associated_object) ; + + switch object.class + case {'0','1'}, + mttAssert(~label.is_inline,... + ['Inline ports not valid for "0" and "1" junctions']) ; + end + + next = 1 + mttGetFieldLength(object,'interface') ; + object = setfield(object,'interface',{next},'name',label.name) ; + object = setfield(object,'interface',{next},'class',[]) ; + object = setfield(object,'interface',{next},'is_inline',label.is_inline) ; + object = setfield(object,'interface',{next},'xy',label.xy) ; + object = setfield(object,'interface',{next},'in',[]) ; + object = setfield(object,'interface',{next},'out',[]) ; + object = setfield(object,'interface',{next},'map',[]) ; + model = setfield(model,'obj',associated_object,object) ; + end + + for j = 1:number_of_objects + object_name = object_names{j} ; + object = getfield(model,'obj',object_name) ; + + number_of_attached_bonds = mttGetFieldLength(object,'bond') ; + number_of_interfaces = mttGetFieldLength(object,'interface') ; + + for k = 1:number_of_interfaces + interface = object.interface(k) ; + + inbond_proximity = [] ; inbond_counter = [] ; + outbond_proximity = [] ; outbond_counter = [] ; + + in_counter = 0 ; + out_counter = 0 ; + + for i = 1:number_of_attached_bonds + bond_number = object.bond(i).number ; + bond = model.bond(bond_number) ; + + if object.bond(i).is_inbond + if isempty(bond.to.interface) + in_counter = in_counter + 1 ; + inbond_proximity(in_counter) = norm(interface.xy - bond.xy2) ; + inbond_counter(in_counter) = bond_number ; + end + else + if isempty(bond.from.interface) + out_counter = out_counter + 1 ; + outbond_proximity(out_counter) = norm(interface.xy - bond.xy1) ; + outbond_counter(out_counter) = bond_number ; + end + end + end + + [in_range,inbond_index] = min(inbond_proximity) ; + [out_range,outbond_index] = min(outbond_proximity) ; + + inbond = inbond_counter(inbond_index) ; + outbond = outbond_counter(outbond_index) ; + + if interface.is_inline + mttAssert(~isempty(inbond_proximity),... + ['No in-bond for interface "',object_name,'[',interface.name,']"']) ; + mttAssert(~isempty(outbond_proximity),... + ['No out-bond for interface "',object_name,'[',interface.name,']"']) ; + + interface.in = inbond ; + interface.out = outbond ; + + model = setfield(model,'bond',{outbond},'from','interface',k) ; + model = setfield(model,'bond',{inbond},'to','interface',k) ; + else + mttAssert(~(isempty(inbond_proximity) & isempty(outbond_proximity)),... + ['No bond for interface "',object_name,'[',interface.name,']"']) ; + + if isempty(inbond_proximity) + interface.out = outbond ; + model = setfield(model,'bond',{outbond},'from','interface',k) ; + elseif isempty(outbond_proximity) + interface.in = inbond ; + model = setfield(model,'bond',{inbond},'to','interface',k) ; + else + mttAssert(in_range~=out_range,... + ['Ambiguous interface "',object_name,'[',interface.name,']"']) ; + + if out_range0,... + ['No operator defined in ',here]) ; + + assigned_ports = [] ; + + for i = 1:length(cr.operator) + if i==1 + operator_names{1} = cr.operator(i).name ; + else + operator_name = cr.operator(i).name ; + mttAssert(~ismember(operator_name,operator_names),... + ['Repeated operator name "',operator_name,'" in ',here]) ; + operator_names{i} = operator_name ; + end + + newly_assigned_ports = mttGetFieldNames(cr.operator(i),'assign') ; + if isempty(assigned_ports) + assigned_ports = newly_assigned_ports ; + else + if ~isempty(newly_assigned_ports) + assigned_ports = [assigned_ports, newly_assigned_ports] ; + end + end + end + + for i = 1:length(interface_ports_with_state) + interface_port = interface_ports_with_state{i} ; + + mttAssert(ismember(interface_port,assigned_ports),... + ['Missing "set" declaration for port "',interface_port,'" in ',here]) ; + end + + + + +function [interface,next] = fetch_interface(statements,next,cr_name) +global mtt_environment + unit_name = 'interface' ; + here = [cr_name,'/',unit_name] ; + + domain_names = mttGetFieldNames(mtt_environment,'domain') ; + + interface = [] ; + number_of_statements = length(statements) ; + + counter = 0 ; + constraint = [] ; + + open = 0 ; + parsing = 1 ; + while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case 'port', + ports = mttGetItemList(line) ; + for n = 1:length(ports) + identifier = mttCutText(ports{n},'[') ; + qualifier = mttExtractText(ports{n},'[',']') ; + [name.domain,name.domain_item] = mttCutText(qualifier,'::') ; + + name.port = identifier ; + mttValidateName(name.port) ; + + if isempty(name.domain) | isempty(mtt_environment) + interface = setfield(interface,'port',name.port,'domain',[]) ; + interface = setfield(interface,'port',name.port,'domain_item',[]) ; + interface = setfield(interface,'port',name.port,'was_generic',1) ; + else + mttAssert(ismember(name.domain,domain_names),... + ['Unrecognised domain "',name.domain,'"']) ; + dom = getfield(mtt_environment,'domain',name.domain,'dom') ; + item = getfield(mtt_environment,'domain',name.domain,'item') ; + + if isempty(item) + public_domain = getfield(mtt_environment,'public_domain',{dom}) ; + item_names = mttGetFieldNames(public_domain,'item') ; + + mttAssert(ismember(name.domain_item,item_names),... + ['Item "',name.domain_item,'" not found in public domain "',name.domain,'"']) ; + item_name = name.domain_item ; + else + mttAssert(isempty(name.domain_item),... + ['Item unspecified in public domain "',name.domain,'"']) ; + item_name = item ; + end + + interface = setfield(interface,'port',name.port,'domain',dom) ; + interface = setfield(interface,'port',name.port,'domain_item',item_name) ; + interface = setfield(interface,'port',name.port,'was_generic',0) ; + end + interface = setfield(interface,'port',name.port,'is_effort_state',0) ; + interface = setfield(interface,'port',name.port,'is_flow_state',0) ; + interface = setfield(interface,'port',name.port,'assign',[]) ; + end + + case {'assert','prefer'}, + counter = counter + 1 ; + constraint{counter} = statement ; + + case '{', + mttAssert(~open,['Unmatched "{" in ',here]) ; + open = 1 ; + case '}', + mttAssert(open,['Unmatched "}" in ',here]) ; + open = 0 ; + otherwise, + error(['Unrecognised_keyword "',keyword,'" in ',here]) ; + end + + mttAssert(~(open & (next==number_of_statements)),... + ['Missing "}" in ',here]) ; + + if (~open) | (next==number_of_statements) + parsing = 0 ; + end + end + + + interface_ports = mttGetFieldNames(interface,'port') ; + number_of_constraints = length(constraint) ; + + for i = 1:number_of_constraints + [keyword,assignment] = mttSeparateText(constraint{i}) ; + [namelist,definition] = mttCutText(assignment,'=>') ; + + mttAssert(~isempty(keyword),... + ['Rule "',constraint{i},'" has no context in cr ',cr_name]) ; + + if ~isempty(namelist) + first = 1 ; + last = length(namelist) ; + if namelist([first,last])=='[]' + ports = mttGetItemList(mttExtractText(namelist,'[',']')) ; + else + ports = {namelist} ; + end + end + + mttAssert(~isempty(ports),... + ['Rule "',constraint{i},'" has no association in cr ',cr_name]) ; + mttAssert(~isempty(definition),... + ['Rule "',constraint{i},'" not defined in cr ',cr_name]) ; + + for j = 1:length(ports) + port_name = ports{j} ; + mttValidateName(port_name) ; + + other_ports = [] ; + counter = 0 ; + for k = 1:length(ports) + if j~=k + counter = counter + 1 ; + other_ports{counter} = ports{k} ; + end + end + + mttAssert(ismember(port_name,interface_ports),... + ['Unreferenced port "',port_name,'" in cr ',cr_name]) ; + + port = getfield(interface,'port',port_name) ; + + switch definition + case 'effort_state', + mttAssert(mttIsEqual(port.is_flow_state,0),... + ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ; + port.is_effort_state = 1 ; + + case 'flow_state', + mttAssert(mttIsEqual(port.is_effort_state,0),... + ['Attempt to overwrite state assignment at port "',port_name,'" in ',here]) ; + port.is_flow_state = 1 ; + + otherwise, + rule_number = 1 + mttGetFieldLength(port,'causality') ; + + port.causality(rule_number).rule = keyword ; + port.causality(rule_number).def = definition ; + port.causality(rule_number).with = other_ports ; + port.causality(rule_number).applied = 0 ; + end + + interface = setfield(interface,'port',port_name,port) ; + end + end + + +function [operator,next] = fetch_operator(statements,next,cr,cr_name) + unit_name = 'operator' ; + here = [cr_name,'/',unit_name] ; + + interface = [] ; + number_of_statements = length(statements) ; + + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + operator = mttGetOperatorContext(line,cr,cr_name) ; + + operator.content = [] ; + operator.var = [] ; + operator.var_default = [] ; + operator.struct = [] ; + operator.set = [] ; + + counter = 0 ; + + open = 0 ; + parsing = 1 ; + while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case '{', + mttAssert(~open,['Unmatched "{" in ',here]) ; + open = 1 ; + + case '}', + mttAssert(open,['Unmatched "}" in ',here]) ; + open = 0 ; + + case 'set', + mttAssert(open,... + ['"set" declarations must be contained inside {...} in ',here]) ; + + operator = mttAppend(operator,'set',{line}) ; + + case 'var', + mttAssert(open,... + ['"var" declarations must be contained inside {...} in ',here]) ; + + variable_list = line ; + [variables,defaults] = mttGetParameters(variable_list) ; + + operator = mttAppend(operator,'var',variables) ; + operator = mttAppend(operator,'var_default',defaults) ; + + case 'struct', + mttAssert(open,... + ['"struct" declarations must be contained inside {...} in ',here]) ; + + [struct_name,variable_list] = mttSeparateText(line) ; + [variables,defaults] = mttGetParameters(variable_list) ; + + mttAssert(mttIsEmptyCellArray(defaults),... + ['"struct" declarations cannot have default values in ',here]) ; + + operator.struct = mttAppend(operator.struct,struct_name,variables) ; + + otherwise, + counter = counter + 1 ; + operator.content{counter} = statement ; + end + + mttAssert(~(open & (next==number_of_statements)),... + ['Missing "}" in ',here]) ; + + if (~open) | (next==number_of_statements) + parsing = 0 ; + end + end + + cr_ports = mttGetFieldNames(cr.interface,'port') ; + for i = 1:length(operator.var) + current_var = operator.var{i} ; + mttAssert(~ismember(current_var,cr.numpar),... + ['Variable "',current_var,'" redeclares CR numerical parameter in ',cr_name]) ; + mttAssert(~ismember(current_var,cr.sympar),... + ['Variable "',current_var,'" redeclares CR parameter in ',cr_name]) ; + mttAssert(~ismember(current_var,cr_ports),... + ['Variable "',current_var,'" redeclares CR port in ',cr_name]) ; + end + + operator = mttParseOperatorEquations(operator,cr,cr_name) ; + + +function context = mttGetOperatorContext(line,cr,cr_name) + index = sort([findstr(line,'|'),findstr(line,'<'),findstr(line,'>')]) ; + assignment = findstr(line,':=') ; + + mttAssert(length(assignment)==1,... + ['Operator declaration must contain a unique ":=" assignment in cr ',cr_name]) ; + mttAssert(length(index)>0,... + ['Operator declaration without ports in cr ',cr_name]) ; + + left_side = index(indexassignment) ; + + mttAssert(length(left_side)>0,... + ['Operator declaration without input ports in cr ',cr_name]) ; + mttAssert(length(right_side)>0,... + ['Operator declaration without output ports in cr ',cr_name]) ; + mttAssert(mod(length(left_side),2)==0 & mod(length(right_side),2)==0,... + ['Operator declaration has mismatched tags in cr ',cr_name]) ; + + context.name = mttClipText(line(assignment+2:right_side(1)-1)) ; + mttAssert(~isempty(context.name),... + ['Operator declaration is anonymous in cr ',cr_name]) ; + + mttValidateName(context.name) ; + + + counter = 0 ; + + for i = 1:length(index)/2 + counter = counter + 1 ; + link = [] ; + + right = 2*i ; + left = right - 1 ; + + if index(right)assignment + link.is_input = 1 ; + end + + + recognised = 1 ; + switch line(index([left,right])) + case '|>', + link.is_flow = 1 ; + link.is_effort = 0 ; + case '<|', + link.is_flow = 0 ; + link.is_effort = 1 ; + case '<>', + link.is_flow = 1 ; + link.is_effort = 1 ; + otherwise, + recognised = 0 ; + end + + mttAssert(recognised,... + ['Unrecognised tags in operator ',context.name,' (cr ',cr_name,')']) ; + + port_declaration = line(index(left):index(right)) ; + port = line(index(left)+1:index(right)-1) ; + mttAssert(~isempty(port),... + ['Empty port in operator ',context.name,' (cr ',cr_name,')']) ; + + [port_name,qualifier] = mttCutText(port,'=') ; + + link.name = port_name ; + + if isempty(qualifier) + link.is_unconstrained = 1 ; + else + link.is_unconstrained = 0 ; + mttAssert(strcmp(qualifier,'0'),... + ['Non-zero port constraint in operator ',context.name,' (cr ',cr_name,')']) ; + end + + context.link(counter) = link ; + end + + + cr_port_names = mttGetFieldNames(cr.interface,'port') ; + + check.is_input = [] ; + check.is_output = [] ; + check.is_effort = [] ; + check.is_flow = [] ; + + for j = 1:length(cr_port_names) + port_check(j) = check ; + end + + for i = 1:counter + port_name = context.link(i).name ; + mttAssert(ismember(port_name,cr_port_names),... + ['Operator declaration uses undefined port "',port_name,'" in cr ',cr_name]) ; + + index = strmatch(port_name,cr_port_names,'exact') ; + + mttAssert(~mttIsEqual(port_check(index).is_input,context.link(i).is_input),... + ['Operator declaration has repeated input ports in cr ',cr_name]) ; + mttAssert( mttIsEqual(port_check(index).is_output,context.link(i).is_input),... + ['Operator declaration has repeated output ports in cr ',cr_name]) ; + mttAssert(~mttIsEqual(port_check(index).is_flow,context.link(i).is_flow),... + ['Operator declaration has repeated flow in cr ',cr_name]) ; + mttAssert(~mttIsEqual(port_check(index).is_effort,context.link(i).is_effort),... + ['Operator declaration has repeated effort in cr ',cr_name]) ; + + port_check(index).is_input = context.link(i).is_input ; + port_check(index).is_output = ~context.link(i).is_input ; + port_check(index).is_flow = context.link(i).is_flow ; + port_check(index).is_effort = context.link(i).is_effort ; + end + + for j = 1:length(cr_port_names) + mttAssert(~isempty(port_check(j).is_input),... + ['Operator declaration has missing input ports in cr ',cr_name]) ; + mttAssert(~isempty(port_check(j).is_output),... + ['Operator declaration has missing output ports in cr ',cr_name]) ; + mttAssert(~isempty(port_check(j).is_flow),... + ['Operator declaration has missing flow in cr ',cr_name]) ; + mttAssert(~isempty(port_check(j).is_effort),... + ['Operator declaration has missing effort in cr ',cr_name]) ; + end ADDED mttroot/ntt/bin/trans/m/mttFetchSpecification.m Index: mttroot/ntt/bin/trans/m/mttFetchSpecification.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttFetchSpecification.m @@ -0,0 +1,189 @@ +function model = mttFetchSpecification(filename) + +model = [] ; + +mttAssert(mttFileExists(filename),... + ['File "',filename,'" not found']) ; + +mttNotify([' ...processing ',filename]) ; +mttWriteNewLine ; + +model.specification = filename ; + +model.source = mttCutText(filename,'_abg.txt') ; +model_name = mttDetachText(model.source,'/') ; + +content = mttReadFile(filename) ; +statements = mttExtractStatements(content) ; + +number_of_statements = length(statements) ; + +abg_declared = 0 ; +next = 0 ; + +parsing = 1 ; +while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case 'abg', + mttAssert(~abg_declared,... + '"abg" declaration must be unique') ; + abg_declared = 1 ; + + abg_name = mttCutText(line,'[') ; + mttAssert(strcmp(abg_name,model_name),... + ['Wrong name:[',abg_name,'] Expecting:[',model_name,']']) ; + + abg_parameter_list = mttExtractText(line,'[',']') ; + [abg_parameters,abg_defaults] = mttGetParameters(abg_parameter_list) ; + + model.name = abg_name ; + + model.sympar = abg_parameters ; + model.sympar_default = abg_defaults ; + + [abg,next] = fetch_abg(statements,next) ; + + model = mttAppendFields(model,abg) ; + + case '{', + error('Unexpected "{" found') ; + case '}', + error('Unexpected "}" found') ; + otherwise, + error(['Unrecognised top-level keyword "',keyword,'"']) ; + end + + if next==number_of_statements + parsing = 0 ; + end +end + +mttCheckBondgraphDeclarations(model) ; + + + +function [abg,next] = fetch_abg(statements,next) +global mtt_environment + + abg = [] ; + unit_name = 'abg' ; + + user_defined_paths = mttGetFieldNames(mtt_environment,'path') ; + + number_of_statements = length(statements) ; + + bondgraph = [] ; + use_declared = 0 ; + open = 0 ; + + parsing = 1 ; + while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case 'use', + mttAssert(open,... + ['"use" declaration must be contained inside {...} in "',unit_name,'"']) ; + mttAssert(~use_declared,... + '"use" declaration must be unique') ; + + use_declared = 1 ; + bondgraph = line ; + + abg.bondgraph = bondgraph ; + + case 'input', + mttAssert(open,... + ['"input" declarations must be contained inside {...} in "',unit_name,'"']) ; + + input_parameter_list = line ; + [input_parameters,input_defaults] = mttGetParameters(input_parameter_list) ; + + abg = mttAppend(abg,'input',input_parameters) ; + abg = mttAppend(abg,'input_default',input_defaults) ; + + case 'numpar', + mttAssert(open,... + ['"numpar" declarations must be contained inside {...} in "',unit_name,'"']) ; + + numerical_parameter_list = line ; + [numerical_parameters,numerical_defaults] = mttGetParameters(numerical_parameter_list) ; + + abg = mttAppend(abg,'numpar',numerical_parameters) ; + abg = mttAppend(abg,'numpar_default',numerical_defaults) ; + + case 'object', + mttAssert(open,... + ['"object" declarations must be contained inside {...} in "',unit_name,'"']) ; + + object_names = mttGetFieldNames(abg,'obj') ; + + [object_name,object_spec] = mttCutText(line,':=') ; + mttAssert(~ismember(object_name,object_names),... + ['Object "',object_name,'" already declared']) ; + + implementation = mttCutText(object_spec,'[') ; + mttAssert(~isempty(implementation),... + ['Incomplete specification:[',line,']']) ; + + object_parameter_list = mttExtractText(line,'[',']') ; + object_parameters = mttGetInstanceParameters(object_parameter_list) ; + + [source,name.item] = mttCutText(implementation,'::') ; + [name.class,name.path] = mttDetachText(source,'/') ; + + if isempty(name.class) + name.class = source ; + name.path = [] ; + else + mttAssert(~isempty(name.path),... + ['Empty path name in "',unit_name,'"']) ; + if name.path(1)=='$' + [path_alias,path_branch] = mttCutText(name.path,'/') ; + path_alias(1) = [] ; + + mttAssert(ismember(path_alias,user_defined_paths),... + ['Path "',path_alias,'" not recognised']) ; + + path_root = getfield(mtt_environment,'path',path_alias) ; + if isempty(path_branch) + name.path = path_root ; + else + name.path = [path_root,'/',path_branch] ; + end + end + end + + abg = setfield(abg,'obj',object_name,'name',name) ; + abg = setfield(abg,'obj',object_name,'parameter',object_parameters) ; + + case '{', + mttAssert(~open,['Unmatched "{" in "',unit_name,'"']) ; + open = 1 ; + case '}', + mttAssert(open,['Unmatched "}" in "',unit_name,'"']) ; + open = 0 ; + otherwise, + error(['Unrecognised_keyword "',keyword,'" in "',unit_name,'"']) ; + end + + mttAssert(~(open & (next==number_of_statements)),... + ['Missing "}" in "',unit_name,'"']) ; + + if (~open) | (next==number_of_statements) + parsing = 0 ; + end + end + + abg = mttSetFieldDefault(abg,'input',[]) ; + abg = mttSetFieldDefault(abg,'input_default',[]) ; + abg = mttSetFieldDefault(abg,'numpar',[]) ; + abg = mttSetFieldDefault(abg,'numpar_default',[]) ; + abg = mttSetFieldDefault(abg,'bondgraph',[]) ; + ADDED mttroot/ntt/bin/trans/m/mttFetchStruct.m Index: mttroot/ntt/bin/trans/m/mttFetchStruct.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttFetchStruct.m @@ -0,0 +1,108 @@ +function model = mttFetchStruct(filename) + +model.representation = 'struct' ; + +mttAssert(mttFileExists(filename),... + ['File "',filename,'" not found']) ; + +mttNotify([' ...processing ',filename]) ; +mttWriteNewLine ; + +model.source = mttCutText(filename,'_struct.txt') ; +content = mttReadFile(filename) ; +statements = mttExtractStatements(content) ; + +number_of_statements = length(statements) ; + +next = 0 ; + +parsing = 1 ; +while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case {'struct','public_struct','private_struct'}, + struct_name = line ; + mttValidateName(struct_name) ; + + [struct,next] = fetch_struct(statements,next,struct_name) ; + model = setfield(model,'item',struct_name,struct) ; + + is_private = strcmp(keyword,'private_struct') ; + model = setfield(model,'item',struct_name,'is_private',is_private) ; + + case '{', + error('Unexpected "{" found') ; + case '}', + error('Unexpected "}" found') ; + otherwise, + error(['Unrecognised top-level keyword "',keyword,'"']) ; + end + + if next==number_of_statements + parsing = 0 ; + end +end + + +function [struct,next] = fetch_struct(statements,next,struct_name) + struct = [] ; + unit_name = 'struct' ; + + number_of_statements = length(statements) ; + + counter = 0 ; + open = 0 ; + + parsing = 1 ; + while parsing + next = next + 1 ; + statement = statements{next} ; + [keyword,line] = mttSeparateText(statement) ; + + switch keyword + case 'var', + mttAssert(open,... + ['"var" declarations must be contained inside {...} in "',unit_name,'"']) ; + mttAssert(~isempty(line),... + ['Undefined "var" in "',unit_name,'"']) ; + + data_name = line ; + mttValidateName(data_name) ; + + counter = counter + 1 ; + struct.var(counter).name = data_name ; + struct.var(counter).type = [] ; + + case '{', + mttAssert(~open,['Unmatched "{" in "',unit_name,'"']) ; + open = 1 ; + case '}', + mttAssert(open,['Unmatched "}" in "',unit_name,'"']) ; + open = 0 ; + otherwise, + mttAssert(open,... + ['Declarations must be contained inside {...} in "',unit_name,'"']) ; + mttAssert(~isempty(line),... + ['Empty declaration in "',unit_name,'"']) ; + + data_name = line ; + mttValidateName(data_name) ; + + data_type = keyword ; + mttValidateName(data_type) ; + + counter = counter + 1 ; + struct.var(counter).name = data_name ; + struct.var(counter).type = data_type ; + end + + mttAssert(~(open & (next==number_of_statements)),... + ['Missing "}" in "',unit_name,'"']) ; + + if (~open) | (next==number_of_statements) + parsing = 0 ; + end + end ADDED mttroot/ntt/bin/trans/m/mttIdentifyDomainCovariables.m Index: mttroot/ntt/bin/trans/m/mttIdentifyDomainCovariables.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttIdentifyDomainCovariables.m @@ -0,0 +1,97 @@ +function compound_item = mttIdentifyDomainCovariables(item,domain,model) + domains = mttGetFieldNames(model,'domain') ; + + domain_name = domain.source ; + domain_shortname = mttDetachText(domain_name,'/') ; + + item_names = mttGetFieldNames(domain,'item') ; + + number_of_bonds = mttGetFieldLength(item,'bond') ; + + if number_of_bonds==0 + compound_item.effort = {item.covar.effort} ; + compound_item.flow = {item.covar.flow} ; + + compound_item.effort_default = {item.covar.effort_default} ; + compound_item.flow_default = {item.covar.flow_default} ; + + else + counter = 0 ; + for k = 1:number_of_bonds + bond = item.bond(k) ; + + [next_domain,next_item] = mttCutText(bond.domain,'::') ; + if isempty(next_item) + mttAssert(ismember(next_item,item_names),... + ['Unrecognised reference "',next_item,'" in domain ',domain_shortname]) ; + + next_item = bond.domain ; + dependent_item = getfield(domain,'item',next_item) ; + compound_domain = mttIdentifyDomainCovariables(dependent_item,domain,model) ; + else + mttAssert(ismember(next_domain,domains),... + ['Unrecognised domain reference "',next_domain,'" in domain ',domain_shortname]) ; + + next_domain_index = getfield(model,'domain',next_domain,'dom') ; + next_domain_item_reference = getfield(model,'domain',next_domain,'item') ; + + mttAssert(isempty(next_domain_item_reference),... + ['Constrained domain reference "',next_domain,'" in domain ',domain_shortname]) ; + + actual_domain = model.dom(next_domain_index) ; + + actual_domain_name = actual_domain.source ; + actual_domain_shortname = mttDetachText(actual_domain_name,'/') ; + + actual_item_names = mttGetFieldNames(actual_domain,'item') ; + mttAssert(ismember(next_item,actual_item_names),... + ['Unrecognised reference "',next_item,'" in domain ',actual_domain_shortname]) ; + + dependent_item = getfield(actual_domain,'item',next_item) ; + mttAssert(~dependent_item.is_private,... + ['No public cross-reference available for "',next_item,'" in domain ',actual_domain_shortname]) ; + + compound_domain = mttIdentifyDomainCovariables(dependent_item,actual_domain,model) ; + end + + for i = 1:length(compound_domain.effort) + counter = counter + 1 ; + if isempty(bond.name) + compound_effort{counter} = compound_domain.effort{i} ; + compound_flow{counter} = compound_domain.flow{i} ; + else + compound_effort{counter} = [bond.name,'.',compound_domain.effort{i}] ; + compound_flow{counter} = [bond.name,'.',compound_domain.flow{i}] ; + end + compound_effort_default{counter} = compound_domain.effort_default{i} ; + compound_flow_default{counter} = compound_domain.flow_default{i} ; + end + end + + depth = length(compound_effort) ; + for n = 1:depth-1 + mttAssert(~ismember(compound_effort{n},{compound_effort{n+1:depth}}),... + ['Repeated effort variable "',compound_effort{n},'" in domain ',domain_shortname]) ; + mttAssert(~ismember(compound_flow{n},{compound_flow{n+1:depth}}),... + ['Repeated flow variable "',compound_flow{n},'" in domain ',domain_shortname]) ; + end + + for n = 1:depth + mttAssert(~ismember(compound_effort{n},{compound_flow{1:depth}}),... + ['Ambiguous effort/flow variable "',compound_effort{n},'" in domain ',domain_shortname]) ; + mttAssert(~ismember(compound_flow{n},{compound_effort{1:depth}}),... + ['Ambiguous flow/effort variable "',compound_flow{n},'" in domain ',domain_shortname]) ; + end + + mttAssert(~ismember('flow',{compound_effort{1:depth}}),... + ['Effort variable called "flow" in domain ',domain_shortname]) ; + mttAssert(~ismember('effort',{compound_flow{1:depth}}),... + ['flow variable called "effort" in domain ',domain_shortname]) ; + + compound_item.effort = compound_effort ; + compound_item.flow = compound_flow ; + + compound_item.effort_default = compound_effort_default ; + compound_item.flow_default = compound_flow_default ; + end + ADDED mttroot/ntt/bin/trans/m/mttIdentifyStructVariables.m Index: mttroot/ntt/bin/trans/m/mttIdentifyStructVariables.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttIdentifyStructVariables.m @@ -0,0 +1,40 @@ +function compound_item = mttIdentifyStructVariables(item,struct,model) + structs = mttGetFieldNames(model,'struct') ; + + struct_name = struct.source ; + struct_shortname = mttDetachText(struct_name,'/') ; + + item_names = mttGetFieldNames(struct,'item') ; + + number_of_vars = mttGetFieldLength(item,'var') ; + + counter = 0 ; + for k = 1:number_of_vars + var = item.var(k) ; + + next_item = var.type ; + if isempty(next_item) + counter = counter + 1 ; + compound_var{counter} = var.name ; + else + mttAssert(ismember(next_item,item_names),... + ['Unrecognised reference "',next_item,'" in struct ',struct_shortname]) ; + + dependent_item = getfield(struct,'item',next_item) ; + compound_struct = mttIdentifyStructVariables(dependent_item,struct,model) ; + + for i = 1:length(compound_struct.var) + counter = counter + 1 ; + compound_var{counter} = [var.name,'.',compound_struct.var{i}] ; + end + end + + variables = length(compound_var) ; + for n = 1:variables-1 ; + mttAssert(~ismember(compound_var{n},{compound_var{n+1:variables}}),... + ['Repeated variable "',compound_var{n},'" in struct ',struct_shortname]) ; + end + + compound_item.var = compound_var ; + end + ADDED mttroot/ntt/bin/trans/m/mttParseOperatorEquations.m Index: mttroot/ntt/bin/trans/m/mttParseOperatorEquations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttParseOperatorEquations.m @@ -0,0 +1,318 @@ +function operator = mttParseOperatorEquations(operator,cr,cr_name) +global mtt_environment + + operator.equation = [] ; +% operator.is_used = 0 ; + + numparlist = cr.numpar ; + symparlist = cr.sympar ; + varlist = operator.var ; + inputlist = cr.input ; + statelist = cr.state ; + + structlist = [] ; + if ~isempty(operator.struct) + struct_names = mttGetFieldNames(operator,'struct') ; + number_of_structs = length(struct_names) ; + for i = 1:number_of_structs + struct_name = struct_names{i} ; + variables = getfield(operator,'struct',struct_name) ; + if i==1 + structlist = variables ; + else + structlist = [structlist,variables] ; + end + end + end + + + inlist = [] ; + outlist = [] ; + inlink = [] ; + outlink = [] ; + + input_counter = 0 ; + output_counter = 0 ; + + for i = 1:length(operator.link) + if operator.link(i).is_input + input_counter = input_counter + 1 ; + inlist{input_counter} = operator.link(i).name ; + inlink(input_counter) = i ; + infree(input_counter) = operator.link(i).is_unconstrained ; + else + output_counter = output_counter + 1 ; + outlist{output_counter} = operator.link(i).name ; + outlink(output_counter) = i ; + outfree(output_counter) = operator.link(i).is_unconstrained ; + end + end + + + operator.assign = [] ; + ports_with_state_assignment = [] ; + + for i = 1:length(operator.set) + [port_covariable,state] = mttCutText(operator.set{i},'=>') ; + mttAssert(~isempty(state),... + ['"set" declarations must use "=>" in cr ',cr_name]) ; + + [port_name,covariable] = mttCutText(port_covariable,'.') ; + mttAssert(~isempty(covariable),... + ['"set" declarations must reference effort/flow covariables in cr ',cr_name]) ; + + port = strmatch(port_name,outlist,'exact') ; + ports_with_state_assignment = [ports_with_state_assignment,port] ; + + mttAssert(~isempty(port),... + ['Output port "',port_name,'" not recognised for "set" declaration in cr ',cr_name]) ; + mttAssert(outfree(port),... + ['Constrained port variable used for "set" declaration in cr ',cr_name]) ; + + actual_port = getfield(cr.interface.port,port_name) ; + mttAssert(actual_port.is_effort_state | actual_port.is_flow_state,... + ['"set" declarations must only be used for effort_states or flow_states in cr ',cr_name]) ; + + if isempty(actual_port.domain) + if actual_port.is_effort_state + covariables = {'effort'} ; + elseif actual_port.is_flow_state + covariables = {'flow'} ; + end + else + public_domain = mtt_environment.public_domain(actual_port.domain) ; + domain_item = getfield(public_domain.item,actual_port.domain_item) ; + + if actual_port.is_effort_state + covariables = domain_item.effort ; + elseif actual_port.is_flow_state + covariables = domain_item.flow ; + end + end + + index = strmatch(covariable,covariables,'exact') ; + mttAssert(~isempty(index),... + ['Unrecognised covariable "',covariable,'" used for "set" declaration in cr ',cr_name]) ; + + if isfield(operator.assign,port_name) + assignment = getfield(operator,'assign',port_name) ; + mttAssert(isempty(assignment.states{index}),... + ['Repeated covariable "',covariable,'" used for "set" declaration in cr ',cr_name]) ; + else + assignment.covar = covariables ; + assignment.state{length(covariables)} = [] ; +% assignment.domain = actual_port.domain ; +% assignment.domain_item = actual_port.domain_item ; + end + + mttAssert(ismember(state,cr.state),... + ['Unrecognised state "',state,'" used for "set" declaration in cr ',cr_name]) ; + + assignment.state{index} = state ; + operator = setfield(operator,'assign',port_name,assignment) ; + end + operator = mttDeleteField(operator,'set') ; + + + port_assignments = mttGetFieldNames(operator,'assign') ; + number_of_assignments = length(port_assignments) ; + for i = 1:number_of_assignments + assignment = getfield(operator,'assign',port_name) ; + for j = 1:length(assignment.state) + mttAssert(~isempty(assignment.state{j}),... + ['Missing covariable "',covariable,'" from "set" declaration in cr ',cr_name]) ; + end + end + + + for i = 1:length(operator.content) + operator.equation(i).chunk = {[]} ; +% operator.equation(i).was_generic = 1 ; +% operator.equation(i).domain = [] ; +% operator.equation(i).domain_item = [] ; +% operator.equation(i).is_effort = [] ; +% operator.equation(i).covariable = [] ; + + counter = 0 ; + + line = operator.content{i} ; + + if ~isempty(mttClipText(line)) + [var,loc] = mttFindEquationVariables(line) ; + + if loc(1)>1 + front = line(1:loc(1)-1) ; + counter = counter + 1 ; + operator.equation(i).chunk{counter} = front ; + end + + last = length(line) ; + + for j = 1:length(var) + [name,component] = mttCutText(var{j},'.') ; + + if isempty(component) + [name,attribute] = mttCutText(name,'''') ; + + numpar = strmatch(name,numparlist,'exact') ; + sympar = strmatch(name,symparlist,'exact') ; + variable = strmatch(name,varlist,'exact') ; + struct = strmatch(name,structlist,'exact') ; + input = strmatch(name,inputlist,'exact') ; + state = strmatch(name,statelist,'exact') ; + + ok = ~(isempty(numpar)&isempty(sympar)&isempty(variable)&isempty(struct)&isempty(input)&isempty(state)) ; + mttAssert(ok,['Variable ',var{j},' not recognised in cr ',cr_name]) ; + + is_numpar = ~isempty(numpar) ; + is_sympar = ~isempty(sympar) ; + is_var = ~isempty(variable) ; + is_struct = ~isempty(struct) ; + is_input = ~isempty(input) ; + is_state = ~isempty(state) ; + is_derivative = 0 ; + + if ~isempty(attribute) + mttAssert(strcmp(attribute,'dt'),... + ['Unrecognised attribute ',attribute,' in cr ',cr_name]) ; + mttAssert(is_state,... + ['Derivative of non-state variable in cr ',cr_name]) ; + is_state = 0 ; + is_derivative = 1 ; + end + + counter = counter + 1 ; + + if is_numpar + operator.equation(i).chunk{counter} = {'numpar',numpar} ; + end + + if is_sympar + operator.equation(i).chunk{counter} = {'sympar',sympar} ; + end + + if is_var + operator.equation(i).chunk{counter} = {'var',variable} ; + end + + if is_struct + operator.equation(i).chunk{counter} = {'struct',struct} ; + end + + if is_input + operator.equation(i).chunk{counter} = {'input',input} ; + end + + if is_state + operator.equation(i).chunk{counter} = {'state',state} ; + end + + if is_derivative + operator.equation(i).chunk{counter} = {'derivative',state} ; + end + + else + + if j==1 + port = strmatch(name,outlist,'exact') ; + + if ~isempty(ports_with_state_assignment) + mttAssert(~any(port==ports_with_state_assignment),... + ['Use "set" declaration to assign output port ',name,' to state in cr ',cr_name]) ; + end + + mttAssert(~isempty(port),... + ['Output port ',name,' not recognised in cr ',cr_name]) ; + mttAssert(outfree(port),... + ['Constrained port variable used in cr ',cr_name]) ; + + counter = counter + 1 ; + operator.equation(i).chunk{counter} = {'link',outlink(port),component} ; + else + port = strmatch(name,inlist,'exact') ; + mttAssert(~isempty(port),... + ['Input port ',name,' not recognised in cr ',cr_name]) ; + mttAssert(infree(port),... + ['Constrained port variable used in cr ',cr_name]) ; + + counter = counter + 1 ; + operator.equation(i).chunk{counter} = {'link',inlink(port),component} ; + end + + +% equation_domain = mttIdentifyUserDomain(mtt_environment,... +% operator.equation(i).domain,.... +% operator.equation(i).domain_item) ; + + covariable = component ; + port_name = name ; + port = getfield(cr.interface.port,port_name) ; + + if isempty(port.domain) + is_effort = strcmp(covariable,'effort') ; + is_flow = strcmp(covariable,'flow') ; + + mttAssert(is_effort|is_flow, ... + ['"',covariable,'" is not a generic covariable']) ; + +% mttAssert(isempty(operator.equation(i).domain),... +% ['Generic interface "',port_name,'" referenced in ',equation_domain,' equation']) ; + else + public_domain = mtt_environment.public_domain(port.domain) ; + actual_domain = getfield(public_domain,'item',port.domain_item) ; + + port_domain = mttIdentifyUserDomain(mtt_environment,port.domain,port.domain_item) ; + + is_effort = ismember(covariable,actual_domain.effort) ; + is_flow = ismember(covariable,actual_domain.flow) ; + + mttAssert(is_effort|is_flow, ... + ['"',covariable,'" is not a covariable defined in domain "',port_domain,'"']) ; + +% if isempty(equation_domain) +% operator.equation(i).was_generic = 0 ; +% operator.equation(i).domain = port.domain ; +% operator.equation(i).domain_item = port.domain_item ; + % operator.equation(i).covariable = covariable ; + % else + % mttAssert(covariable==operator.equation(i).covariable, ... + % ['Equation cannot combine different covariables: [',covariable,',',operator.equation(i).covariable,']') ; +% end + end + +% if isempty(operator.equation(i).is_effort) +% if is_effort +% operator.equation(i).is_effort = 1 ; +% else +% operator.equation(i).is_effort = 0 ; +% end +% else +% mttAssert(operator.equation(i).is_effort==is_effort,... +% ['Effort and flow covariables appear in equation: "',operator.content{i},'"']) ; +% end + end + + next = loc(j) + length(var{j}) ; + + if j1,... + ['Less than two interfaces at 0-junction ',here]) ; + + imposed_effort = [] ; + resultant_flow = [] ; + + for j = 1:number_of_interfaces + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + + if isempty(inbond) + bond(j) = outbond ; + orientation(j) = 0 ; + else + bond(j) = inbond ; + orientation(j) = 1 ; + end + + [effort,flow,unicausal] = mttGetBondCausality(model,bond(j)) ; + + if ~isempty(effort) + if effort==orientation(j) + mttAssert(isempty(imposed_effort),... + ['Over-determined effort at 0-junction ',here]) ; + imposed_effort = bond(j) ; + end + end + + if ~isempty(flow) + if flow==orientation(j) + mttAssert(isempty(resultant_flow),... + ['Over-determined flow at 0-junction ',here]) ; + resultant_flow = bond(j) ; + end + end + end + + for j = 1:number_of_interfaces + if ~isempty(imposed_effort) + if bond(j)~=imposed_effort + model = mttUpdateBondCausality(model,bond(j),~orientation(j),[],[]) ; + end + end + + if ~isempty(resultant_flow) + if bond(j)~=resultant_flow + model = mttUpdateBondCausality(model,bond(j),[],~orientation(j),[]) ; + end + end + end + + case '1', + mttAssert(number_of_interfaces>1,... + ['Less than two interfaces at 1-junction ',here]) ; + + imposed_flow = [] ; + resultant_effort = [] ; + + for j = 1:number_of_interfaces + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + + if isempty(inbond) + bond(j) = outbond ; + orientation(j) = 0 ; + else + bond(j) = inbond ; + orientation(j) = 1 ; + end + + [effort,flow,unicausal] = mttGetBondCausality(model,bond(j)) ; + + if ~isempty(effort) + if effort~=orientation(j) + mttAssert(isempty(resultant_effort),... + ['Over-determined effort at 1-junction ',here]) ; + resultant_effort = bond(j) ; + end + end + + if ~isempty(flow) + if flow~=orientation(j) + mttAssert(isempty(imposed_flow),... + ['Over-determined flow at 1-junction ',here]) ; + imposed_flow = bond(j) ; + end + end + end + + for j = 1:number_of_interfaces + if ~isempty(resultant_effort) + if bond(j)~=resultant_effort + model = mttUpdateBondCausality(model,bond(j),orientation(j),[],[]) ; + end + end + + if ~isempty(imposed_flow) + if bond(j)~=imposed_flow + model = mttUpdateBondCausality(model,bond(j),[],orientation(j),[]) ; + end + end + end + end + end + end + ADDED mttroot/ntt/bin/trans/m/mttPropagateDomains.m Index: mttroot/ntt/bin/trans/m/mttPropagateDomains.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttPropagateDomains.m @@ -0,0 +1,111 @@ +function model = mttPropagateDomains(model,branch) + is_root_model = (nargin==1) ; + + objects = mttGetFieldNames(model,'obj') ; + + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + if is_root_model + branch = mttDetachText(model.source,'/') ; + end + here = [branch,':',object_name] ; + + if ~isempty(object.abg) + + for j = 1:mttGetFieldLength(object,'interface') + port_name = object.interface(j).name ; + + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + inmap = object.interface(j).map.in ; + outmap = object.interface(j).map.out ; + + [inbond_domain,inbond_domain_item] = mttGetBondDomain(model,inbond) ; + [outbond_domain,outbond_domain_item] = mttGetBondDomain(model,outbond) ; + [inmap_domain,inmap_domain_item] = mttGetBondDomain(object,inmap) ; + [outmap_domain,outmap_domain_item] = mttGetBondDomain(object,outmap) ; + + [model,inbond_ok] = mttUpdateBondDomain(model,inbond,inmap_domain,inmap_domain_item) ; + [model,outbond_ok] = mttUpdateBondDomain(model,outbond,outmap_domain,outmap_domain_item) ; + [object,inmap_ok] = mttUpdateBondDomain(object,inmap,inbond_domain,inbond_domain_item) ; + [object,outmap_ok] = mttUpdateBondDomain(object,outmap,outbond_domain,outbond_domain_item) ; + + ok = inbond_ok & outbond_ok & inmap_ok & outmap_ok ; + mttAssert(ok,['Domain conflict at port "',port_name,'" in ',here]) ; + end + + if is_root_model + branch = object_name ; + else + branch = [branch,'/',object_name] ; + end + + object = mttPropagateDomains(object,branch) ; + model = setfield(model,'obj',object_name,object) ; + + elseif ~isempty(object.cr) + + interface = object.cr.interface ; + port_names = mttGetFieldNames(interface,'port') ; + + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(interface,'port',port_name) ; + + inbond = port.in ; + outbond = port.out ; + + [model,inbond_ok] = mttUpdateBondDomain(model,inbond,port.domain,port.domain_item) ; + [model,outbond_ok] = mttUpdateBondDomain(model,outbond,port.domain,port.domain_item) ; + + ok = inbond_ok & outbond_ok ; + mttAssert(ok,['Domain conflict at port "',port_name,'" in ',here]) ; + end + + else + + number_of_interfaces = mttGetFieldLength(object,'interface') ; + + switch object.class + case {'0','1'}, + index = 0 ; + finding_domain = 1 ; + + while finding_domain + index = index + 1 ; + + inbond = object.interface(index).in ; + outbond = object.interface(index).out ; + + if isempty(inbond) + bond_number = outbond ; + else + bond_number = inbond ; + end + + [existing_domain,existing_domain_item] = mttGetBondDomain(model,bond_number) ; + + found_domain = ~isempty(existing_domain) ; + finding_domain = ~found_domain & index0 + RHS.name{j} = [' + ',RHS.name{j}] ; + else + RHS.name{j} = [' - ',RHS.name{j}] ; + end + end + + case 'cell', + [name,covar] = mttCutText(namelist(var{1}).var,'.') ; + RHS.name{1} = name ; + + if strcmp(covar,'effort') | strcmp(covar,'effort_state') + RHS.is_effort = 1 ; + else + RHS.is_effort = 0 ; + end + end + + for k = 1:dimension + if LHS.is_effort + covar = covariables.effort{k} ; + else + covar = covariables.flow{k} ; + end + + content = [LHS.name,'.',strrep(covar,'.','__')] ; + indent = char(32*ones(1,length(content)+3)) ; + + for j = 1:length(RHS.name) + if RHS.is_effort(j) + covar = covariables.effort{k} ; + else + covar = covariables.flow{k} ; + end + + if j==1 + if strcmp(RHS.name{1},'0') + content = [content,' = ',RHS.name{1}] ; + else + content = [content,' = ',RHS.name{1},'.',strrep(covar,'.','__')] ; + end + else + content = [content,'\n',indent,RHS.name{j},'.',strrep(covar,'.','__')] ; + end + end + + content = [content,' ;'] ; + + if ~isempty(content) + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = content ; + end + end + + else + op = [sse(i).operator] ; + [cr,operator] = mttCutText(op,'___') ; + + if ~strcmp(eqn{eqn_counter},'') + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = [''] ; + end + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = ['// ',op] ; + + + [root,hierarchy] = mttCutText(cr,'__') ; + + level = length(findstr(cr,'__')) ; + for j = 1:level + [obj{j},hierarchy] = mttCutText(hierarchy,'__') ; + end + + object = getfield(model,'obj',obj{1}) ; + for j = 2:level + object = getfield(object,'obj',obj{j}) ; + end + + index = strmatch(operator,{object.cr.operator.name},'exact') ; + cr_definition = object.cr ; + operator_definition = cr_definition.operator(index) ; + + + + structlist = [] ; + if ~isempty(operator_definition.struct) + struct_names = mttGetFieldNames(operator_definition,'struct') ; + number_of_structs = length(struct_names) ; + for i = 1:number_of_structs + struct_name = struct_names{i} ; + variables = getfield(operator_definition,'struct',struct_name) ; + if i==1 + structlist = variables ; + else + structlist = [structlist,variables] ; + end + end + end + + + + + reassigned_state_list = [] ; + counter = 0 ; + + + port_names = mttGetFieldNames(cr_definition.interface,'port') ; + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(cr_definition,'interface','port',port_name) ; + + if ~isempty(port.assign) + assignment = port.assign ; + + + if port.was_generic & ~isempty(port.domain) + covar = mttGetCovariables(model.env,port.domain,port.domain_item) ; + if port.is_effort_state + covar = covariables.effort ; + else + covar = covariables.flow ; + end + + for k = 1:length(assignment.state) + counter = counter + 1 ; + reassigned_state_list.name{counter} = assignment.state{k} ; + reassigned_state_list.covar{counter} = covar ; + end + + + block_size = length(covar) ; + for var = 1:block_size + segment = [] ; + + for k = 1:length(assignment.state) + segment{1} = [cr,'___',port_name,'.',strrep(covar{var},'.','__')] ; + segment{2} = [' = '] ; + segment{3} = [cr,'___',assignment.state{k},'___',strrep(covar{var},'.','__'),'.state ;'] ; + + ini_counter = ini_counter + 1 ; + ini{ini_counter} = [segment{1},segment{2},segment{3}] ; + end + end + else + + for k = 1:length(assignment.state) + segment{1} = [cr,'___',port_name,'.',strrep(assignment.covar{k},'.','__')] ; + segment{2} = [' = '] ; + segment{3} = [cr,'___',assignment.state{k},'.state ;'] ; + + ini_counter = ini_counter + 1 ; + ini{ini_counter} = [segment{1},segment{2},segment{3}] ; + end + end + end + end + + + equations = operator_definition.equation ; + for j = 1:length(equations) + equation = equations(j) ; + number_of_chunks = mttGetFieldLength(equation,'chunk') ; + + equation.domain = [] ; + equation.domain_item = [] ; + + for k = 1:number_of_chunks + chunk = equation.chunk{k} ; + + switch class(chunk) + case 'cell' + type = chunk{1} ; + index = chunk{2} ; + + switch type + case 'link' + port_name = operator_definition.link(index).name ; + port = getfield(cr_definition,'interface','port',port_name) ; + + if port.was_generic & ~isempty(port.domain) + if isempty(equation.domain) + equation.domain = port.domain ; + equation.domain_item = port.domain_item ; + else + same_domain = equation.domain==port.domain ; + same_domain_item = strcmp(equation.domain_item,port.domain_item) ; + mttAssert(same_domain&same_domain_item,... + ['Attempt to overwrite implicit variables with conflicting domains in "',... + operator_definition.content{j},'"']) ; + end + end + end + end + end + + + covariables = mttGetCovariables(model.env,equation.domain,equation.domain_item) ; +% if equation.is_effort +% covar = covariables.effort ; +% else +% covar = covariables.flow ; +% end + + block_size = length(covariables.effort) ; + + + for line = 1:block_size + segment = [] ; + content = [] ; + + for k = 1:number_of_chunks + chunk = equation.chunk{k} ; + + switch class(chunk) + case 'cell' + type = chunk{1} ; + index = chunk{2} ; + + switch type + case 'link' + port_variable = [cr,'___',operator_definition.link(index).name] ; + + if strcmp(chunk{3},'generic___effort') + segment{k} = [port_variable,'.',strrep(covariables.effort{line},'.','__')] ; + elseif strcmp(chunk{3},'generic___flow') + segment{k} = [port_variable,'.',strrep(covariables.flow{line},'.','__')] ; + else + segment{k} = [port_variable,'.',strrep(chunk{3},'.','__')] ; + end + +% if length(chunk)>2 +% segment{k} = [port_variable,'.',strrep(chunk{3},'.','__')] ; +% else +% segment{k} = [port_variable,'.',strrep(covar{line},'.','__')] ; +% end + + case 'numpar' + segment{k} = [cr,'___',cr_definition.numpar{index}] ; + + case 'sympar' + parameter = [cr_definition.parameter{index}] ; + if isnumeric(parameter) + segment{k} = num2str(parameter) ; + else + segment{k} = [cr_definition.parameter{index}] ; + end + + case 'var' + segment{k} = [op,'___',operator_definition.var{index}] ; + + case 'struct' + segment{k} = [op,'___',structlist{index}] ; + + case 'input' + segment{k} = [cr,'___',cr_definition.input{index}] ; + + case 'state' + state = cr_definition.state{index} ; + if isempty(reassigned_state_list) + state_reassignment = [] ; + else + state_reassignment = strmatch(state,reassigned_state_list.name,'exact') ; + end + + if isempty(state_reassignment) + segment{k} = [cr,'___',state,'.state'] ; + else + state_covar = reassigned_state_list.covar{line} ; + segment{k} = [cr,'___',state,'___',state_covar{1},'.state'] ; + end + +% segment{k} = [cr,'___',cr_definition.state{index},'.state'] ; + + case 'derivative' + state = cr_definition.state{index} ; + if isempty(reassigned_state_list) + state_reassignment = [] ; + else + state_reassignment = strmatch(state,reassigned_state_list.name,'exact') ; + end + + if isempty(state_reassignment) + segment{k} = [cr,'___',state,'.derivative'] ; + else + state_covar = reassigned_state_list.covar{line} ; + segment{k} = [cr,'___',state,'___',state_covar{1},'.derivative'] ; + end + +% segment{k} = [cr,'___',cr_definition.state{index},'.derivative'] ; + + end + otherwise + chunk = strrep(chunk,':=','=') ; + segment{k} = chunk ; + end + end + + content = [tab,segment{1}] ; + for k = 2:length(segment) + content = [content,segment{k}] ; + end + content = [content,' ;'] ; + + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = content ; + end + end + + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = ['// End of ',op] ; + eqn_counter = eqn_counter + 1 ; + eqn{eqn_counter} = [''] ; + end + end + + eqn = eqn' ; + ini = ini' ; + + +function write_equations(eqn,ini,model) + filename = [model.source,'_include_ode.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + fprintf(fid,'\n\n') ; + + tab = char(32*ones(1,3)) ; + for i = 1:length(ini) + formatted_equation = [tab,ini{i},'\n'] ; + fprintf(fid,formatted_equation) ; + end + fprintf(fid,'\n') ; + for i = 1:length(eqn) + formatted_equation = [tab,eqn{i},'\n'] ; + fprintf(fid,formatted_equation) ; + end + + fclose(fid) ; + ADDED mttroot/ntt/bin/trans/m/mttWriteSystemInitialisation.m Index: mttroot/ntt/bin/trans/m/mttWriteSystemInitialisation.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttWriteSystemInitialisation.m @@ -0,0 +1,435 @@ +function mttWriteSystemInitialisation(model) + +assignment.numpar = assign_numerical_parameters(model) ; +assignment.sympar = assign_symbolic_parameters(model) ; +assignment.input = assign_input_variables(model) ; +assignment.invar = assign_input_covariables(model) ; +assignment.state = assign_state_variables(model) ; + +write_set_numpar(assignment,model) ; +write_set_input(assignment,model) ; +write_set_state(assignment,model) ; + + + +function code = assign_symbolic_parameters(model) + mttNotify('...assigning symbolic parameters') ; + mttWriteNewLine ; + + model_name = mttDetachText(model.source,'/') ; + + code = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'sympar') ; + + for i = 1:number_of_variables + variable_name = model.sympar{i} ; + default = model.sympar_default{i} ; + + if isempty(default) + line = line + 1 ; + code{line} = [model_name,'___',variable_name,' = 1.0 ;'] ; + else + line = line + 1 ; + code{line} = [model_name,'___',variable_name,' = ',default,' ;'] ; + end + end + + +function code = assign_numerical_parameters(model,root,branch) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...assigning numerical parameters') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + else + current_branch = branch ; + end + + code = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'numpar') ; + + for i = 1:number_of_variables + variable_name = model.numpar{i} ; + default = model.numpar_default{i} ; + + line = line + 1 ; + if isempty(default) + code{line} = [current_branch,'___',variable_name,' = 1.0 ;'] ; + else + code{line} = [current_branch,'___',variable_name,' = ',default,' ;'] ; + end + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_code = [] ; + if ~isempty(object.abg) + additional_code = assign_numerical_parameters(object,root,next_branch) ; + elseif ~isempty(object.cr) + additional_code = assign_numerical_parameters(object.cr,root,next_branch) ; + end + + if isempty(code) + code = additional_code ; + else + line = length(code) ; + for j = 1:length(additional_code) + if ~ismember(additional_code{j},code) + line = line + 1 ; + code{line} = additional_code{j} ; + end + end + end + end + + +function code = assign_input_variables(model,root,branch) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...assigning input variables') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + else + current_branch = branch ; + end + + code = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'input') ; + + for i = 1:number_of_variables + variable_name = model.input{i} ; + default = model.input_default{i} ; + + line = line + 1 ; + if isempty(default) + code{line} = [current_branch,'___',variable_name,' = 0.0 ;'] ; + else + code{line} = [current_branch,'___',variable_name,' = ',default,' ;'] ; + end + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_code = [] ; + if ~isempty(object.abg) + additional_code = assign_input_variables(object,root,next_branch) ; + elseif ~isempty(object.cr) + additional_code = assign_input_variables(object.cr,root,next_branch) ; + end + + if isempty(code) + code = additional_code ; + else + line = length(code) ; + for j = 1:length(additional_code) + if ~ismember(additional_code{j},code) + line = line + 1 ; + code{line} = additional_code{j} ; + end + end + end + end + + +function code = assign_input_covariables(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...assigning input covariables') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + code = [] ; + line = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if ~inbond.effort + if ~strcmp(object.class,'Df') + covar = covariables.effort ; + end + elseif inbond.flow + if ~strcmp(object.class,'De') + covar = covariables.flow ; + end + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + code{line} = [current_branch,'__',object_name,'.',covariable,' = 0.0 ;'] ; + end + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + + if outbond.effort + covar = covariables.effort ; + elseif ~outbond.flow + covar = covariables.flow ; + end + + for j = 1:length(covar) + line = line + 1 ; + covariable = strrep(covar{j},'.','__') ; + code{line} = [current_branch,'__',object_name,'.',covariable,' = 0.0 ;'] ; + end + end + end + + additional_code = [] ; + if ~isempty(object.abg) + additional_code = assign_input_covariables(object,root,next_branch,env) ; + end + + if isempty(code) + code = additional_code ; + else + line = length(code) ; + for j = 1:length(additional_code) + if ~ismember(additional_code{j},code) + line = line + 1 ; + code{line} = additional_code{j} ; + end + end + end + end + + +function code = assign_state_variables(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...assigning state variables') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + code = [] ; + line = 0 ; + + if isfield(model,'state') + assigned_states = [] ; + counter = 0 ; + + port_names = mttGetFieldNames(model.interface,'port') ; + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(model,'interface','port',port_name) ; + + if ~isempty(port.assign) + assignment = port.assign ; + + if port.was_generic & ~isempty(port.domain) + covariables = mttGetCovariables(env,port.domain,port.domain_item) ; + if port.is_effort_state + covar = covariables.effort ; + default = covariables.effort_default ; + else + covar = covariables.flow ; + default = covariables.flow_default ; + end + + block_size = length(covar) ; + for k = 1:length(assignment.state) + counter = counter + 1 ; + assigned_states{counter} = assignment.state{k} ; + + for var = 1:block_size + line = line + 1 ; + if isempty(default{var}) + code{line} = [current_branch,'___',assignment.state{k},'___',covar{var},'.state = 0.0 ;'] ; + else + code{line} = [current_branch,'___',assignment.state{k},'___',covar{var},'.state = ',default{var},' ;'] ; + end + end + end + end + end + end + + number_of_variables = mttGetFieldLength(model,'state') ; + + for i = 1:number_of_variables + variable_name = model.state{i} ; + default = model.state_default{i} ; + + if ~ismember(variable_name,assigned_states) + line = line + 1 ; + if isempty(default) + code{line} = [current_branch,'___',variable_name,'.state = 0.0 ;'] ; + else + code{line} = [current_branch,'___',variable_name,'.state = ',default,' ;'] ; + end + end + end + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_code = [] ; + if ~isempty(object.abg) + additional_code = assign_state_variables(object,root,next_branch,env) ; + elseif ~isempty(object.cr) + additional_code = assign_state_variables(object.cr,root,next_branch,env) ; + end + + if isempty(code) + code = additional_code ; + else + line = length(code) ; + for j = 1:length(additional_code) + if ~ismember(additional_code{j},code) + line = line + 1 ; + code{line} = additional_code{j} ; + end + end + end + end + + +function write_set_numpar(assignment,model) + filename = [model.source,'_include_set_numpar.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Numerical Parameters for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_assigned_list(fid,[],assignment.numpar,model_name) ; + + fclose(fid) ; + + +function write_set_input(assignment,model) + filename = [model.source,'_include_set_input.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Default Inputs for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_assigned_list(fid,'symbolic_parameters',assignment.sympar,model_name) ; + write_assigned_list(fid,'input_variables',assignment.input,model_name) ; + write_assigned_list(fid,'input_covariables',assignment.invar,model_name) ; + + fclose(fid) ; + + +function write_set_state(assignment,model) + filename = [model.source,'_include_set_state.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Initial states for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_assigned_list(fid,[],assignment.state,model_name) ; + + fclose(fid) ; + + +function write_assigned_list(fid,var_type,var_list,model_name) + if ~isempty(var_list) + if ~isempty(var_type) + fprintf(fid,'\n\n') ; + fprintf(fid,['// ',var_type]) ; + end + fprintf(fid,'\n') ; + + var_list = sort(var_list) ; + + width = 0 ; + for i = 1:length(var_list) + [left,right] = mttCutText(var_list{i},'=') ; + width = max(width,length(left)) ; + end + + tab = char(32*ones(1,3)) ; + for i = 1:length(var_list) + [left,right] = mttCutText(var_list{i},'=') ; + + nominal_width = width ; + actual_width = length(left) ; + + gap = nominal_width - actual_width ; + whitespace = char(32*ones(1,gap)) ; + + formatted_assignment = [tab,left,whitespace,' = ',right,'\n'] ; + fprintf(fid,formatted_assignment) ; + end + end ADDED mttroot/ntt/bin/trans/m/mttWriteSystemMapping.m Index: mttroot/ntt/bin/trans/m/mttWriteSystemMapping.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttWriteSystemMapping.m @@ -0,0 +1,528 @@ +function mttWriteSystemMapping(model) + +sympar = map_system_sympars(model) ; +input = map_system_inputs(model) ; +invar = map_system_invars(model) ; +outvar = map_system_outvars(model) ; +state = map_system_states(model) ; + +derivative = differentiate(state) ; + +mapping.input = invar ; +if ~isempty(input) + mapping.input = [mapping.input,input] ; +end +if ~isempty(sympar) + mapping.input = [mapping.input,sympar] ; +end + +mapping.output = outvar ; +mapping.state = state ; +mapping.derivative = derivative ; + +write_get_input(mapping,model) ; +write_get_state(mapping,model) ; + +write_put_input(mapping,model) ; +write_put_state(mapping,model) ; +write_put_output(mapping,model) ; +write_put_derivative(mapping,model) ; + + + +function map = map_system_sympars(model) + mttNotify('...mapping system inputs (symbolic parameters)') ; + mttWriteNewLine ; + + model_name = mttDetachText(model.source,'/') ; + + map = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'sympar') ; + + for i = 1:number_of_variables + variable_name = model.sympar{i} ; + default_value = model.sympar_default{i} ; + + if isempty(default_value) + line = line + 1 ; + map{line} = [model_name,'___',variable_name] ; + end + end + + +function map = map_system_inputs(model,root,branch) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system inputs (input variables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + number_of_variables = mttGetFieldLength(model,'input') ; + + for i = 1:number_of_variables + variable_name = model.input{i} ; + + line = line + 1 ; + map{line} = [current_branch,'___',variable_name] ; + end + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_inputs(object,root,next_branch) ; + elseif ~isempty(object.cr) + additional_map = map_system_inputs(object.cr,root,next_branch) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function map = map_system_invars(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system inputs (input covariables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if ~inbond.effort + if ~strcmp(object.class,'Df') + covar = covariables.effort ; + end + elseif inbond.flow + if ~strcmp(object.class,'De') + covar = covariables.flow ; + end + end + + for j = 1:length(covar) + line = line + 1 ; + map{line} = [current_branch,'__',object_name,'.',strrep(covar{j},'.','__')] ; + end + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + covar = [] ; + + if outbond.effort + covar = covariables.effort ; + elseif ~outbond.flow + covar = covariables.flow ; + end + + for j = 1:length(covar) + line = line + 1 ; + map{line} = [current_branch,'__',object_name,'.',strrep(covar{j},'.','__')] ; + end + end + end + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_invars(object,root,next_branch,env) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function map = map_system_outvars(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system outputs (output covariables)') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if inbond.effort + covar = covariables.effort ; + elseif ~inbond.flow + covar = covariables.flow ; + end + + for j = 1:length(covar) + line = line + 1 ; + map{line} = [current_branch,'__',object_name,'.',strrep(covar{j},'.','__')] ; + end + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + covar = [] ; + + if ~outbond.effort + if ~strcmp(object.class,'Sf') + covar = covariables.effort ; + end + elseif outbond.flow + if ~strcmp(object.class,'Se') + covar = covariables.flow ; + end + end + + for j = 1:length(covar) + line = line + 1 ; + map{line} = [current_branch,'__',object_name,'.',strrep(covar{j},'.','__')] ; + end + end + end + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_outvars(object,root,next_branch,env) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function map = map_system_states(model,root,branch,env) + is_root_model = nargin==1 ; + + if is_root_model + mttNotify('...mapping system states') ; + mttWriteNewLine ; + + root = model ; + current_branch = mttDetachText(model.source,'/') ; + env = model.env ; + else + current_branch = branch ; + end + + map = [] ; + line = 0 ; + + if isfield(model,'state') + assigned_states = [] ; + counter = 0 ; + + port_names = mttGetFieldNames(model.interface,'port') ; + for j = 1:length(port_names) + port_name = port_names{j} ; + port = getfield(model,'interface','port',port_name) ; + + if ~isempty(port.assign) + assignment = port.assign ; + + if port.was_generic & ~isempty(port.domain) + covariables = mttGetCovariables(env,port.domain,port.domain_item) ; + if port.is_effort_state + covar = covariables.effort ; + else + covar = covariables.flow ; + end + + block_size = length(covar) ; + for k = 1:length(assignment.state) + counter = counter + 1 ; + assigned_states{counter} = assignment.state{k} ; + + for var = 1:block_size + line = line + 1 ; + map{line} = [current_branch,'___',assignment.state{k},'___',covar{var},'.state'] ; + end + end + end + end + end + + number_of_variables = mttGetFieldLength(model,'state') ; + + for i = 1:number_of_variables + variable_name = model.state{i} ; + + if ~ismember(variable_name,assigned_states) + line = line + 1 ; + map{line} = [current_branch,'___',variable_name,'.state'] ; + end + end + end + + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + next_branch = [current_branch,'__',object_name] ; + + additional_map = [] ; + if ~isempty(object.abg) + additional_map = map_system_states(object,root,next_branch,env) ; + elseif ~isempty(object.cr) + additional_map = map_system_states(object.cr,root,next_branch,env) ; + end + + if isempty(map) + map = additional_map ; + else + line = length(map) ; + for j = 1:length(additional_map) + if ~ismember(additional_map{j},map) + line = line + 1 ; + map{line} = additional_map{j} ; + end + end + end + end + + +function derivative = differentiate(state) + mttNotify('...mapping system derivatives') ; + mttWriteNewLine ; + + for i = 1:length(state) + derivative{i} = strrep(state{i},'.state','.derivative') ; + end + + +function write_get_input(mapping,model) + filename = [model.source,'_include_get_input.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Input get-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttInput',mapping.input,model_name,1) ; + + fclose(fid) ; + + +function write_put_input(mapping,model) + filename = [model.source,'_include_put_input.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Input put-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttInput',mapping.input,model_name,0) ; + + fclose(fid) ; + + +function write_get_state(mapping,model) + filename = [model.source,'_include_get_state.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// State get-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttState',mapping.state,model_name,1) ; + + fclose(fid) ; + + +function write_put_state(mapping,model) + filename = [model.source,'_include_put_state.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// State put-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttState',mapping.state,model_name,0) ; + + fclose(fid) ; + + +function write_put_output(mapping,model) + filename = [model.source,'_include_put_output.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Output put-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttOutput',mapping.output,model_name,0) ; + + fclose(fid) ; + + +function write_put_derivative(mapping,model) + filename = [model.source,'_include_put_derivative.h'] ; + fid = fopen(filename,'w') ; + + mttNotify(['...creating ',filename]) ; + mttWriteNewLine ; + + fprintf(fid,['// Derivative put-mapping for Ordinary Differential Equations\n']) ; + fprintf(fid,'\n') ; + fprintf(fid,['// file: ',filename,'\n']) ; + fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; + + model_name = mttDetachText(model.source,'/') ; + + write_mapping(fid,'_mttDerivative',mapping.derivative,model_name,0) ; + + fclose(fid) ; + + +function write_mapping(fid,array_name,var_list,model_name,is_inward_mapping) + if ~isempty(var_list) + var_list = sort(var_list) ; + + width = 0 ; + for i = 1:length(var_list) + width = max(width,length(var_list{i})) ; + end + + tab = char(32*ones(1,3)) ; + + fprintf(fid,'\n') ; + for i = 1:length(var_list) + variable = var_list{i} ; + + if is_inward_mapping + nominal_width = width ; + actual_width = length(variable) ; + + gap = nominal_width - actual_width ; + whitespace = char(32*ones(1,gap)) ; + + formatted_mapping = [tab,variable,whitespace,' = ',array_name,'[',num2str(i-1),'] ;\n'] ; + else + formatted_mapping = [tab,array_name,'[',num2str(i-1),'] = ',variable,' ;\n'] ; + end + + fprintf(fid,formatted_mapping) ; + end + end ADDED mttroot/ntt/bin/trans/m/mttWriteSystemSfun.m Index: mttroot/ntt/bin/trans/m/mttWriteSystemSfun.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/m/mttWriteSystemSfun.m @@ -0,0 +1,250 @@ +function mttWriteSystemSfun(model) + +model_name = mttDetachText(model.source,'/') ; + +working_directory = pwd ; +working_directory = strrep(working_directory,'\','/') ; + +filename = [working_directory,'/',model_name,'_sfun.cpp'] ; +fid = fopen(filename,'w') ; + +mttNotify(['...creating ',filename]) ; +mttWriteNewLine ; + +model_name = mttDetachText(model.source,'/') ; + +fprintf(fid,['// Simulation Code for "',model_name,'"\n']) ; +fprintf(fid,'\n') ; +fprintf(fid,['// file: ',filename ,'\n']) ; +fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; +fprintf(fid,'\n') ; + +write_sfun(fid,model) ; + +fclose(fid) ; + + +function write_sfun(fid,model) + model_name = mttDetachText(model.source,'/') ; + counter = mttCountSystemMapping(model) ; + + fprintf(fid,['#define S_FUNCTION_NAME ',model_name,'_sfun' ,'\n']) ; + fprintf(fid,['#define S_FUNCTION_LEVEL 2' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_def.h"' ,'\n']) ; + + if isfield(model,'app') + if ~isempty(model.app) + fprintf(fid,['#include "',model_name,'_include_apps.h"' ,'\n']) ; + end + end + + fprintf(fid,['#include "simstruc.h"' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static double *_mttInput ;' ,'\n']) ; + fprintf(fid,['static double *_mttState ;' ,'\n']) ; + fprintf(fid,['static double *_mttDerivative ;' ,'\n']) ; + fprintf(fid,['static double *_mttOutput ;' ,'\n']) ; + fprintf(fid,['static double _mttTime ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static unsigned int _mttIndex ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['const int _mttNumInputs = ',num2str(counter.input),' ;' ,'\n']) ; + fprintf(fid,['const int _mttNumOutputs = ',num2str(counter.output),' ;' ,'\n']) ; + fprintf(fid,['const int _mttNumStates = ',num2str(counter.state),' ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + + fprintf(fid,['// system equations' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_set_numpar (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_set_numpar.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_set_input (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_set_input.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_set_state (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_set_state.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_get_input (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_get_input.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_get_state (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_get_state.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_put_state (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_put_state.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_put_derivative (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_put_derivative.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_put_output (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_put_output.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void ',model_name,'_ode (void) {' ,'\n']) ; + fprintf(fid,['#include "',model_name,'_include_ode.h"' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + + fprintf(fid,['// utility procedures' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static double *array_of_double (size_t n)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' void *p = calloc (n, sizeof (double)) ;' ,'\n']) ; + fprintf(fid,[' if (! p) fprintf (stderr, "*** ERROR: failed to allocate memory") ;','\n']) ; + fprintf(fid,[' return (double *) p ;' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void initialise_arrays (void)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' _mttInput = array_of_double(_mttNumInputs) ;' ,'\n']) ; + fprintf(fid,[' _mttOutput = array_of_double(_mttNumOutputs) ;' ,'\n']) ; + fprintf(fid,[' _mttState = array_of_double(_mttNumStates) ;' ,'\n']) ; + fprintf(fid,[' _mttDerivative = array_of_double(_mttNumStates) ;' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void check_finite(SimStruct *S, double *array, unsigned int index)','\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' const char *array_name ;' ,'\n']) ; + fprintf(fid,[' char warning[128] ;' ,'\n']) ; + fprintf(fid,[' if ((array[index] <= 0.0) || (array[index] >= 0.0)) {' ,'\n']) ; + fprintf(fid,[' ; // ...no problem' ,'\n']) ; + fprintf(fid,[' } else {' ,'\n']) ; + fprintf(fid,[' if (array == _mttInput) {' ,'\n']) ; + fprintf(fid,[' array_name = "_mttInput" ;' ,'\n']) ; + fprintf(fid,[' } else if (array == _mttState) {' ,'\n']) ; + fprintf(fid,[' array_name = "_mttState" ;' ,'\n']) ; + fprintf(fid,[' } else if (array == _mttOutput) {' ,'\n']) ; + fprintf(fid,[' array_name = "_mttOutput" ;' ,'\n']) ; + fprintf(fid,[' } else if (array == _mttDerivative) {' ,'\n']) ; + fprintf(fid,[' array_name = "_mttDerivative" ;' ,'\n']) ; + fprintf(fid,[' } else {' ,'\n']) ; + fprintf(fid,[' array_name = "unknown_array" ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,[' sprintf(warning,"(time %%f) Non-finite array element: %%s[%%d]",_mttTime,array_name,index) ;','\n']) ; + fprintf(fid,[' ssWarning(S,warning) ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + + fprintf(fid,['// S-function methods' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void mdlInitializeSizes(SimStruct *S)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' ssSetNumSFcnParams(S,0) ;' ,'\n']) ; + fprintf(fid,[' if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return ;','\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' ssSetNumContStates(S,_mttNumStates) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumDiscStates(S,0) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' if (!ssSetNumInputPorts(S,1)) return ;' ,'\n']) ; + fprintf(fid,[' ssSetInputPortWidth(S,0,_mttNumInputs) ;' ,'\n']) ; + fprintf(fid,[' ssSetInputPortDirectFeedThrough(S,0,1) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' if (!ssSetNumOutputPorts(S,1)) return ;' ,'\n']) ; + fprintf(fid,[' ssSetOutputPortWidth(S,0,_mttNumOutputs) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' ssSetNumSampleTimes(S,1) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumRWork(S,0) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumIWork(S,0) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumPWork(S,0) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumModes(S,0) ;' ,'\n']) ; + fprintf(fid,[' ssSetNumNonsampledZCs(S,0) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' ssSetOptions(S,SS_OPTION_EXCEPTION_FREE_CODE) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' initialise_arrays() ;' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void mdlInitializeSampleTimes(SimStruct *S)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' ssSetSampleTime(S,0,CONTINUOUS_SAMPLE_TIME) ;' ,'\n']) ; + fprintf(fid,[' ssSetOffsetTime(S,0,0.0) ;' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['#define MDL_INITIALIZE_CONDITIONS' ,'\n']) ; + fprintf(fid,['static void mdlInitializeConditions(SimStruct *S)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' ',model_name,'_set_numpar() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_set_state() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_put_state() ;' ,'\n']) ; + fprintf(fid,[' for (_mttIndex=0; _mttIndex<_mttNumStates; _mttIndex++) ssGetContStates(S)[_mttIndex] = _mttState[_mttIndex] ;','\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void mdlOutputs(SimStruct *S,int_T tid)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' UNUSED_ARG(tid) ;' ,'\n']) ; + fprintf(fid,[' for (_mttIndex=0; _mttIndex<_mttNumStates; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' _mttState[_mttIndex] = ssGetContStates(S)[_mttIndex] ;' ,'\n']) ; + fprintf(fid,[' check_finite(S,_mttState,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,[' for (_mttIndex=0; _mttIndex<_mttNumInputs; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' _mttInput[_mttIndex] = *ssGetInputPortRealSignalPtrs(S,0)[_mttIndex] ;','\n']) ; + fprintf(fid,[' check_finite(S,_mttInput,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,[' _mttTime = ssGetT(S) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' ',model_name,'_get_input() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_get_state() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_ode() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_put_output() ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' for(_mttIndex=0; _mttIndex<_mttNumOutputs; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' check_finite(S,_mttOutput,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' ssGetOutputPortRealSignal(S,0)[_mttIndex] = _mttOutput[_mttIndex] ;','\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['#define MDL_DERIVATIVES' ,'\n']) ; + fprintf(fid,['static void mdlDerivatives(SimStruct *S)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' for (_mttIndex=0; _mttIndex<_mttNumStates; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' _mttState[_mttIndex] = ssGetContStates(S)[_mttIndex] ;' ,'\n']) ; + fprintf(fid,[' check_finite(S,_mttState,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,[' for (_mttIndex=0; _mttIndex<_mttNumInputs; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' _mttInput[_mttIndex] = *ssGetInputPortRealSignalPtrs(S,0)[_mttIndex] ;','\n']) ; + fprintf(fid,[' check_finite(S,_mttInput,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,[' _mttTime = ssGetT(S) ;' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,[' ',model_name,'_get_input() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_get_state() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_ode() ;' ,'\n']) ; + fprintf(fid,[' ',model_name,'_put_derivative() ;' ,'\n']) ; + fprintf(fid,[' ' ,'\n']) ; + fprintf(fid,[' if (_mttTime==0)' ,'\n']) ; + fprintf(fid,[' for(_mttIndex=0; _mttIndex<_mttNumStates; _mttIndex++) ssGetdX(S)[_mttIndex] = 0.0 ;','\n']) ; + fprintf(fid,[' else' ,'\n']) ; + fprintf(fid,[' for(_mttIndex=0; _mttIndex<_mttNumStates; _mttIndex++) {' ,'\n']) ; + fprintf(fid,[' check_finite(S,_mttDerivative,_mttIndex) ;' ,'\n']) ; + fprintf(fid,[' ssGetdX(S)[_mttIndex] = _mttDerivative[_mttIndex] ;' ,'\n']) ; + fprintf(fid,[' }' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['static void mdlTerminate(SimStruct *S)' ,'\n']) ; + fprintf(fid,['{' ,'\n']) ; + fprintf(fid,[' UNUSED_ARG(S);' ,'\n']) ; + fprintf(fid,[' free (_mttInput) ;' ,'\n']) ; + fprintf(fid,[' free (_mttOutput) ;' ,'\n']) ; + fprintf(fid,[' free (_mttState) ;' ,'\n']) ; + fprintf(fid,[' free (_mttDerivative) ;' ,'\n']) ; + fprintf(fid,['}' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + fprintf(fid,['' ,'\n']) ; + + fprintf(fid,['#ifdef MATLAB_MEX_FILE' ,'\n']) ; + fprintf(fid,['#include "simulink.c"' ,'\n']) ; + fprintf(fid,['#else' ,'\n']) ; + fprintf(fid,['#include "cg_sfun.h"' ,'\n']) ; + fprintf(fid,['#endif' ,'\n']) ; ADDED mttroot/ntt/bin/trans/mttAppend.m Index: mttroot/ntt/bin/trans/mttAppend.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttAppend.m @@ -0,0 +1,11 @@ +function information = mttAppend(information,field,items) + if isfield(information,field) + previous = getfield(information,field) ; + if isempty(previous) + information = setfield(information,field,items) ; + else + information = setfield(information,field,[previous,items]) ; + end + else + information = setfield(information,field,items) ; + end ADDED mttroot/ntt/bin/trans/mttAppendFields.m Index: mttroot/ntt/bin/trans/mttAppendFields.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttAppendFields.m @@ -0,0 +1,11 @@ +function information = mttAppendFields(information,extra) + if isstruct(information) & isstruct(extra) + information_fields = fieldnames(information) ; + extra_fields = fieldnames(extra) ; + + for i = 1:length(extra_fields) + field_name = extra_fields{i} ; + extra_field = getfield(extra,field_name) ; + information = setfield(information,field_name,extra_field) ; + end + end ADDED mttroot/ntt/bin/trans/mttAssert.m Index: mttroot/ntt/bin/trans/mttAssert.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttAssert.m @@ -0,0 +1,7 @@ +function mttAssert(rule,msg) + if ~isempty(rule) + if ~rule + error(['MTT: ',msg]) ; + end + end + ADDED mttroot/ntt/bin/trans/mttAssign.m Index: mttroot/ntt/bin/trans/mttAssign.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttAssign.m @@ -0,0 +1,7 @@ +function [register,ok] = mttAssign(register,new_value) + if isempty(register) + register = new_value ; + ok = 1 ; + else + ok = register==new_value ; + end ADDED mttroot/ntt/bin/trans/mttCheckBondgraphDeclarations.m Index: mttroot/ntt/bin/trans/mttCheckBondgraphDeclarations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCheckBondgraphDeclarations.m @@ -0,0 +1,97 @@ +function mttCheckBondgraphDeclarations(model) + + for i = 1:length(model.sympar) + mttAssert(~ismember(model.sympar{i},model.numpar),... + ['Same name (',model.sympar{i},') used for "numpar" and "abg[...]" parameters']) ; + mttAssert(~ismember(model.sympar{i},model.input),... + ['Same name (',model.sympar{i},') used for "input" and "abg[...]" parameters']) ; + end + + for i = 1:length(model.numpar) + mttAssert(~ismember(model.numpar{i},model.input),... + ['Same name (',model.numpar{i},') used for "numpar" and "input" parameters']) ; + mttAssert(~ismember(model.numpar{i},model.sympar),... + ['Same name (',model.numpar{i},') used for "numpar" and "abg[...]" parameters']) ; + end + + for i = 1:length(model.input) + mttAssert(~ismember(model.input{i},model.sympar),... + ['Same name (',model.input{i},') used for "input" and "abg[...]" parameters']) ; + mttAssert(~ismember(model.input{i},model.numpar),... + ['Same name (',model.input{i},') used for "numpar" and "input" parameters']) ; + end + + all_parameters = [] ; + + if ~isempty(model.sympar) + all_parameters = model.sympar ; + end + if ~isempty(model.numpar) + if isempty(all_parameters) + all_parameters = model.numpar ; + else + all_parameters = [all_parameters, model.numpar] ; + end + end + if ~isempty(model.input) + if isempty(all_parameters) + all_parameters = model.input ; + else + all_parameters = [all_parameters, model.input] ; + end + end + + object_names = mttGetFieldNames(model,'obj') ; + + if ~isempty(all_parameters) + for i = 1:length(object_names) + object_name = object_names{i} ; + object = getfield(model,'obj',object_name) ; + + for j = 1:length(object.parameter) + object_parameter = object.parameter{j} ; + if ~isnumeric(object_parameter) + mttAssert(ismember(object_parameter,all_parameters),... + ['Object parameter "',object.parameter{j},'" not previously declared']) ; + end + end + end + + for j = 1:length(all_parameters) + current_parameter = all_parameters{j} ; + other_parameters = all_parameters ; + other_parameters(j) = [] ; + + mttAssert(~ismember(current_parameter,other_parameters),... + ['Repeated parameter/input name "',current_parameter,'"']) ; + end + end + + + counter = 0 ; + all_instance_parameters = [] ; + + for i = 1:length(object_names) + object_name = object_names{i} ; + object = getfield(model,'obj',object_name) ; + + for j = 1:length(object.parameter) + object_parameter = object.parameter{j} ; + if ~isnumeric(object_parameter) + counter = counter + 1 ; + all_instance_parameters{counter} = object_parameter ; + end + end + end + + for k = 1:length(all_parameters) + parameter = all_parameters{k} ; + if isempty(all_instance_parameters) + mttAssert(0,['Declared parameter/input "',parameter,'" not used']) ; + else + mttAssert(ismember(parameter,all_instance_parameters),... + ['Declared parameter/input "',parameter,'" not used']) ; + end + end + + ADDED mttroot/ntt/bin/trans/mttCheckInterfaceDeclarations.m Index: mttroot/ntt/bin/trans/mttCheckInterfaceDeclarations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCheckInterfaceDeclarations.m @@ -0,0 +1,69 @@ +function mttCheckInterfaceDeclarations(model) + + for i = 1:length(model.sympar) + mttAssert(~ismember(model.sympar{i},model.numpar),... + ['Same name (',model.sympar{i},') used for "numpar" and "abg[...]" parameters']) ; + mttAssert(~ismember(model.sympar{i},model.input),... + ['Same name (',model.sympar{i},') used for "input" and "abg[...]" parameters']) ; + end + + for i = 1:length(model.numpar) + mttAssert(~ismember(model.numpar{i},model.input),... + ['Same name (',model.numpar{i},') used for "numpar" and "input" parameters']) ; + mttAssert(~ismember(model.numpar{i},model.sympar),... + ['Same name (',model.numpar{i},') used for "numpar" and "abg[...]" parameters']) ; + end + + for i = 1:length(model.input) + mttAssert(~ismember(model.input{i},model.sympar),... + ['Same name (',model.input{i},') used for "input" and "abg[...]" parameters']) ; + mttAssert(~ismember(model.input{i},model.numpar),... + ['Same name (',model.input{i},') used for "numpar" and "input" parameters']) ; + end + + all_parameters = [] ; + + if ~isempty(model.sympar) + all_parameters = model.sympar ; + end + if ~isempty(model.numpar) + if isempty(all_parameters) + all_parameters = model.numpar ; + else + all_parameters = [all_parameters, model.numpar] ; + end + end + if ~isempty(model.input) + if isempty(all_parameters) + all_parameters = model.input ; + else + all_parameters = [all_parameters, model.input] ; + end + end + + object_names = mttGetFieldNames(model,'obj') ; + + if ~isempty(all_parameters) + for i = 1:length(object_names) + object_name = object_names{i} ; + object = getfield(model,'obj',object_name) ; + + for j = 1:length(object.parameter) + object_parameter = object.parameter{j} ; + if ~isnumeric(object_parameter) + mttAssert(ismember(object_parameter,all_parameters),... + ['Object parameter "',object.parameter{j},'" not previously declared']) ; + end + end + end + + for j = 1:length(all_parameters) + current_parameter = all_parameters{j} ; + other_parameters = all_parameters ; + other_parameters(j) = [] ; + + mttAssert(~ismember(current_parameter,other_parameters),... + ['Repeated parameter/input name "',current_parameter,'"']) ; + end + end + ADDED mttroot/ntt/bin/trans/mttCheckStateDeclarations.m Index: mttroot/ntt/bin/trans/mttCheckStateDeclarations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCheckStateDeclarations.m @@ -0,0 +1,57 @@ +function mttCheckStateDeclarations(model) + for i = 1:length(model.sympar) + mttAssert(~ismember(model.sympar{i},model.state),... + ['Same name (',model.sympar{i},') used for "state" and "abg[...]" parameters']) ; + end + + for i = 1:length(model.numpar) + mttAssert(~ismember(model.numpar{i},model.state),... + ['Same name (',model.numpar{i},') used for "numpar" and "state" parameters']) ; + end + + for i = 1:length(model.input) + mttAssert(~ismember(model.input{i},model.state),... + ['Same name (',model.input{i},') used for "input" and "state" parameters']) ; + end + + for i = 1:length(model.state) + mttAssert(~ismember(model.state{i},model.sympar),... + ['Same name (',model.state{i},') used for "state" and "abg[...]" parameters']) ; + mttAssert(~ismember(model.state{i},model.numpar),... + ['Same name (',model.state{i},') used for "state" and "numpar" parameters']) ; + mttAssert(~ismember(model.state{i},model.input),... + ['Same name (',model.state{i},') used for "state" and "input" parameters']) ; + end + + all_parameters = [] ; + + if ~isempty(model.sympar) + all_parameters = model.sympar ; + end + if ~isempty(model.numpar) + if isempty(all_parameters) + all_parameters = model.numpar ; + else + all_parameters = [all_parameters, model.numpar] ; + end + end + if ~isempty(model.input) + if isempty(all_parameters) + all_parameters = model.input ; + else + all_parameters = [all_parameters, model.input] ; + end + end + + for j = 1:length(all_parameters) + current_parameter = all_parameters{j} ; + mttAssert(~ismember(current_parameter,model.state),... + ['Repeated parameter/state name "',current_parameter,'"']) ; + end + + for j = 1:length(model.state) + current_state = model.state{j} ; + mttAssert(~ismember(current_state,all_parameters),... + ['Repeated parameter/state name "',current_state,'"']) ; + end + ADDED mttroot/ntt/bin/trans/mttClipText.m Index: mttroot/ntt/bin/trans/mttClipText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttClipText.m @@ -0,0 +1,8 @@ +function clipped_text = mttClipText(text) + if isempty(text) + clipped_text = [] ; + else + index = 1:length(text) ; + useful = index(~isspace(text)) ; + clipped_text = text(min(useful):max(useful)) ; + end ADDED mttroot/ntt/bin/trans/mttCompare.m Index: mttroot/ntt/bin/trans/mttCompare.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCompare.m @@ -0,0 +1,7 @@ +function comparison = mttCompare(left,right) + if isempty(left) | isempty(right) + comparison = [] ; + else + comparison = (left==right) ; + end + ADDED mttroot/ntt/bin/trans/mttCompareCausalCompletion.m Index: mttroot/ntt/bin/trans/mttCompareCausalCompletion.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCompareCausalCompletion.m @@ -0,0 +1,6 @@ +function is_stable = mttCompareCausalCompletion(current,previous) + is_stable_flow = current.flows==previous.flows ; + is_stable_effort = current.efforts==previous.efforts ; + is_stable = is_stable_flow & is_stable_effort ; + + ADDED mttroot/ntt/bin/trans/mttCompareDomainCompletion.m Index: mttroot/ntt/bin/trans/mttCompareDomainCompletion.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCompareDomainCompletion.m @@ -0,0 +1,3 @@ +function is_stable = mttCompareDomainCompletion(current,previous) + is_stable = current.assignments==previous.assignments ; + ADDED mttroot/ntt/bin/trans/mttCompressText.m Index: mttroot/ntt/bin/trans/mttCompressText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCompressText.m @@ -0,0 +1,6 @@ +function compressed_text = mttCompressText(text) + if isempty(text) + compressed_text = [] ; + else + compressed_text = text(~isspace(text)) ; + end ADDED mttroot/ntt/bin/trans/mttCountObjects.m Index: mttroot/ntt/bin/trans/mttCountObjects.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCountObjects.m @@ -0,0 +1,23 @@ +function model = mttCountObjects(model) + + object_names = mttGetFieldNames(model,'obj') ; + number_of_objects = length(object_names) ; + + model.count.obj = number_of_objects ; + model.count.cr = 0 ; + + for i = 1:number_of_objects + object_name = object_names{i} ; + object = getfield(model,'obj',object_name) ; + + if ~isempty(object.cr) + model.count.cr = model.count.cr + 1 ; + end + + if isfield(object,'obj') + next = mttCountObjects(object) ; + model.count.obj = model.count.obj + next.count.obj ; + model.count.cr = model.count.cr + next.count.cr ; + end + end + ADDED mttroot/ntt/bin/trans/mttCountSystemMapping.m Index: mttroot/ntt/bin/trans/mttCountSystemMapping.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCountSystemMapping.m @@ -0,0 +1,195 @@ +function counter = mttCountSystemMapping(model) + +sympars = count_system_sympars(model) ; +inputs = count_system_inputs(model) ; +invars = count_system_invars(model) ; +outvars = count_system_outvars(model) ; +states = count_system_states(model) ; + +counter.input = sympars + inputs + invars ; +counter.output = outvars ; +counter.state = states ; + + +function counter = count_system_sympars(model) + number_of_variables = mttGetFieldLength(model,'sympar') ; + counter = 0 ; + + for i = 1:number_of_variables + default_value = model.sympar_default{i} ; + if isempty(default_value) + counter = counter + 1 ; + end + end + + +function counter = count_system_inputs(model) + number_of_variables = mttGetFieldLength(model,'input') ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + additional_variables = 0 ; + if ~isempty(object.abg) + additional_variables = count_system_inputs(object) ; + elseif ~isempty(object.cr) + additional_variables = count_system_inputs(object.cr) ; + end + + number_of_variables = number_of_variables + additional_variables ; + end + + counter = number_of_variables ; + + +function counter = count_system_invars(model,root,env) + is_root_model = nargin==1 ; + + if is_root_model + root = model ; + env = model.env ; + end + + number_of_variables = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if ~inbond.effort + if ~strcmp(object.class,'Df') + covar = covariables.effort ; + end + elseif inbond.flow + if ~strcmp(object.class,'De') + covar = covariables.flow ; + end + end + + number_of_variables = number_of_variables + length(covar) ; + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + covar = [] ; + + if outbond.effort + covar = covariables.effort ; + elseif ~outbond.flow + covar = covariables.flow ; + end + + number_of_variables = number_of_variables + length(covar) ; + end + end + + additional_variables = 0 ; + if ~isempty(object.abg) + additional_variables = count_system_invars(object,root,env) ; + end + + number_of_variables = number_of_variables + additional_variables ; + end + + counter = number_of_variables ; + + +function counter = count_system_outvars(model,root,env) + is_root_model = nargin==1 ; + + if is_root_model + root = model ; + env = model.env ; + end + + number_of_variables = 0 ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + switch object.class + case {'SS','Se','Sf','De','Df'} + inbond_number = object.interface.in ; + outbond_number = object.interface.out ; + + inbond = model.bond(inbond_number) ; + outbond = model.bond(outbond_number) ; + + if ~isempty(inbond) + covariables = mttGetCovariables(env,inbond.domain,inbond.domain_item) ; + covar = [] ; + + if inbond.effort + covar = covariables.effort ; + elseif ~inbond.flow + covar = covariables.flow ; + end + + number_of_variables = number_of_variables + length(covar) ; + end + + if ~isempty(outbond) + covariables = mttGetCovariables(env,outbond.domain,outbond.domain_item) ; + covar = [] ; + + if ~outbond.effort + if ~strcmp(object.class,'Sf') + covar = covariables.effort ; + end + elseif outbond.flow + if ~strcmp(object.class,'Se') + covar = covariables.flow ; + end + end + + number_of_variables = number_of_variables + length(covar) ; + end + end + + additional_variables = 0 ; + if ~isempty(object.abg) + additional_variables = count_system_outvars(object,root,env) ; + end + + number_of_variables = number_of_variables + additional_variables ; + end + + counter = number_of_variables ; + + +function counter = count_system_states(model) + number_of_variables = mttGetFieldLength(model,'state') ; + + objects = mttGetFieldNames(model,'obj') ; + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + additional_variables = 0 ; + if ~isempty(object.abg) + additional_variables = count_system_states(object) ; + elseif ~isempty(object.cr) + additional_variables = count_system_states(object.cr) ; + end + + number_of_variables = number_of_variables + additional_variables ; + end + + counter = number_of_variables ; ADDED mttroot/ntt/bin/trans/mttCreateAlternativeEquations.m Index: mttroot/ntt/bin/trans/mttCreateAlternativeEquations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCreateAlternativeEquations.m @@ -0,0 +1,563 @@ +function ese = mttCreateAlternativeEquations(model) + +ese = write_equations(model) ; +ese = ese' ; + +filename = [model.source,'_ese.txt'] ; +fid = fopen(filename,'w') ; + +fprintf(fid,['// Elementary System Equations\n']) ; +fprintf(fid,'\n') ; +fprintf(fid,['// file: ',filename,'\n']) ; +fprintf(fid,['// written by MTT on ',datestr(now),'\n']) ; +fprintf(fid,'\n\n') ; + +fprintf(fid,['ese ',mttDetachText(model.source,'/'),' {']) ; +fprintf(fid,'\n') ; + +tab = char(32*ones(1,3)) ; + +for i = 1:length(ese) + fprintf(fid,[tab,ese{i},'\n']) ; +end + +fprintf(fid,'}') ; + +fclose(fid) ; + + + +function ese = write_equations(model,branch) + is_root_model = (nargin==1) ; + + if is_root_model + branch = mttDetachText(model.source,'/') ; + end + +% ese{1} = ' ' ; +% ese{2} = ['// ESE representation for module: ',branch] ; +% ese{3} = ' ' ; +% +% line = 3 ; + + line = 0 ; + + indent = char(32*ones(1,6)) ; + + + objects = mttGetFieldNames(model,'obj') ; + + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + here = [branch,':',object_name] ; + + switch object.class + case 'SS', + + for j = 1:mttGetFieldLength(object,'interface') + flow_equation = [] ; + effort_equation = [] ; + + port_name = object.interface(j).name ; + + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + + if ~isempty(inbond) + bond = model.bond(inbond) ; + + extern = [branch,'__',object_name,'___flow'] ; + intern = [branch,'___f[',num2str(inbond),']'] ; + if bond.flow + flow_equation = [intern,' = ',extern,' ;'] ; + else + flow_equation = [extern,' = ',intern,' ;'] ; + end + + extern = [branch,'__',object_name,'___effort'] ; + intern = [branch,'___e[',num2str(inbond),']'] ; + if bond.effort + effort_equation = [extern,' = ',intern,' ;'] ; + else + effort_equation = [intern,' = ',extern,' ;'] ; + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + + if ~isempty(outbond) + bond = model.bond(outbond) ; + + extern = [branch,'__',object_name,'___flow'] ; + intern = [branch,'___f[',num2str(outbond),']'] ; + if bond.flow + flow_equation = [extern,' = ',intern,' ;'] ; + else + flow_equation = [intern,' = ',extern,' ;'] ; + end + + extern = [branch,'__',object_name,'___effort'] ; + intern = [branch,'___e[',num2str(outbond),']'] ; + if bond.effort + effort_equation = [intern,' = ',extern,' ;'] ; + else + effort_equation = [extern,' = ',intern,' ;'] ; + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + end + + case '0', + + imposed_effort = [] ; + resultant_flow = [] ; + + for i = 1:mttGetFieldLength(object,'interface') + inbond = object.interface(i).in ; + outbond = object.interface(i).out ; + + if isempty(inbond) + bond_number(i) = outbond ; + orientation(i) = 0 ; + else + bond_number(i) = inbond ; + orientation(i) = 1 ; + end + + [effort(i),flow(i)] = mttGetBondCausality(model,bond_number(i)) ; + + if effort(i)==orientation(i) + imposed_effort_bond = bond_number(i) ; + imposed_effort = [branch,'___e[',num2str(imposed_effort_bond),']'] ; + end + if flow(i)==orientation(i) + resultant_flow_bond = bond_number(i) ; + resultant_flow = [branch,'___f[',num2str(resultant_flow_bond),']'] ; + end + end + + + for i = 1:mttGetFieldLength(object,'interface') + if bond_number(i)~=imposed_effort_bond + line = line + 1 ; + derived_effort = [branch,'___e[',num2str(bond_number(i)),']'] ; + ese{line} = [derived_effort,' = ',imposed_effort,' ;'] ; + end + end + + waiting = 1 ; + offset = char(32*ones(1,length(resultant_flow)+1)) ; + + for i = 1:mttGetFieldLength(object,'interface') + next_flow = [] ; + + if bond_number(i)~=resultant_flow_bond + next_flow = [branch,'___f[',num2str(bond_number(i)),']'] ; + line = line + 1 ; + + if waiting + if orientation(i) + ese{line} = [resultant_flow,' = ',next_flow] ; + else + ese{line} = [resultant_flow,' = -',next_flow] ; + end + waiting = 0 ; + else + if orientation(i) + ese{line} = [offset,'+ ',next_flow] ; + else + ese{line} = [offset,'- ',next_flow] ; + end + end + end + end + ese{line} = [ese{line},' ;'] ; + + case '1', + + imposed_flow = [] ; + resultant_effort = [] ; + + for i = 1:mttGetFieldLength(object,'interface') + inbond = object.interface(i).in ; + outbond = object.interface(i).out ; + + if isempty(inbond) + bond_number(i) = outbond ; + orientation(i) = 0 ; + else + bond_number(i) = inbond ; + orientation(i) = 1 ; + end + + [effort(i),flow(i)] = mttGetBondCausality(model,bond_number(i)) ; + + if flow(i)~=orientation(i) + imposed_flow_bond = bond_number(i) ; + imposed_flow = [branch,'___f[',num2str(imposed_flow_bond),']'] ; + end + if effort(i)~=orientation(i) + resultant_effort_bond = bond_number(i) ; + resultant_effort = [branch,'___e[',num2str(resultant_effort_bond),']'] ; + end + end + + + for i = 1:mttGetFieldLength(object,'interface') + if bond_number(i)~=imposed_flow_bond + line = line + 1 ; + derived_flow = [branch,'___f[',num2str(bond_number(i)),']'] ; + ese{line} = [derived_flow,' = ',imposed_flow,' ;'] ; + end + end + + waiting = 1 ; + offset = char(32*ones(1,length(resultant_effort)+1)) ; + + for i = 1:mttGetFieldLength(object,'interface') + next_effort = [] ; + + if bond_number(i)~=resultant_effort_bond + next_effort = [branch,'___e[',num2str(bond_number(i)),']'] ; + line = line + 1 ; + + if waiting + if orientation(i) + ese{line} = [resultant_effort,' = ',next_effort] ; + else + ese{line} = [resultant_effort,' = -',next_effort] ; + end + waiting = 0 ; + else + if orientation(i) + ese{line} = [offset,'+ ',next_effort] ; + else + ese{line} = [offset,'- ',next_effort] ; + end + end + end + end + ese{line} = [ese{line},' ;'] ; + + otherwise, + + if ~isempty(object.cr) + operators = object.cr.operator ; + interface = object.cr.interface ; + port_names = mttGetFieldNames(interface,'port') ; + + link_counter = 0 ; + + for i = 1:length(port_names) + port_name = port_names{i} ; + port = getfield(interface,'port',port_name) ; + terminal = [branch,'__',object_name,'___',port_name] ; + + inbond = port.in ; + outbond = port.out ; + + if ~isempty(inbond) + bond = model.bond(inbond) ; + + intern = [branch,'___f[',num2str(inbond),']'] ; + if bond.flow + link_counter = link_counter + 1 ; + link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ; + + if port.is_flow_state + flow_equation = [intern,' = ',terminal,'___flow_state ;'] ; + else + flow_equation = [intern,' = ',terminal,'___flow ;'] ; + end + else + link_counter = link_counter + 1 ; + link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ; + + if port.is_flow_state + flow_equation = [terminal,'___flow_state = ',intern,' ;'] ; + else + flow_equation = [terminal,'___flow = ',intern,' ;'] ; + end + end + + intern = [branch,'___e[',num2str(inbond),']'] ; + if bond.effort + link_counter = link_counter + 1 ; + link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ; + + if port.is_effort_state + effort_equation = [terminal,'___effort_state = ',intern,' ;'] ; + else + effort_equation = [terminal,'___effort = ',intern,' ;'] ; + end + else + link_counter = link_counter + 1 ; + link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ; + + if port.is_effort_state + effort_equation = [intern,' = ',terminal,'___effort_state ;'] ; + else + effort_equation = [intern,' = ',terminal,'___effort ;'] ; + end + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + + if ~isempty(outbond) + bond = model.bond(outbond) ; + + intern = [branch,'___f[',num2str(outbond),']'] ; + if bond.flow + link_counter = link_counter + 1 ; + link(link_counter) = create_link(1,0,1,port_name,port.is_flow_state) ; + + if port.is_flow_state + flow_equation = [terminal,'___flow_state = ',intern,' ;'] ; + else + flow_equation = [terminal,'___flow = ',intern,' ;'] ; + end + else + link_counter = link_counter + 1 ; + link(link_counter) = create_link(0,0,1,port_name,port.is_flow_state) ; + + if port.is_flow_state + flow_equation = [intern,' = ',terminal,'___flow_state ;'] ; + else + flow_equation = [intern,' = ',terminal,'___flow ;'] ; + end + end + + intern = [branch,'___e[',num2str(outbond),']'] ; + if bond.effort + link_counter = link_counter + 1 ; + link(link_counter) = create_link(0,1,0,port_name,port.is_effort_state) ; + + if port.is_effort_state + effort_equation = [intern,' = ',terminal,'___effort_state ;'] ; + else + effort_equation = [intern,' = ',terminal,'___effort ;'] ; + end + else + link_counter = link_counter + 1 ; + link(link_counter) = create_link(1,1,0,port_name,port.is_effort_state) ; + + if port.is_effort_state + effort_equation = [terminal,'___effort_state = ',intern,' ;'] ; + else + effort_equation = [terminal,'___effort = ',intern,' ;'] ; + end + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + end + + number_of_operators = length(operators) ; + op_counter = 1 ; + + matching = 1 ; + while matching + operator = operators(op_counter) ; + + links = length(link) ; + op_links = length(operator.link) ; + op_linked = zeros(op_links,1) ; + + for j = 1:op_links + for k = 1:links + if compare_links(link(k),operator.link(j)) + op_linked(j) = k ; + break ; + end + end + end + + input_counter = 0 ; + output_counter = 0 ; + input = [] ; + output = [] ; + + if all(op_linked) + for j = 1:op_links + current_link = link(op_linked(j)) ; + port_name = current_link.name ; + + if current_link.is_effort + if current_link.is_state + link_name = [branch,'__',object_name,'___',port_name,'___effort_state'] ; + else + link_name = [branch,'__',object_name,'___',port_name,'___effort'] ; + end + end + if current_link.is_flow + if current_link.is_state + link_name = [branch,'__',object_name,'___',port_name,'___flow_state'] ; + else + link_name = [branch,'__',object_name,'___',port_name,'___flow'] ; + end + end + if current_link.is_input + input_counter = input_counter + 1 ; + input{input_counter} = link_name ; + else + output_counter = output_counter + 1 ; + output{output_counter} = link_name ; + end + end + + if input_counter>0 + input_list = ['[',input{1}] ; + for j = 2:input_counter + input_list = [input_list,',',input{j}] ; + end + input_list = [input_list,']'] ; + end + + if output_counter>0 + output_list = ['[',output{1}] ; + for j = 2:output_counter + output_list = [output_list,',',output{j}] ; + end + output_list = [output_list,']'] ; + end + + if input_counter>0 + line = line + 1 ; + ese{line} = [output_list,' = '] ; + end + + line = line + 1 ; + ese{line} = [indent,branch,'__',object_name,'___',operator.name] ; + + if output_counter>0 + line = line + 1 ; + ese{line} = [indent,indent,input_list,' ;'] ; + end + + link(op_linked) = [] ; + end + + op_counter = op_counter + 1 ; + matching = ~isempty(link) & (op_counter<=number_of_operators) ; + end + + mttAssert(isempty(link),... + ['Unattached ports in "cr" implementation in ',here]) ; + end + end + end + + for i = 1:length(objects) + object_name = objects{i} ; + object = getfield(model,'obj',object_name) ; + + here = [branch,':',object_name] ; + + if ~isempty(object.abg) + for j = 1:mttGetFieldLength(object,'interface') + inbond = object.interface(j).in ; + outbond = object.interface(j).out ; + inmap = object.interface(j).map.in ; + outmap = object.interface(j).map.out ; + + line = line + 1 ; + ese{line} = ' ' ; + + if ~isempty(inbond) + bond = model.bond(inbond) ; + + extern = [branch,'__',object_name,'___f[',num2str(inmap),']'] ; + intern = [branch,'___f[',num2str(inbond),']'] ; + if bond.flow + flow_equation = [intern,' = ',extern,' ;'] ; + else + flow_equation = [extern,' = ',intern,' ;'] ; + end + + extern = [branch,'__',object_name,'___e[',num2str(inmap),']'] ; + intern = [branch,'___e[',num2str(inbond),']'] ; + if bond.effort + effort_equation = [extern,' = ',intern,' ;'] ; + else + effort_equation = [intern,' = ',extern,' ;'] ; + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + + if ~isempty(outbond) + bond = model.bond(outbond) ; + + extern = [branch,'__',object_name,'___f[',num2str(outmap),']'] ; + intern = [branch,'___f[',num2str(outbond),']'] ; + if bond.flow + flow_equation = [extern,' = ',intern,' ;'] ; + else + flow_equation = [intern,' = ',extern,' ;'] ; + end + + extern = [branch,'__',object_name,'___e[',num2str(outmap),']'] ; + intern = [branch,'___e[',num2str(outbond),']'] ; + if bond.effort + effort_equation = [intern,' = ',extern,' ;'] ; + else + effort_equation = [extern,' = ',intern,' ;'] ; + end + + line = line + 1 ; + ese{line} = flow_equation ; + + line = line + 1 ; + ese{line} = effort_equation ; + end + end + next_branch = [branch,'__',object_name] ; + + object_ese = write_equations(object,next_branch) ; + + ese = [ese, object_ese] ; + line = length(ese) ; + end + end + + +function link = create_link(is_input,is_effort,is_flow,name,is_state) + link.is_input = is_input ; + link.is_effort = is_effort ; + link.is_flow = is_flow ; + link.name = name ; + link.is_state = is_state ; + +function boolean = compare_links(actual_link,op_link) + input_is_same = actual_link.is_input==op_link.is_input ; + effort_is_same = actual_link.is_effort==op_link.is_effort ; + flow_is_same = actual_link.is_flow==op_link.is_flow ; + name_is_same = strcmp(actual_link.name,op_link.name) ; + + boolean = input_is_same & effort_is_same & flow_is_same & name_is_same ; + + ADDED mttroot/ntt/bin/trans/mttCutText.m Index: mttroot/ntt/bin/trans/mttCutText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttCutText.m @@ -0,0 +1,14 @@ +function [left,right] = mttCutText(text,delimiter) + if isempty(text) + left = [] ; + right = [] ; + else + where = min(findstr(text,delimiter)) ; + if isempty(where) + left = mttClipText(text) ; + right = [] ; + else + left = mttClipText(text(1:where-1)) ; + right = mttClipText(text(where+length(delimiter):length(text))) ; + end + end ADDED mttroot/ntt/bin/trans/mttDeleteField.m Index: mttroot/ntt/bin/trans/mttDeleteField.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttDeleteField.m @@ -0,0 +1,6 @@ +function model = mttDeleteField(structure,field_name) + if isfield(structure,field_name) + model = rmfield(structure,field_name) ; + else + model = structure ; + end ADDED mttroot/ntt/bin/trans/mttDetachText.m Index: mttroot/ntt/bin/trans/mttDetachText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttDetachText.m @@ -0,0 +1,14 @@ +function [detached_text,preceding_text] = mttDetachText(text,delimiter) + if isempty(text) + detached_text = [] ; + preceding_text = [] ; + else + where = max(findstr(text,delimiter)) ; + if isempty(where) + detached_text = [] ; + preceding_text = mttClipText(text) ; + else + detached_text = mttClipText(text(where+length(delimiter):length(text))) ; + preceding_text = mttClipText(text(1:where-1)) ; + end + end ADDED mttroot/ntt/bin/trans/mttElapseTime.m Index: mttroot/ntt/bin/trans/mttElapseTime.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttElapseTime.m @@ -0,0 +1,4 @@ +function elapsed_time = mttElapseTime(t0) + current_time = mttGetTime ; + elapsed_time.cpu = current_time.cpu - t0.cpu ; + elapsed_time.clock = etime(current_time.clock,t0.clock) ; ADDED mttroot/ntt/bin/trans/mttExtractStatements.m Index: mttroot/ntt/bin/trans/mttExtractStatements.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttExtractStatements.m @@ -0,0 +1,55 @@ +function statements = mttExtractStatements(content) + input = 1 ; + output = 0 ; + line = [] ; + + searching = 0 ; + processing = 1 ; + while processing + line = [line,content{input}] ; + line = mttCutText(line,'//') ; + + if ~isempty(line) + semicolon = findstr(line,';') ; + leftbrace = findstr(line,'{') ; + rightbrace = findstr(line,'}') ; + terminator = sort([semicolon,leftbrace,rightbrace]) ; + + if isempty(terminator) + searching = 1 ; + else + first = 1 ; + N = length(terminator) ; + L = length(line) ; + + for i = 1:N + last = terminator(i) - 1 ; + if first<=last + output = output + 1 ; + statements{output} = mttClipText(line(first:last)) ; + end + + if ismember(line(terminator(i)),{'{','}'}) + output = output + 1 ; + statements{output} = line(terminator(i)) ; + end + first = last + 2 ; + end + + if terminator(N)==L + line = [] ; + searching = 0 ; + else + line = mttClipText(line(terminator(N):L)) ; + end + end + end + input = input + 1 ; + processing = input<=length(content) ; + + if searching + mttAssert(input<=length(content),... + 'End of file found with an incomplete statement') ; + end + end + ADDED mttroot/ntt/bin/trans/mttExtractText.m Index: mttroot/ntt/bin/trans/mttExtractText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttExtractText.m @@ -0,0 +1,13 @@ +function extracted_text = mttExtractText(text,left,right) + if isempty(text) + extracted_text = [] ; + else + where_left = min(findstr(text,left)) ; + where_right = min(findstr(text,right)) ; + + if ~isempty(where_left) & ~isempty(where_right) + extracted_text = mttClipText(text(where_left+length(left):where_right-1)) ; + else + extracted_text = [] ; + end + end ADDED mttroot/ntt/bin/trans/mttFileExists.m Index: mttroot/ntt/bin/trans/mttFileExists.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttFileExists.m @@ -0,0 +1,4 @@ +function boolean = mttFileExists(filename) + + boolean = exist(filename)==2 ; + ADDED mttroot/ntt/bin/trans/mttFindEquationVariables.m Index: mttroot/ntt/bin/trans/mttFindEquationVariables.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttFindEquationVariables.m @@ -0,0 +1,67 @@ +function [varlist,location] = mttFindEquationVariables(line) + line = mttClipText(line) ; + + if isempty(line) + namelist = [] ; + location = [] ; + else + numbers = (line>=48 & line<=57) ; + letters = (line>=65 & line<=90)|(line>=97 & line<=122) ; + underscores = (line==95) ; + dots = (line==46) ; + apostrophes = (line==39) ; + + mask = (numbers|letters|underscores|dots|apostrophes) ; + + buffer = line ; + buffer(~mask) = char(32*ones(1,sum(~mask))) ; + + next = 1 ; + last = length(buffer) ; + + counter = 0 ; + + finding = any(mask) ; + while finding + i = min(find(~isspace(buffer(next:last))))+next-1 ; + + if isempty(i) + finding = 0 ; + else + if i>last + finding = 0 ; + else + if i==last + j = last ; + else + j = min(find(isspace(buffer(i+1:last))))+i ; + + if isempty(j) + j = last ; + else + j = j - 1 ; + end + end + + if ~mttIsNumericText(buffer(i:j)) + var_found = 1 ; + + if j %i bonds are unicausal\n'],... + model.causal_completion.unicausal) ; + end ADDED mttroot/ntt/bin/trans/mttNotifyDomainCompletion.m Index: mttroot/ntt/bin/trans/mttNotifyDomainCompletion.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyDomainCompletion.m @@ -0,0 +1,6 @@ +function mttNotifyDomainCompletion(model) + + domain = floor(100*model.domain_completion.assignments/model.domain_completion.bonds) ; + + fprintf([' ...domain allocation is %i%% complete [%i/%i]\n'],... + domain,model.domain_completion.assignments,model.domain_completion.bonds) ; ADDED mttroot/ntt/bin/trans/mttNotifyEquationSort.m Index: mttroot/ntt/bin/trans/mttNotifyEquationSort.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyEquationSort.m @@ -0,0 +1,23 @@ +function is_complete = mttNotifyEquationSort(sort_iteration,... + number_of_unsorted_equations,number_of_equations,... + number_of_known_covariables,number_of_covariables,... + number_of_known_interface_variables,number_of_interface_variables) ; + +% number_of_known_covariables = number_of_known_covariables - 1 ; + number_of_known_interface_variables = number_of_known_interface_variables - 1 ; + + number_of_sorted_equations = number_of_equations - number_of_unsorted_equations ; + + sorted = floor(100*number_of_sorted_equations/number_of_equations) ; + covar = floor(100*number_of_known_covariables/number_of_covariables) ; + interface_var = floor(100*number_of_known_interface_variables/number_of_interface_variables) ; + + fprintf([' ...%i%% complete [%i/%i]\n'],... + sorted,number_of_sorted_equations,number_of_equations) ; + fprintf([' matching %i%% co_variables [%i/%i] and'],... + covar,number_of_known_covariables,number_of_covariables) ; + fprintf([' %i%% interface_variables [%i/%i]\n'],... + interface_var,number_of_known_interface_variables,number_of_interface_variables) ; + + is_complete = (sorted==100) & (covar==100) & (interface_var==100) ; + ADDED mttroot/ntt/bin/trans/mttNotifyEquationSortProblems.m Index: mttroot/ntt/bin/trans/mttNotifyEquationSortProblems.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyEquationSortProblems.m @@ -0,0 +1,7 @@ +function mttNotifyEquationSortProblems(name_known,namelist) + fprintf(' ...undetermined interface_variables are:\n') ; + for i = 2:length(namelist) + if ~name_known(i) + fprintf([' ',namelist{i},'\n']) ; + end + end ADDED mttroot/ntt/bin/trans/mttNotifyEquationSummary.m Index: mttroot/ntt/bin/trans/mttNotifyEquationSummary.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyEquationSummary.m @@ -0,0 +1,7 @@ +function mttNotifyEquationSummary(number_of_equations,number_of_covariables,number_of_interface_variables) + mttNotify([' ...model has ',num2str(number_of_equations),' equations']) ; + mttWriteNewLine ; + mttNotify([' with ',num2str(number_of_covariables),' co_variables']) ; + mttNotify([' and ',num2str(number_of_interface_variables),' interface_variables']) ; + mttWriteNewLine ; + ADDED mttroot/ntt/bin/trans/mttNotifyNumberOfBonds.m Index: mttroot/ntt/bin/trans/mttNotifyNumberOfBonds.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyNumberOfBonds.m @@ -0,0 +1,4 @@ +function mttNotifyOfBonds(model) + + number_of_bonds = model.causal_completion.bonds ; + fprintf(' ...model has %i bonds',number_of_bonds) ; ADDED mttroot/ntt/bin/trans/mttNotifyNumberOfObjects.m Index: mttroot/ntt/bin/trans/mttNotifyNumberOfObjects.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttNotifyNumberOfObjects.m @@ -0,0 +1,5 @@ +function mttNotifyOfObjects(model) + + number_of_objects = model.count.obj ; + number_of_crs = model.count.cr ; + fprintf(' ...model has %i active objects (%i implemented by CRs)',number_of_objects,number_of_crs) ; ADDED mttroot/ntt/bin/trans/mttReadFile.m Index: mttroot/ntt/bin/trans/mttReadFile.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttReadFile.m @@ -0,0 +1,23 @@ +function content = mttReadFile(filename) + +file_exists = exist(filename)==2 ; +if file_exists + fid = fopen(filename,'r') ; + reading = 1 ; + + counter = 0 ; + while reading + line = fgetl(fid) ; + if ~isempty(line) + if line==-1 + reading = 0 ; + else + counter = counter + 1 ; + content{counter} = line ; + end + end + end + fclose(fid) ; +else + error(['file_not_found[',filename,']']) +end ADDED mttroot/ntt/bin/trans/mttSeparateText.m Index: mttroot/ntt/bin/trans/mttSeparateText.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttSeparateText.m @@ -0,0 +1,14 @@ +function [left,right] = mttSeparateText(text) + if isempty(text) + left = [] ; + right = [] ; + else + whitespace = min(find(isspace(text))) ; + if isempty(whitespace) + left = text ; + right = [] ; + else + left = text(1:whitespace-1) ; + right = mttClipText(text(whitespace+1:length(text))) ; + end + end ADDED mttroot/ntt/bin/trans/mttSetFieldDefault.m Index: mttroot/ntt/bin/trans/mttSetFieldDefault.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttSetFieldDefault.m @@ -0,0 +1,11 @@ +function structure = mttSetFieldDefault(structure,component,value) + undefined = 0 ; + if isfield(structure,component) + undefined = isempty(getfield(structure,component)) ; + else + undefined = 1 ; + end + + if undefined + structure = setfield(structure,component,value) ; + end ADDED mttroot/ntt/bin/trans/mttUpdateBondCausality.m Index: mttroot/ntt/bin/trans/mttUpdateBondCausality.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttUpdateBondCausality.m @@ -0,0 +1,63 @@ +%function [model,bond_not_failed,diagnostic] = mttUpdateBondCausality(... +% model,bond_number,effort_causality,flow_causality,uni_causality) +function [model,bond_not_failed] = mttUpdateBondCausality(... + model,bond_number,effort_causality,flow_causality,uni_causality) + + if isempty(bond_number) + bond_not_failed = 1 ; +% diagnostic = [] ; + else + [model.bond(bond_number).effort,effort_ok] = ... + update_causality(model.bond(bond_number).effort,effort_causality) ; + [model.bond(bond_number).flow,flow_ok] = ... + update_causality(model.bond(bond_number).flow,flow_causality) ; + [model.bond(bond_number).unicausal,unicausal_ok] = ... + update_causality(model.bond(bond_number).unicausal,uni_causality) ; + + [model.bond(bond_number),unicausal_checked] = ... + check_unicausal(model.bond(bond_number)) ; + + bond_not_failed = effort_ok & flow_ok & unicausal_ok & unicausal_checked ; +% diagnostic = [effort_ok,flow_ok,unicausal_ok,unicausal_checked] ; + end + + +function [value,ok] = update_causality(value,new_value) + ok = 1 ; + + if ~isempty(new_value) + if isempty(value) + value = new_value ; + else + ok = value==new_value ; + end + end + +function [bond,ok] = check_unicausal(bond) + unicausal_defined = ~isempty(bond.unicausal) ; + effort_defined = ~isempty(bond.effort) ; + flow_defined = ~isempty(bond.flow) ; + + ok = 1 ; + + if unicausal_defined + switch bond.unicausal + case 0, + if effort_defined & flow_defined + ok = bond.effort==~bond.flow ; + elseif effort_defined & ~flow_defined + bond.flow = ~bond.effort ; + elseif flow_defined & ~effort_defined + bond.effort = ~bond.flow ; + end + case 1, + if effort_defined & flow_defined + ok = bond.effort==bond.flow ; + elseif effort_defined & ~flow_defined + bond.flow = bond.effort ; + elseif flow_defined & ~effort_defined + bond.effort = bond.flow ; + end + end + end + ADDED mttroot/ntt/bin/trans/mttUpdateBondDomain.m Index: mttroot/ntt/bin/trans/mttUpdateBondDomain.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttUpdateBondDomain.m @@ -0,0 +1,41 @@ +function [model,bond_not_failed] = mttUpdateBondDomain(... + model,bond_number,imposed_domain,imposed_domain_item) + + if isempty(bond_number) + bond_not_failed = 1 ; + else + [model.bond(bond_number).domain,domain_ok] = ... + update_domain(model.bond(bond_number).domain,imposed_domain) ; + if domain_ok + [model.bond(bond_number).domain_item,domain_item_ok] = ... + update_domain_item(model.bond(bond_number).domain_item,imposed_domain_item) ; + else + domain_item_ok = 0 ; + end + + bond_not_failed = domain_ok & domain_item_ok ; + end + + +function [value,ok] = update_domain(value,new_value) + ok = 1 ; + + if ~isempty(new_value) + if isempty(value) + value = new_value ; + else + ok = value==new_value ; + end + end + +function [value,ok] = update_domain_item(value,new_value) + ok = 1 ; + + if ~isempty(new_value) + if isempty(value) + value = new_value ; + else + ok = strcmp(value,new_value) ; + end + end + ADDED mttroot/ntt/bin/trans/mttValidateName.m Index: mttroot/ntt/bin/trans/mttValidateName.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttValidateName.m @@ -0,0 +1,18 @@ +function mttValidateName(name) + mttAssert(~isempty(name),'Empty name') ; + + numbers = (name>=48 & name<=57) ; + letters = (name>=65 & name<=90)|(name>=97 & name<=122) ; + underscores = (name==95) ; + + is_alphanumeric = all(numbers|letters|underscores) ; + starts_with_letter = isletter(name(1)) ; + + valid_name = is_alphanumeric & starts_with_letter ; +% mtt_prefix = strncmp(name,'mtt_',4) ; + mtt_delimiter = ~isempty(findstr(name,'__')) ; + +% mttAssert(~mtt_prefix,['"',name,'" must not contain "mtt_" prefix']) ; + mttAssert(~mtt_delimiter,['"',name,'" must not contain contiguous "_" delimiters']) ; + mttAssert(valid_name,['"',name,'" is not a valid name']) ; + mttAssert(length(name)<32,['"',name,'" must be shortened to less than 32 characters']) ; ADDED mttroot/ntt/bin/trans/mttVerifyAlternativeEquations.m Index: mttroot/ntt/bin/trans/mttVerifyAlternativeEquations.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttVerifyAlternativeEquations.m @@ -0,0 +1,41 @@ +function delta = mttVerifyEquations(primary,secondary) + searching = 1 ; + + length_primary = length(primary) ; + length_secondary = length(secondary) ; + + i = 1 ; + j = 1 ; + k = 1 ; + fprintf('k=%i: i=%i j=%i L=%i\n',k,i,j,length_secondary) ; + + while searching + k = k + 1 ; + if strcmp(primary(i),secondary(j)) + secondary(j) = [] ; + length_secondary = length_secondary - 1 ; + fprintf('k=%i: i=%i j=%i L=%i\n',k,i,j,length_secondary) ; + + i = i + 1; + j = 1 ; + else + j = j + 1 ; + end + + if length_secondary<1 + searching = 0 ; + elseif j>length_secondary + i = i + 1 ; + j = 1 ; + end + + if i>length_primary + searching = 0 ; + end + end + + delta = secondary ; + + fprintf('Verification complete after %i iterations\n',k) ; + fprintf('...%i new records found\n',length(delta)) ; + ADDED mttroot/ntt/bin/trans/mttWriteNewLine.m Index: mttroot/ntt/bin/trans/mttWriteNewLine.m ================================================================== --- /dev/null +++ mttroot/ntt/bin/trans/mttWriteNewLine.m @@ -0,0 +1,3 @@ +function mttWriteNewLine + fprintf('\n') ; +