Introduction to CPN Tools

I’ve been doing demonstrations of CPN Tools for almost 10 years now. At first, I did demonstrations with Troels Bjerre Sørensen and later alone. Next week, I’m chairing a hands-on session with CPN Tools, and rather than doing demos again, I decided to condense some material from the CPN Tools help pages (old version here) into a sort of introductory manual and create some introduction videos to get people started.

You can download the manual as a PDF file or as a fancy EPUB file for use on your e-book reader (it works on iPad and iPhone and probably also on Nokia devices and crappy phones). The EPUB is a bit crappy, as I’ve not worked on positioning the images so they look good on an e-reader.

You can marvel at me massacring the English language as well as over-use of iMovie effects in the below YouTube videos. Video 1 may not be the most interesting one, so feel free to skip to video 2.

13 thoughts on “Introduction to CPN Tools

  1. Dr. Westergaard:

    Would you please send or direct me to a very basic step by step tutorial for CPN, with a create, declaration, hierarchy and simulation example in one application? A simple seven step tutorial would be great.


    Jim Rodger

  2. Greetings Dr. Westergaard, I like the tutorials thank you for these. However, I do not see any fundamental tutorial where users can learn how to create Petri Nets from scratch using CPN Tools. All your tutorials focus too much on using your built-in examples, which may not be so helpful to beginners. I thought I’d let you know so you could perhaps incorporate this feedback and improve the documentation of this excellent tool.

    1. Dear Hamman Samuel,

      Thank you for your comment. I agree that the tutorials are more aimed at getting to use the tool using the built-in examples. We often use this method to get new students acquainted with the tool as starting with a blank canvas can be daunting.

      There is a third party who has compiled and recorded tutorials on CPN Tools, however. You can see a Youtube playlist at I have not watched all the videos thru end-to-end, but it seems to have a couple videos starting with a new model instead of a built-in example.

      I will definitely take your comment into account (and agree that both a video showing how to set up a first simple model and one showing how to get started on a larger modeling project would be useful), but I am afraid that time constraints will make it impossible for myself to undertake this task in the near future. Should you or somebody else undertake this endeavor, I’ll of course make sure to feature the result if it can be helpful to others.

  3. dear Dr. Westergaard

    there is a little bug in cpntools

    I will explain the bug by a example

    my Petri Net is simple and constructed from:
    – place P1 (source) (int,10`1)
    – place P2 (destination)(int,without int_mark)
    transition T1 with action y:=3 (in code segment)
    arc1 from P1 to T1 with expression (!y)`1
    arc2 From T1 to P2 with expression (!y)`1

    in declaration I put : globref y = 2;

    so i have a enabled transition T1 (in green) 🙂

    if i fire T1 there is 3 tokens in P2 and 7 tokens in P1 !!!!!!!!!

    why the action of the transition , was executed befaore the evaluation of the two expressions of arcs.

    the logic behavior is : I must have 8 token in p1 ,not 7.
    And in then next fire i must find 5 token in p1 (because the action y:=3 is executed after the first fire).

    thank you

    1. Dear Tarek,

      Thanks for your comment. While I can understand you would expect 8 tokens on p1, there definitely needs to be 3 on p1 after one execution, using the interpretation that first tokens are consumed, then the code segment is executed, and finally new tokens are produced.

      This interpretation, while alluring, cannot be realized in code. The reason is that code segments can bind variables. Code segments are guaranteed to be executed only once, while arcs may be evaluated more than once. Thus we can bind the input variables using some of the arcs, execute the code segment and evaluate all remaining arcs. There is no clear distinction between input and output arcs as an input arc can depend on the output of the code segment.

      For this reason, arcs are not allowed to have side effects or depend on external factors (like the probability functions or reference variables). This is actually in the documentation, though hidden a bit ( Thus, in your example we get the right behavior for the outgoing arc but the wrong on the input arc because you illegally use a reference variable.

      To make your example work, remove the reference variable from (at least) the input arc. Instead use a regular CPN variable (var v: INT) and make your code segment return the value you are interested in, the reference either before or after setting it.

      In general I advise against using reference variables except for setting parameters. When you change reference variables, you run into many unexpected situations; for example, if you use a reference variable in a guard, you do not get the behavior you expect (and it is forbidden, see but works correctly if you never update a reference variable and is useful for doing multiple simulations with different parameters; this is so much of a problem that I’ve even suggested a special kind of transitions allowing you to use reference variables in guards, see Instead, use a place and update a single token on that place. The place can a fusion place and hence available on all pages.

  4. dear Dr. Westergaard

    how to get the current value of tokens in a place.

    i have a place p1 connected to t1 with arc1

    i would like to add a condition on arc1 like “if there is 5 tokens in p1 then … else if p1 = 10 then ….”

    thank you

  5. dear Dr. Westergaard

    thank you very much for your great efforts

    but please tell us if there is videos or simple tutos, talking about
    the cpn monitors, they are a very strong tools, but not very clear.

    the help in cpn tools web page is difficult to be understood.

    thank you

    1. Dear jellad,

      There are no video tutorials that I am aware of. You can follow the extensive tutorials at along with the annotated example from

      If video tutorials are important, you can indicate your interest at (though that is only advisory).

  6. Hello,

    I’m working on a modeling and simulation project by using CPN Tools and I find some difficulties in the use of ‘union’ constructor. Please could you help me to solve this:

    I put the following declarations:

    colset Ref = with a |b;
    colset Cont = with c;
    colset Kanban = with k;
    colset ContRef= product Ref* Cont;
    colset KanbanRef = product Ref* Kanban;
    colset Stock = union Ref +ContRef +KanbanRef;

    So when I put ‘Stock’ as my place ‘P1’ type and I put in the following marking: 20`a ++ 2` (a, c) it shows me an error message that I have to write: 20`Ref ++ 2`ContRef, instead of a and (a, c).

    However, it’s not what I really want because Ref and ContRef are considered as sets in my case study. While this place ‘P1’must contains elements like (a, b …).


    1. Hi Sara,

      Unions don’t work exactly like that. SML uses what is called disjoint unions where you need to identify the original set the value came from. In your example, you don’t specify a set, but only the identifier (which confusingly is allowed to have the same name as the set).

      Hence, the only allowed vlaues of your Stocks type are Ref, ContRef, or KanbanRef (using the construct as such, it pretty much works as the enum construct you use for Ref).

      Instead you should use the syntax
      colset Stock = union Ref:Ref +ContRef:ContRef +KanbanRef:KanbanRef;

      A value of Stock might then be “Ref(a)” or “ContRef(a, c)”

      Hope this helps!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.