Wellcome to the Skilltree site

Wellcome to the Skilltree site!

Skilltree is a design language. In that, it features the opposite of a CASE (Computer-Aided Software Engineering) tool. It allows to specify software logic in object-oriented Pseudocode and then, to generate diagrams, design documents, code starters (in C++ and Python, at present) and plan the project. I undertook to start my own research, because I was displeased with both paradigm and performance of the CASE tools of the time (twenty years ago), and I must confess that I have not looked back upon their progress ever since, so I am not interested in comparison and I wish everyone who uses CASE regularly and is happy with it to live long and prosper.

I have been working on the Skilltree project, in parallel with my regular development and instruction work, since 1994 and on its automation since 1999. I have been using Skilltree regularly to develop my own projects, and have also used it to initiate experienced procedural programers to object-oriented programming (using C++).

Skilltree is work in progress. There is still much work ahead, however, I believe it is now sufficiently featured to be used by - and benefit – the object-oriented developer community. Skilltree is written entirely in Python and is open-source. While I would approciate assistance, I have yet much work to do, before I can dispatch the source in ordelry manner to SourceForge. (Unfortunately, this is not the usual open source project. A product that, in itself, pretends to teach others how to write cannot be delivered half-finished, in the state of a messy working prototype. For example, I am yet to reverse-engineer the software by means of itself.)

To try and appreciate Skilltree, download the Skilltree Windows installer from the Skilltree site at http://www.swskilltree.org/Design/1/1/4.html and install. (The distribution comes in executable form, which already contains Python inside.) Alternatively, you may download the Python sources, install missing third-party libraries (wxPython etc.) and run it from the Pyhtom interpreter. However, Skilltree has never been tested under other platforms (than Windows), and its dependence upon third-party software (which may have to be configured) may require some tweaking, on other platforms.

Unfortunately (or rather, fortunately, from a professional viewpoint), you must be prepared to learn a programming-like language (rather than tweak the controls of a GUI application). There is no two-hour crash course. Once you have the “Skilltree Explorer” GUI running, It is highly recommended that you proceed by studying the tutorial. From the “Help” menu, select “Skilltree help”. Open the “Tutorial” subtree and then the first tutorial – “Programming level”. Study it carefully. This is a “hands on” tutorial. It is recommended that you follow the instructions for entering and changing the ongoing Skilltree project and compare your results with the tutorial. You can download the base Skilltree source – as well as all major stages along the way – from the Skilltree site. From the “Help” menu select “Tutorial sources”.

In addition, you can download some sample Skilltree sources. From the “Help” menu, select ”Sample Designs”.

Good luck, and I wish you will find the language and methodolgy helpful!

Skilltree is – and will remain – open source. The object-oriented developer community is invited to use it free of charge – see “Licence” in the “Help” menu.

Please forward bug reports, notes, suggestions, (and, best of all – patches) to me, at avner@swskilltree.org.

     Avner Ben.

Language feature: “Composite Need”

 Originally posted 27 Dec 2008 by Avner Ben. Intent: to allow useful code generation and reverse engineering by extending Skilltree to allow nesting Need in (another) Need arguments and result.

Update:

11 January2012 by Avner Ben: name changes.
3 October 2012 by Avner Ben: Adjust to the latest Skilltree notation.

MOtivation:

“Composite” Need addresses a reverse engineering problem. Consider this Python code:

def logHello(a, b, c):
    a.open(b.getName(c.getPath())).log("hello world!")

The single line of code in this method involves four messsages, However, only the first – a.open() – may be expressed in Skilltree as proper Need at present. The other messages hide inside, silently supplying the arguments and disposing of the result.

Problem:

In an ideal world (or in Assembly Language or COBOL), each Skilltree Need would map to a single line of code, and each line of  proceduralcode would map to a single Skilltree Need. In reality, however, the lack of support for composite Need compromises the mapping of a Skilltree specification to useful code.

  • An issue with automatic reverse-engineering (a feature under construction): Reversing a single-Need Skilltree from the code sample above would loose 75% of the original logic.
  • An issue with code generation: In order to generate the full code from the (essentially-partial) Skilltree, the designer must resort to either of the following two Skilltree styles, both insufficient:
    1. To specify only the main Need (and loose the rest). One then must finish the code manually.
      SOFTWARE COMPONENT Default
      CAPABILITY to log hello
          INPUT (1, formal) logger,
          - (2, formal) configurator, (3, formal) the system
          SIGNATURE logHello(:Logger, :Configurator, :System)
      ENTITY Logger
          CAPABILITY to open Log File
              INPUT (FORMAL) full name
              OUTPUT (FORMAL) Log File
              SIGNATURE open(:String):LogFile
      ENTITY Log File
          CAPABILITY to log message
              INPUT (FORMAL) string
              SIGNATURE log(:string)
      ENTITY Configurator
          CAPABILITY to get File Name
              INPUT (Formal) path
              OUTPUT (Formal) full name
              SIGNATURE getName(:string) :string
      ENTITY System
          CAPABILITY to get path name
              OUTPUT (Formal) current path
              SIGNATURE getPath(:string)
      BREAKDOEN OF CAPABILITY to log hello
          USE CASE Logging example
          Need to open Log File

      …generates…

      def logHello(aLogger, aConfigurator, theSystem):
          '''to log hello
          - Input: (1, formal) logger,
            (2, formal) configurator, (3, formal) the system'''
          // Message: to open Log File
          aLogger.open()

      Note that one cannot rely upon hints in the “Input” and “Output” rules to guide the implementer, because (1) these belong to the capability (rather the Need) and will go with it wherever else needed, and (2) because skill documentation is not copied under messages. The only option is insert this comment in the documentation of the enclosing capability (“to log hello”), which is far-fetched. 

    2. To arrange all Needs in sequence. One then must edit the code starter manually, to get the desired nested form. (Note that the messages are ordered by time-sequence, i.e. actual order of execution.)
      BREAKDOEN OF CAPABILITY to log hello
          USE CASE Logging example
          Need to get path name
          Need to get File Name
          Need to open Log File
          Need to log message

      …generates…

      def logHello(aLogger, aConfigurator, theSystem):
          '''to log hello
          - Input: (1, formal) logger,
            (2, formal) configurator, (3, formal) the system'''
          // Message: to get path name
          theSystem.getPath()
          // Message: to get File Name
          aConfigurator.getName()
          // Message: to open Log File
          aLogger.open()
          // Message: to log message
          aLogFile.log("hello world!")

The challenge:

To extend Skilltree syntax to allow Composite Needs – i.e. Needs that generate lines of code, many-to-one (many needs to one line of code), instead of one-to-one (one need to one line of code) - as of now).
Minor challenges:

  • To adjust generated code documentation.
  • To adjust use case minispec graphics.

Solution:

  • The USING and GIVING Need attributes shall reference a familiar capability.
    • In this case, they generate an Composite Need, bound to the respective argument slot.
    • Otherwise, they continue to generate a variable name.
  • In addition, the USING and GIVING Need attributes may form a recursive structure (i.e. an inner need tree).
  • Note a semantic difference: “Using” substitutes the formal output of the apability with the value to be used. “Giving” specifies the receiver object of the result of the capability to be used. In the first case, the capability is on the left; in the second case, the capability is on the right!

The Skilltree:

 

BREAKDOWN OF CAPABILITY to log hello
    // Input: (1, formal) logger,
    // - (2, formal) configurator, (3, formal) the system
    Need to open Log File
        // Input: (Formal) full name
        // Output: (Formal) Log File
        USING to get File Name
            // Input: (Formal) path
            // Output: (Formal) full name
            USING to get path name
                // Output: (Formal) current path
        GIVING to log message

Design decisions:

  • USING values are bound to INPUT (FORMAL) rules, position dependent.
    • In order to skip unused parameters (ie, that are not bound to ready values), it should be possible to indicate the exact binding, using anew syntax: (FOR [PARAMETER]).
  • GIVING values are bound to the first formal OUTPUT rule, for now. (This should be extended in the future, to allow multiple return values that need be assigned, as in Python).
  • Here is the fully-qualified example:
    BREAKDOEN OF CAPABILITY to log hello
        // Input: (1, formal) logger,
        // - (2, formal) configurator, (3, formal) the system
        Need to open Log File
            // input: full name
            // Output: (Formal) Log File
            USING to get File Name (FOR full name)
                // Input: (Formal) path
                // Output: (Formal) full name
                USING to get path name (FOR path)
                    // Output: (Formal) current path
        GIVING to log message (FOR Log File)

The code:

A “composite” (ie, tree-like) documentation style is, of-course, out of the question, since code documentation is strictly line-oriented. The documentation is oredered by time sequence. Nested messages are adorned as either “in argument” or “to the result”.

def logHello(aLogger, aConfigurator, theSystem):
    '''to log hello
    - Input: (1, formal) logger,
      (2, formal) configurator, (3, formal) the system'''
    // Message, in argument: to get path name
    // Message, in argument: to get File Name
    // Message: to open Log File
    // Message, to the result: to log message
    aLogger.open(aConfigurator.getName(theSystem.getPath())).log("hello world!")

Note that the comments are not qualified (by message path). This would be overkill! A reverse engineering engine can do the matching by analysis of the order of execution in the composite statement below.

Sequence diagram:

This medium follows, by defintion, a strict ordering: time sequence. Consequently, the mesages are ordered accordingly (as in the code documentation). The nesting is hinted by faint arrows marked “arg” and “res” respectively, pointing down. Some adustment is made to the start position of message text (to allow for the hint arrows).

Pseudocode:

This is one point where the tree chart deviates from the original Skilitree source. The prospect of an alternate flow that goes up would distort the general call tree order – down and right. The only ordering left is the simple time sequence, as in the sequence diagram.

Wire chart:

This medium is already displaying coupling in the right margin. Compound Need is a case of data coupling, so there is no need for radical adjustments.

Short form:

  • INPUT/OUTPUT rules that correspond to USING/GIVING Need attributes are automatically elevated to FORMAL (and created to begin with) if missing (position dependent).
  • USING/GIVING rules do not generate capabilities by default. Unknown capabilities (i.e. text starting with “to”) result in error.

Issues:

The following rare or complicated cases will not be supported (at least not in the first release):

  • Inner capability trees. There is no technical problem in parsing such Skilltree, but this style seems to invites trouble, at least in theory. (So, this decision may change in the future.) Rationale: The “composite” structure in composite need applies only to input and output and is related to need (use of capabilities) rather than the capabilities themselves. Therefore, this looks (at least in theory) like an improper place to specify functional breakdown. Capabilities that are used for the first time within a composite need must still be specified in a separate use case (or where needed simply). 
    • As ususal, the need under the USING/GIVING, that is detailed in another use case, will be hyperlinked.
  • Composite Need by assignment, (where the assignment operator represents a significant capability).
  • Control constructs (selection and iteration) within USING/GIVING. Some languages enable such practices, e.g.
    • Selection is possible, in C and Python, using ternary if to specify the argument.
    • Iteration is possible, in Python, using list comprehension.