297
QSMM Programmer Manual for QSMM Version 1.16 28 July 2014 by Oleg Volkov

QSMM Programmer Manual · QSMM Programmer Manual for QSMM Version 1.16 28 July 2014 by Oleg Volkov

  • Upload
    dangdat

  • View
    230

  • Download
    2

Embed Size (px)

Citation preview

QSMM Programmer Manual

for QSMM Version 1.16

28 July 2014

by Oleg Volkov

Copyright c© 2012, 2013, 2014 Oleg Volkov.

Permission is granted to copy, distribute and/or modify this document under the terms ofthe GNU Free Documentation License, Version 1.3 or any later version published by the FreeSoftware Foundation; with the Invariant Sections being just “GNU General Public License”,with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included inthe section entitled “GNU Free Documentation License”.

i

Table of Contents

Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.1 What Is Intelligence? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 Spur-driven Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Building Blocks for Intelligent Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.4 Animate Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.5 System Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.6 Obtaining QSMM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.7 Reporting Bugs and Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.8 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.9 Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.10 Linking with the Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.11 Getting the Version of the Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.12 Object Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.13 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 Optimal Action Generation Engine . . . . . . . . . . . . . . . . . . . . . . . . . 112.1 Event History Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.2 Small and Large Actors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3 Basic Datatypes and Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.4 Creating an Actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.5 Incrementing Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.6 Incrementing Spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.7 Event History N-gram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.8 Generating an Optimal Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292.9 Customizing a Relative Probability Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342.10 Specifying Weights of Output Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402.11 Automatic Spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452.12 Controlling Random Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472.13 Other Parameters of an Actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482.14 Example of Using the Actor API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

3 Statistics Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573.1 Types of Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573.2 Structures for Accessing Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583.3 Reading and Writing Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603.4 Enumerating States and Cycle Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633.5 Providing Initial Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643.6 Getting the Reason of a Storage Failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683.7 Example of Using the Storage API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

ii

4 Multinode Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754.1 Principle of Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754.2 Creating a Multinode Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784.3 Instruction Meta-class Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

4.3.1 Function Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824.3.2 Event Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834.3.3 Registering the Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864.3.4 Setting the Instruction Parameters String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 874.3.5 Setting the Number of Instruction Outcomes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894.3.6 Function Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

4.4 Instruction Class Set Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914.4.1 Function Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914.4.2 Event Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924.4.3 Registering the Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934.4.4 Registering Instruction Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944.4.5 Setting the Number of States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994.4.6 Function Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

4.5 Creating Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1024.6 Creating the Model Instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1054.7 Incrementing Time and Spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1074.8 Transferring Control Between Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1094.9 Handling Instruction Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124.10 Setting Look-ahead Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1134.11 Setting Instruction Classes Weights . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1144.12 Working with System and User Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1174.13 Dumping a State Transition Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1204.14 Dumping an Action Emission Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1234.15 Controlling Random Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1254.16 Associating Parameters with a Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1264.17 Enumerating Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1274.18 Tracing Model Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1294.19 Error Handling for a Multinode Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1304.20 Example of Working in Large-scale Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

5 Assembler Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1435.1 Basic Datatypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1435.2 Assembler Program Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1435.3 Assembler Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

5.3.1 jmp Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455.3.2 jprob Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455.3.3 choice Instruction Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455.3.4 casels Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1465.3.5 joe Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1475.3.6 stt Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1475.3.7 nop and nop1 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1515.3.8 lookup Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1525.3.9 abort Instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1525.3.10 User Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

5.4 Disassembling a Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1535.5 Inspecting an Assembler Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1585.6 Printing an Assembler Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1605.7 Parsing an Assembler Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1655.8 Loading a Parsed Program into a Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

iii

5.9 Using Probability Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1715.9.1 Variables in an Assembler Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1715.9.2 Controlled Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1725.9.3 Output Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1775.9.4 Auxiliary Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

5.10 Using Probabilities Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1835.10.1 Defining Probabilities Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1835.10.2 Referencing Probabilities Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1845.10.3 Getting Output Probabilities Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

5.11 Cloning a Probability Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1895.12 Memory Efficient Cloning a Probability Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1915.13 Unloading a Probability Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1945.14 Using the Assembler Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

5.14.1 Changing Line Number and File Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1955.14.2 Including Other Source Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1955.14.3 Defining Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1965.14.4 Defining Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1975.14.5 Generating Unique Location Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1985.14.6 Specifying State Transition Networks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1985.14.7 Getting a Preprocessed Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

5.15 Example of Working with an Assembler Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

6 Miscellaneous Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2126.1 Random Number Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

6.1.1 Creating a Random Number Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2126.1.2 Generating Random Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2136.1.3 Custom Random Number Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

6.2 Ordinary and Sparse Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2176.3 Messages and Message Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

6.3.1 Creating a Message List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2186.3.2 Creating Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2196.3.3 Adding Messages to a Message List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2206.3.4 Dumping a Message List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

6.4 Exchanging Data Packets in a Multithreaded Program . . . . . . . . . . . . . . . . . . . . . . . . . . . 2216.4.1 Registering Interaction Sides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2226.4.2 Exchanging Data Packets Between Sides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2226.4.3 Tracing Exchange of Data Packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2236.4.4 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2246.4.5 Example Program that Exchanges Data Packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

6.5 The Implementation of Functionality of STL map Template . . . . . . . . . . . . . . . . . . . . . . . 2296.5.1 Creating Maps and Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2306.5.2 Operations on Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2336.5.3 Operations on Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2356.5.4 Example of Using a Mapping Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

iv

7 Example Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2397.1 optact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2397.2 apsamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2417.3 optpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2437.4 test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2447.5 fw-simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2517.6 parse-asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2527.7 asm-disasm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2537.8 asmat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2557.9 tohuff-test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2567.10 optact-p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2597.11 predict-test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2627.12 langlearn-test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

GNU General Public License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274

GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

Function and Macro Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285

Type Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

Concept Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289

Acknowledgements 1

Acknowledgements

The author of this manual expresses thanks to Bryan Barnes for proofreading Section 1.1 [WhatIs Intelligence?], page 2, Section 1.2 [Spur-driven Behavior], page 3, Section 1.3 [Building Blocksfor Intelligent Machines], page 4, and Section 1.4 [Animate Machines], page 5.

Chapter 1: Introduction 2

1 Introduction

QSMM is a recursive acronym for “QSMM State Machine Model.” That kind of a state machi-ne makes possible to implement a system with intelligent behavior. The extent to which thesystem will be intelligent depends on basic properties of the state machine and on a specificimplementation of a system that relies on it.

From the point of view of a programmer, a system he develops is represented by the statemodel that needs to be programmed. To promote the development, the programmer can usevarious function libraries and frameworks. QSMM is an intelligent state model developmentframework. It is a C function and macro library which by its author’s belief could facilitate thedevelopment of systems with intelligent behavior.

The package source code is distributed under the terms of the GNU General Public License,Version 3 or any later version published by the Free Software Foundation. See [GNU GeneralPublic License], page 274, for the text of the License.

This manual specifically is covered by the GNU Free Documentation License, Version 1.3 orany later version published by the Free Software Foundation. See [GNU Free DocumentationLicense], page 280, for the text of the License.

1.1 What Is Intelligence?

There are many definitions for intelligence as well as types of intelligence. Most definitionsinclude lists of activities inherent to humans, such as reasoning, planning, solving problems, thi-nking abstractly, comprehending complex ideas, learning from experience, and adapting effecti-vely to the environment. When attempting to develop intelligent machines, researchers try tomake them perform a subset of those activities with as high a level of plausibility as possible.However, from the standpoint of knowledge formalization and for a more precise formulationof research goals, it would be useful to point out the smallest subset of activities, which whenperformed by an animate being or inanimate machine, can be considered as an indication thatit is intelligent enough.

First, it is necessary to mention that intelligence implies a goal (in the “Handbook of HumanIntelligence” Sternberg and Salter defined intelligence as “goal-directed adaptive behavior”). Inthe case of animate being, the goal is surviving, in the case of a machine created by humans thegoal is solving tasks assigned by humans. Animals show their basic intelligence, e.g. when theyadapt to the environment, seek for food, and build nests. One can say today’s machines showtheir intelligence by effectively doing tasks they are intended to do. This is not a too distortedinterpretation of intelligence if we review the book “Symbolic Logic and Intelligent Machines”of Edmund C. Berkeley published in 1959, where the author called intelligent machines theelectromechanical arrangements, which solve problems that involve logic.

The advanced level of intelligence can be defined as the production and use of work tools.As it has turned out, the production and use of work tools is peculiar not only to humans,but also to chimpanzees and to a number of other animals. For example, chimpanzees are ableto find stones of appropriate weights and sizes and crack nuts using them. Another kind ofactivity using tools that chimpanzees are able to do is find long and thin sticks to kill smallrodents, which live in the trunks of a certain species of trees, and extract them for food. Thechimpanzees not only find ready-to-use work tools in nature, but they can also produce them.For example, chimpanzees can construct arrangements consisting of small tree branches and putthem into termite mounds to eat termites that crawled on them. Another notable example is anexperiment conducted on a pygmy chimpanzee when he was successfully trained to manufacturea sharp stone tool to cut the string, which opens the door of the trap and gives him access tosweets.

Chapter 1: Introduction 3

In the digital world supported by computers, work tools are computer programs that helpto solve various tasks. That is, in the computer environment, the advanced level of intelligenceis closely connected with a capability of synthesis and use of algorithms. A machine with anadvanced level of intelligence must be capable of automated synthesis of algorithms in someform or fashion. Such machines could then internally generate a computer program, possiblyconsisting of a set of subroutines, which solves a task assigned by a human.

There does exist a higher level of intelligence, which is peculiar only to humans and notto chimpanzees that we will call an expert level of intelligence. Indeed, in what manner dohumans and chimpanzees differ in essence if they both can produce and use work tools? Onecan say humans perform their activity consciously and chimpanzees do not posses that degreeof consciousness. Such explanations are worthless from both scientific and practical viewpointsbecause when a chimpanzee does something, he can consider that he does it with the fullconsciousness and awareness of what he does and why.

In the book “The complete idiot’s guide to Human Prehistory,” its author Robert J. Meiercarefully pointed out an important fact about the production and use of burins. Such speciallysharpened stones archaeologists find during excavations that correspond to the time, startingfrom which, tentatively speaking, creatures that have been living on Earth could be calledhumans. Burins are tools created for manufacturing other tools. Chimpanzees do not maketools for making other tools. That is, the expert level of intelligence peculiar only to humansconsists of the ability to organize processing chains in which one kind of work tool is used toproduce other kinds of work tools. The established concept for this is “production of the meansof production.”

In the computer environment, programmers create such tools as compilers, various operating,execution, and development environments that help to create other computer programs. Amachine with an expert level of intelligence created by humans would be one that is capable ofthe automated synthesis of algorithms, which the machine will use to synthesize other algorithmsto solve problems assigned by humans more efficiently. Creation of such a machine is a quitespecific goal that researchers could try to achieve.

1.2 Spur-driven Behavior

The basic problem one needs to solve when creating an intelligent machine that performsautomated synthesis of algorithms, is discovering a way or manner in which a job is assignedto the machine. There are sophisticated approaches to solving this problem, e.g. by creatingspecifications that consist of rules and constraints. The QSMM framework uses the simplestapproach, in which a developer must reduce the task to an optimization task, which goal isthe maximization of increment or decrement velocities of a set of numeric quantities. Thosenumeric quantities could be logarithms of probabilities that should be maximized, energy valuesthat should be minimized, or the sum of incentives, which are given to the machine when a parti-ally designed algorithm successfully reaches some point in solving the task. The machine thenhas to synthesize by trial and error an algorithm, which when executed, solves the optimizationtask as best as possible. The classical approach to such synthesis is to use a genetic algorithmthat evolves a target algorithm by multiple iterations to maximize the value of a fitness function.The QSMM framework uses a different and generally much more effective approach, where thesynthesis of an algorithm is performed simultaneously with its execution.

Historically, in the QSMM framework, the value of a numeric quantity, which increment ordecrement velocity is maximized, is called a spur. Every such numeric quantity specifies a spurtype, to which the values of spur belong. To increase the efficiency of an algorithm synthesis,a programmer should provide a transparent way to evaluate spur values, which then allows anintelligent machine to better understand the correlation between changes made in the algorithmbeing synthesized and changes in spur. Developing a proper way of spur evaluation is one of the

Chapter 1: Introduction 4

most complex tasks needed to be solved when creating an intelligent machine using the QSMM

framework.

1.3 Building Blocks for Intelligent Machines

In the QSMM framework, a generic building block for creating machines capable of goal-directedadaptive behavior, which implies automated synthesis of algorithms for achieving a goal, ishistorically called an optimal action generation engine or an actor for short. One can thinkof an actor as a set of neurons, possibly very large one. An actor has a number of adjustablemodes, parameters, supports limited customization of its algorithms, and actually implementsa probabilistic mapping—a function that ambiguously maps an argument from a set of possiblearguments to a result from a set of possible outcomes. Such function, when invoked one time,can return one result, and when invoked another time, can return yet another result for thesame argument.

Behavior of probabilistic mapping is modulated by spur. Supposing a result returned by aprobabilistic mapping for its specific argument somehow affects spur increment velocities, thefunction of the atomic building block of an intelligent machine that corresponds to a particularargument of the probabilistic mapping will be returning more often a result of the mappingthat maximizes those spur increment velocities. An intelligent machine might include varioussuperpositions of probabilistic mappings, its inputs and outputs, and those superpositions wouldspecify an adaptive generic state model aimed to solve general or specific problems.

An important concept related to the possibility of using a result of a probabilistic mapping(directly or after transforming) as an argument (or as its part) of that probabilistic mapping isstate—a variable that changes its value based on its previous value. A machine typically usesvarious kinds of states that can be interlinked in different ways and make up its whole integralstate. An integral state of the machine corresponds to a point in solving an assigned task. If tosolve an assigned task the machine has to interact with the environment, then the integral statewill somehow link with a state of the environment. By implementing probabilistic mappings,the QSMM framework provides the means for goal-directed tracking of the current environmentstate which may be needed to know when producing goal-directed adaptive behavior.

If a machine executes an algorithm, possibly in the process of synthesizing of that algorithm,then the integral state of the machine will be in some way linked with a state of the algorithm,which was put in the algorithm by its developer. Principal states of algorithms are better investi-gated by example of deterministic finite automatons, which representation in a programmi-ng language could correspond to assembler programs with specially organized instruction sets.Those instruction sets include: (1) custom instructions, which perform effective work and canreturn an outcome from a set of possible outcomes; (2) conditional jump instructions, whichtransfer control to a custom instruction at a specific location in the program on the basis of anoutcome returned by a previously invoked custom instruction; (3) simple jump instructions thattransfer control to a custom instruction at a specific location in the program unconditionally.In such assembler programs, principal states of the algorithm are custom instructions and jumpinstructions specify mappings between those states. An argument of mapping is a superpositionof a prior principal state and outcome of a custom instruction invoked in that state. The resultof mapping is a new principal state. By using probabilistic mappings supported by the QSMM

framework instead of hard-coded deterministic mappings, a researcher can develop adaptiveassembler programs that produce goal-directed behavior.

As one may realize, adaptive assembler programs are related to automated synthesis of algori-thms. The QSMM framework provides the means to work with such assembler programs thatinclude converting the text of a fuzzily specified assembler program to a system based on one ortwo probabilistic mappings, executing the assembler program with simultaneous adjusting jump

Chapter 1: Introduction 5

probabilities to solve an assigned task more efficiently, and converting a resulting assemblerprogram back to a text representation.

Elaboration of the concept of environment for synthesis and execution of assembler programsis a multinode environment in which different nodes can contain different assembler programs.In the QSMM framework, node means a callable state submodel. An assembler program ofone node, when being executed, can call another node, i.e. transfer control to that node toexecute its assembler program and then transfer control back after finishing execution of thelatter program. Nodes correspond to subroutines, which synthesis and execution a researchercould relate to setting up processing chains with production and the use of different work tools.

As a helpful add-on for developing intelligent machines by means of C programming language,the QSMM framework provides an API for exchanging data packets in multithreaded programs,which can be used to simplify communication between different parts of your application, anda C implementation of functionality of STL map and multimap templates, which can be used tocreate mapping objects in C programs without the need to rewrite those programs in C++ and,therefore, increase their complexity.

1.4 Animate Machines

Implementation of adaptive probabilistic mapping requires providing a method of selection ofa result of the mapping for an argument of the mapping. This method could be based on adeterministic process, which is deterministic changing the integral state of a system that containssuperpositions of deterministic mappings, inputs, outputs, and memory variables. This processis the way today’s computers operate. The method might require the use of pseudorandomnumber generators which operation is also based on deterministic processes. However, e.g. whencreating implementations of adaptive probabilistic mappings in the form of electric circuits, itcan become practically reasonable to use stochastic physical processes as a source of randomness.One can think of such a stochastic physical process as changing the integral state of a machine,which implementation uses probabilistic mappings provided by nature.

Suppose an intelligent machine, which uses probabilistic mappings provided by nature, solvesan optimization task assigned by humans, which consists in the maximization of incrementvelocity of a numeric quantity. Consider a situation that, at a particular point of time, theincrement velocity has gone down, so the machine needs to change its own behavior to increasethe increment velocity even more. In other words, the machine is now in a difficult situation thatmeans an increase of complexity of choices the machine has to perform to increase the incrementvelocity. The complexity of choice for a stochastic act, i.e. calling a nature-provided probabilisticmapping for a particular value of its argument, depends on how many possible distinguishedoutcomes the act has, which might affect how the stochastic act changes the entropy of nature.

One could relate the abstract idea of good and bad to the concept of choice complexity.The good would support a certain level of choice complexity. The survival of an animate beingwould be to preserve its ability to perform choices with a sufficient degree of complexity. This hassomething in common with the definition of life as a characteristic, which distinguishes objectsthat have signaling and self-sustaining processes from those that do not1. In our case, thesignaling is the way of exchanging information within superpositions of probabilistic mappings,and the basic self-sustaining process is supporting certain level of choice complexity.

1.5 System Requirements

Although the package source code can be adapted for use with many of available operatingsystems and compilers, the GNU/Linux system and GCC is a preferable combination to bui-ld the library and accompanying programs. The source code supports 32-bit and 64-bit build

1 Koshland Jr, Daniel E. (March 22, 2002). “The Seven Pillars of Life”. Science 295 (5563): 2215–2216.doi:10.1126/science.1068489).

Chapter 1: Introduction 6

modes. The library had been tested to build and pass tests on MS Windows in Cygwin and Mi-nGW/MSYS environments (a modern version of MinGW/MSYS environment should be used).

By default, the package uses a pseudorandom number generator implemented by functi-on rand from the standard C library, which has the following drawbacks: (1) it is usually avery simple function, not intended to pass serious statistical tests for pseudorandom numbergenerators; (2) streams of pseudorandom numbers returned by that function may vary on di-fferent platforms; (3) multiple instances of a pseudorandom number generator implemented bythat function are only imitated and cannot be seeded separately. To solve these issues, thepackage can be configured to use a high-quality pseudorandom number generator provided bythe GNU Scientific Library. There are no special requirements for a version of that library touse with the package—all recent versions can be used. QSMM starting from version 1.15 canalso utilize a user-supplied random number generator, e.g. implemented by a developer by handor which is a wrapper for a random number generator provided by another library.

The package uses the exponent function to compute relative probabilities of signal emitting.The absolute value of the argument of the exponent function sometimes can be big enough, whichmay cause the floating-point overflow (which yields infinity) or underflow (which yields 0). Tominimize the number of such overflows and underflows during program execution, long doubleversion of the exponent function expl is used instead of ordinary function exp on platformswhere function expl and macro isfinite are available in the standard C library. If either orboth of them are unavailable, then sporadic floating-point overflows and underflows shall notsubstantially decrease program efficiency.

However, if one considers that ordinary double precision is not sufficient, or if he makesmodifications to the algorithm and overflows or underflows occur frequently even when longdouble precision is used, then the package can be configured to use MPFR and GNU MP librariesto solve these issues (former library depends on latter). There are no special requirements for aversion of the MPFR library to use with the package—all recent versions can be used. A versionof the GNU MP library should be used, which is compatible with a version of the MPFR library;see the documentation for the MPFR library for more information.

A few example programs included in the package distribution use the Curses library. Onthe GNU/Linux system and Cygwin it is the ncurses library. On MinGW/MSYS it is thepdcurses library. If you do not have the corresponding library on your system, the package canbe configured to bypass building example programs that use it.

A number of example programs included in the package distribution use the POSIX threadsAPI. On MinGW/MSYS building those example programs requires the use of an additionallibrary that implements the API. If necessary, the package can be configured not to build theexample programs.

1.6 Obtaining QSMM

The official homepage of the QSMM project is

http://qsmm.org/

Additional information on the project is contained in a set of standard pages for a projecthosted at SourceForge.net, which can be accessed via

http://sourceforge.net/projects/qsmm/

The package distribution can be downloaded from the project files page provided bySourceForge.net at

http://sourceforge.net/projects/qsmm/files/

Chapter 1: Introduction 7

1.7 Reporting Bugs and Getting Help

It should be said that algorithms, which solve optimization tasks with moderate efficiency, canbe automatically synthesized from scratch using the QSMM framework only for a small subsetof tasks. To increase efficiency, the developer has to provide a proper template for a synthesizedalgorithm in the form of a generic state model using a C program and/or as a fuzzily specifiedassembler program with a custom instruction set. The developer may also improve algorithmsimplemented in the QSMM framework or use them in more efficient modes, which were unforeseenby the package author; in some cases that can be done without changing and recompiling thepackage source code.

Besides limitations caused by imperfection of algorithms used, the package may have bugs.To facilitate quicker fixing bugs in the package and the package documentation, please reportthem to a mailing list for QSMM package users. See below for details about accessing the mailinglist.

If you want a new feature to appear in the package, e.g. a new API function, without whichit is hard or even impossible to write some kind of applications, then please submit that to amailing list for QSMM package users too.

Package users are encouraged to ask questions, ask for technical support, which indeed mayrequire fixing implicit bugs in the package, and inform the author of real examples of packageuse via the mailing list. That kind of activity will hopefully improve the package. The mailinglist information page is available at

https://lists.sourceforge.net/lists/listinfo/qsmm-users

Using that page you can subscribe to the mailing list, unsubscribe from the list, view list archives,and do other actions.

Software described in this manual is provided “as is,” in the hope that it will be useful, butwithout any warranty. See [GNU General Public License], page 274, for more details.

1.8 Installation

For package installation instructions, please see file ‘INSTALL’ at the root of the package distri-bution. Those instructions are not provided in this manual to not to duplicate the same text intwo documentation files. At the same time, instructions given in file ‘INSTALL’ can be used tobuild other documentation files, including this manual.

1.9 Header Files

Command make install installs QSMM header files to subdirectory ‘qsmm’ in a directory for Cheader files set by the ‘configure’ script, usually ‘/usr/local/include/’ or ‘/usr/include/’.Below there are the list and the description of header files being installed.

‘qsmm.h’ The main header file of the framework. Contains most of datatype, function, andmacro definitions, which may be needed by a developer.

‘internal.h’A header file that contains an API used internally by the framework. The API

was documented in previous versions of the framework, but is undocumented inthis version to not to overcomplicate the manual with excessive details. That API

could not be made invisible outside of the library because of the need to preservebackward compatibility. The preprocessor #include directive includes the headerfile in header file ‘qsmm.h’.

‘side.h’ A self-contained header file for the Side API. That simple API provides means forexchanging data packets, especially signals, between threads in a multithreadedprogram. In some cases, program structure with a number of interacting sides, which

Chapter 1: Introduction 8

execute in separate threads and exchange signals, can simplify program developmentor experimenting. Command make install installs the header file when the packageis configured to use the POSIX threads API (see file ‘INSTALL’ at the root of thepackage distribution, for information on package configuring).

‘map.h’ A self-contained header file for the C implementation of functionality of STL map

and multimap templates.

‘version.h’A header file with macro QSMM_HEADERS_VERSION defined to a version of the package.That macro could be used to check whether versions of the headers and the li-brary conform. The preprocessor #include directive includes the header file inheader file ‘qsmm.h’. The contents of ‘version.h’ are generated using template‘qsmm/version.h.in’ in the package distribution.

When you include these header files in a program with a preprocessor #include directive,you should specify directory prefix ‘qsmm’. For example, to include header file ‘qsmm.h’, youshould write

#include <qsmm/qsmm.h>

C functions declared in the header files are wrapped in extern "C" declarations, so when aC++ source file includes these header files, correct linkage is provided with functions containedin the QSMM library.

1.10 Linking with the Library

When linking with a shared version of the QSMM library, dependencies on other libraries thatmay be used by the QSMM library are compiled in the file of shared library, and you do not needto specify them in a link command. (Those dependencies are defined at a package configuringphase when you execute the ‘configure’ script.) An example command to link with a sharedversion of the library is

gcc example.o -L/usr/local/lib -lqsmm

You need to specify option -L/usr/local/lib if the library is installed in directory‘/usr/local/lib/’ and that directory is not on standard search path of your linker.

When linking with a static version of the library, in a link command you should also specifylibraries the QSMM library depends on using such linker options as -lgsl, -lmpfr, -lgmp, and-lm. An example command to produce a fully statically linked executable is

gcc -static example.o -lqsmm -lgsl -lm

Alternatively, you can link via command libtool, which uses file ‘libqsmm.la’ copied tothe library directory when installing the package. That file describes all necessary dependenciesneeded to produce an executable linked against the library, which are useful in case of staticlinking.

1.11 Getting the Version of the Library

Currently, the version of the QSMM library is specified in major.minor format. In the future,versions with greater major number may require considerable backward-incompatible changesat source code level for programs that use the library.

To get a string representation of the version, the following API function from the ‘qsmm.h’header can be used.

[Function]const char * qsmm_version ()This function returns the version of the QSMM library as a string in major.minor format,e.g. ‘1.16’.

Chapter 1: Introduction 9

To examine the version of QSMM library headers, which were used when compiling a program,the following macro from the ‘version.h’ header included by the preprocessor #include directi-ve in the ‘qsmm.h’ header can be used.

[Macro]QSMM_HEADERS_VERSIONThis macro is defined to a string representation of the version of QSMM library headersinstalled, e.g. ‘1.16’, which normally should be equal to the version of a QSMM library usedwhen linking the program.

1.12 Object Handles

In the QSMM API, to refer to various objects handles are used. A handle is an opaque typedpointer to a QSMM internal structure, the contents of which cannot be examined or changed byan application program, except via API functions that take a handle of that type as an argument.The type of a handle corresponds to the type of an object the handle refers to. Dereferencinghandles is useless, as they all have incomplete types. Because a handle is a pointer, it can havethe NULL value. The table below lists handle types used in the QSMM API, corresponding objecttypes, and references to sections in this manual with detailed descriptions of those handle types.

Handle Type Object Type Reference to a Section in this Manual

qsmm_t multinode model Section 4.2 [Creating a Multinode Model],page 78.

qsmm_actor_t actor Section 2.3 [Basic Datatypes and Macros],page 14.

qsmm_actpair_t actor pair Section 4.6 [Creating the Model Instance],page 105.

qsmm_instr_t assembler instruction Section 5.1 [Basic Datatypes], page 143.

qsmm_iter_t map iterator Part of the C implementation of functionalityof STL map and multimap templates. SeeSection 6.5.1 [Creating Maps and Iterators],page 230.

qsmm_map_t map Part of the C implementation of functionalityof STL map and multimap templates. SeeSection 6.5.1 [Creating Maps and Iterators],page 230.

qsmm_msg_t message Section 6.3.2 [Creating Messages], page 219.

qsmm_msglist_t message list Section 6.3.1 [Creating a Message List],page 218.

qsmm_prg_t assembler program Section 5.1 [Basic Datatypes], page 143.

qsmm_rng_t random number generator Section 6.1.1 [Creating a Random NumberGenerator], page 212.

Chapter 1: Introduction 10

qsmm_side_t interaction side Part of the Side API. See Section 6.4.1 [Regi-stering Interaction Sides], page 222.

qsmm_storage_t statistics storage Section 3.1 [Types of Storage], page 57.

qsmm_vec_t vector Section 6.2 [Ordinary and Sparse Vectors],page 217.

In a multithreaded program, it is generally acceptable to use different handles in differentthreads concurrently on condition that the handles are not interrelated. The handles areinterrelated e.g. in a situation when one handle refers to a component of an object referredto by another handle.

1.13 Error Handling

If a QSMM API function returns a value of type int, then it can be an error code. All error codesare negative. Zero and positive return values may indicate additional information regardingsuccessful completion of a function call. If a QSMM API function does not return a value of typeint, it may not return an error code, because error condition cannot arise within the function,or at least this was assumed when the function had first appeared in the QSMM API.

If not otherwise noted in the description of an error code of a QSMM API function, returningthe error code by the function means the system state remains unchanged, i.e. just after callingthe function the system is in the same state as just before calling the function.

To get the textual description of an error code, the following API function from the ‘qsmm.h’header can be used.

[Function]const char * qsmm_err_str (int err )This function returns the textual description of QSMM API error code err. For invalid errorcodes, string "(invalid error code)" is returned.

When you use the QSMM package for creating multinode models, you can associate an errorhandler with a model. In this case, the error handler may receive extended information on anerror occurred. The use of the error handler may eliminate the need to check return codes ofcalls to QSMM API functions, which take argument qsmm_t, to determine whether any of thesefunctions has failed. See Section 4.19 [Error Handling for a Multinode Model], page 130, forinformation on using error handlers.

Chapter 2: Optimal Action Generation Engine 11

2 Optimal Action Generation Engine

An optimal action generation engine, called an actor for short, interacts with an applicationprogram or the environment by means of exchanging signals. The actor emits output signals(or action signals) on the basis of input signals supplied to it. A list of occurrences of input andoutput signals with particular moments of time when those occurrences took place representsthe event history of the actor.

The actor generates output signals according to spur increments, which belong to one ormore spur types and are supplied to it along with input signals. See Section 1.2 [Spur-drivenBehavior], page 3, for definitions of spur and spur type.

To every spur type there correspond a way of spur perception, spur weight, and a type oftime used to compute spur increment velocity. A list of definitions of spur types used by theactor specifies its spur scheme.

2.1 Event History Example

An example of event history is shown in Figure 2.1. Filled dots denote input signals, andunfilled dots denote output signals. Above each dot, a signal identifier is indicated. In theexample event history pattern “input signal–input signal–input signal–output signal” is used,but in your programs you can use other patterns. Values below the time line indicate spurincrements that take place between receiving input signals.

To make a description of actor operating principles clearer, a single spur type is used in theexample. The spur type has a normal way of spur perception, weight 1, and a continuous typeof time used to compute spur increment velocity. For that spur type, the goal of actor operationis to emit output signals to increase the value of the spur as quicker as possible.

Figure 2.1: an example of event history

An actor state, represented by a list of signal identifiers of fixed length, on the basis of whichthe actor chooses an output signal, is called an action choice state. Typically, but not always,it is a known current system or environment state, for which it is needed to produce an optimalaction. In the example it is indicated that an action choice state is a list of identifiers of inputsignals, which are received by the actor between emitting output signals. An action choice state,denoted in the figure by a horizontal square bracket, is represented by list <1, 2, 5>. In somecases, it might be necessary to include in an action choice state the last output signal emitted.Thus, an example action choice state would be represented by list <7, 1, 2, 5>.

The actor generates output signals stochastically. Probability of emitting a specific outputsignal by the actor when producing an action is calculated using statistics collected over theevent history. The actor keeps track of output signals emitted in action choice states since thebeginning of its operation. It emits more often output signals, which give higher spur incrementvelocities calculated over periods of time passed between the moment when an action choicestate has been active and the next moment the same action choice state is active again1.

For example, let us suppose that the actor has recorded that output signal 9 emitted inaction choice state <1, 2, 5> provides spur increment +100 over a period of 20 units until the

1 In the QSMM package more complex formulas are used, so you should consider this statement as a simplifi-cation, which makes the algorithm easier to understand, but which does not fully agree with the practice.

Chapter 2: Optimal Action Generation Engine 12

actor registers action choice state <1, 2, 5> in the event history again. Let us assume that theactor has also recorded that output signal 8 emitted in action choice state <1, 2, 5> providesspur increment +120 over a period of 15 units until the actor registers action choice state <1,2, 5> the next time in the event history. Therefore, when generating future actions for actionchoice state <1, 2, 5>, the actor chooses signal 8 with higher probability than signal 9, becausethe former one has greater spur increment velocity2. When the actor emits the same outputsignal in the same action choice state more than once, the statistics is accumulated, and meanspur increment velocity is used to calculate the probability of output signal choice.

Specific moments of time, when the actor emits output signals, are determined by an appli-cation program that uses the actor. That is, for example, for action choice state <1, 2, 5> anActor API function did return to the application program information that the actor considersit is optimal to emit output signal 8. However, particular moment of time, when the actor emitsthat output signal, has to be chosen by the application program.

2.2 Small and Large Actors

The most time-consuming operation, which usually has to be frequently performed by an actor,is stochastic emitting an optimal output signal. The only actor type that was implemented inQSMM before version 1.15 is a small actor. The small actor performs the operation of stochasticemitting an optimal output signal in the following steps.

1. Relative probabilities of all output signals, which could be emitted, are calculated.

2. An optimal output signal to emit is chosen stochastically according to those relative probabi-lities using a random number generator.

From the standpoint of computer implementation, the most time-consuming is the first stepwhen the actor calculates relative probabilities of all possible output signals. Calculating everyrelative probability requires access to statistics storage, which is why it is time-expensive. Forexample, to choose an optimal output signal from a set of 16 output signals, 16 evaluations ofa function, which returns a relative probability of signal emitting, have to be performed by thesmall actor. This situation is illustrated in Figure 2.2.

Figure 2.2: emitting an output signal in an action choice state of small actor

To speed up emitting output signals by an actor, in QSMM version 1.15, there had beenintroduced the concept of large actor. A large actor provides fast stochastic selection of theoutput signal when the number of those signals is large or even huge. The only limitation is theamount of available memory for storing control structures of the large actor.

Efficiency in solving a problem by a large actor (as well as by small one) depends on afunction that returns a relative probability of signal emitting. The default function used by a

2 The actual formula also uses the number of signals encountered between the occurrence of action choice state<1, 2, 5>, in which the actor emits signal 8 or 9, and the next occurrence of action choice state <1, 2, 5> inthe event history.

Chapter 2: Optimal Action Generation Engine 13

large actor can provide moderate efficiency in solving certain kinds of problems, among which theidentification of current environment state. Those developers, who are unsatisfied with resultsproduced using that function, can supply a custom function via corresponding API calls.

Fast stochastic choice of output signals by a large actor is supported by using a tree thatcontains nodes, which are controlled by a small actor. With every tree node, the followingentities are associated.

1. An action choice state: either the root one, for which an optimal output signal has to begenerated, or an intermediate one.

2. A small array of relative probabilities of output signals (that typically contains a fewelements), which are either output signals of the large actor or intermediate output si-gnals. To every intermediate output signal there corresponds an intermediate action choicestate, which is located at a deeper hierarchy level.

Tree structure is illustrated in Figure 2.3, where indexed letters “s” represent intermediateaction choice states, and indexed letters “o” represent intermediate output signals.

Figure 2.3: emitting an output signal in an action choice state of large actor

A large actor performs the operation of stochastic emitting an optimal output signal by thefollowing algorithm.

1. Assign an action choice state, for which an optimal output signal has to be generated bythe large actor, to current intermediate action choice state.

2. Stochastically produce an optimal output signal for current intermediate action choice stateby a small actor associated with the large actor. This operation requires calculating relativeprobabilities of all output signals (typically a few ones) that correspond to current intermedi-ate action choice state.

Chapter 2: Optimal Action Generation Engine 14

3. An output signal generated at step 2 can be either an intermediate output signal or anoutput signal of the large actor. If the output signal is the one of the large actor, thenfinish.

4. Change current intermediate action choice state to one that corresponds to the intermediateoutput signal and go to step 2.

Thus, using a tree, represented in Figure 2.3, to choose an optimal output signal from a set of16 output signals, only 8 evaluations of a function, which returns a relative probability of signalemitting, are necessary. A taller binary tree provides the selection of optimal output signal froma set of 256 output signals using 16 evaluations of the function.

The structure of the tree affects the weights (or, in other words, the relative profile probabi-lities) of output signals of a large actor and the speed of emitting those signals by the actor.Large actors use n-ary Huffman trees to stochastically produce optimal output signals. By usinga Huffman tree built for a given list of output signal weights, emitting output signals, whichhave greater weights, requires the same or smaller number of evaluations of relative probabilityfunction compared with emitting output signals that have lesser weights.

Although having much the same API, small and large actors are not fully interchangeable.There are specifics of using actors of every type.

2.3 Basic Datatypes and Macros

A small or a large actor is referred to by an actor handle.

[Data type]qsmm_actor_tThis is a type for an actor handle. It is a pointer, so variables of this type can have zero value.Function qsmm_actor_create allocates a new actor handle. Function qsmm_actor_destroy

frees an existing actor handle. After allocating an actor handle, it can be passed to API

functions that take argument qsmm_actor_t until the handle is freed.

A special datatype exists for signal identifiers.

[Data type]qsmm_sig_tA datatype for storing signal identifiers defined as unsigned int. However, the supportednumber of signals cannot exceed the maximum value for the int type because of the way ofhow the library source code is written. The type could be changed to unsigned short toreduce the amount of memory needed to store statistics collected over the event history.

The following macros are associated with a datatype for signal identifiers.

[Macro]QSMM_SIG_INVALIDRepresents an invalid signal identifier. It is often used as a substitute for the NULL value ofsignal identifier, because identifier 0 is a valid one. Is defined as ((qsmm_sig_t) -1).

[Macro]QSMM_SIG_MAXRepresents the maximum possible value of signal identifier. Currently, for identifiers of theunsigned int type is defined to the maximum value of the int type. For identifiers of theunsigned short type, this macro could be defined as (QSMM_SIG_INVALID-1).

2.4 Creating an Actor

To create and destroy an actor, the following functions can be used.

[Function]int qsmm_actor_create (const struct qsmm actor desc s *desc_p,qsmm actor t *actor_p )

This function creates an actor using parameters specified in *desc p and stores a newlyallocated actor handle in *actor p.

Chapter 2: Optimal Action Generation Engine 15

The function returns a non-negative value on success or a negative error code on failure increating an actor. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Either argument actor p is 0 or parameters specified in *desc p are invalid.

QSMM_ERR_NOMEM

There was not enough memory to create an actor.

QSMM_ERR_BIGMDL

A large actor is to be created, but a multinode model, which shall provide operati-on of the actor, is too complicated. See Section 4.6 [Creating the Model Instance],page 105, for a description of error QSMM_ERR_BIGMDL which can be raised byfunction qsmm_engine_create when creating the multinode model instance andwhich causes function qsmm_actor_create to return this error code.

[Function]void qsmm_actor_destroy (qsmm actor t actor )This function destroys an actor specified by actor handle actor. After actor destruction, theactor handle must not be used. If actor is 0, then the function will do nothing.

A structure, a pointer to which is an argument of function qsmm_actor_create, along withan associated datatype, a union, and enclosed structures is described below.

[Structure]qsmm_actor_desc_sThis structure describes parameters for creating an actor. It contains the following fields.

[Field]char use_flat_storageA flag that specifies whether the actor should use flat storage or map storage for collectingstatistics on the event history. If the value of this field is non-zero and the value of fieldlarge_desc_p is zero, then flat storage will be used. If the value of this field is non-zero and the value of field large_desc_p is non-zero, then error QSMM_ERR_INVAL will bereported. If the value of this field is zero, then map storage will be used.

Flat storage is a preallocated storage presumably of big size, but with quick access todata elements. Map storage is a dynamically allocated storage presumably of lesser size,but with slower access to data elements; binary trees are used for backing storage. SeeSection 3.1 [Types of Storage], page 57, for additional information on statistics storagetypes.

[Field]int nspurThe number of spur types used by the actor. Must be greater than 0. If the actor is thelarge one, then a small actor, which is associated with the large actor, will use 1+nspur

spur types, where an implicitly added spur type with the lowest index corresponds to theautomatic spur of the small actor. See Section 2.11 [Automatic Spur], page 45, for moreinformation on that spur.

[Field]int ngram_szThe length of a list of signal identifiers, which defines an action choice state. Must begreater than 0. The longer the list is the more events in the event history are typicallyneeded to train the actor.

[Field]int profile_pool_szA non-negative size of the pool of probabilities lists in normal form that could be preparedand then set for particular action choice state n-grams. For a small actor, it is the maxi-mum number of unique sorted lists of output signal probabilities, which could be storedin the actor’s memory. For a large actor, it is the maximum number of Huffman trees of

Chapter 2: Optimal Action Generation Engine 16

unique structure, which could be stored in the actor’s memory (not counting an automati-cally created default Huffman tree that corresponds to case when profile probabilities ofall output signals are equal). To determine whether a Huffman tree has to be reused,a temporary Huffman tree could be created, which is why the value of this field shouldgenerally be greater by 1 than the number of Huffman trees of unique structure requiredto represent sorted lists of output signal probabilities.

[Field]int compatThe compatibility level of algorithms used by the actor. Must be 0 or 1. Value 0 meansto use original algorithms that were implemented in QSMM before version 1.15. Value 1means to use enhanced algorithms:

– use a simpler formula for automatic spur increment;

– in a formula, which gives a relative probability of output signal choice, additionallymultiply the mean discrete cycle period by a value returned by function qsmm_get_

actor_naction_per_evt and possibly by 2.

Setting a value of this field to 1 is recommended for your new programs. This manualdoes not include outdated details specific to the original algorithms.

[Field]double sparse_fill_maxThe maximum fill ratio for vectors that hold relative probabilities of output signals choice,on the basis of which the actor decides when to use sparse vectors instead of ordinaryvectors. Must be a number between 0 and 1 (inclusive). Value 0 indicates that the actormust always use ordinary vectors. Value 1 indicates that the actor must always use sparsevectors. Values between 0 and 1 indicate the maximum percentage (divided by 100) ofnon-zero elements in sparse vectors relative to the number of vector dimensions.

Note: when a large actor is created (i.e. field large_desc_p has a non-zerovalue), forgetting to set field sparse_fill_max to a positive value, e.g. to 0.2,will cause bad actor performance.

[Field]qsmm_rng_t rngThe handle of a random number generator to be used by the actor. See Section 6.1[Random Number Generators], page 212, for information on how to create, destroy randomnumber generators, and perform other operations on them. Can be 0, in which case aninstance of default random number generator is automatically created for use by the actorand destroyed upon actor destruction.

[Field]enum qsmm_actor_sig_spec_e sig_spec_typeThe type of specification of the number and directions of signals used by the actor. Here“signal direction” means whether a signal is input one, output one, or belongs to bothtypes.

Value QSMM_ACTOR_SIG_SPEC_IN_OUT means that the number of input signals and thenumber of output signals are specified in field sig_spec of this structure.

Value QSMM_ACTOR_SIG_SPEC_MASK means that the total number of signals and a mask,which describes directions of those signals, are specified in field sig_spec of this structure.

[Field]union qsmm_actor_sig_spec_u sig_specA specification of the number and direction of signals used by the actor.

If field sig_spec_type of this structure has value QSMM_ACTOR_SIG_SPEC_IN_OUT, thenthe specification of the number and direction of signals must be stored in sig_spec.in_

out.

If field sig_spec_type of this structure has value QSMM_ACTOR_SIG_SPEC_MASK, then thespecification of the number and direction of signals must be stored in sig_spec.mask.

Chapter 2: Optimal Action Generation Engine 17

[Field]struct qsmm_pair_sig_s * range_sig_pRanges of signal identifiers in a list that defines an action choice state. Those ranges areused to check the validity of a list of signal identifiers, which defines current action choicestate, in various Actor API functions, to reduce the memory footprint of flat storage if asmall actor uses such storage, and to reduce the number of nodes in a multinode modelthat corresponds to a large actor. In future versions of the package, the ranges can beused for other purposes. To reduce the memory footprint of the actor, it is recommendedto specify the ranges as precisely as possible.

If this field has a non-zero value, then it must be a pointer to an array of ngram_szelements, which correspond to elements of a list that defines an action choice state, whereeach element is a pair. Field first of a pair defines the minimum value of signal identifierand field second of a pair defines the maximum value of signal identifier. The value offirst must be less than or equal to the value of second, and the value of second must beless than the total number of signals of the actor specified using fields sig_spec_type andsig_spec of this structure. If field range_sig_p has zero value, then it will be assumedthat every signal in the list, which defines an action choice state, can be in the range 0 tothe total number of signals of the actor (exclusive).

[Field]struct qsmm_actor_large_desc_s * large_desc_pParameters of large actor. A non-zero value of this field indicates to create a large actor.

To improve compatibility with future versions of the library, an instance of structure qsmm_

actor_desc_s, a pointer to which is passed to function qsmm_actor_create, should be zeroedusing function memset before setting values of structure fields.

[Enumeration]qsmm_actor_sig_spec_eThis enumeration specifies how the number and direction of signals of an actor are storedin field sig_spec of structure qsmm_actor_desc_s. The enumeration contains the followingelements.

QSMM_ACTOR_SIG_SPEC_IN_OUT

The actor has specified number of input signals and specified number of outputsignals. A segment of output signal identifiers follows a segment of input signalidentifiers. For example, if the actor has 6 input signals and 4 output signals,then signals 0, 1, 2, 3, 4, 5 will be input ones, and signals 6, 7, 8, 9 will beoutput ones. The numbers of input and output signals should be stored in fieldsig_spec.in_out of structure qsmm_actor_desc_s.

QSMM_ACTOR_SIG_SPEC_MASK

The actor has specified total number of signals. Every signal can be input one.A mask is given that describes which of those signals are also output ones. Thetotal number of signals and the mask should be stored in field sig_spec.mask

of structure qsmm_actor_desc_s.

[Union]qsmm_actor_sig_spec_uThis union describes in two possible forms the number and direction of signals of an actor.Field sig_spec of structure qsmm_actor_desc_s holds that information. The union containsthe following fields.

[Field]struct qsmm_actor_sig_spec_in_out_s in_outThe number of input signals and the number of output signals. This field is used whenfield sig_spec_type of structure qsmm_actor_desc_s has value QSMM_ACTOR_SIG_SPEC_

IN_OUT.

Chapter 2: Optimal Action Generation Engine 18

[Field]struct qsmm_actor_sig_spec_mask_s maskThe total number of signals and a subset of output signals. This field is used when fieldsig_spec_type of structure qsmm_actor_desc_s has value QSMM_ACTOR_SIG_SPEC_MASK.

[Structure]qsmm_actor_sig_spec_in_out_sThis structure specifies the number of input signals and the number of output signals of anactor. It contains the following fields.

[Field]int nsig_inThe number of input signals of the actor. Must be greater than 0.

[Field]int nsig_outThe number of output signals of the actor. Must be greater than 1.

The sum of values in fields nsig_in and nsig_out must be less than or equal to QSMM_SIG_

MAX+1.

[Structure]qsmm_actor_sig_spec_mask_sThis structure specifies the total number of signals and a subset of output signals of an actor.It contains the following fields.

[Field]char * is_sig_ctrl_pIf the value of this field is zero, then all actor signals will be output ones; some or allof those signals can be input ones. If the value of this field is non-zero, then the fieldmust contain a pointer to an array that holds nsig (see the next field) elements. A zeroelement indicates that a signal with a corresponding identifier is an input signal. A non-zero element indicates that a signal with a corresponding identifier is an output signaland possibly input one. The array must contain at least two non-zero elements. Whencreating an actor, the array is copied to an internal structure of the actor.

[Field]int nsigThe total number of signals of the actor. Must be greater than 1 and less than or equalto QSMM_SIG_MAX+1.

[Structure]qsmm_pair_sig_sThis structure represents a pair of signals, e.g. a signal range. It contains the following fields.

[Field]qsmm_sig_t firstThe first element of the pair. If the pair represents a range of signals, then the minimumvalue of signal identifier.

[Field]qsmm_sig_t secondThe second element of the pair. If the pair represents a range of signals, then the maximumvalue of signal identifier.

[Structure]qsmm_actor_large_desc_sThis structure specifies parameters of large actor. It contains only one field, but is designedas a structure to simplify adding new parameters of large actor in future versions of thepackage.

[Field]int tree_arityThe maximum number of child nodes of every node of Huffman trees used for stochasticselection of optimal output signals by the large actor. Must be greater than 1. You canuse value 2 in most cases. It is better to use the number of output signals of large actorequal to positive integer powers of the value of this field.

Chapter 2: Optimal Action Generation Engine 19

To improve compatibility with future versions of the library, an instance of structure qsmm_

actor_large_desc_s (a pointer to which is assigned to field large_desc_p of structure qsmm_actor_desc_s) should be zeroed using function memset before setting the value of field tree_

arity.

Below there is given sample code for creating a small actor.

int rc;

qsmm_actor_t actor=0;

struct qsmm_actor_desc_s actor_desc;

struct qsmm_actor_sig_spec_in_out_s *spec_in_out_p;

memset(&actor_desc,0,sizeof(actor_desc));

actor_desc.nspur=1;

actor_desc.ngram_sz=3;

actor_desc.compat=1;

actor_desc.sig_spec_type=QSMM_ACTOR_SIG_SPEC_IN_OUT;

spec_in_out_p=&actor_desc.sig_spec.in_out;

spec_in_out_p->nsig_in=6;

spec_in_out_p->nsig_out=4;

if ((rc=qsmm_actor_create(&actor_desc,&actor))<0)

fprintf(stderr,"qsmm_actor_create: %s\n",qsmm_err_str(rc));

Below there is given sample code for creating a large actor.

int rc;

qsmm_actor_t actor=0;

struct qsmm_pair_sig_s range_sig[3];

struct qsmm_actor_desc_s actor_desc;

struct qsmm_actor_large_desc_s large_desc;

struct qsmm_actor_sig_spec_in_out_s *spec_in_out_p;

memset(&range_sig,0,sizeof(range_sig));

range_sig[0].second=5;

range_sig[1].second=5;

range_sig[2].second=5;

memset(&large_desc,0,sizeof(large_desc));

large_desc.tree_arity=2;

memset(&actor_desc,0,sizeof(actor_desc));

actor_desc.nspur=1;

actor_desc.ngram_sz=3;

actor_desc.compat=1;

actor_desc.sparse_fill_max=0.2;

actor_desc.sig_spec_type=QSMM_ACTOR_SIG_SPEC_IN_OUT;

spec_in_out_p=&actor_desc.sig_spec.in_out;

spec_in_out_p->nsig_in=6;

spec_in_out_p->nsig_out=4096;

actor_desc.range_sig_p=range_sig;

// signal list, which defines an action choice state, is assumed to

// consist only of input signals of the actor

actor_desc.large_desc_p=&large_desc;

if ((rc=qsmm_actor_create(&actor_desc,&actor))<0)

fprintf(stderr,"qsmm_actor_create: %s\n",qsmm_err_str(rc));

Parameters specified when creating an actor can be obtained later using the following functi-ons.

Chapter 2: Optimal Action Generation Engine 20

[Function]int qsmm_get_actor_nspur (qsmm actor t actor )This function returns a positive integer equal to the number of spur types used by actor,which is specified in field nspur of structure qsmm_actor_desc_s when creating the actor byfunction qsmm_actor_create.

[Function]int qsmm_get_actor_ngram_sz (qsmm actor t actor )This function returns a positive integer number equal to the length of a list of signal identifiers,which defines an action choice state of an actor. It is the length, which is specified in fieldngram_sz of structure qsmm_actor_desc_s when creating the actor using function qsmm_

actor_create.

[Function]int qsmm_get_actor_profile_pool_sz (qsmm actor t actor )This function returns a non-negative integer number equal to the size of the pool of probabili-ties lists in normal form of actor. It is the size, which is specified in field profile_pool_sz ofstructure qsmm_actor_desc_s when creating the actor using function qsmm_actor_create.

[Function]int qsmm_get_actor_compat (qsmm actor t actor )This function returns a non-negative integer number equal to a compatibility level of algori-thms used by actor, which is specified in field compat of structure qsmm_actor_desc_s whencreating the actor by function qsmm_actor_create.

[Function]int qsmm_get_actor_nsig (qsmm actor t actor )This function returns a positive integer equal to the total number of signals of actor.

If the value of field sig_spec_type of structure qsmm_actor_desc_s passed to functionqsmm_actor_create when creating the actor is equal to QSMM_ACTOR_SIG_SPEC_IN_OUT, thenthe total number of signals will be the sum of values of fields nsig_in and nsig_out ofstructure qsmm_actor_sig_spec_in_out_s specified in field sig_spec.in_out of structureqsmm_actor_desc_s.

If the value of field sig_spec_type is equal to QSMM_ACTOR_SIG_SPEC_MASK, then the totalnumber of signals will be the value of field sig_spec.mask.nsig of structure qsmm_actor_

desc_s.

[Function]int qsmm_get_actor_nsig_out (qsmm actor t actor )This function returns a positive integer equal to the number of output signals of actor.

If the value of field sig_spec_type of structure qsmm_actor_desc_s passed to function qsmm_

actor_create when creating the actor is equal to QSMM_ACTOR_SIG_SPEC_IN_OUT, then thenumber of output signals will be the value of field sig_spec.in_out.nsig_out of structureqsmm_actor_desc_s.

If the value of field sig_spec_type is equal to QSMM_ACTOR_SIG_SPEC_MASK, then the numberof output signals will be the number of non-zero elements in an array pointed by field sig_

spec.mask.is_sig_ctrl_p of structure qsmm_actor_desc_s.

[Function]double qsmm_get_actor_sparse_fill_max (qsmm actor t actor )This function returns the maximum fill ratio for vectors that hold relative probabilities ofoutput signals choice, on the basis of which actor decides when to use sparse vectors insteadof ordinary vectors. It is a value, which is specified in field sparse_fill_max of structureqsmm_actor_desc_s when creating the actor using function qsmm_actor_create.

[Function]const struct qsmm_pair_sig_s * qsmm_get_actor_range_sig(qsmm actor t actor )

This function returns a pointer to an array (stored in an internal structure of an actor),which describes possible ranges of signals in a list of signal identifiers, which defines an actionchoice state. The contents of the array are specified using field range_sig_p of structure

Chapter 2: Optimal Action Generation Engine 21

qsmm_actor_desc_s when creating the actor by function qsmm_actor_create. The numberof elements in the array is equal to the length of a list of signal identifiers, which defines anaction choice state. That length can be retrieved by function qsmm_get_actor_ngram_sz.

A datatype, which represents a statistics storage handle, is qsmm_storage_t. The handle ofstatistics storage of an actor can be obtained using the following function.

[Function]qsmm_storage_t qsmm_get_actor_storage (qsmm actor t actor )This function returns the handle of storage used by actor for collecting statistics on the eventhistory. If the actor is the large one, then the storage will hold only part of the statistics.Other part of the statistics will be stored in Huffman trees created within a multinode modelthat corresponds to the large actor. This function never returns 0.

A datatype, which represents a multinode model that corresponds to a large actor, is qsmm_t.The handle of a multinode model of an actor can be obtained using the following function.

[Function]qsmm_t qsmm_get_actor_large_model (qsmm actor t actor )This function returns the handle of a multinode model used by a large actor to stochasticallygenerate optimal output signals. If an actor is not large one, then 0 will be returned. Thisfunction can be used to determine whether an actor is large one, in which case the functionalways returns a non-zero value.

2.5 Incrementing Time

There are two types of time associated with an actor.

The actor tracks discrete time equal to the number of input signals received plus the numberof output signals emitted by the actor since the beginning of its operation. The actor normallyuses discrete time when calculating probabilities of output signals choice.

The actor can also track continuous time equal to a logical period of time the event historyoccupies since the start of actor operation. The actor can use continuous time to compute spurincrement velocities when calculating probabilities of output signals choice.

To convey information to an actor that a period of continuous time has passed in eventhistory, during which there were no input signals received by the actor, the following functioncan be used.

[Function]int qsmm_actor_time_delta (qsmm actor t actor, double time_delta )This function increments by time delta the value of continuous time associated with actor.

On success, a non-negative value is returned. If time delta is not a finite number or if theincremented value of continuous time becomes non-finite or negative, then no increment willbe performed, and negative error code QSMM_ERR_INVAL will be returned.

To get the current value of continuous time associated with an actor, the following functioncan be used.

[Function]double qsmm_get_actor_continuous_time (qsmm actor t actor )This function returns the value of continuous time associated with actor. The returned valueis always finite and non-negative.

To get or set the value of discrete time associated with an actor, the following functions canbe used.

[Function]long qsmm_get_actor_discrete_time (qsmm actor t actor )This function returns the value of discrete time associated with actor.

Chapter 2: Optimal Action Generation Engine 22

[Function]void qsmm_set_actor_discrete_time (qsmm actor t actor, long tmd )This function sets the value of discrete time associated with actor to tmd.

A type of time used by a small actor when calculating spur increment velocity is specifiedvia the following enumeration.

[Enumeration]qsmm_time_eThis enumeration specifies a type of time. It contains the following elements.

QSMM_TIME_DISCRETE

Discrete time.

QSMM_TIME_CONTINUOUS

Continuous time.

A large actor normally uses continuous time when calculating increment velocities of spurof types, the number of which was specified when creating the actor. Internally, a small actorassociated with the large actor normally uses discrete time when calculating the incrementvelocity of the automatic spur.

To retrieve or set the type of time, according to which a small actor calculates incrementvelocity of spur of a particular type, the following functions can be used.

[Function]int qsmm_get_actor_spur_time (qsmm actor t actor, int spur_type,enum qsmm time e *time_type_p )

This function sets *time type p to a type of time, according to which actor calculatesincrement velocity for spur type spur type. Spur types have zero-based indices. If ti-me type p is 0, then *time type p will not be set.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of spur type is negative or is greater than or equal to the number ofspur types specified when creating the actor.

QSMM_ERR_NOSYS

The actor is the large one.

[Function]int qsmm_set_actor_spur_time (qsmm actor t actor, int spur_type,enum qsmm time e time_type )

This function sets to time type a type of time, according to which actor calculates incrementvelocity for spur type spur type. Spur types have zero-based indices. If the value of time typeis invalid, then behavior of the actor will be undefined.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of spur type is negative or is greater than or equal to the number ofspur types specified when creating the actor.

QSMM_ERR_NOSYS

The actor is the large one.

Function qsmm_actor_create initializes types of time for all spur types of a newly createdsmall actor to QSMM_TIME_CONTINUOUS.

Chapter 2: Optimal Action Generation Engine 23

2.6 Incrementing Spur

The value of the spur of given type an actor keeps track of can be incremented using the followingfunction.

[Function]int qsmm_actor_spur_delta (qsmm actor t actor, int spur_type, doublespur_delta )

This function increments by spur delta the value of the spur of type spur type an actor hasbeen accumulating. Spur types, the number of which was specified when creating the actor,have zero-based indices. Special spur type −1 of a large actor corresponds to the automaticspur of a small actor associated with the large actor. The value of spur delta can be negative.

On success, a non-negative value is returned. If the actor is the small one and spur type isnegative, or if the actor is the large one and spur type is less than −1, or if spur type isgreater than or equal to the number of spur types specified when creating the actor, or ifspur delta is non-finite, or if the incremented value of the spur becomes non-finite, then noincrement will be performed and negative error code QSMM_ERR_INVAL will be returned.

To get the current value of the spur of given type an actor keeps track of, the followingfunction can be used.

[Function]int qsmm_get_actor_spur (qsmm actor t actor, int spur_type, double*spur_p )

This function sets *spur p to a current value of the spur of type spur type an actor has beenaccumulating. Spur types, the number of which was specified when creating the actor, havezero-based indices. Special spur type −1 of a large actor corresponds to the automatic spurof a small actor associated with the large actor. If spur p is 0, then *spur p will not be set,otherwise *spur p will always be finite.

On success, a non-negative value is returned. If the actor is the small one and spur type isnegative, or if the actor is the large one and spur type is less than −1, or if spur type isgreater than or equal to the number of spur types specified when creating the actor, thennegative error code QSMM_ERR_INVAL will be returned.

2.7 Event History N-gram

An action choice state is a list of signal identifiers of fixed length, on the basis of which an actorcan generate an output signal. That length has to be specified in field ngram_sz of structureqsmm_actor_desc_s when creating the actor using function qsmm_actor_create and can beretrieved later by function qsmm_get_actor_ngram_sz.

There is a window associated with an actor, the contents of which are n-grams of lengthngram_sz from the event history. When creating an actor, elements of the window are initializedto 0. For example, when ngram_sz is equal to 3, the contents of the window just after creatingthe actor are <0, 0, 0>.

The contents of the window shift one signal left and a new signal from the event historybecomes the last signal of the window after a call to function qsmm_actor_shl_sig, qsmm_actor_reg_sig_in, or qsmm_actor_reg_sig_action. Shifting the contents of the window onesignal left also implies incrementing by 1 discrete time tracked by the actor.

To shift the contents of the window one signal left and append a new signal from the eventhistory, so that the window would contain an n-gram that represents an action choice state,function qsmm_actor_reg_sig_in should be used. This function updates statistics, collectedover the event history, using information recorded when the same action choice state has occurredthe previous time in the event history.

To shift the contents of the window one signal left and append a new signal, which is anoutput signal generated by the actor (or another output signal the application program has

Chapter 2: Optimal Action Generation Engine 24

chosen to emit), function qsmm_actor_reg_sig_action should be used. You should usuallycall this function after a call to qsmm_actor_reg_sig_in. It records for an action choice statediscrete and continuous time of the last occurrence of the action choice state in the event history,an output signal emitted in that action choice state, and current value of the spur of every typethe actor has been accumulating.

Note: because function qsmm_actor_reg_sig_action records time and values ofspur for an action choice state, which has just occurred in the event history, functionsqsmm_actor_time_delta and qsmm_actor_spur_delta usually should not be calledbetween a call to qsmm_actor_reg_sig_in and a subsequent call to qsmm_actor_

reg_sig_action.

In all other cases, to shift the contents of the window one signal left and append a new signalfrom the event history, function qsmm_actor_shl_sig should be used. This function does notupdate statistics collected over the event history.

In Figure 2.4, there is shown an example of changing a window, which holds current n-gramfrom the event history, caused by calls to Actor API functions. This example corresponds tofirst eight events from event history shown in Figure 2.1. N-grams, which represent action choicestates, are marked by thick lines.

Figure 2.4: example of changing current n-gram of event history

Functions, which shift the contents of the window one signal left and increment by 1 discretetime tracked by an actor, are described in detail below.

[Function]int qsmm_actor_shl_sig (qsmm actor t actor, qsmm sig t sig_last,qsmm sig t *sig_first_p )

This function shifts one signal left the contents of a window of actor, which holds currentn-gram from the event history, and appends signal sig last to the end of the window. Discretetime tracked by the actor is incremented by 1. A signal, which was at the beginning of thewindow before the shift, is returned in *sig first p if sig first p is not 0.

For example, if the window contained signals <3, 6, 2>, then after executing lines of code

qsmm_sig_t sig_first=QSMM_SIG_INVALID;

qsmm_actor_shl_sig(actor,4,&sig_first);

the window would contain signals <6, 2, 4>, and sig_first would be equal to 3.

On success, the function returns a non-negative value. If sig last is greater than or equal tothe number of signals of the actor, then negative error code QSMM_ERR_INVAL will be returned.

Chapter 2: Optimal Action Generation Engine 25

[Function]int qsmm_actor_reg_sig_in (qsmm actor t actor, qsmm sig t sig )This function shifts one signal left the contents of a window of actor, which holds currentn-gram from the event history, and appends signal sig to the end of the window. Discretetime tracked by the actor is incremented by 1. The resulting contents of the window areconsidered to be an n-gram that represents an action choice state. If that action choice statedid not occur earlier in the event history, then the function finishes execution.

If that action choice state did occur earlier in the event history, then for a pair, whichconsists of the action choice state and an output signal emitted when the action choice statehas occurred the previous time in the event history (that moment is referred to below as thetime of the last occurrence of the pair), statistics is updated in the following way:

– the number of occurrences of the pair is incremented;

– the sum of periods of discrete time for the pair is incremented by the difference betweencurrent discrete time and discrete time recorded when the pair has occurred the lasttime;

– the sum of periods of continuous time for the pair is incremented by the differencebetween current continuous time and continuous time recorded when the pair hasoccurred the last time;

– if automatic spur is used, then it will be incremented by the logarithm of the probabilityof occurrence of the pair in the event history (see Section 2.11 [Automatic Spur], page 45,for additional information);

– for every type of spur the actor has been accumulating, the sum of spur increments forthe pair is incremented by the difference between the current value of the spur and thevalue of the spur recorded when the pair has occurred the last time.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of sig is greater than or equal to the number of signals of the actor.

QSMM_ERR_NGRAM

After shifting one signal left the contents of an actor window, which holds currentn-gram from the event history, and appending signal sig to the end of the window,that window would correspond to an invalid action choice state. To determinethe validity of an action choice state, it is checked for accordance with allowedranges of signal identifiers specified using field range_sig_p of structure qsmm_

actor_desc_s when creating the actor.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the actor in indeterminate state.

QSMM_ERR_NOMEM

A statistics storage access function did return out of memory error. This couldleave the actor in indeterminate state.

When you want to store an action choice state n-gram of length greater than 1 in an actorwindow that holds current n-gram from the event history, you normally use a series of calls toqsmm_actor_shl_sig followed by a call to qsmm_actor_reg_sig_in:

int ii;

for (ii=0; ii<NGRAM_SZ-1; ii++)

if (qsmm_actor_shl_sig(actor,sig_ngram[ii],0)<0) goto Error;

if (qsmm_actor_reg_sig_in(actor,sig_ngram[NGRAM_SZ-1])<0) goto Error;

Chapter 2: Optimal Action Generation Engine 26

Note that, in some cases, it is necessary not to completely replace the contents of the window, soNGRAM_SZ should be changed to a value less than the length of a list of signal identifiers, whichrepresents an action choice state.

[Function]int qsmm_actor_reg_sig_action (qsmm actor t actor, qsmm sig t sig )This function registers signal sig as an output signal of actor emitted in an action choicestate, which corresponds to the contents of a window that holds current n-gram from theevent history.

The function records the following information for that action choice state:

– discrete time of the last occurrence of the action choice state in the event history equalto current discrete time tracked by the actor;

– continuous time of the last occurrence of the action choice state in the event historyequal to current continuous time tracked by the actor;

– the output signal emitted in the action choice state;

– current value of the spur of every type the actor has been accumulating.

Finally, the function shifts one signal left the contents of the window, which holds currentn-gram from the event history, and appends signal sig to the end of the window. Discretetime tracked by the actor is incremented by 1.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Signal sig is not an output signal of the actor.

QSMM_ERR_NGRAM

The contents of an actor window, which holds current n-gram from the eventhistory, correspond to an invalid action choice state. To determine the validity ofan action choice state, it is checked for accordance with allowed ranges of signalidentifiers specified using field range_sig_p of structure qsmm_actor_desc_s

when creating the actor.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the actor’s memory in indeterminatestate. If the actor’s memory is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the actor’s memory state will become determinate.

QSMM_ERR_NOMEM

A statistics storage access function did return out of memory error. This couldleave the actor’s memory in indeterminate state. If the actor’s memory is inindeterminate state, then after removing a reason of the error, the operation canbe repeated, and if the function succeeds, then the actor’s memory state willbecome determinate.

To shift the contents of the window one signal right and decrement by 1 discrete time trackedby the actor, the following function can be used.

[Function]int qsmm_actor_shr_sig (qsmm actor t actor, qsmm sig t sig_first,qsmm sig t *sig_last_p )

This function shifts one signal right the contents of an actor window, which holds currentn-gram from the event history, and prepends signal sig first to the beginning of the window.Discrete time tracked by the actor is decremented by 1. A signal, which was at the end ofthe window before the shift, is returned in *sig last p if sig last p is not 0.

On success, the function returns a non-negative value. If sig first is greater than or equal tothe number of signals of the actor, then negative error code QSMM_ERR_INVAL will be returned.

Chapter 2: Optimal Action Generation Engine 27

When using function qsmm_actor_shr_sig, remember that functions qsmm_actor_reg_sig_in and qsmm_actor_reg_sig_action should normally be called for increasing (or at least forequal) values of discrete time tracked by the actor. That is, after calling function qsmm_actor_

shr_sig certain number of times, function qsmm_actor_shl_sig usually should be called thecorresponding number of times to restore discrete time to the original value.

In some cases, it is necessary to analyze actor’s behavior when current action choice state isanother state. To do that, it is required to save the contents of the window, which holds currentn-gram from the event history, replace the contents with another n-gram, call an Actor API

function that calculates probabilities of emitting output signals, and finally restore the originalcontents of the window. An internal buffer, which holds the contents of the window, can beobtained using the following function.

[Function]qsmm_sig_t * qsmm_get_actor_sig_ngram (qsmm actor t actor )This function returns a pointer to an internal buffer of actor, which represents a window thatholds current n-gram from the event history. This function never returns 0. The numberof elements in the buffer is equal to the value specified in field ngram_sz of structure qsmm_

actor_desc_s when creating the actor using function qsmm_actor_create, which is the valuereturned by function qsmm_get_actor_ngram_sz.

To enumerate n-grams of action choice states, information on which is stored in the actor’smemory, the following function can be used.

[Function]int qsmm_actor_enum_ngrams (qsmm actor t actor, intngram_prefix_sz, const qsmm sig t *sig_ngram_prefix_p,qsmm enum ngrams callback func t callback_func, void *paramp )

This function enumerates n-grams of action choice states, information on which is stored inthe memory of actor. For a small actor, these are states, information on which is held instatistics storage of the actor, a handle to which can be obtained using function qsmm_get_

actor_storage. For a large actor, these are states from the union of the following statesets:

– states, to which there were assigned references to Huffman trees, but for which instancesof those trees have not been created yet;

– states, for which nodes in the multinode model were created to store instances of Huffmantrees;

– states, information on which is held in statistics storage of the large actor, a handle towhich can be obtained using function qsmm_get_actor_storage.

The function enumerates the above action choice states that have prefix sig ngram prefix pof length ngram prefix sz. If ngram prefix sz is 0, then sig ngram prefix p can be 0.

The process of enumeration is a repeated calling callback function callback func, to which anaction choice state n-gram and user parameter paramp are passed. If the callback functionreturns a positive value, then the process of enumeration will be continued. If the callbackfunction returns zero, then the process of enumeration will be terminated, and function qsmm_

actor_enum_ngrams will report success. If the callback function returns a negative value,then the process of enumeration will be terminated, and function qsmm_actor_enum_ngrams

will report failure.

In the current implementation, function qsmm_actor_enum_ngrams does not support recursivecalling from the callback function for the same actor.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 2: Optimal Action Generation Engine 28

QSMM_ERR_INVAL

The value of ngram prefix sz is less than 0 or is greater than the length of a listof signal identifiers, which defines an action choice state.

QSMM_ERR_CALLBACK

The callback function did return an error.

QSMM_ERR_STORAGE

Statistics storage failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The type of a pointer to a callback function, which is called for every enumerated actionchoice state, is described below.

[Data type]qsmm_enum_ngrams_callback_func_tThis is a type of callback function pointer, to which the following declaration corresponds:

typedef int (*qsmm_enum_ngrams_callback_func_t)(

qsmm_actor_t actor,

const qsmm_sig_t *sig_ngram_p,

void *paramp);

The callback function is called for every enumerated action choice state of an actor. Thelist of signal identifiers of an action choice state is passed via argument sig ngram p. Thelength of that list is equal to a value, which has to be specified in field ngram_sz of structureqsmm_actor_desc_s when creating the actor using function qsmm_actor_create and whichcan be retrieved later by function qsmm_get_actor_ngram_sz. A user parameter is passedvia argument paramp.

The callback function might return a positive value if the process of enumeration should becontinued, zero if the process of enumeration should be terminated, or a negative value onerror.

To remove information on an action choice state from the actor’s memory, the followingfunction can be used.

[Function]int qsmm_actor_remove_ngram (qsmm actor t actor, const qsmm sig t*sig_ngram_p )

This function removes information on an action choice state, specified by list of signal identi-fiers sig ngram p, from the memory of actor. The length of the list is equal to a value,which has to be specified in field ngram_sz of structure qsmm_actor_desc_s when creatingthe actor using function qsmm_actor_create and which can be retrieved later by functionqsmm_get_actor_ngram_sz.

For a small actor, the function removes information on the action choice state held in statisticsstorage of the actor, a handle to which can be obtained using function qsmm_get_actor_

storage. For a large actor, the function removes the following pieces of information if theyexist in the actor’s memory:

– a reference to a Huffman tree assigned to the action choice state;

– a node in the multinode model (that corresponds to the large actor), in which an instanceof Huffman tree is stored;

– information on the action choice state held in statistics storage of the large actor, ahandle to which can be obtained using function qsmm_get_actor_storage.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 2: Optimal Action Generation Engine 29

QSMM_ERR_NGRAM

Argument sig ngram p specifies an invalid action choice state n-gram. Todetermine the validity of an action choice state n-gram, it is checked foraccordance with allowed ranges of signal identifiers specified using field range_

sig_p of structure qsmm_actor_desc_s when creating the actor.

QSMM_ERR_NOTFOUND

The actor’s memory does not contain information on the action choice state,nothing to remove.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the actor’s memory in indetermi-nate state. If the actor’s memory is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds orreturns QSMM_ERR_NOTFOUND, then the actor’s memory state will become determi-nate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave theactor’s memory in indeterminate state. If the actor’s memory is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds or returns QSMM_ERR_NOTFOUND, then the actor’smemory state will become determinate.

2.8 Generating an Optimal Action

To calculate probabilities of emitting output signals for an action choice state, which is storedin an actor window that holds current n-gram from the event history, the following function canbe used.

[Function]int qsmm_actor_calc_action_prob (qsmm actor t actor, int rez1,qsmm sig t sig_beg, qsmm sig t sig_end, enum qsmm prob e prob_type )

This function fills the internal array of actor with probabilities of type prob type calculatedfor an action choice state, which is stored in an actor window that holds current n-gram fromthe event history. Argument rez1 is reserved for future use and must be equal to 0.

For a small actor, the contents of the internal array that holds probabilities calculated canbe used to stochastically choose an optimal output signal by function qsmm_get_actor_sig_

action. For a large actor, function qsmm_actor_calc_action_prob operates much moreslowly and should be used only when values of probabilities have to be obtained. Largeactors support calling function qsmm_get_actor_sig_action, which returns control quickly,without prior calling function qsmm_actor_calc_action_prob.

Arguments sig beg and sig end can be both zero or may specify identifiers of the first si-gnal (inclusive) and of the last signal (exclusive) of a signal segment for which the functionshould calculate probabilities. In the internal array that holds probabilities calculated, theprobability of the first signal of that signal segment has offset sig beg. Array elements withinthe signal segment, which do not correspond to output signals, are set to 0. If sig end is0, then the total number of actor signals will be used for the value of the last signal of thesignal segment. The function will execute faster when the signal segment is shorter, so it isrecommended to specify the segment as precisely as possible.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 2: Optimal Action Generation Engine 30

QSMM_ERR_INVAL

The value of sig beg is greater than or equal to a value (incremented by 1) ofthe last signal of the signal segment, or the value of sig end is greater than thetotal number of signals of the actor, or the value of prob type is invalid.

QSMM_ERR_NGRAM

The contents of an actor window, which holds current n-gram from the eventhistory, correspond to an invalid action choice state. To determine the validity ofan action choice state, it is checked for accordance with allowed ranges of signalidentifiers specified using field range_sig_p of structure qsmm_actor_desc_s

when creating the actor.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave a large actor in indeterminate state. Ifthe large actor is in indeterminate state, then after removing a reason of the error,the operation can be repeated, and if the function succeeds, then the actor’s statewill become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave a largeactor in indeterminate state. If the large actor is in indeterminate state, thenafter removing a reason of the error, the operation can be repeated, and if thefunction succeeds, then the actor’s state will become determinate.

A type of probabilities function qsmm_actor_calc_action_prob must calculate is specifiedusing an enumeration described below. The enumeration is also used in several other cases.

[Enumeration]qsmm_prob_eThis enumeration specifies a type of probabilities. It contains the following elements.

QSMM_PROB_AGGR

Aggregate probabilities based on learned and profile probabilities.

For a small actor, to calculate probabilities of type QSMM_PROB_AGGR, probabilitiesof types QSMM_PROB_LEARNT and QSMM_PROB_PROFILE (see below) are calculated,each learned probability is multiplied by a corresponding profile probability, andthe resulting array of values is normalized. For a large actor, the above operationis performed by the small actor for all nodes of the Huffman tree.

For a small actor, if you do not use profile probabilities, then it will be faster tocalculate probabilities of type QSMM_PROB_LEARNT, which are equal to probabili-ties of type QSMM_PROB_AGGR in this case.

For a large actor, probabilities of type QSMM_PROB_AGGR are ordinarily equal toprobabilities of type QSMM_PROB_LEARNT, because profile probabilities typicallyfollow only from a positional relationship of nodes of the Huffman tree (probabili-ties assigned to edges, which come from tree nodes to their child nodes, are usuallyequal), and those profile probabilities are taken into account when calculatingprobabilities of type QSMM_PROB_LEARNT.

QSMM_PROB_LEARNT

Learned probabilities, according to which optimal actions may be produced.

QSMM_PROB_PROFILE

For a small actor, profile probabilities specified a priori in statistics storage (seeSection 3.2 [Structures for Accessing Storage], page 58, for information on how topass profile probabilities to storage access functions to write them to storage). Fora large actor, profile probabilities, which follow from the structure of a Huffmantree that corresponds to an action choice state.

Chapter 2: Optimal Action Generation Engine 31

QSMM_PROB_FQ

Probabilities proportional to observed frequencies of emitting output signals.Those frequencies are automatically incremented for output signals with identi-fiers passed to function qsmm_actor_reg_sig_action, but the increment isactually performed by function qsmm_actor_reg_sig_in when the same acti-on choice state occurs again in the event history.

QSMM_PROB_COUNT

The last element of the enumeration equal to the number of supported types ofprobabilities.

To obtain a pointer to an internal array that holds probabilities of emitting output signals,which are calculated by function qsmm_actor_calc_action_prob, the following function can beused.

[Function]double * qsmm_get_actor_choice_sig_prob (qsmm actor t actor )This function returns a pointer to an internal array of actor, which holds (possibly relative)probabilities of emitting output signals. Using that pointer, the array can be examined ormodified by an application program. This function never returns 0. The number of elementsin the array is equal to the total number of signals of the actor returned by function qsmm_

get_actor_nsig. The array can be filled with probabilities of desired type using functionqsmm_actor_calc_action_prob. For a small actor, the contents of the array are used byfunction qsmm_get_actor_sig_action to stochastically generate an output signal, in whichcase the array may contain values of positive infinity or relative probabilities that do not sumup to 1.

Function qsmm_get_actor_choice_sig_prob locks the internal array of probabilities: whenthe internal array is represented by a sparse vector, the sparse vector is converted toan ordinary vector; after the conversion, the actor always uses ordinary vectors untilthe internal array of probabilities is released by function qsmm_actor_choice_sig_prob_

release. Forgetting to call function qsmm_actor_choice_sig_prob_release after a call toqsmm_get_actor_choice_sig_prob may dramatically decrease actor performance.

To release a locked internal array of probabilities, the following function can be used.

[Function]void qsmm_actor_choice_sig_prob_release (qsmm actor t actor )This function releases an internal array of actor that holds (possibly relative) probabilities ofemitting output signals, which could have been locked by function qsmm_get_actor_choice_

sig_prob. If the array is not locked, then the function will do nothing. After the release,a pointer that might have been previously obtained by function qsmm_get_actor_choice_

sig_prob must not be used.

When the internal array is locked or if is called for a large actor, function qsmm_actor_

calc_action_prob uses an ordinary vector for storing probabilities of emitting output signals,so elements of that ordinary vector can be accessed via a pointer returned by function qsmm_

get_actor_choice_sig_prob. When the internal array is released, function qsmm_actor_calc_

action_prob called for a small actor can use an ordinary or sparse vector for storing probabilitiesof emitting output signals depending on properties of the probability profile and on the value offield sparse_fill_max of structure qsmm_actor_desc_s specified when creating the actor.

There is a way to obtain the handle of an ordinary or sparse vector that holds probabilitiesof emitting output signals. It is a cheap operation that does not perform locking or convertinga sparse vector to an ordinary vector. The vector is returned as is, in read-only mode. SeeSection 6.2 [Ordinary and Sparse Vectors], page 217, for information on how to access theelements of the returned vector.

Chapter 2: Optimal Action Generation Engine 32

[Function]qsmm_vec_t qsmm_get_actor_choice_sig_prob_vec (qsmm actor tactor )

This function returns the handle of an ordinary or sparse vector of actor, which holds (possiblyrelative) probabilities of emitting output signals. This function never returns 0. The vectorcan be filled with probabilities of desired type using function qsmm_actor_calc_action_

prob. For a small actor, the contents of the vector are used by function qsmm_get_actor_

sig_action to stochastically generate an output signal.

To stochastically generate an output signal, the following function can be used.

[Function]int qsmm_get_actor_sig_action (qsmm actor t actor, int rez1,qsmm sig t sig_beg, qsmm sig t sig_end, qsmm sig t *sig_action_p )

If an actor is a small one, this function stochastically generates an output signal accordingto (possibly relative) probabilities stored in the internal array of the actor. That array canbe filled with probabilities of desired type using function qsmm_actor_calc_action_prob.A pointer to the array is returned by function qsmm_get_actor_choice_sig_prob. A read-only view of the array, which can speed up accessing its contents, is returned by functionqsmm_get_actor_choice_sig_prob_vec.

If an actor is a large one, this function stochastically generates an optimal output signalwithout using the aforementioned internal array. A Huffman tree is used to provide fast choiceof an output signal (the number of those signals can be very large) by the actor accordingto probabilities of type QSMM_PROB_AGGR, which can be computed by function qsmm_actor_

calc_action_prob. However, for large actors, there is no need to call that function beforecalling function qsmm_get_actor_sig_action; the number of calls to function qsmm_actor_

calc_action_prob should be made as little as possible, because for those actors that functionoperates very slowly.

A generated output signal is stored in *sig action p if sig action p is not 0. Argument rez1is reserved for future use and must be equal to 0.

Arguments sig beg and sig end can be both zero or may specify identifiers of the first signal(inclusive) and of the last signal (exclusive) of a signal segment, to which the generatedoutput signal should belong. However, for a large actor, the signal segment must include alloutput signals of the actor; see Section 2.10 [Specifying Weights of Output Signals], page 40,for information on how to choose an optimal output signal from different subsets of outputsignals of a large actor. In the internal array of small actor, a probability of the first signalof that signal segment has offset sig beg. If sig end is 0, then the total number of actorsignals will be used for the value of the last signal of the signal segment. The functionwill execute faster when the signal segment is shorter, so it is recommended to specify thesegment as precisely as possible. For a small actor, the function does not check whether asignal it generates actually belongs to a set of output signals of the actor: if an element of theinternal array within the signal segment has a positive value, then a corresponding signal canbe potentially returned by the function. If one or more relative probabilities in the internalarray within the signal segment have values of positive infinity, then for a small actor thefunction will choose an output signal as a uniformly distributed random element from the setof signals to which such infinite relative probabilities correspond.

To stochastically generate an output signal, the actor uses either a random number generatorsupplied via field rng of structure qsmm_actor_desc_s when creating the actor by functionqsmm_actor_create or an instance of default random number generator allocated automati-cally if 0 is specified in that field. The handle of a random number generator used by anactor can be obtained via function qsmm_get_actor_rng, e.g. to seed the generator.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 2: Optimal Action Generation Engine 33

QSMM_ERR_INVAL

One of the following conditions is met:

– the value of sig beg is greater than or equal to a value (incremented by 1)of the last signal of the signal segment;

– the value of sig end is greater than the total number of signals of the actor;

– the actor is the large one, and the value of sig beg is greater than the lowestoutput signal identifier of the actor;

– the actor is the large one, and the value of sig end is less than the highestoutput signal identifier of the actor plus 1;

– the actor is the small one and the internal array does not contain (withinthe signal segment) relative probabilities equal to positive infinity, but thesum of relative probabilities within the signal segment is not finite.

QSMM_ERR_WEIGHT

The actor is the small one, and a negative number or a non-finite number, whichis not a positive infinity, was encountered in the internal array within the signalsegment.

QSMM_ERR_NOCHOICE

The actor is the small one, and the internal array does not contain at least onepositive element within the signal segment.

QSMM_ERR_NGRAM

The actor is the large one, and the contents of an actor window, which holdscurrent n-gram from the event history, correspond to an invalid action choi-ce state. To determine the validity of an action choice state, it is checked foraccordance with allowed ranges of signal identifiers specified using field range_

sig_p of structure qsmm_actor_desc_s when creating the actor.

QSMM_ERR_STORAGE

Failure of statistics storage of a large actor. This could leave the large actor inindeterminate state.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation by a large actor. Thiscould leave the large actor in indeterminate state.

For a small actor, an optimal action is typically produced and registered using a sequence offunction calls like this:

qsmm_sig_t sig_action=QSMM_SIG_INVALID;

if (qsmm_actor_calc_action_prob(actor, 0, NSIG_IN, NSIG_IN+NSIG_OUT,

QSMM_PROB_LEARNT)<0)

goto Error;

if (qsmm_get_actor_sig_action(actor, 0, NSIG_IN, NSIG_IN+NSIG_OUT,

&sig_action)<0)

goto Error;

if (qsmm_actor_reg_sig_action(actor,sig_action)<0) goto Error;

However, if, in a particular case, the application program chooses on its own which outputsignal to emit, then calls to qsmm_actor_calc_action_prob and qsmm_get_actor_sig_action

can be omitted, but the small actor should be still notified of an output signal actually emittedusing a call to qsmm_actor_reg_sig_action.

For a large actor, to produce and register an optimal action, a call to qsmm_actor_calc_

action_prob is redundant and only decreases performance. The sequence of function calls lookslike this:

Chapter 2: Optimal Action Generation Engine 34

qsmm_sig_t sig_action=QSMM_SIG_INVALID;

if (qsmm_get_actor_sig_action(actor, 0, NSIG_IN, NSIG_IN+NSIG_OUT,

&sig_action)<0)

goto Error;

if (qsmm_actor_reg_sig_action(actor,sig_action)<0) goto Error;

Large actors do not support choosing an output signal by an application program. That is,for a large actor, it is incorrect to omit the call to qsmm_get_actor_sig_action before callingqsmm_actor_reg_sig_action, or to pass to the latter function a signal identifier other thanthat, which was returned by a preceding call to qsmm_get_actor_sig_action.

In QSMM version 1.16 there is introduced a function, which retrieves a probability of thelast output signal generated. The function returns control quickly even when called for a largeactor and can be used to calculate the time of emitting an output signal, e.g. according to theexponential probability distribution.

[Function]double qsmm_get_actor_prob_action (qsmm actor t actor )This function returns the probability of the last output signal generated by actor in functionqsmm_get_actor_sig_action. For a small actor, it is a probability that corresponds to theelement of an internal array of the actor, which holds relative probabilities of emitting outputsignals. For a large actor, it is the probability of a path from the root of the Huffman treeto its leaf that corresponds to the output signal. The returned value is always in the range0 to 1 (inclusive). If function qsmm_get_actor_sig_action is not yet called, then 0 will bereturned.

2.9 Customizing a Relative Probability Function

Efficient operation of a small or large actor, i.e. optimality of actions the actor produces, dependson the form of a function that returns a relative probability of output signal choice. It may wellbe true that, for different kinds of applications, different functions are more suitable. TheQSMM package provides a few built-in functions, which the programmer may select for use byan actor. Unfortunately, the author of the package experiences problems in: (1) providing asound theoretical basis for using those functions in the package (that basis might not exist forsome functions); (2) devising functions that give better efficiency than the functions currentlyprovided in the package. Author’s own experimenting had shown that, for some special cases,there do exist other functions, which give better efficiency, but he did fail to find general formsfor those functions, which would make possible to use them for wider ranges of values of actorparameters. To provide a way to solve the above problems by developers, in QSMM startingfrom version 1.15, there is supported a possibility to specify via the Actor API a custom relativeprobability function for use by an actor. To retrieve or set the type of relative probabilityfunction, the following functions can be used.

[Function]enum qsmm_relprob_e qsmm_get_actor_relprob_type (qsmm actor tactor )

This function returns the type of a function, which is used by an actor to calculate the relativeprobability of output signal choice. If the actor is the large one, then there will be returnedthe type of a function, which is used by a small actor associated with the large actor.

[Function]void qsmm_set_actor_relprob_type (qsmm actor t actor, enumqsmm relprob e relprob_type )

This function sets to relprob type the type of a function, which is used by actor to calculatethe relative probability of output signal choice. If the actor is the large one, then there willbe set the type of a function, which is used by a small actor associated with the large actor.If the value of relprob type is invalid, then behavior of the library will be undefined.

Chapter 2: Optimal Action Generation Engine 35

An enumeration that specifies supported types of relative probability function is describedbelow.

[Enumeration]qsmm_relprob_eThis enumeration specifies supported types of a function, which is used by an actor tocalculate the relative probability of output signal choice. It contains elements describedbelow.

In the description of elements h is an action choice state, z is an output signal, ne is thenumber of spur types, T is actor temperature multiplied by some constant, F (h, z) is arelative probability of emitting an output signal, l is a mean discrete time period between anoccurrence of action choice state h, in which output signal z was emitted, and subsequentoccurrence of h, multiplied by a value returned by function qsmm_get_actor_naction_per_

evt. That discrete time period is called a discrete cycle period for short. The mean numberof output signals of the actor is denoted by nout (see Section 2.13 [Other Parameters of anActor], page 48, for more information on computing that number). Spur weight for spur typei is denoted by W [i]. Function C(h, z, i), which is the ratio of spur increment velocities, iscomputed depending on the way of spur perception for spur type i (see further on in thissection).

QSMM_RELPROB_BUILTIN1

The relative probability function is defined by formula

F (h, z) =(√

κ(√

κ+√κ+ 1

)(nout − 1)

) 1T

∑ne

i=1W [i]C(h, z, i),

where κ = 2l. Paper “An Approach to Optimal Action Generation for a Systemthat Interacts with the Environment” available from the project homepage provi-des more details pertaining to the formula.

QSMM_RELPROB_BUILTIN2

The relative probability function is defined by formula

F (h, z) = nl+12T

∑ne

i=1W [i]C(h, z, i)out .

The author has empirically found the formula when developing version 1.15 of thepackage and making the actor generate output signals with frequencies proporti-onal to probabilities of those output signals. The probabilities were specified apriori, and spur increments supplied to the actor were equal to logarithms ofthose probabilities.

QSMM_RELPROB_BUILTIN3

[New in QSMM 1.16] The relative probability function is defined by formula

F (h, z) = nlT

∑ne

i=1W [i]C(h, z, i)out .

The formula is a simplification of a formula that corresponds to relative probabili-ty function type QSMM_RELPROB_BUILTIN2 and is meant for developers who preferbeauty and/or simplicity.

QSMM_RELPROB_USER1

The relative probability function is defined by formula

F (h, z) = exp

(f(l)

T

ne∑i=1

W [i]C(h, z, i)

),

where f(l) is a function of type qsmm_relprob_user1_func_t supplied by aprogrammer via a call to qsmm_set_actor_relprob_helper (see further on inthis section). If function f(l) is not supplied, then 1 will be used for it.

Chapter 2: Optimal Action Generation Engine 36

QSMM_RELPROB_USER2

[New in QSMM 1.16] The relative probability function is defined by formula

F (h, z) = egT ,

where g is a function of type qsmm_relprob_user2_func_t supplied by aprogrammer via a call to qsmm_set_actor_relprob_helper (see further on inthis section). Function g receives the value of z and statistics associated with hand z that might be needed to devise a sophisticated relative probability function.

When creating a small actor, function qsmm_actor_create initializes the type of relativeprobability function to QSMM_RELPROB_BUILTIN1. When creating a large actor, function qsmm_

actor_create initializes the type of relative probability function of a small actor, which isassociated with the large actor, to QSMM_RELPROB_BUILTIN2.

Types for functions f(l) and g are described below.

[Data type]qsmm_relprob_user1_func_tThis is a type for a pointer to a helper function that can be supplied by a programmer whenthe type of relative probability function is set to QSMM_RELPROB_USER1. To this type thefollowing declaration corresponds:

typedef double (*qsmm_relprob_user1_func_t)(

qsmm_actor_t actor,

double cycle_period,

void *paramp);

The handle of an actor that has called the helper function is passed via argument actor. Thevalue of l is passed via argument cycle period. A user parameter specified when setting thehelper function is passed via argument paramp. The helper function should return the valueof f(l).

[Data type]qsmm_relprob_user2_func_tThis is a type for a pointer to a helper function that should be supplied by a programmerwhen the type of relative probability function is set to QSMM_RELPROB_USER2. To this typethe following declaration corresponds:

typedef double (*qsmm_relprob_user2_func_t)(

qsmm_actor_t actor,

qsmm_sig_t sig_cycle,

const struct qsmm_state_s *state_p,

const struct qsmm_cycle_s *cycle_p,

const struct qsmm_sspur_s *sspur_p,

const struct qsmm_cspur_s *cspur_p,

void *paramp);

The handle of an actor that has called the helper function is passed via argument actor. Thevalue of z is passed via argument sig cycle. Statistics associated with h and z is passed viaarguments state p, cycle p, sspur p, and cspur p. See Section 3.2 [Structures for AccessingStorage], page 58, for a description of corresponding structures. A user parameter specifiedwhen setting the helper function is passed via argument paramp. The helper function shouldreturn the value of g.

To obtain working parameters of an actor, in the body of helper function such functionsas qsmm_get_actor_nsig_ctrl and qsmm_get_actor_discrete_cycle_period_mean may becalled. See Section 2.13 [Other Parameters of an Actor], page 48, for a detailed description ofthese functions.

To retrieve or set a helper function for an actor, the following functions can be used.

Chapter 2: Optimal Action Generation Engine 37

[Function]void qsmm_get_actor_relprob_helper (qsmm actor t actor, void**helper_func_pp, void **helper_func_param_pp )

This function retrieves information on a helper function, which is used by actor whencalculating a relative probability of output signal choice. If helper func pp is not 0, then thefunction will set *helper func pp to a pointer to the helper function. If helper func param ppis not 0, then the function will set *helper func param pp to a user parameter of the helperfunction specified when setting the helper function for the actor. If there is no helper functionset for the actor, and helper func pp is not 0, then this function will set *helper func pp to 0.If the actor is the large one, then this function will retrieve information on a helper function,which is used by a small actor associated with the large actor. A particular interpretationof a pointer, which is stored in *helper func pp, depends on the type of relative probabilityfunction set for the actor using a call to qsmm_set_actor_relprob_type.

[Function]void qsmm_set_actor_relprob_helper (qsmm actor t actor, void*helper_func_p, void *helper_func_param_p )

This function sets a pointer to a helper function, which is used by actor when calculating arelative probability of output signal choice, to helper func p and a user parameter of thathelper function to helper func param p. If the actor is the large one, then this function willset the helper function for a small actor associated with the large actor.

A particular interpretation of pointer helper func p depends on the type of relative probabi-lity function set for the actor using a call to qsmm_set_actor_relprob_type. Providinga pointer that does not conform with the type of relative probability function will lead toundefined behavior of the library. The value of helper func p can be 0, which means thatthere is no helper function set for the actor (this makes a certain sense when the type ofrelative probability function is QSMM_RELPROB_USER1).

To provide an example of using functions qsmm_set_actor_relprob_type and qsmm_set_

actor_relprob_helper, let us suppose that a developer has proved that it is mathematicallycorrect to use a function for calculating a relative probability of output signal choice, which differsfrom the function of type QSMM_RELPROB_BUILTIN2 in the following: instead of expression l+1,expression l is used in the numerator of the exponent. To make an actor to calculate a relativeprobability using this function, the developer may define a helper function like

#include <math.h>

static double get_relprob_exp_mlt(qsmm_actor_t actor,

double cycle_period,

void *paramp) {

return log(qsmm_get_actor_nsig_ctrl(actor))*cycle_period/2;

}

To set this helper function for use by an actor, the developer may write function calls

qsmm_set_actor_relprob_type(actor,QSMM_RELPROB_USER1);

qsmm_set_actor_relprob_helper(actor,&get_relprob_exp_mlt,0);

Alternatively, in QSMM version 1.16, to use that relative probability function, the developermay write function calls shown below. See further on in this section for a description of functionqsmm_set_actor_ktemperature.

qsmm_set_actor_relprob_type(actor,QSMM_RELPROB_BUILTIN3);

qsmm_set_actor_ktemperature(actor,2);

In formulas for a relative probability function, which were given earlier in this section, functionC(h, z, i), the ratio of spur increment velocities, is the function computed differently dependingon the way of spur perception for spur type i. The way of spur perception determines whetherthat ratio will be generally positive or negative for generally positive or negative spur increments

Chapter 2: Optimal Action Generation Engine 38

supplied to the actor. There are two supported ways of spur perception: normal and inverse.The normal way of spur perception provides generally positive ratio for generally positive spurincrements and generally negative ratio for generally negative spur increments. The inverse wayof spur perception provides generally negative ratio for generally positive spur increments andgenerally positive ratio for generally negative spur increments.

A way of spur perception for a spur type can be specified using the following enumeration.

[Enumeration]qsmm_spur_perception_eThis enumeration specifies a way of perception for a spur type. It contains elements describedbelow.

In the description of elements t denotes discrete or continuous time used to computespur increment velocity, E[i] denotes the value of the spur of type i the actor currentlyaccumulated, H(h,z)[i] denotes the sum of increments of spur of type i for cycles of type 〈h, z〉registered in the event history since the beginning of actor operation, and ω(h,z) denotes thesum of periods of discrete or continuous time for those cycles of type 〈h, z〉. A cycle of type〈h, z〉 is a segment of event history between occurrence of action choice state h, in whichoutput signal z was emitted, and subsequent occurrence of h.

QSMM_SPUR_PERCEPTION_NORMAL

The value of C(h, z, i) is the ratio of spur increment velocity for a cycle type tothe absolute value of the mean spur increment velocity:

C(h, z, i) =

tH(h,z)[i]∣∣E[i]

∣∣ω(h,z) , if E[i] 6= 0 ∧ ω(h,z) > 0;

0, otherwise.

When spur increments over the event history are non-negative, the value ofC(h, z, i) increases as spur increment velocity increases. When spur incrementvelocity for a cycle type is positive and is equal to the mean spur incrementvelocity, the value of C(h, z, i) will be equal to 1.

QSMM_SPUR_PERCEPTION_INVERSE

The value of C(h, z, i) is the negative ratio of the absolute value of the mean spurincrement velocity to spur increment velocity for a cycle type:

C(h, z, i) =

−∣∣E[i]

∣∣ω(h,z)

tH(h,z)[i], if t > 0 ∧H(h,z)[i] 6= 0;

0, otherwise.

When spur increments over the event history are negative, the value of C(h, z, i)increases as spur increment velocity increases. When spur increment velocity fora cycle type is negative and is equal to the mean spur increment velocity, thevalue of C(h, z, i) will be equal to 1.

An inverse way of spur perception could be used to countervail negative spurwith another spur, which is negative, but which would be perceived as positiveone because of an inverse way of perception specified.

To retrieve or set the way of perception for a spur type, the following functions can be used.

[Function]int qsmm_get_actor_spur_perception (qsmm actor t actor, intspur_type, enum qsmm spur perception e *spur_perception_p )

This function sets *spur perception p to a way of perception for spur type spur type ofactor. Spur types, the number of which was specified when creating the actor, have zero-based indices. Special spur type −1 of a large actor corresponds to the automatic spur of a

Chapter 2: Optimal Action Generation Engine 39

small actor associated with the large actor. If spur perception p is 0, then *spur perception pwill not be set.

On success, the function returns a non-negative value. If the actor is the small one andspur type is negative, or if the actor is the large one and spur type is less than −1, or ifspur type is greater than or equal to the number of spur types specified when creating theactor, then negative error code QSMM_ERR_INVAL will be returned.

[Function]int qsmm_set_actor_spur_perception (qsmm actor t actor, intspur_type, enum qsmm spur perception e spur_perception )

This function sets a way of perception for spur type spur type of actor to spur perception.Spur types, the number of which was specified when creating the actor, have zero-basedindices. Special spur type −1 of a large actor corresponds to the automatic spur of a smallactor associated with the large actor. If the value of spur perception is invalid, then behaviorof the actor will be undefined.

On success, the function returns a non-negative value. If the actor is the small one andspur type is negative, or if the actor is the large one and spur type is less than −1, or ifspur type is greater than or equal to the number of spur types specified when creating theactor, then negative error code QSMM_ERR_INVAL will be returned.

Function qsmm_actor_create initializes ways of perception for all spur types of a newlycreated actor to QSMM_SPUR_PERCEPTION_NORMAL.

To retrieve or set W [i], spur weight, the following functions can be used.

[Function]int qsmm_get_actor_spur_weight (qsmm actor t actor, int spur_type,double *weight_p )

This function sets *weight p to weight for spur type spur type of actor. Spur types, thenumber of which was specified when creating the actor, have zero-based indices. Special spurtype −1 of a large actor corresponds to the automatic spur of a small actor associated withthe large actor. If weight p is 0, then *weight p will not be set, otherwise *weight p willalways be finite.

On success, the function returns a non-negative value. If the actor is the small one andspur type is negative, or if the actor is the large one and spur type is less than −1, or ifspur type is greater than or equal to the number of spur types specified when creating theactor, then negative error code QSMM_ERR_INVAL will be returned.

[Function]int qsmm_set_actor_spur_weight (qsmm actor t actor, int spur_type,double weight )

This function sets weight for spur type spur type of actor to weight. Spur types, the numberof which was specified when creating the actor, have zero-based indices. Special spur type−1 of a large actor corresponds to the automatic spur of a small actor associated with thelarge actor.

On success, the function returns a non-negative value. If the actor is the small one andspur type is negative, or if the actor is the large one and spur type is less than −1, or ifspur type is greater than or equal to the number of spur types specified when creating theactor, or if weight is not finite, then negative error code QSMM_ERR_INVAL will be returned.

Function qsmm_actor_create initializes weights for all spur types of a newly created actorto 1.

In the formulas for a relative probability function, T denotes actor temperature multiplied bysome constant. Actor temperature is a concept that follows from the use of an exponential formfor this function, which in some ways resembles formulas related to the Boltzmann distribution.In most of the relative probability functions, actor temperature is a coefficient, by which all spurweights are divided.

Chapter 2: Optimal Action Generation Engine 40

The perfect relative probability function would be the one that provides maximum operatingefficiency for an actor without the need to tune up the temperature of the actor by hand, i.e.the function for which default temperature equal to 1 could always be used. If the functionis imperfect, its application is not intended one, or when applying the simulated annealingapproach for solving a problem, to adjust the temperature of the actor to increase its operatingefficiency, the following functions can be used.

[Function]double qsmm_get_actor_ktemperature (qsmm actor t actor )This function returns the temperature (multiplied by some constant) of actor. The returnedvalue is always finite and positive. If the actor is the large one, then the function will returnthe temperature of a small actor associated with the large actor.

[Function]int qsmm_set_actor_ktemperature (qsmm actor t actor, double val )This function sets the temperature (multiplied by some constant) of actor to val. If the actoris the large one, then the function will set the temperature of a small actor associated withthe large actor.

On success, the function returns a non-negative value. If val is not a finite number or is nota positive number, then negative error code QSMM_ERR_INVAL will be returned.

Function qsmm_actor_create initializes the temperature (multiplied by some constant) of anewly created actor to 1.

2.10 Specifying Weights of Output Signals

The weight of an output signal of actor is an additional coefficient, by which a relative probabilityof emitting the output signal is multiplied. To disable emitting an output signal, set its weightequal to 0.

It is essential to note that by reasons described in Section 2.13 [Other Parameters of anActor], page 48, changing default weights of output signals of a small actor, in general, makesits behavior ill-defined and should be avoided. Changing the weights seems to be the correctprocedure only for a large actor, because this procedure does not alter the number of choicealternatives at decision points along the pathways to output signals.

Every output signal of small actor can have weight assigned to it with or without bindingto a specific action choice state. Output signals of large actor can only have weights bound tospecific action choice states.

For a small actor, output signal weight bound to an action choice state can be specifiedusing a preloaded probability profile for the action choice state or as a profile probability held instatistics storage of the small actor. See Section 3.2 [Structures for Accessing Storage], page 58,for information on how to pass profile probabilities to storage access functions to write themto storage. For a large actor, the only supported way to specify output signal weights is usingpreloaded probability profiles for action choice states.

If a small actor has a preloaded probability profile specified for current action choicestate, then function qsmm_actor_calc_action_prob will copy output signal weights from thepreloaded probability profile to a working array of output signal weights that ordinarily holdsweights assigned to output signals without binding to a particular action choice state. Thecontents of that working array can be inspected or modified using functions qsmm_get_actor_sig_weight and qsmm_set_actor_sig_weight described below. Function qsmm_actor_create

initializes weights of all output signals of a newly created small actor, which are stored in theworking array, to 1. If an output signal of a small actor has a profile probability specified for anaction choice state in statistics storage of the actor, then the overall weight of the output signal(which can be emitted in that action choice state) will be the product of a corresponding weightin the working array and that profile probability.

Chapter 2: Optimal Action Generation Engine 41

For a small actor, weights stored in the working array are always applied to relative probabili-ties computed within function qsmm_actor_calc_action_prob, disregarding of a requested typeof probabilities to calculate. For a large actor, the working array is not used. After multiplyingcomputed relative probabilities by corresponding weights, function qsmm_actor_calc_action_

prob normalizes the resulting array to obtain probabilities that sum up to 1.

[Function]int qsmm_get_actor_sig_weight (qsmm actor t actor, qsmm sig t sig,double *weight_p )

This function sets *weight p to the weight of output signal sig of actor. If weight p is 0,then *weight p will not be set, otherwise *weight p will always be a finite and a non-negativenumber.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Signal sig is not an output signal of the actor.

QSMM_ERR_NOSYS

The actor is the large one.

[Function]int qsmm_set_actor_sig_weight (qsmm actor t actor, qsmm sig t sig,double weight )

This function sets the weight of output signal sig of actor to weight.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Signal sig is not an output signal of the actor, or weight is not a finite numberor is a negative number.

QSMM_ERR_NOSYS

The actor is the large one.

A preloaded probability profile for an action choice state of an actor is defined by a list ofprobabilities in normal form and a one-to-one correspondence between elements of that list andidentifiers of output signals of the actor. In QSMM, that correspondence is called a permutationof output signals for short. Splitting a preloaded probability profile into a probabilities list innormal form and a permutation of output signals is done to reduce the memory footprint of anactor, especially of large one.

For a small actor, the normal form of a list of probabilities is simply a sorted form of thatlist. For a large actor, the normal form of a given list of probabilities is a resulting list ofprobabilities that correspond to leaves of a Huffman tree created for a sorted form of the given listof probabilities. Indices of probabilities in the resulting list are equal to indices of correspondingsource probabilities in the sorted list. Note that actually used profile probabilities, which followfrom the structure of a Huffman tree, may differ from source profile probabilities for which thatHuffman tree was created.

There is a concept of a pool of probabilities lists in normal form, which corresponds to anactor. Probabilities lists in normal form added to the pool cannot be removed from the pool,except by destroying the actor using function qsmm_actor_destroy. The size of the pool isspecified in field profile_pool_sz of structure qsmm_actor_desc_s when creating the actorusing function qsmm_actor_create and can be retrieved later by function qsmm_get_actor_

profile_pool_sz.

The pool contains unique probabilities lists in normal form. That is, for a large actor, toelements of the pool there correspond Huffman trees with unique positional arrangements of

Chapter 2: Optimal Action Generation Engine 42

nodes. For that type of actor, even when preloading a probability profile, to which there doescorrespond a probabilities list in normal form already contained in the pool, the actor createsa temporary Huffman tree to obtain the normal form of the list. The temporary Huffman treetakes up one element in the pool, which is why the size of the pool should generally be greaterby 1 than the number of unique probabilities lists in normal form one needs to load into thepool.

There is also a concept of a pool of permutations of output signals, which corresponds toan actor. The pool contains unique permutations. As opposed to the pool of probabilitieslists in normal form, the size of which has to be specified when creating the actor, the pool ofpermutations of output signals grows dynamically and its size does not need to be specified inadvance. Permutations of output signals added to the pool cannot be removed from the pool,except by destroying the actor using function qsmm_actor_destroy.

To split a list of weights of output signals of an actor into a unique probabilities list in normalform and a unique permutation of output signals, the following function can be used.

[Function]int qsmm_actor_profile_add (qsmm actor t actor, qsmm sig t sig_beg,qsmm sig t sig_end, const double *weight_p, int *profile_p, int *permut_p )

This function preloads a list of weights of output signals into actor. The weights are passedvia array weight p. If weight p is 0, then this will be interpreted as if array weight p containsall weights equal to 1.

Arguments sig beg and sig end can be both zero or may specify identifiers of the first signal(inclusive) and the last signal (exclusive) for the list of weights. In array weight p, the weightof the first signal of that list has offset sig beg. If sig end is 0, then the total number of actorsignals will be used for the value of the last signal of the list. Values of elements of arrayweight p, which do not correspond to output signals of the actor, are ignored.

If profile p is not 0, then the function will set *profile p to a non-negative index of a uniqueprobabilities list in normal form that corresponds to the list of weights. That index willidentify either a unique probabilities list in normal form just added to the pool of these listsor such a list which already contained in the pool. The length of the unique probabilitieslist in normal form is equal to the number of positive elements in array weight p, whichcorrespond to output signals of the actor within a range specified using sig beg and sig end.

If permut p is not 0, then the function will set *permut p to a non-negative index of aunique permutation of output signals, which corresponds to the list of weights. That indexwill identify either a unique permutation of output signals just added to the pool of thesepermutations or such a permutation which already contained in the pool. The length of theunique permutation of output signals is equal to the length of the unique probabilities list innormal form.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

One of the following conditions is met:

– the value of sig beg is greater than or equal to a value (incremented by 1)of the last signal of the list of weights;

– the value of sig end is greater than the total number of signals of the actor;

– the sum of elements in array weight p, which correspond to output signalsof the actor within a range specified using sig beg and sig end, is not finite.

QSMM_ERR_WEIGHT

A negative or a non-finite element, which corresponds to an output signal of theactor, was encountered in array weight p within a range specified using sig begand sig end.

Chapter 2: Optimal Action Generation Engine 43

QSMM_ERR_NOCHOICE

Array weight p does not contain at least one positive element that corresponds toan output signal of the actor within a range specified using sig beg and sig end.

QSMM_ERR_MPROF

No room in the pool of probabilities lists in normal form, the size of which wasspecified when creating the actor.

QSMM_ERR_STORAGE

Failure of statistics storage of a large actor. This could leave the actor inindeterminate state. If the actor is in indeterminate state, then after removi-ng a reason of the error, the operation can be repeated, and if the functionsucceeds, then the actor’s state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave theactor’s memory in indeterminate state. If the actor’s memory is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the actor’s memory state will become determi-nate.

Function qsmm_actor_profile_add may operate slowly, which is especially true for a largeactor when a Huffman tree is created. To speed up preloading a number of probability profiles,to which the same sorted list of weights of output signals corresponds, one can perform thefollowing procedure.

1. Preload the first probability profile using function qsmm_actor_profile_add, which returnsan index of probabilities list in normal form and an index of the permutation of outputsignals that identify the preloaded profile.

2. For every other probability profile, sort a list of weights of output signals, which correspondsto the profile (all profiles have the same sorted form of that list), to obtain a permutationof output signals. Actually, it is necessary to sort a list of pairs, each consisting of weightand output signal identifier, in ascending order of weights.

3. Register every such permutation of output signals using function qsmm_actor_permut_add

(described below) to obtain an index of unique permutation of output signals, which can beused along with an index of probabilities list in normal form, obtained at step 1, to identifya preloaded probability profile other than the first one.

[Function]int qsmm_actor_permut_add (qsmm actor t actor, int sz, constqsmm sig t *sig_p )

This function adds a permutation of output signals of actor to a pool for these permutations,which corresponds to the actor, if the pool does not already contain this permutation. Thepermutation is specified by array sig p of length sz and must be a subset of identifiers ofoutput signals of the actor.

On success, the function returns a non-negative index of a permutation of output signals justadded to the pool or which already contained in the pool. That index uniquely identifies thepermutation in the pool. On failure, the function returns a negative error code. Currently,the following error codes can be returned.

QSMM_ERR_INVAL

The value of sz is less than 1, or array sig p contains duplicate elements or anelement, which is not an identifier of output signal of the actor.

QSMM_ERR_NOMEM

There was not enough memory to add the permutation of output signals to thepool.

Chapter 2: Optimal Action Generation Engine 44

The purpose of the following functions is to retrieve or set up a correspondence between anaction choice state and a list of weights of output signals, which can be emitted in that actionchoice state.

[Function]int qsmm_get_actor_ngram_profile (qsmm actor t actor, int rez1, int*profile_p, int *permut_p, const qsmm sig t *sig_ngram_p )

This function retrieves a correspondence between an action choice state of an actor and alist of weights of output signals, which can be emitted in that action choice state. The listof weights is specified by an index of probabilities list in normal form and an index of thepermutation of output signals. The action choice state is defined by list of signal identifierssig ngram p of length specified in field ngram_sz of structure qsmm_actor_desc_s whencreating the actor. Argument rez1 is reserved for future use and must be equal to 0.

If profile p is not 0, then the function will set *profile p to an index of probabilities list innormal form that corresponds to the list of weights of output signals. If permut p is not0, then the function will set *permut p to an index of the permutation of output signals,which corresponds to the list of weights of output signals. If the function sets *profile p and*permut p to −1, then this will be an indication that the default list of weights of outputsignals has been assigned to the action choice state. In such a list, all output signals of theactor have equal weights, with the exception that for a large actor actual weights that followfrom the structure of a Huffman tree are all equal only if the length of the list is a positiveinteger power of arity of the tree.

On success, the function returns a non-negative value. If array sig ngram p specifies aninvalid action choice state n-gram, then negative error code QSMM_ERR_NGRAM will be returned.

[Function]int qsmm_set_actor_ngram_profile (qsmm actor t actor, int rez1, intprofile, int permut, const qsmm sig t *sig_ngram_p )

This function sets up a correspondence between an action choice state of an actor and alist of weights of output signals, which can be emitted in that action choice state. The listof weights is specified by profile, which is an index of probabilities list in normal form, andby permut, which is an index of the permutation of output signals. The action choice stateis defined by list of signal identifiers sig ngram p of length specified in field ngram_sz ofstructure qsmm_actor_desc_s when creating the actor. Argument rez1 is reserved for futureuse and must be equal to 0.

A special combination of profile and permut both equal to −1 is an indication to assign adefault list of weights of output signals to the action choice state. The default list specifiesequal weights for all output signals of the actor, with the exception that, for a large actor,actual weights that follow from the structure of a Huffman tree are all equal only if the lengthof the default list is a positive integer power of arity of the tree.

If the actor is the small one, the function keeps intact statistics collected for the action choicestate during actor operation, which is held in storage of the actor. If the actor is the large one,the function also keeps intact statistics held in storage, a handle to which can be retrievedby function qsmm_get_actor_storage. However, the function destroys a Huffman tree thatmay have been created for the action choice state, in which another part of statistics collectedfor that state during actor operation is stored.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument profile is not a valid index of probabilities list in normal form orargument permut is not a valid index of the permutation of output signals and,at the same time, profile and permut are not both equal to −1, or the length of

Chapter 2: Optimal Action Generation Engine 45

a probabilities list in normal form specified by profile is not equal to the lengthof a permutation of output signals specified by permut.

QSMM_ERR_NGRAM

Argument sig ngram p specifies an invalid action choice state n-gram. Todetermine the validity of an action choice state n-gram, it is checked foraccordance with allowed ranges of signal identifiers specified using field range_

sig_p of structure qsmm_actor_desc_s when creating the actor.

QSMM_ERR_NOSYS

The actor is the small one, and the total number of possible action choice staten-grams, calculated on the basis of allowed ranges of signal identifiers specifi-ed using field range_sig_p of structure qsmm_actor_desc_s when creating theactor, exceeds INT_MAX.

QSMM_ERR_STORAGE

Failure of statistics storage of a large actor. This could leave the actor inindeterminate state. If the actor is in indeterminate state, then after removi-ng a reason of the error, the operation can be repeated, and if the functionsucceeds, then the actor’s state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave theactor’s memory in indeterminate state. If the actor’s memory is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the actor’s memory state will become determi-nate.

2.11 Automatic Spur

Automatic spur is an important concept related to an actor. This concept corresponds to the ideathat an intrinsic feature of intelligent system would be adherence to the principle of minimumenergy (or maximum probability). The use of the automatic spur may substantially increasethe efficiency of actor operation and allow application of an actor in cases when there are noexplicit spur increments supplied to it.

Automatic spur is especially useful when output signals of an actor represent its internalstates and each action choice state is a superposition of the previous internal state of the actorand an input signal received when the actor was in that previous internal state. That is, theactor operates as a finite automaton, which has a certain number of internal states, and currentinternal state changes on the basis of the previous internal state and an input signal received.In this case, automatic spur is a measure of adequacy of a model of internal states within theactor to a sequence of input signals received.

In QSMM, the common approach to building a state model for identifying internal states ofa (possibly abstract) entity to solve a problem is the use of a spur scheme with two spur types,which correspond to negative (inhibitory) spur and positive (excitatory) spur that countervaileach other. Negative spur is the automatic spur, which typically has a normal way of perception.Positive spur is the user-supplied one, specific to the problem to be solved.

If is used by an actor, automatic spur is equal to the sum of automatic spur incrementscalculated within function qsmm_actor_reg_sig_in for action choice states that occur in theevent history during actor operation for which prior occurrences in the event history exist. If theprior occurrence of an action choice state exists, then within function qsmm_actor_reg_sig_in

there will be known an output signal that was emitted in the action choice state when it hadoccurred the previous time. (For the last occurrence, an output signal emitted in the actionchoice state is not yet known in qsmm_actor_reg_sig_in.)

Chapter 2: Optimal Action Generation Engine 46

An automatic spur increment is calculated for a pair that represents logical consequenceh → z and consists of action choice state h and output signal z emitted in that action choicestate. The automatic spur increment is equal to the natural logarithm of the probability ofoccurrence of that pair in the event history:

lnν(h,z)

Kt0.

Here ν(h,z) is the number of occurrences of the pair in the event history since the beginning ofactor operation, t0 is the discrete time of the previous occurrence of the pair in the event history(recorded when function qsmm_actor_reg_sig_action was called), and 0 < K ≤ 1 is the meannumber of output signals per one signal in the event history.

When an actor uses one spur type at all, which corresponds to the automatic spur, it isrecommended to set the type of relative probability function for the actor to QSMM_RELPROB_

BUILTIN2 or QSMM_RELPROB_BUILTIN3. However, it is also recommended using the automaticspur in pair with another, countervailing spur, which measures progress in solving the problemin some other way.

To query or set an actor spur type, which corresponds to the automatic spur, functionsdescribed below can be used. By default, automatic spur is not used by an actor created byfunction qsmm_actor_create, except that the automatic spur is used by an implicitly createdsmall actor associated with a large actor.

[Function]int qsmm_get_actor_auto_spur_type (qsmm actor t actor )This function returns the non-negative index of a spur type, which corresponds to theautomatic spur used by an actor, or negative error code QSMM_ERR_NOTFOUND if the actordoes not use the automatic spur.

[Function]int qsmm_set_actor_auto_spur_type (qsmm actor t actor, intspur_type )

This function sets to spur type a spur type that corresponds to the automatic spur used byactor. Spur types have zero-based indices. If spur type is equal to −1, then the actor willnot use the automatic spur (this will not affect the use of the automatic spur by a small actorassociated with the large actor).

On success, the function returns a non-negative value. If spur type is less than −1 or isgreater than or equal to the number of spur types specified when creating the actor, thennegative error code QSMM_ERR_INVAL will be returned.

To query or set the value of K, the following functions can be used.

[Function]double qsmm_get_actor_naction_per_evt (qsmm actor t actor )This function returns a number greater than 0 and less than or equal to 1, which specifiesthe mean number of output signals per one signal in the event history of actor.

[Function]int qsmm_set_actor_naction_per_evt (qsmm actor t actor, doubleval )

This function sets the mean number of output signals per one signal in the event history ofactor to val.

On success, the function returns a non-negative value. If val is not a finite number, or isa number less than or equal to 0, or is a number greater than 1, then negative error codeQSMM_ERR_INVAL will be returned.

Function qsmm_actor_create initializes the mean number of output signals per one signalin (future) event history of a newly created actor to 0.5, which means that every second signalin the event history of the actor is expected to be an output signal.

Chapter 2: Optimal Action Generation Engine 47

A small actor can use at most one spur type that corresponds to the automatic spur. Functi-ons qsmm_get_actor_auto_spur_type and qsmm_set_actor_auto_spur_type called for a smallactor retrieve and set the index of a spur type, which corresponds to that automatic spur.

A large actor can use at most two spur types that correspond to the automatic spur.Automatic spur of the first type is used by a small actor associated with the large actor.Increments of that spur are calculated for action choice states, which correspond to nodes ofHuffman trees traversed when generating output signals by the large actor. Increments of theautomatic spur of the second type are calculated for action choice states from the event historyof the large actor. Functions qsmm_get_actor_auto_spur_type and qsmm_set_actor_auto_

spur_type called for a large actor retrieve and set the index of a spur type that corresponds tothe latter automatic spur.

Historically, a large actor is created with the automatic spur of the first type turned on bydefault. A developer may want to turn off the automatic spur of the first type and make thelarge actor use automatic spur of the second type instead. To turn off the use of automatic spurof the first type by large actor actor_large, write lines of code

qsmm_set_actor_auto_spur_type(

qsmm_get_actpair_actor_env(

qsmm_get_actpair(qsmm_get_actor_large_model(actor_large))),

-1);

To conserve memory, a spur type, which corresponds to this automatic spur, can be reused foranother purpose. For a small actor associated with the large actor, this spur type has index0. Keep in mind that by default, the small actor uses discrete time to compute the incrementvelocity for this spur type. For the large actor, this spur type has special index −1.

2.12 Controlling Random Behavior

A random number generator used by an actor, either supplied when creating the actor or, ifnot supplied, an instance of default random number generator allocated automatically, can beobtained using the following function.

[Function]qsmm_rng_t qsmm_get_actor_rng (qsmm actor t actor )This function returns the handle of a random number generator used by actor when producingactions. This function never returns 0.

The handle of a random number generator returned is typically used to seed the generatorafter creating the actor. See Section 6.1 [Random Number Generators], page 212, for informationon how to seed a random number generator and perform other operations on it.

A useful approach to testing the efficiency of operation of an intelligent system developedusing the QSMM framework is comparing a measure of efficiency of normal operation of thesystem with a measure of efficiency of operation of the system when actors, which are parts ofthe system, behave almost completely randomly. The greater is the difference between thosevalues the more optimization mechanism provided by the actors increases overall optimality ofsystem operation.

To query the current mode of behavior of an actor and to switch the actor to nonoptimal ornormal behavior, the following functions can be used.

[Function]int qsmm_get_actor_random (qsmm actor t actor )This function returns a positive value if actor is currently in the nonoptimal behavior modeor zero value if the actor is in the optimal (normal) behavior mode. This function neverreturns negative values.

Chapter 2: Optimal Action Generation Engine 48

[Function]void qsmm_set_actor_random (qsmm actor t actor, int flag )This function switches the current mode of behavior of an actor to the nonoptimal or theoptimal (normal) mode. If flag is non-zero, then the current mode will be switched to thenonoptimal one. If flag is zero, then the current mode will be switched to the optimal one.

For a small actor, a nonoptimal or optimal mode of behavior affects how function qsmm_

actor_calc_action_prob calculates probabilities of types QSMM_PROB_AGGR and QSMM_PROB_

LEARNT. When the mode is the nonoptimal one, equal probabilities are generated, multipliedby output signal weights, and normalized; when the type of probabilities is QSMM_PROB_AGGR,a probability profile, if it exists in actor’s statistics storage, is also applied to the internalarray that holds probabilities.

For a large actor, a nonoptimal or optimal mode of behavior is actually a mode used by asmall actor associated with the large actor.

Function qsmm_actor_create initializes the current mode of behavior of a newly createdactor to the optimal (normal) one.

2.13 Other Parameters of an Actor

When using a custom function, which returns a relative probability of output signal choice, orproviding coherent operation of a stack of actors, it may be necessary to know a discrete timeperiod of the last cycle processed by an actor or the mean discrete time period of all cyclesprocessed by the actor since the beginning of its operation. This information can be obtainedusing the following functions.

[Function]long qsmm_get_actor_discrete_cycle_period_last (qsmm actor tactor )

This function returns a discrete time period of the last cycle registered by actor in functionqsmm_actor_reg_sig_in. The returned value is always non-negative.

If function qsmm_actor_reg_sig_in is not yet called, then zero will be returned. Whenfunction qsmm_actor_reg_sig_in is called at least once, zero will be returned if at the lastcall to qsmm_actor_reg_sig_in a cycle is not encountered.

[Function]double qsmm_get_actor_discrete_cycle_period_mean (qsmm actor tactor )

This function returns the mean discrete time period of all cycles registered by actor in functi-on qsmm_actor_reg_sig_in since the beginning of actor operation. If there are no cyclesregistered yet, then zero will be returned. The function returns only finite and non-negativevalues.

A function, which calculates a relative probability of output signal choice, typically uses aparameter equal to the number of actor’s output signals to perform the calculation. Functionqsmm_actor_create creates an actor with a particular number of output signals. However,during operation of a small actor, its output signal weights can be changed using function qsmm_

set_actor_sig_weight or by assigning preloaded probability profiles to action choice statesusing function qsmm_set_actor_ngram_profile, and those weights may correspond to a lessernumber of output signals. For example, if the actor had four output signals, and the weight ofone of them were set to zero, then the actual number of output signals would be three. Thesame applies to a probability profile that can be specified for an action choice state (in actor’sstatistics storage for a small actor or using function qsmm_set_actor_ngram_profile for a largeactor): if the profile probability of an output signal is equal to zero, then the actual number ofoutput signals will be less than the number of output signals defined when creating the actor.

However, the concept of the actual number of output signals is somewhat weak. The weaknessshows up when positive weights (or profile probabilities) of output signals are not equal. In this

Chapter 2: Optimal Action Generation Engine 49

case, the actual number of output signals might not be simply the number of output signals thathave positive weights (or profile probabilities). For example, if four signals have weights <0.33,0.33, 0.33, 0.01>, then the actual number of output signals will rather be three than four.

When loading an assembler program into a node or changing values of controlled probabi-lity variables of a node, the QSMM package uses the following algorithm for the approximatecalculation of the actual number of output signals, which corresponds to a list of weights.

1. Zero c, the resulting number of output signals.

2. Calculate a, the arithmetic mean of all positive weights of output signals.

3. For every output signal weight b, if b > a, then add 1 to c, otherwise add b/a to c.

During actor operation, when calculating relative probabilities of emitting output signalsin action choice states, to different action choice states there may correspond different actualnumbers of output signals. If a function, which returns a relative probability of output signalchoice, uses only one parameter that denotes the number of output signals, there may arise aneed to introduce the concept of the mean number of actor’s output signals, which is, in fact,weaker than the concept of the actual number of output signals. The mean number of outputsignals of an actor could be calculated on the basis of actual numbers of output signals fromwhich the actor chooses a specific output signal each time it produces an action, i.e. on thebasis of actual numbers of output signals for particular occurrences of action choice states inthe event history, and might be the arithmetic or geometric mean of those actual numbers ofoutput signals.

The mean number of output signals can be retrieved or set using the following functions.

[Function]double qsmm_get_actor_nsig_ctrl (qsmm actor t actor )This function returns the mean number of output signals of actor. It is either the numberof output signals calculated from the contents of structure qsmm_actor_desc_s, passed tofunction qsmm_actor_create when creating the actor, or the number of output signals previ-ously set using function qsmm_set_actor_nsig_ctrl. Function qsmm_get_actor_nsig_ctrl

can be called from a custom function that returns a relative probability of output signal choi-ce if the function uses a formula that involves the number of output signals. A value returnedby function qsmm_get_actor_nsig_ctrl is always finite and is greater than or equal to 2.

[Function]int qsmm_set_actor_nsig_ctrl (qsmm actor t actor, double val )This function sets the mean number of output signals of actor to val. The mean number ofoutput signals is used by built-in functions, which return a relative probability of output signalchoice, and can be used by a custom relative probability function supplied by a developer.

On success, the function returns a non-negative value. If val is not a finite number or is anumber less than 2, then negative error code QSMM_ERR_INVAL will be returned.

In the simplest case, when output signal weights are not changed during actor operationand profile probabilities are not used, there is no need to modify the mean number of outputsignals, which was initially set by function qsmm_actor_create. Otherwise, a program, whichuses a small actor, should calculate in some way the mean number of output signals and setthat number for the actor by function qsmm_set_actor_nsig_ctrl.

If an array of signal weights or a probability profile specifies that only one signal can be chosen(i.e. if the array of signal weights contains a single positive element or if a probability profile foran action choice state contains a single positive probability of an output signal), then the best willbe not to call functions qsmm_actor_shl_sig, qsmm_actor_reg_sig_in, and qsmm_actor_reg_

sig_action at all. In this case, action choice can be performed in a deterministic way (withoutusing the actor), and discrete time shall not be incremented. However, if functions qsmm_actor_shl_sig and qsmm_actor_reg_sig_in were already called, then for proper accumulation ofstatistics for the action choice state, it would be appropriate to register that the only allowed

Chapter 2: Optimal Action Generation Engine 50

output signal using a call to qsmm_actor_reg_sig_action and then to backtrack discrete time(using several calls to qsmm_actor_shr_sig) to the moment before feeding the action choicestate n-gram to the actor.

The historical limitation for the minimum mean number of actor’s output signals, which canbe set using function qsmm_set_actor_nsig_ctrl, is 2. When computing the mean numberof output signals on the basis of actual numbers of output signals for particular occurrences ofaction choice states in the event history, if there is no signal, which is only allowed to be emittedin an action choice state, and the actual number of output signals computed for an array ofsignal weights or a probability profile is less than 2, then you may either use 2 for the actualnumber of output signals for the particular occurrence of action choice state to calculate themean number of output signals or change the array of signal weights or the probability profilein such a way that they will give more freedom for the actor to choose output signals.

To calculate the mean number of output signals, when an action choice state has a probabilityprofile specified, the precomputed actual number of output signals can be fetched from theprobability profile. You still need to store the actual number of output signals, computed inadvance, in the profile. To fetch the precomputed actual number of output signals from aprobability profile of an action choice state and to determine an output signal if the profileallows only one output signal to be emitted, the following function can be used.

[Function]int qsmm_get_actor_profile_nsig_ctrl (qsmm actor t actor, int*nsig_pos_p, double *nsig_ctrl_p, qsmm sig t *sig_action_p )

This function retrieves information associated with a probability profile for current actionchoice state of an actor held in its statistics storage. The current action choice state is theone, which corresponds to the contents of a window that holds current n-gram from the eventhistory.

If nsig pos p is not 0, then the function will set *nsig pos p to the number of output signals,which can be emitted by the actor in its current action choice state and which have positiveprofile probabilities assigned. If nsig pos p is not 0, and current action choice state does nothave a probability profile specified, then *nsig pos p will be set to 0.

If nsig ctrl p is not 0, then the function will set *nsig ctrl p to the actual number of outputsignals that can be emitted by the actor in its current action choice state. If nsig ctrl pis not 0, and current action choice state does not have a probability profile specified, then*nsig ctrl p will be set to 0.

If the probability profile allows only one output signal to be emitted, then *nsig pos p willbe set to 1 (if nsig pos p is not 0), *nsig ctrl p will be set to 1 (if nsig ctrl p is not 0),and *sig action p will be set to that output signal (if sig action p is not 0). If sig action pis not 0, and current action choice state does not have a probability profile specified or theprobability profile does not allow a single output signal to be emitted, then *sig action p willbe set to QSMM_SIG_INVALID.

See Section 3.2 [Structures for Accessing Storage], page 58, for information on how to pass thenumber of output signals, which have positive profile probabilities assigned, the actual numberof output signals, and a single output signal, which can be emitted (if it exists), to storageaccess functions to write them to statistics storage, which handle can be obtained usingfunction qsmm_get_actor_storage, so these parameters can be retrieved later by functionqsmm_get_actor_profile_nsig_ctrl.

If current action choice state has a probability profile specified, then the function will returna positive value. If current action choice state does not have a probability profile specified,then the function will return 0.

On failure, the function returns a negative error code. Currently, the following error codescan be returned.

Chapter 2: Optimal Action Generation Engine 51

QSMM_ERR_NGRAM

The contents of an actor window, which holds current n-gram from the eventhistory, correspond to an invalid action choice state. To determine the validity ofan action choice state, it is checked for accordance with allowed ranges of signalidentifiers specified using field range_sig_p of structure qsmm_actor_desc_s

when creating the actor.

QSMM_ERR_STORAGE

Statistics storage failure.

QSMM_ERR_NOMEM

A statistics storage access function did return out of memory error.

2.14 Example of Using the Actor API

In the example of using the Actor API, an agent controlled by the sample program has to finda short path to the gold in a labyrinth and then to an exit from the labyrinth. The image ofthe labyrinth is encoded in the sample program using a subset of ASCII characters that looklike pseudographics. You can change the image to test the behavior of the agent for variousconfigurations of the labyrinth.

To find a resulting path, the agent visits the labyrinth the number of times defined by macroNVISIT. A visit is considered finished when the agent moves to a cell where the labyrinth exitis located. A simulated annealing approach is used, in which the temperature of the actorgradually decreases. Macro KT_0 defines the initial temperature of the actor, and macro KT_1

defines the final temperature.

At the last visit of the labyrinth, the sample program shows the image of the labyrinth andmovements of the agent in it, prints an indication whether the agent took the gold, and displayscurrent length of visiting path. After the agent finishes the last visit of the labyrinth, a usercan press Q to exit from the sample program, small G to print the map of learned directions ofmovements from every cell of the labyrinth (reachable from the labyrinth entry) to a cell withthe gold, or capital G to print the map of learned directions of movements from every cell ofthe labyrinth to the labyrinth exit after taking the gold. When the user presses Q, the programprints the number of visits of the labyrinth for which the agent took the gold and exits.

A random seed can be specified by a program argument. If the random seed is non-negative,then the actor will operate normally. If the random seed is negative, then the actor will generateoutput signals completely randomly. You could compare the behavior of the agent for these twomodes of program execution.

Each labyrinth cell is a rectangle 4x3. Maximum zero-based indices of a column and arow of labyrinth cell are defined by macros MAX_X and MAX_Y. Coordinates of the entry cellof the labyrinth relative to its upper left corner are defined by macros ENTRY_X and ENTRY_Y.Characters ‘*’ at cell corners denote a cell with the gold. If there are several such cells, thenvisiting any of them will be considered as taking the gold, which is provided in a single copyper visit of the labyrinth. Characters ‘#’ at cell corners denote a labyrinth exit. A labyrinth canhave more than one exit.

Space characters denote allowed movement paths, and other characters denote places towhich movement is impossible. If a cell is reachable from the labyrinth entry, then it must havetwo spaces in the middle. Every reachable cell must also have two spaces or two non-spacesat the top and at the bottom (in the middle), which indicates whether movement is allowedto an adjacent cell located at the north and/or the south. When modifying the picture of thelabyrinth, make sure that cells are properly aligned and connected, and there are no pathsoutside of the labyrinth, otherwise an assertion failure will occur.

The source code of the example is provided in file ‘samples/labyr2.c’ in the package di-stribution and is also given below. Command make builds the sample program if the QSMM

Chapter 2: Optimal Action Generation Engine 52

package is configured by the ‘configure’ script to use the Curses library. See file ‘INSTALL’ atthe root of the package distribution, for information on the ‘configure’ script.

#include <assert.h>

#include <math.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#if defined(HAVE_CURSES_H)

# include <curses.h>

#elif defined(HAVE_NCURSES_CURSES_H)

# include <ncurses/curses.h>

#endif

#include <qsmm/qsmm.h>

#define NVISIT 200

#define MAX_X 14

#define MAX_Y 14

#define ENTRY_X 0

#define ENTRY_Y 14

#define NSIG_IN (2*(MAX_X+1)*(MAX_Y+1))

#define KT_0 NVISIT

#define KT_1 1.0

#define CHK_FAIL(func, ...) \

do { \

int rc=func(__VA_ARGS__); \

if (rc<0) { \

fprintf(stderr, #func ": %s\n", qsmm_err_str(rc)); \

goto Exit; \

} \

} \

while (0)

enum direct_e {

DIRECT_NORTH=0,

DIRECT_EAST =1,

DIRECT_SOUTH=2,

DIRECT_WEST =3

};

static long state_fq[3][MAX_Y+1][MAX_X+1];

static qsmm_actor_t actor=0;

static int show_gradient(char is_gf);

static int opaque_maze(enum direct_e direct) {

static const char *picture[]={

// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

"+--------+-----+--------------------------#..#",

"| | | |", // 0

"| * * | | # #",

"| | | |", // 1

"| * * | | +-----+ |",

"| | | | | |", // 2

"| | | | | +-----+ |",

"| | | | | | | |", // 3

"| | | | | | | |",

Chapter 2: Optimal Action Generation Engine 53

"| | | | | | | |", // 4

"| +-----+ | | | | |",

"| | | | | |", // 5

"| | | | | |",

"| | | | | |", // 6

"| +-----------+ +-----+ | | |",

"| | | | | |", // 7

"| | | | | |",

"| | | | | |", // 8

"| +-----------+ +-----+ | | |",

"| | | | | |", // 9

"| | | | | |",

"| | | | | |", // 10

"+--------------+ | | +-----+ |",

"| | | | |", // 11

"| | | | |",

"| | | | |", // 12

"+--------------+ +-----+ +-----+ |",

"| | | |", // 13

"| | | |",

"| | | |", // 14

"+..+-----------------------------+-----+-----+"

};

static char is_gf=0;

static int path_len, visit=0, xx=-1, yy=-1;

int rc, col, row, result=0;

if (xx<0 || yy<0) {

if (visit==NVISIT-1) {

if (!initscr()) exit(2);

noecho();

for (row=0; row<(MAX_Y+1)*2+1; row++)

mvaddstr(row,0,picture[row]);

}

xx=ENTRY_X;

yy=ENTRY_Y;

path_len=0;

}

assert(xx>=0 && xx<=MAX_X);

assert(yy>=0 && yy<=MAX_Y);

col=xx*3+1;

row=yy*2+1;

assert(picture[row][col]==’ ’ && picture[row][col+1]==’ ’);

assert((picture[row-1][col]==’ ’ && picture[row-1][col+1]==’ ’) ||

(picture[row-1][col]!=’ ’ && picture[row-1][col+1]!=’ ’));

assert((picture[row+1][col]==’ ’ && picture[row+1][col+1]==’ ’) ||

(picture[row+1][col]!=’ ’ && picture[row+1][col+1]!=’ ’));

switch (direct) {

case DIRECT_NORTH:

if (picture[row-1][col]!=’ ’ || picture[row-1][col+1]!=’ ’)

return 3;

yy--;

break;

case DIRECT_EAST:

if (picture[row][col+2]!=’ ’) return 3;

xx++;

break;

case DIRECT_SOUTH:

if (picture[row+1][col]!=’ ’ || picture[row+1][col+1]!=’ ’)

return 3;

yy++;

break;

case DIRECT_WEST:

if (picture[row][col-1]!=’ ’) return 3;

xx--;

break;

Chapter 2: Optimal Action Generation Engine 54

default:

assert(0);

}

path_len++;

if (visit==NVISIT-1) mvaddstr(row,col," ");

col=xx*3+1;

row=yy*2+1;

state_fq[2][yy][xx]++;

state_fq[(int) is_gf][yy][xx]++;

if (visit==NVISIT-1) {

char ss[128];

int picture_w=strlen(picture[0]);

mvaddstr(row,col,"[]");

sprintf(ss," Gold found: %d",is_gf);

mvaddstr(1,picture_w+2,ss);

sprintf(ss,"Path length: %d",path_len);

mvaddstr(3,picture_w+2,ss);

move((MAX_Y+1)*2+3,0);

refresh();

usleep(125000);

}

if (picture[row-1][col-1]==’*’ && picture[row-1][col+2]==’*’ &&

picture[row+1][col-1]==’*’ && picture[row+1][col+2]==’*’) {

if (!is_gf) {

is_gf=1;

result=1;

}

}

else if (picture[row-1][col-1]==’#’ && picture[row-1][col+2]==’#’ &&

picture[row+1][col-1]==’#’ && picture[row+1][col+2]==’#’) {

is_gf=0;

result=2;

xx=-1;

yy=-1;

if (visit==NVISIT-1) {

int sel=-1;

while (1) {

row=(MAX_Y+1)*2+3;

mvaddstr(row,2,"[g] - gradient before taking the gold");

mvaddstr(row+1,2,"[G] - gradient after taking the gold");

mvaddstr(row+2,2,"[Q] - quit");

rc=getch();

if (sel>=0) mvaddstr(row+sel,0," ");

if (rc==’q’ || rc==’Q’) break;

switch (rc) {

case ’g’: sel=0; show_gradient(0); break;

case ’G’: sel=1; show_gradient(1); break;

}

mvaddstr(row+sel,0,">");

}

endwin();

}

else visit++;

}

return result;

}

static int show_gradient(char is_gf) {

int ii, xx, yy, result=-1;

qsmm_sig_t *sig_ngram_p=qsmm_get_actor_sig_ngram(actor);

assert(!is_gf || is_gf==1);

sig_ngram_p[0]=is_gf;

for (yy=0; yy<=MAX_Y; yy++) {

sig_ngram_p[2]=yy;

Chapter 2: Optimal Action Generation Engine 55

for (xx=0; xx<=MAX_X; xx++) {

const char *ccp=0;

double prob_max=-1, *prob_p;

enum direct_e direct=DIRECT_NORTH;

sig_ngram_p[1]=xx;

if (state_fq[(int) is_gf][yy][xx]<1) continue;

CHK_FAIL(qsmm_actor_calc_action_prob, actor,

0, NSIG_IN, NSIG_IN+4, QSMM_PROB_LEARNT);

prob_p=qsmm_get_actor_choice_sig_prob(actor);

for (ii=0; ii<4; ii++) {

double prob=prob_p[NSIG_IN+ii];

if (prob_max>=prob) continue;

prob_max=prob;

direct=ii;

}

qsmm_actor_choice_sig_prob_release(actor);

switch (direct) {

case DIRECT_NORTH: ccp="^ "; break;

case DIRECT_EAST: ccp="> "; break;

case DIRECT_SOUTH: ccp="v "; break;

case DIRECT_WEST: ccp="< "; break;

}

mvaddstr(yy*2+1,xx*3+1,ccp);

}

}

result=0;

Exit:

return result;

}

int main(int argc, char **argv) {

int rc, visit, path_len=0, n_gold_found=0, seed=0, exit_code=1;

double ktemperature=KT_0, mut=pow(KT_1/KT_0,1.0/NVISIT);

struct qsmm_pair_sig_s range_sig[3];

struct qsmm_actor_desc_s actor_desc;

struct qsmm_actor_sig_spec_in_out_s *iop=&actor_desc.sig_spec.in_out;

memset(range_sig,0,sizeof(range_sig));

range_sig[0].second=1;

range_sig[1].second=MAX_X;

range_sig[2].second=MAX_Y;

memset(&actor_desc,0,sizeof(actor_desc));

actor_desc.nspur=1;

actor_desc.ngram_sz=3;

actor_desc.compat=1;

actor_desc.sig_spec_type=QSMM_ACTOR_SIG_SPEC_IN_OUT;

actor_desc.range_sig_p=range_sig;

iop->nsig_in=NSIG_IN;

iop->nsig_out=4;

CHK_FAIL(qsmm_actor_create,&actor_desc,&actor);

CHK_FAIL(qsmm_set_actor_naction_per_evt,actor,0.25);

if (argc>1) seed=atoi(argv[1]);

if (seed<0) qsmm_set_actor_random(actor,1);

qsmm_rng_seed(qsmm_get_actor_rng(actor),abs(seed));

for (visit=0; visit<NVISIT; visit++) {

char is_gf=0;

int xx=ENTRY_X, yy=ENTRY_Y;

CHK_FAIL(qsmm_set_actor_ktemperature,actor,ktemperature);

while (1) {

qsmm_sig_t sig_action=QSMM_SIG_INVALID;

enum direct_e direct;

CHK_FAIL(qsmm_actor_shl_sig,actor,is_gf,0);

CHK_FAIL(qsmm_actor_shl_sig,actor,xx,0);

CHK_FAIL(qsmm_actor_reg_sig_in,actor,yy);

Chapter 2: Optimal Action Generation Engine 56

CHK_FAIL(qsmm_actor_calc_action_prob, actor,

0, NSIG_IN, NSIG_IN+4, QSMM_PROB_LEARNT);

CHK_FAIL(qsmm_get_actor_sig_action, actor,

0, NSIG_IN, NSIG_IN+4, &sig_action);

CHK_FAIL(qsmm_actor_reg_sig_action,actor,sig_action);

CHK_FAIL(qsmm_actor_time_delta,actor,1);

direct=sig_action-NSIG_IN;

rc=opaque_maze(direct);

switch (rc) {

case 0:

break;

case 1:

is_gf=1;

n_gold_found++;

break;

case 2:

if (is_gf) CHK_FAIL(qsmm_actor_spur_delta,actor,0,1);

break;

case 3:

continue;

default:

assert(0);

}

if (rc==2) break;

switch (direct) {

case DIRECT_NORTH: yy--; break;

case DIRECT_EAST: xx++; break;

case DIRECT_SOUTH: yy++; break;

case DIRECT_WEST: xx--; break;

default: assert(0);

}

path_len++;

}

ktemperature*=mut;

}

printf("\nn_gold_found=%d\n",n_gold_found);

exit_code=0;

Exit:

qsmm_actor_destroy(actor);

return exit_code;

}

Chapter 3: Statistics Storage 57

3 Statistics Storage

Statistics storage is used to hold information on action choice states and cycle types collectedover the event history since the beginning of actor operation. Additionally, statistics storage canhold probability profiles assigned to action choice states. The proper use of probability profilesmay substantially increase the efficiency of operation of a system you develop. Statistics storageis automatically created for an actor by function qsmm_actor_create and destroyed by functionqsmm_actor_destroy.

Storage API functions provide means to get the number of spur types supported by storage,to read and write a condition for an action choice state and statistics for a cycle type, to removeinformation on an action choice state from storage, to enumerate action choice states and cycletypes, information on which is held in storage.

A powerful mechanism, which can be used by a developer, is setting storage redirectionfunctions that return initial conditions for action choice states and initial statistics for cycletypes when Storage API functions need this information. The mechanism can be especiallyhelpful when specifying the same probability profile for a large number of nodes of a multinodemodel. Because probability profiles are stored within data structures of action choice statesand cycle types, instances of those structures will not be used (and possibly allocated) untilconditions for action choice states and statistics for cycle types are updated the first time. Suchdelayed use (and possible allocation) of the instances may reduce the memory footprint of storageand speed up program startup.

3.1 Types of Storage

There are two types of statistics storage supported: flat and map. The type of statistics storageof an actor has to be specified using field use_flat_storage of structure qsmm_actor_desc_s

when creating the actor by function qsmm_actor_create.

Flat storage uses preallocated arrays and does not perform memory allocation when statisticsis written to storage. Therefore, flat storage operates quickly but may require a huge amountof working memory. To reduce the amount of memory occupied by flat storage of an actor,specify allowed ranges of signal identifiers in action choice state n-grams using field range_sig_

p of structure qsmm_actor_desc_s as precisely as possible when creating the actor by functionqsmm_actor_create.

Map storage uses binary trees to hold statistics and dynamically allocates the workingmemory. When map storage does not hold probability profiles, it contains information onaction choice states and cycle types that did occur at least one time in the event history. In thiscase, at the beginning of actor operation the storage occupies a small amount of memory, whichgradually increases as more action choice states and cycle types occur the first time in the eventhistory.

Map storage has two shortcomings. The first is that a map storage operates slower thanthe flat storage. The second is that when a map storage holds statistics for all possible actionchoice states and cycle types, it occupies much more memory than the flat storage requires. Thesecond shortcoming is not a hindrance, because not all possible action choice states and cycletypes usually occur in the event history, and because the actor usually operates shorter timethan it is required for a large number of action choice states and cycle types to occur the firsttime in the event history.

Storage of flat or map type is referred to by a storage handle.

[Data type]qsmm_storage_tThis is a type for a storage handle. It is a pointer, so variables of this type can have zerovalue. A storage handle can be obtained for an actor by function qsmm_get_actor_storage

and passed to API functions that take argument qsmm_storage_t until the actor is destroyed.

Chapter 3: Statistics Storage 58

The number of spur types supported by storage, which is represented by a storage handle,can be obtained using the following function.

[Function]int qsmm_get_storage_nspur (qsmm storage t storage )This function returns the number of spur types, statistics on which can be held in storage.The returned value is always positive.

3.2 Structures for Accessing Storage

The following structure holds a condition for an action choice state.

[Structure]qsmm_state_sThis structure is used for storing a condition for an action choice state. It contains thefollowing fields.

[Field]int nsig_posThis field contains information on the number of types of cycles that start at this actionchoice state and have positive profile probabilities assigned. The meanings of variousvalues of this field are given below.

0 The action choice state does not have a probability profile specified.

i > 1 The number of types of cycles that start at this action choice state and havepositive profile probabilities assigned. Is used to determine whether to utilizeordinary vectors or sparse vectors to store relative probabilities of outputsignals choice.

i < 0 Only one cycle type has a positive profile probability assigned, and −i− 1 isequal to an output signal, which is only allowed by the probability profile.

1 Disallowed and causes undefined behavior.

[Field]long tmd0A non-negative value of this field indicates discrete time of emitting an output signal,which corresponds to the last cycle started at this action choice state, recorded just beforeemitting the output signal. A negative value indicates that there were no cycles startedat this action choice state yet.

[Field]double tmc0A non-negative value of this field indicates continuous time that corresponds to the valueof field tmd0. A negative value indicates that there were no cycles started at this actionchoice state yet.

[Field]double nsig_ctrlThe actual number of output signals, which corresponds to a probability profile for theaction choice state. See Section 2.13 [Other Parameters of an Actor], page 48, for theexplanation of the concept of the actual number of output signals for an action choicestate.

[Field]qsmm_sig_t sig_cycle_nextAn output signal that indicates the direction of the last cycle started at this action choicestate. If there are no cycles started at this action choice state yet, then the value of thisfield will be QSMM_SIG_INVALID.

To an action choice state there corresponds an array of instances of a structure, which holdsan initial value of the spur recorded when the last cycle was started at the action choice state.The number of elements in the array is equal to the number of spur types supported by storage.

Chapter 3: Statistics Storage 59

The structure contains only one field, but is designed as a structure to simplify adding to anaction choice state for research purposes other information associated with a spur type. Whenstorage prepares an instance of this structure for the first use, it initializes the instance withzeroes by function memset, so fields you may have added initially will have zero values.

The structure is described below.

[Structure]qsmm_sspur_sThis structure holds a condition associated with a spur type for an action choice state. Thestructure contains the following field.

[Field]double val0A value of the spur recorded when the last cycle was started at the action choice state,i.e. at the latest time when an output signal was emitted in this action choice state.

The following structure holds statistics for a cycle type.

[Structure]qsmm_cycle_sThis structure holds statistics for a cycle type, i.e. a pair that consists of an action choicestate and an output signal, which could be emitted in that action choice state. The structurecontains the following fields.

[Field]long fqThe number of cycles, which belong to this cycle type, registered in the event history sofar.

[Field]long period_sum_dThe total length of cycles, which belong to this cycle type, registered in the event historyso far, measured in discrete time.

[Field]double period_sum_cThe total length of cycles, which belong to this cycle type, registered in the event historyso far, measured in continuous time.

[Field]double profileA profile probability—weight, by which a relative probability of output signal choice ismultiplied. Is used when field nsig_pos of an instance of structure qsmm_state_s, whichholds a condition for corresponding action choice state, contains a non-zero value. If isused, then the sum of profile probabilities for all cycle types for the action choice statemust be equal to 1.

To a cycle type there corresponds an array of instances of a structure, which holds the sumof spur increments over cycles of that type. The number of elements in the array is equal to thenumber of spur types supported by storage.

The structure contains only one field, but is designed as a structure to simplify adding to acycle type for research purposes other information associated with a spur type. When storageprepares an instance of this structure for the first use, it initializes the instance with zeroes byfunction memset, so fields you may have added initially will have zero values.

The structure is described below.

[Structure]qsmm_cspur_sThis structure holds statistics associated with a spur type for a cycle type. The structurecontains the following field.

Chapter 3: Statistics Storage 60

[Field]double delta_sumThe sum of spur increments over cycles of this type occurred in the event history so far.Each spur increment is the difference between the value of the spur at the time of cycleend and the value of the spur at the time of cycle start stored in field val0 of structureqsmm_sspur_s.

To a cycle type an action choice state and an output signal correspond. The time of cyclestart is the time when in the event history there did occur that action choice state, inwhich that output signal was emitted. The time of cycle end is the time when the actionchoice state did occur again in the event history.

3.3 Reading and Writing Statistics

To read and write a condition for an action choice state, the following functions can be used.

[Function]int qsmm_get_storage_state_stats (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p, struct qsmm state s *state_p,struct qsmm sspur s *sspur_p )

This function reads from a storage a condition for an action choice state specified by list ofsignal identifiers sig ngram p of length ngram sz. If state p is not 0, then the condition willbe copied to *state p. If sspur p is not 0, then conditions for spur of supported types will becopied to an array pointed by sspur p. The array must be capable of holding the number ofelements returned by function qsmm_get_storage_nspur.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_set_storage_state_stats (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p, const struct qsmm state s*state_p, const struct qsmm sspur s *sspur_p )

This function writes to storage a condition for an action choice state specified by list of signalidentifiers sig ngram p of length ngram sz. If state p is not 0, then condition *state p willbe copied to storage. If sspur p is not 0, then conditions for spur of supported types will becopied to storage from an array pointed by sspur p. The number of array elements copied isreturned by function qsmm_get_storage_nspur.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

Chapter 3: Statistics Storage 61

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To update a condition for an action choice state, you first need to read an existing conditi-on using function qsmm_get_storage_state_stats, then set values of some fields, and finallywrite the condition using function qsmm_set_storage_state_stats. For example, updatingparameters of a probability profile for an action choice state to new values nsig_pos and nsig_

ctrl could be performed using a block of code like this:

struct qsmm_state_s state;

if (qsmm_get_storage_state_stats(storage, ngram_sz, sig_ngram_p,

&state, 0)<0)

goto Error;

state.nsig_pos=nsig_pos;

state.nsig_ctrl=nsig_ctrl;

if (qsmm_set_storage_state_stats(storage, ngram_sz, sig_ngram_p,

&state, 0)<0)

goto Error;

To read and write statistics for a cycle type, the following functions can be used.

[Function]int qsmm_get_storage_cycle_stats (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p, qsmm sig t sig_cycle_next,struct qsmm cycle s *cycle_p, struct qsmm cspur s *cspur_p )

This function reads statistics for a cycle type from storage. The cycle type is represented byan action choice state, specified by list of signal identifiers sig ngram p of length ngram sz,and by a cycle direction specified by signal sig cycle next.

If cycle p is not 0, then the statistics will be copied to *cycle p. If cspur p is not 0, thenstatistics for spur of supported types will be copied to an array pointed by cspur p. Thearray must be capable of holding the number of elements returned by function qsmm_get_

storage_nspur.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_set_storage_cycle_stats (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p, qsmm sig t sig_cycle_next, conststruct qsmm cycle s *cycle_p, const struct qsmm cspur s *cspur_p )

This function writes statistics for a cycle type to storage. The cycle type is represented byan action choice state, specified by list of signal identifiers sig ngram p of length ngram sz,and by a cycle direction specified by signal sig cycle next.

If cycle p is not 0, then statistics *cycle p will be copied to storage. If cspur p is not 0,then statistics for spur of supported types will be copied to storage from an array pointed bycspur p. The number of array elements copied is returned by function qsmm_get_storage_

nspur.

Chapter 3: Statistics Storage 62

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To update statistics for a cycle type, you first need to read statistics using function qsmm_get_

storage_cycle_stats, then set values of some fields, and finally write statistics using functionqsmm_set_storage_cycle_stats. For example, updating a profile probability1 for a cycle typeto new value profile could be performed using a block of code like this:

struct qsmm_cycle_s cycle;

if (qsmm_get_storage_cycle_stats(storage, ngram_sz, sig_ngram_p,

sig_cycle_next, &cycle, 0)<0)

goto Error;

cycle.profile=profile;

if (qsmm_set_storage_cycle_stats(storage, ngram_sz, sig_ngram_p,

sig_cycle_next, &cycle, 0)<0)

goto Error;

In the current version of the package storage is used to hold statistics for action choice staten-grams of fixed length. However, as you might see, functions that read and write statistics aswell as some other functions, which belong to the Storage API, take argument ngram_sz thatspecifies the length of action choice state n-gram. This argument is reserved for future use inthe sense that in the future single storage can be used to hold statistics for action choice staten-grams of varying lengths.

To speed up program operation, Storage API functions perform minimal checks on the validityof their arguments. When the arguments have invalid values, program behavior is undefined.

To remove information on an action choice state from storage, the following function can beused.

[Function]int qsmm_storage_remove_state (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p )

This function removes from storage information on an action choice state specified by list ofsignal identifiers sig ngram p of length ngram sz. The information includes a condition forthe action choice state and statistics for all types of cycles that start at the action choicestate. For map storage, memory allocated for holding this information is freed.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Information on an action choice state n-gram, which is specified by argumentssig ngram p and ngram sz, not found in storage, nothing to remove.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

1 A profile probability does not fall into the category “statistics,” but it is stored along with statistics for acycle type.

Chapter 3: Statistics Storage 63

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

3.4 Enumerating States and Cycle Types

To enumerate action choice states, information on which is held in storage, the following functioncan be used.

[Function]int qsmm_storage_enum_states (qsmm storage t storage, intngram_prefix_sz, const qsmm sig t *sig_ngram_prefix_p,qsmm enum states callback func t callback_func, void *paramp )

This function enumerates action choice states, information on which is held in storage.Only those action choice states, which n-grams have prefix sig ngram prefix p of lengthngram prefix sz, are enumerated. If ngram prefix sz is 0, then sig ngram prefix p can be 0.

The process of enumeration is a repeated calling callback function callback func, to which anaction choice state n-gram and user parameter paramp are passed. If the callback functionreturns a positive value, then the process of enumeration will be continued. If the callbackfunction returns zero, then the process of enumeration will be terminated, and functionqsmm_storage_enum_states will report success. If the callback function returns a negativevalue, then the process of enumeration will be terminated, and function qsmm_storage_enum_

states will report failure.

In the current implementation, function qsmm_storage_enum_states does not supportrecursive calling from the callback function for the same storage.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_CALLBACK

The callback function did return an error.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The type of a pointer to a callback function, which is called for every enumerated actionchoice state, is described below.

[Data type]qsmm_enum_states_callback_func_tThis is a type of callback function pointer, to which the following declaration corresponds:

typedef int (*qsmm_enum_states_callback_func_t)(

qsmm_storage_t storage,

int ngram_sz,

const qsmm_sig_t *sig_ngram_p,

void *paramp);

The callback function is called for every enumerated action choice state of storage. The listof signal identifiers of an action choice state is passed via argument sig ngram p, and thelength of the list is passed via argument ngram sz. A user parameter is passed via argumentparamp.

Chapter 3: Statistics Storage 64

The callback function might return a positive value if the process of enumeration should becontinued, zero if the process of enumeration should be terminated, or a negative value onerror.

To enumerate cycle types for an action choice state, i.e. output signals, where each outputsignal along with the action choice state makes up a cycle type, the following function can beused.

[Function]int qsmm_get_storage_cycle_next (qsmm storage t storage, intngram_sz, const qsmm sig t *sig_ngram_p, qsmm sig t *sig_cycle_next_p )

This function retrieves the next cycle type, information on which is held in storage. Thenext cycle type is retrieved for an action choice state specified by list of signal identifierssig ngram p of length ngram sz. The next cycle type is represented by an output signal,which along with the action choice state makes up a cycle type.

When calling the function, *sig cycle next p must contain an output signal for which it isnecessary to obtain an output signal that corresponds to the next cycle type.

If *sig cycle next p is equal to QSMM_SIG_INVALID, then on successful function completion*sig cycle next p will contain an output signal that corresponds to the first cycle type forthe action choice state.

If *sig cycle next p is not equal to QSMM_SIG_INVALID, then on successful functioncompletion *sig cycle next p will contain an output signal greater than output signal*sig cycle next p specified when calling the function, which corresponds to the next cycletype for the action choice state.

The first (or the next) output signal retrieved corresponds to the first (or to the next) cycletype, information on which is held in storage. If there is no such cycle type found, then*sig cycle next p will be set to QSMM_SIG_INVALID.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NGRAM

Storage does not support holding information on an action choice state n-gramspecified by arguments sig ngram p and ngram sz.

QSMM_ERR_STORAGE

Storage failure. See Section 3.6 [Getting the Reason of a Storage Failure], page 68,for information on how to get the reason of the failure.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

3.5 Providing Initial Statistics

Before the first use, instances of structures qsmm_state_s, qsmm_sspur_s, qsmm_cycle_s, andqsmm_cspur_s, which hold conditions for action choice states and statistics for cycle types, areinitialized by Storage API functions with zeroes with the help of function memset. For everyinstance of structure qsmm_state_s, the following assignments are also performed: values offields tmd0 and tmc0 are set to −1, and the value of field sig_cycle_next is set to QSMM_SIG_

INVALID.

An application program can provide functions, which will be called by Storage API functionsat time of initialization of the instances, and which may perform application-specific initializati-on. Those functions will be called during operations of access to a condition for an action choicestate or statistics for a cycle type when storage does not contain requested information aboutthe action choice state or the cycle type.

Chapter 3: Statistics Storage 65

Functions, which perform application-specific initialization, may e.g. set parameters of aprobability profile for an action choice state. They may also call Storage API functions for otheraction choice states, e.g. to copy parameters of a probability profile from another action choicestate.

[Data type]qsmm_get_state_stats_func_tThis is a type for a pointer to a redirection function that performs application-specific ini-tialization of a condition for an action choice state. To this type the following declarationcorresponds:

typedef int (*qsmm_get_state_stats_func_t)(

qsmm_storage_t storage,

int ngram_sz,

const qsmm_sig_t *sig_ngram_p,

struct qsmm_state_s *state_p,

struct qsmm_sspur_s *sspur_p,

void *paramp);

Upon function call, *state p and array sspur p contain preinitialized values. The functioncan set *state p and/or elements of array sspur p to application-specific initial conditionfor an action choice state of storage. The action choice state is specified by list of signalidentifiers sig ngram p of length ngram sz. Elements of array sspur p correspond to spurtypes supported by storage. The number of those elements is returned by function qsmm_get_

storage_nspur. Argument paramp is a user parameter specified when setting the redirectionfunction.

The function must return a non-negative value on success or one of the following negativeerror codes on failure.

QSMM_ERR_STORAGE

Storage failure. The storage message list is expected to contain a message thatdescribes the reason of the failure. See Section 3.6 [Getting the Reason of aStorage Failure], page 68, for more information on storage message list.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To retrieve or set a redirection function, which performs application-specific initialization ofa condition for an action choice state, the following functions can be used.

[Function]int qsmm_get_storage_state_stats_redir (qsmm storage t storage,qsmm get state stats func t *get_state_stats_func_p, void **param_pp )

This function retrieves a redirection function (previously set), which performs application-specific initialization of conditions for action choice states that could be held in storage. Ifget state stats func p is not 0, then *get state stats func p will be set to a pointer to thatredirection function or to 0 if there is no such function assigned to the storage. If param ppis not 0, then *param pp will be set to a user parameter of that redirection function specifiedwhen assigning the redirection function to the storage. Function qsmm_get_storage_state_

stats_redir shall return a non-negative value.

[Function]int qsmm_set_storage_state_stats_redir (qsmm storage t storage,qsmm get state stats func t get_state_stats_func, void *paramp )

This function sets a redirection function, which performs application-specific initialization ofconditions for action choice states that could be held in storage. A pointer to the redirectionfunction is specified by argument get state stats func. A user parameter of the redirectionfunction is specified by argument paramp. If get state stats func is 0, then no redirectionfunction, which performs application-specific initialization of conditions for action choice

Chapter 3: Statistics Storage 66

states, will be used for the storage. Function qsmm_set_storage_state_stats_redir shallreturn a non-negative value.

[Data type]qsmm_get_cycle_stats_func_tThis is a type for a pointer to a redirection function that performs application-specific initi-alization of statistics for a cycle type. To this type the following declaration corresponds:

typedef int (*qsmm_get_cycle_stats_func_t)(

qsmm_storage_t storage,

int ngram_sz,

const qsmm_sig_t *sig_ngram_p,

qsmm_sig_t sig_cycle_next,

struct qsmm_cycle_s *cycle_p,

struct qsmm_cspur_s *cspur_p,

void *paramp);

Upon function call, *cycle p and array cspur p contain preinitialized values. The functioncan set *cycle p and/or elements of array cspur p to application-specific initial statistics for acycle type of storage. The cycle type is specified by an action choice state and output signalsig cycle next that indicates a cycle direction. The action choice state is specified by listof signal identifiers sig ngram p of length ngram sz. Elements of array cspur p correspondto spur types supported by storage. The number of those elements is returned by functionqsmm_get_storage_nspur. Argument paramp is a user parameter specified when setting theredirection function.

The function must return a non-negative value on success or one of the following negativeerror codes on failure.

QSMM_ERR_STORAGE

Storage failure. The storage message list is expected to contain a message thatdescribes the reason of the failure. See Section 3.6 [Getting the Reason of aStorage Failure], page 68, for more information on storage message list.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To retrieve or set a redirection function, which performs application-specific initialization ofstatistics for a cycle type, the following functions can be used.

[Function]int qsmm_get_storage_cycle_stats_redir (qsmm storage t storage,qsmm get cycle stats func t *get_cycle_stats_func_p, void **param_pp )

This function retrieves a redirection function, which performs application-specific initializati-on of statistics for cycle types that could be held in storage. If get cycle stats func p is not0, then *get cycle stats func p will be set to a pointer to that redirection function or to 0 ifthere is no such function assigned to the storage. If param pp is not 0, then *param pp willbe set to a user parameter of that redirection function specified when assigning the redirecti-on function to the storage. Function qsmm_get_storage_cycle_stats_redir shall return anon-negative value.

[Function]int qsmm_set_storage_cycle_stats_redir (qsmm storage t storage,qsmm get cycle stats func t get_cycle_stats_func, void *paramp )

This function sets a redirection function, which performs application-specific initialization ofstatistics for cycle types that could be held in storage. A pointer to the redirection functionis specified by argument get cycle stats func. A user parameter of the redirection functionis specified by argument paramp. If get cycle stats func is 0, then no redirection function,which performs application-specific initialization of statistics for cycle types, will be used forthe storage. Function qsmm_set_storage_cycle_stats_redir shall return a non-negativevalue.

Chapter 3: Statistics Storage 67

When there is used a redirection function, which performs application-specific initializationof statistics for cycle types, it may be necessary to provide a redirection function, which returnsthe next type of cycles that start at an action choice state. The latter redirection function willprovide correct enumeration of cycle types, which have profile probabilities assigned, in caseof when those probabilities are supplied by external means (e.g. in a situation when an actionchoice state uses another action choice state as the source of probability profile).

[Data type]qsmm_get_cycle_next_func_tThis is a type for a pointer to a redirection function, which returns the next type of cyclesthat start at an action choice state. To this type the following declaration corresponds:

typedef int (*qsmm_get_cycle_next_func_t)(

qsmm_storage_t storage,

int ngram_sz,

const qsmm_sig_t *sig_ngram_p,

qsmm_sig_t *sig_cycle_next_p,

void *paramp);

An action choice state, information on which is held in storage, is specified by list of signalidentifiers sig ngram p of length ngram sz. Upon function call, *sig cycle next p containsan output signal for which it is necessary to obtain an output signal that corresponds tothe next cycle type. If *sig cycle next p is equal to QSMM_SIG_INVALID, then on successfullyperformed redirection, *sig cycle next p must contain an output signal that corresponds tothe first cycle type for the action choice state. If *sig cycle next p is not equal to QSMM_

SIG_INVALID, then on successfully performed redirection, *sig cycle next p must contain anoutput signal greater than output signal *sig cycle next p passed upon the function call,which corresponds to the next cycle type for the action choice state. If such the first orthe next cycle type is not found, then *sig cycle next p must be set to QSMM_SIG_INVALID.Argument paramp is a user parameter specified when setting the redirection function.

If the function successfully performs the redirection and possibly updates output signal*sig cycle next p, then it must return a positive value. If the function does not performthe redirection, then it must return 0, so the next cycle type will be retrieved by functi-on qsmm_get_storage_cycle_next without the redirection. On failure, the function mustreturn one of the following negative error codes.

QSMM_ERR_STORAGE

Storage failure. The storage message list is expected to contain a message thatdescribes the reason of the failure. See Section 3.6 [Getting the Reason of aStorage Failure], page 68, for more information on storage message list.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To retrieve or set a redirection function, which returns the next type of cycles that start atan action choice state, the following functions can be used.

[Function]int qsmm_get_storage_cycle_next_redir (qsmm storage t storage,qsmm get cycle next func t *get_cycle_next_func_p, void **param_pp )

This function retrieves a redirection function that returns the next type of cycles, which startat an action choice state and information on which is held in storage. If get cycle next func pis not 0, then *get cycle next func p will be set to a pointer to that redirection function or to0 if there is no such function assigned to the storage. If param pp is not 0, then *param ppwill be set to a user parameter of that redirection function specified when assigning theredirection function to the storage. Function qsmm_get_storage_cycle_next_redir shallreturn a non-negative value.

Chapter 3: Statistics Storage 68

[Function]int qsmm_set_storage_cycle_next_redir (qsmm storage t storage,qsmm get cycle next func t get_cycle_next_func, void *paramp )

This function sets a redirection function that returns the next type of cycles, which startat an action choice state and information on which is held in storage. A pointer to theredirection function is specified by argument get cycle next func. A user parameter of theredirection function is specified by argument paramp. If get cycle next func is 0, then noredirection function that returns the next type of cycles, which start at an action choice state,will be used for the storage. Function qsmm_set_storage_cycle_next_redir shall return anon-negative value.

3.6 Getting the Reason of a Storage Failure

When a Storage API function returns error code QSMM_ERR_STORAGE, the function generates oneor more messages that describe an error occurred. The error messages are held in a message listassociated with storage. The message list is cleared upon entry to every Storage API functionthat might return error code QSMM_ERR_STORAGE. See Section 6.3 [Messages and Message Lists],page 218, for more information on working with error message lists.

A message list is represented by a handle of type qsmm_msglist_t. A message list associatedwith storage can be obtained using the following function.

[Function]qsmm_msglist_t qsmm_get_storage_msglist (qsmm storage t storage )This function returns the handle of a message list associated with storage. This functionnever returns 0.

When a Storage API function returns error code QSMM_ERR_STORAGE to an applicationprogram, which executable is named prg_name, the error message list can be dumped to stderr

using a line of code like this:

qsmm_msglist_dump(qsmm_get_storage_msglist(storage),prg_name,0,0,stderr);

3.7 Example of Using the Storage API

When working with an actor, a helpful feature would be the ability to save the state of the actorto a file and restore that state from the file later. This feature is not built in the package, but itcan be programmed by a developer manually using Actor and Storage APIs. Example functionsthat save and load the state of a small actor are available in file ‘samples/load_save.c’ in thepackage distribution and are also given in this section.

The following actor parameters are not saved and loaded by the functions.

• The type of a function that returns a relative probability of output signal choice. This typecan be retrieved by function qsmm_get_actor_relprob_type and set by function qsmm_

set_actor_relprob_type.

• A helper function used when computing a relative probability of output signal choice. Thishelper function can be retrieved by function qsmm_get_actor_relprob_helper and set byfunction qsmm_set_actor_relprob_helper.

• The contents of the internal array that holds probabilities of output signals choice. Apointer to this contents can be retrieved by function qsmm_get_actor_choice_sig_prob.After working with the contents, it should be released by function qsmm_actor_choice_

sig_prob_release. A read-only view of the internal array as an ordinary or sparse vectorcan be obtained by function qsmm_get_actor_choice_sig_prob_vec.

• The contents of the pool of probabilities lists in normal form. A probabilities list can beadded to the pool by function qsmm_actor_profile_add.

• The contents of the pool of permutations of output signals. A permutation of output signalscan be added to the pool by functions qsmm_actor_profile_add and qsmm_actor_permut_

add.

Chapter 3: Statistics Storage 69

• Probability profiles assigned to specific action choice states. For an action choice state, itsprobability profile can be retrieved by function qsmm_get_actor_ngram_profile and setby function qsmm_set_actor_ngram_profile.

• The mean discrete cycle period. This period can be retrieved by function qsmm_get_actor_

discrete_cycle_period_mean.

• Storage redirection functions if they are used. These functions can be retrieved for storage ofthe actor by qsmm_get_storage_state_stats_redir, qsmm_get_storage_cycle_stats_redir, and qsmm_get_storage_cycle_next_redir, or set for storage of the actor by qsmm_

set_storage_state_stats_redir, qsmm_set_storage_cycle_stats_redir, and qsmm_

set_storage_cycle_next_redir.

Function save_actor_state saves the state of an actor to a specified stream. It returns 0on success, −1 on soft errors, such as out of memory error, −2 on stream write errors, and −3if the actor is the large one.

Function load_actor_state loads the state of an actor from a specified stream. Beforecalling the function, an actor, which state is to be loaded and which handle is passed to thefunction, must be created by function qsmm_actor_create. This actor must be a small one, theactor and actor which state was saved to the stream must have the same numbers of signals andsupported spur types, the same length of action choice state n-gram, the same ranges of allowedsignal identifiers in action choice state n-grams, and the same sets of identifiers of output signals.The function returns 0 on success, −1 on soft errors, −2 on stream read errors, −3 on errorsin read data, and −4 on incompatibility between parameters of an actor specified by an actorhandle passed to the function and parameters read from the stream.

#include <assert.h>

#include <math.h>

#include <stdlib.h>

#include <string.h>

#include <qsmm/qsmm.h>

#define ERRRET(code) \

do { \

result=(code); \

goto Exit; \

} \

while (0)

#define LOAD(var) \

do { \

if (fread(&var,sizeof(var),1,filep)!=1) ERRRET(-2); \

} \

while (0)

#define SAVE(var) \

do { \

if (fwrite(&var,sizeof(var),1,filep)!=1) ERRRET(-2); \

} \

while (0)

struct param_s {

int err;

int nspur;

FILE *filep;

struct qsmm_cspur_s *cspur_p; // [nspur]

struct qsmm_sspur_s *sspur_p; // [nspur]

Chapter 3: Statistics Storage 70

};

static int save_acstate(qsmm_storage_t storage,

int ngram_sz,

const qsmm_sig_t *sig_ngram_p,

void *paramp) {

int ii, spur_type, nspur, result=-1;

qsmm_sig_t sig_next=QSMM_SIG_INVALID;

FILE *filep;

struct param_s *param_p=paramp;

struct qsmm_state_s state;

nspur=param_p->nspur;

filep=param_p->filep;

SAVE(ngram_sz);

for (ii=0; ii<ngram_sz; ii++) SAVE(sig_ngram_p[ii]);

if (qsmm_get_storage_state_stats(storage, ngram_sz, sig_ngram_p,

&state, param_p->sspur_p)<0)

goto Exit;

SAVE(state);

for (spur_type=0; spur_type<nspur; spur_type++)

SAVE(param_p->sspur_p[spur_type]);

while (1) {

struct qsmm_cycle_s cycle;

if (qsmm_get_storage_cycle_next(storage, ngram_sz,

sig_ngram_p, &sig_next)<0)

goto Exit;

SAVE(sig_next);

if (sig_next==QSMM_SIG_INVALID) break;

if (qsmm_get_storage_cycle_stats(storage, ngram_sz, sig_ngram_p,

sig_next, &cycle,

param_p->cspur_p)<0)

goto Exit;

SAVE(cycle);

for (spur_type=0; spur_type<nspur; spur_type++)

SAVE(param_p->cspur_p[spur_type]);

}

result=1;

Exit:

if (result<0) param_p->err=result;

return result;

}

int save_actor_state(qsmm_actor_t actor, FILE *filep) {

char is_random=qsmm_get_actor_random(actor)?1:0;

int ii, rc, spur_type, result=-1, nsig=qsmm_get_actor_nsig(actor),

nspur=qsmm_get_actor_nspur(actor),

ngram_sz=qsmm_get_actor_ngram_sz(actor),

auto_spur_type=qsmm_get_actor_auto_spur_type(actor);

long tmd=qsmm_get_actor_discrete_time(actor);

double tmc=qsmm_get_actor_continuous_time(actor),

naction_per_evt=qsmm_get_actor_naction_per_evt(actor),

nsig_ctrl=qsmm_get_actor_nsig_ctrl(actor),

ktemperature=qsmm_get_actor_ktemperature(actor);

qsmm_sig_t sig_next, *sig_ngram_p=qsmm_get_actor_sig_ngram(actor);

struct param_s param;

const struct qsmm_pair_sig_s *range_sig_p=qsmm_get_actor_range_sig(actor);

memset(&param,0,sizeof(param));

if (qsmm_get_actor_large_model(actor)) ERRRET(-3);

if (auto_spur_type==QSMM_ERR_NOTFOUND) auto_spur_type=-1;

SAVE(is_random);

SAVE(nsig);

SAVE(nspur);

Chapter 3: Statistics Storage 71

SAVE(ngram_sz);

SAVE(auto_spur_type);

SAVE(tmd);

SAVE(tmc);

SAVE(naction_per_evt);

SAVE(nsig_ctrl);

SAVE(ktemperature);

for (ii=0; ii<ngram_sz; ii++) {

const struct qsmm_pair_sig_s *pair_p=range_sig_p+ii;

SAVE(pair_p->first);

SAVE(pair_p->second);

}

for (spur_type=0; spur_type<nspur; spur_type++) {

double spur=0, spur_weight=0;

enum qsmm_spur_perception_e spur_perception=QSMM_SPUR_PERCEPTION_NORMAL;

enum qsmm_time_e spur_time=QSMM_TIME_CONTINUOUS;

rc=qsmm_get_actor_spur(actor,spur_type,&spur);

assert(rc>=0);

SAVE(spur);

rc=qsmm_get_actor_spur_weight(actor,spur_type,&spur_weight);

assert(rc>=0);

SAVE(spur_weight);

rc=qsmm_get_actor_spur_perception(actor, spur_type,

&spur_perception);

assert(rc>=0);

SAVE(spur_perception);

rc=qsmm_get_actor_spur_time(actor,spur_type,&spur_time);

assert(rc>=0);

SAVE(spur_time);

}

for (sig_next=0; sig_next<nsig; sig_next++) {

double weight_sig=0;

rc=qsmm_get_actor_sig_weight(actor,sig_next,&weight_sig);

if (rc==QSMM_ERR_INVAL) continue;

assert(rc>=0);

SAVE(sig_next);

SAVE(weight_sig);

}

sig_next=QSMM_SIG_INVALID;

SAVE(sig_next);

for (ii=0; ii<ngram_sz; ii++) SAVE(sig_ngram_p[ii]);

param.nspur=nspur;

param.filep=filep;

if (!(param.cspur_p=malloc(sizeof(*param.cspur_p)*nspur)) ||

!(param.sspur_p=malloc(sizeof(*param.sspur_p)*nspur)))

goto Exit;

if (qsmm_storage_enum_states(qsmm_get_actor_storage(actor), 0, 0,

&save_acstate, &param)<0) {

if (param.err<0) ERRRET(param.err);

goto Exit;

}

ii=0;

SAVE(ii);

result=0;

Exit:

if (param.sspur_p) free(param.sspur_p);

if (param.cspur_p) free(param.cspur_p);

return result;

}

int load_actor_state(qsmm_actor_t actor, FILE *filep) {

char is_random=0;

int ii, rc, spur_type, ngram_allo=1, nsig=0, nspur=0, ngram_sz=0,

Chapter 3: Statistics Storage 72

result=-1, auto_spur_type=-1;

long tmd=0;

double tmc0, tmc=0, naction_per_evt=0, nsig_ctrl=0, ktemperature=0;

qsmm_sig_t sig_next, *sig_ngram_p, *sig_ngram_storage_p=0;

const struct qsmm_pair_sig_s *range_sig_p;

qsmm_storage_t storage;

struct qsmm_cspur_s *cspur_p=0;

struct qsmm_sspur_s *sspur_p=0;

if (qsmm_get_actor_large_model(actor)) ERRRET(-4);

LOAD(is_random);

LOAD(nsig);

LOAD(nspur);

LOAD(ngram_sz);

LOAD(auto_spur_type);

LOAD(tmd);

LOAD(tmc);

LOAD(naction_per_evt);

LOAD(nsig_ctrl);

LOAD(ktemperature);

if (nsig!=qsmm_get_actor_nsig(actor)) ERRRET(-4);

if (nspur!=qsmm_get_actor_nspur(actor)) ERRRET(-4);

if (ngram_sz!=qsmm_get_actor_ngram_sz(actor)) ERRRET(-4);

if (auto_spur_type<-1 || auto_spur_type>=nspur) ERRRET(-3);

qsmm_set_actor_random(actor,is_random);

rc=qsmm_set_actor_auto_spur_type(actor,auto_spur_type);

assert(rc>=0);

qsmm_set_actor_discrete_time(actor,tmd);

if (!isfinite(tmc) || tmc<0) ERRRET(-3);

tmc0=qsmm_get_actor_continuous_time(actor);

rc=qsmm_actor_time_delta(actor,tmc-tmc0);

assert(rc>=0);

if (!isfinite(naction_per_evt) ||

naction_per_evt<=0 || naction_per_evt>1)

ERRRET(-3);

rc=qsmm_set_actor_naction_per_evt(actor,naction_per_evt);

assert(rc>=0);

if (!isfinite(nsig_ctrl) || nsig_ctrl<2) ERRRET(-3);

rc=qsmm_set_actor_nsig_ctrl(actor,nsig_ctrl);

assert(rc>=0);

if (!isfinite(ktemperature) || ktemperature<=0) ERRRET(-3);

rc=qsmm_set_actor_ktemperature(actor,ktemperature);

assert(rc>=0);

range_sig_p=qsmm_get_actor_range_sig(actor);

for (ii=0; ii<ngram_sz; ii++) {

struct qsmm_pair_sig_s range;

const struct qsmm_pair_sig_s *pair_p=range_sig_p+ii;

LOAD(range.first);

LOAD(range.second);

if (range.first!=pair_p->first) ERRRET(-4);

if (range.second!=pair_p->second) ERRRET(-4);

}

for (spur_type=0; spur_type<nspur; spur_type++) {

double spur=0, spur0=0, spur_weight=0;

enum qsmm_spur_perception_e spur_perception=QSMM_SPUR_PERCEPTION_NORMAL;

enum qsmm_time_e spur_time=QSMM_TIME_CONTINUOUS;

LOAD(spur);

if (!isfinite(spur)) ERRRET(-3);

rc=qsmm_get_actor_spur(actor,spur_type,&spur0);

assert(rc>=0);

rc=qsmm_actor_spur_delta(actor,spur_type,spur-spur0);

assert(rc>=0);

LOAD(spur_weight);

if (!isfinite(spur_weight)) ERRRET(-3);

rc=qsmm_set_actor_spur_weight(actor,spur_type,spur_weight);

assert(rc>=0);

Chapter 3: Statistics Storage 73

LOAD(spur_perception);

rc=qsmm_set_actor_spur_perception(actor,spur_type,spur_perception);

assert(rc>=0);

LOAD(spur_time);

rc=qsmm_set_actor_spur_time(actor,spur_type,spur_time);

assert(rc>=0);

}

while (1) {

double weight_sig=0;

LOAD(sig_next);

if (sig_next==QSMM_SIG_INVALID) break;

LOAD(weight_sig);

if (!isfinite(weight_sig) || weight_sig<0) ERRRET(-3);

rc=qsmm_set_actor_sig_weight(actor,sig_next,weight_sig);

if (rc==QSMM_ERR_INVAL) ERRRET(-4);

assert(rc>=0);

}

sig_ngram_p=qsmm_get_actor_sig_ngram(actor);

for (ii=0; ii<ngram_sz; ii++) {

LOAD(sig_next);

if (sig_next>=nsig) ERRRET(-3);

sig_ngram_p[ii]=sig_next;

}

if (!(sig_ngram_storage_p=

malloc(ngram_allo*sizeof(*sig_ngram_storage_p))) ||

!(cspur_p=malloc(nspur*sizeof(*cspur_p))) ||

!(sspur_p=malloc(nspur*sizeof(*sspur_p))))

goto Exit;

storage=qsmm_get_actor_storage(actor);

while (1) {

int ngram_storage_sz=0;

struct qsmm_state_s state;

LOAD(ngram_storage_sz);

if (ngram_storage_sz<1) break;

if (ngram_allo<ngram_storage_sz) {

qsmm_sig_t *sig_new_p=

realloc(sig_ngram_storage_p,

ngram_storage_sz*sizeof(*sig_ngram_storage_p));

if (!sig_new_p) goto Exit;

sig_ngram_storage_p=sig_new_p;

ngram_allo=ngram_storage_sz;

}

for (ii=0; ii<ngram_storage_sz; ii++)

LOAD(sig_ngram_storage_p[ii]);

LOAD(state);

for (spur_type=0; spur_type<nspur; spur_type++)

LOAD(sspur_p[spur_type]);

if (qsmm_set_storage_state_stats(storage, ngram_storage_sz,

sig_ngram_storage_p,

&state, sspur_p)<0)

goto Exit;

while (1) {

struct qsmm_cycle_s cycle;

LOAD(sig_next);

if (sig_next==QSMM_SIG_INVALID) break;

LOAD(cycle);

for (spur_type=0; spur_type<nspur; spur_type++)

LOAD(cspur_p[spur_type]);

if (qsmm_set_storage_cycle_stats(storage, ngram_storage_sz,

sig_ngram_storage_p,

sig_next, &cycle, cspur_p)<0)

goto Exit;

}

}

result=0;

Chapter 3: Statistics Storage 74

Exit:

if (sspur_p) free(sspur_p);

if (cspur_p) free(cspur_p);

if (sig_ngram_storage_p) free(sig_ngram_storage_p);

return result;

}

Chapter 4: Multinode Model 75

4 Multinode Model

Multinode model is the concept of using a single actor or a pair of actors for multiple situations,in which producing optimal actions is necessary. Those situations might relate to differententities that are either components of a system you develop, which choose optimal actions usingthe QSMM framework, or entities external to the system and which behavior is to be learned.Nodes of multinode model represent the entities. The special case of multinode model is asingle-node model.

In multinode models used within the QSMM framework, there can exist not more than onenode that possesses control at any moment of time. Possessing control means executing asubroutine associated with a node, using which the node can produce actions, or, in short,executing the node. A node can produce or choose actions either deterministically or stochasti-cally. When using a stochastic physical process, such as interference of individual electrons, toproduce random numbers used by the subroutine, the node will choose actions in more or lessliteral sense. Otherwise, when a pseudorandom number generator is used, the choice of actionswill be determined by information the node receives from the environment.

A node can call other nodes. When a node finishes execution, it returns control to a callernode or to the system if the system calls the node. Within the QSMM framework, nodes mightalso call each other recursively.

Every node of multinode model belongs to a particular class of nodes with common behavior.As of QSMM version 1.16, the only supported type of node classes is instruction class set.Instruction class sets are used to implement automatic synthesis of assembler programs thatconsist of instructions.

4.1 Principle of Operation

Nodes produce actions by means of invocation of assembler instructions, which perform effecti-ve work, in an instruction execution environment. A schematic diagram of a multinode modelimplementation is represented in Figure 4.1. The implementation consists of an environmentstate identification engine, an instruction emitting engine, and the instruction execution envi-ronment.

The environment state identification engine guesses current state of a node specified by anode index received from the instruction execution environment. The node is a component ofthe instruction execution environment and can represent an entity in the external environmentwith which a system you develop interacts. In simple cases, when single-node models are used, asingle node may correspond to the whole environment external to the system, which is why theengine is called the environment state identification engine. That engine sends guessed currentnode state to the instruction emitting engine. The latter engine emits an assembler instructionbased on a node state received and a node index used when guessing that node state.

The instruction execution environment is set up by the developer according to a problem themultinode model has to solve. The main job of the instruction execution environment is handlinginvocation of assembler instructions, which identifiers are received from the instruction emittingengine. An invoked assembler instruction may change the value of the spur of a particular typeaccumulated by both engines and a node index sent to those engines, i.e. switch the node context.The invoked instruction returns an instruction outcome and possibly changes the contents of thesegment of look-ahead signals. An identifier of the invoked instruction, the instruction outcome,and the segment of look-ahead signals are sent to the environment state identification engineand take part in guessing the next node state.

Guessing node states and choosing which assembler instructions to invoke are spur-drivenprocesses. That is, for example, the goal of the operation of a multinode model could beto identify states of entities contained in the external environment and to perform assembler

Chapter 4: Multinode Model 76

instructions to maximize the velocity of increment of spur received along with other input fromthose entities. The concept of a period of time necessary to perform an assembler instructionis applied to calculate the velocity of increment of spur. When executing an instruction, timetracked by both engines is incremented by that period (this is not shown in Figure 4.1). Nodesof a multinode model share common time and spur, so guessing current node state and choosingwhich instruction to invoke depend on successfulness in solving a problem by all nodes of themodel.

Figure 4.1: schematic diagram of model implementation

An actor, which output signals biuniquely correspond to node (entity) states, represents theenvironment state identification engine.

A tuple, which consists of an index of a node state identified by the actor at the previousoperation step and of a list of signal identifiers of fixed length, represents an action choice stateof the actor. One element of that list conveys information on an instruction invoked at theprevious operation step and its outcome returned. The list may also contain the segment oflook-ahead signals. When multiple nodes are used, a node identifier is additionally included inthe action choice state. Figure 4.2 represents the structure of action choice states of the actor.Current state is not part of action choice state, but is shown, because it is the next signal in theevent history after action choice state signals.

Figure 4.2: action choice states of environment state identification engine

The instruction emitting engine is implemented as an actor, which action choice state isrepresented by an index of node state. When multiple nodes are used, a node identifier is alsoincluded in the action choice state. Figure 4.3 represents the structure of action choice states of

Chapter 4: Multinode Model 77

the actor. An output signal is not a part of action choice state, but is shown, because it is thenext signal in the event history after action choice state signals.

Figure 4.3: action choice states of instruction emitting engine

The environment state identification engine normally uses an additional spur type thatcorresponds to the automatic spur, which is a measure of adequacy of a state model withinthe engine to a sequence of received signals. See Section 2.11 [Automatic Spur], page 45, foradditional information.

A helpful feature of a multinode model is the ability to convert internal data stored in itsengines to a representation in the form of an assembler program. One can think of such featureas an automatic synthesis of an assembler program that solves an assigned task.

The important thing, which should be realized by the developer, is that automatic synthesisof the assembler program may work only in a situation when there does exist a program witha steady state model that solves an assigned task. The steady state model is a state modelin which states have predictable input from the instruction execution environment. The inputis transmitted to the states in the form of node identifiers, instruction identifiers, instructionoutcomes, and look-ahead signals.

The following concepts were introduced to make possible automatic synthesis of assemblerprograms.

Instruction meta-classRepresents an instruction name, without taking into account optional instructionparameters that follow the instruction name after a whitespace character. The nameof instruction meta-class is the name of instruction that does not include instructionparameters. Example:

move

This instruction meta-class might represent an instruction that moves an agent inthe environment in specific direction. However, a movement direction is not includedin the name of the instruction meta-class.

Instruction classRepresents an instruction name, optionally followed by instruction parameters. Di-stinct strings, where every string consists of an instruction name and normalizedinstruction parameters (see Section 4.3.4 [Setting the Instruction Parameters String],page 87, for a description of normalization rules), correspond to distinct instructionclasses. Example:

move north

This instruction class might represent an instruction that moves an agent in theenvironment one step in the north direction.

An instruction class has a specific number of instruction outcomes that can beanalyzed by the environment state identification engine after instruction invocationwhen determining a new node state and then making a decision, which instructionto execute next.

Chapter 4: Multinode Model 78

For example, instruction ‘move north’ and other movement instructions mightreturn a bitmask of four bits (i.e. an integer number in the range 0 to 15) afterperforming the move. A bit of the bitmask equal to 0 might indicate that there is anobstacle in a corresponding direction, thus giving a piece of information to the agentabout configuration of the environment. Depending on the implementation of theagent, it may be useful to return the special instruction outcome 16 if a movementinstruction is invoked, but there is an obstacle in a corresponding direction, whichdisallows the move.

Instruction class setIs a node class that represents a set of instruction classes and its properties. Forexample, instruction class set ‘walker’, which could be used to investigate the envi-ronment, might contain the following instruction classes:

move north

move east

move south

move west

Instruction instanceAn instance of instruction class in an assembler program. For example, in assemblerprogram fragment

move north

joe 14, return_back

move north

...

return_back:

move south

...

there are two instances of instruction class ‘move north’.

4.2 Creating a Multinode Model

A multinode model is referred to by a model handle.

[Data type]qsmm_tThis is a type for a model handle. It is a pointer, so variables of this type can have zerovalue. Function qsmm_create allocates a new model handle. Function qsmm_destroy freesan existing model handle. After allocating a model handle, it can be passed to API functionsthat take argument qsmm_t until the handle is freed.

To create and destroy a multinode model, the following functions can be used.

[Function]int qsmm_create (const struct qsmm desc s *desc_p, qsmm t *model_p )This function creates a multinode model using parameters specified in *desc p and stores anewly allocated model handle in *model p.

The function returns a non-negative value on success or a negative error code on failure increating a multinode model. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Either argument model p is 0 or parameters specified in *desc p are invalid.

QSMM_ERR_NOMEM

There was not enough memory to create a multinode model.

Chapter 4: Multinode Model 79

[Function]void qsmm_destroy (qsmm t model )This function destroys a multinode model specified by model handle model. After multinodemodel destruction, the model handle must not be used. If model is 0, then the function willdo nothing.

A structure, a pointer to which is an argument of function qsmm_create, is described below.

[Structure]qsmm_desc_sThis structure describes parameters for creating a multinode model. It contains the followingfields.

[Field]char use_flat_storageA flag, which specifies whether flat storage or map storage should be used by a pair ofactors that correspond to the multinode model. Is assigned to field use_flat_storage

of structure qsmm_actor_desc_s passed to function qsmm_actor_create when creatingeach actor of the pair. It is permissible to use flat storage when fields is_large_env andis_large_opt of this structure have zero values. If the value of field use_flat_storage

is non-zero and it is not permissible to use flat storage, then error QSMM_ERR_INVAL willbe reported.

[Field]char dont_use_instr_class_weightsA flag that specifies whether to not to set weights of output signals of the instructi-on emitting engine equal to weights of instruction classes specified by functions qsmm_

set_instr_class_weight, qsmm_set_instr_class_weight_by_name_f, and qsmm_set_

instr_meta_class_weight. The absence of necessity to set the weights of output signalsmakes the multinode model execute faster, especially when a sparse probability profile isspecified for the action emission matrix of a node, and the number of instruction classesin the instruction class set of the node is large. If the flag is not 0, then those functionswill raise error QSMM_ERR_NOSYS.

[Field]char is_determ_optA flag that imposes the following restriction on action emission matrices of all nodes of themultinode model: for every node state an action emission matrix must define deterministicchoice of an instruction class emitted in that node state. When loading assembler programsinto nodes, states are assumed to begin just before user and mixed type instructions, andthere is no need to mark unnamed states by stt instructions. It is permissible to set thisfield to a non-zero value only when field dont_use_instr_class_weights has a non-zerovalue and field is_large_opt has zero value. Otherwise, error QSMM_ERR_INVAL will bereported.

[Field]char is_large_envA flag, which specifies whether a large actor or a small actor should be created for theenvironment state identification engine. The large actor will use binary Huffman trees.It is permissible to set this field to a non-zero value only when field use_flat_storage

has zero value and field compat has value 1. Otherwise, error QSMM_ERR_INVAL will bereported.

[Field]char is_large_optA flag, which specifies whether a large actor or a small actor should be created for theinstruction emitting engine. The large actor will use binary Huffman trees. It is permissibleto set this field to a non-zero value only when fields use_flat_storage and is_determ_

opt have zero values, field dont_use_instr_class_weights has a non-zero value, andfield compat has value 1. Otherwise, error QSMM_ERR_INVAL will be reported.

Chapter 4: Multinode Model 80

[Field]int nspurThe number of spur types used in the multinode model. This number includes theautomatic spur, though that spur might not be really used. If the value of field is_

determ_opt is zero, then the value of field nspur must be greater than 1. If the value offield is_determ_opt is non-zero, then the value of field nspur must be greater than 0.

[Field]int stack_sz_maxThe maximum allowed number of frames in the node call stack. If the actual numberof stack frames exceeds the maximum allowed number, then error QSMM_ERR_STACKOVR

will be raised. If the maximum allowed number of stack frames is too big, then stackoverflow may occur without raising the error. That kind of stack overflow typically causesa segmentation fault. The value of this field must be greater than 0.

[Field]int ngram_env_la_szThe length of a segment of extra signals in an action choice state of the environment stateidentification engine that take part in the identification of a new node state. If this numberis positive, then assembler programs cannot be loaded into nodes of the model. The valueof this field must be non-negative.

[Field]int nsig_ngram_env_laThe number of signals that are allowed to be the elements of a segment of extra signalsof action choice state, the length of which is specified in field ngram_env_la_sz. If thelength is positive, then the number of signals must also be positive. If the length is zero,then the number of signals must also be zero.

[Field]int profile_pool_env_szA non-negative size of the pool of probabilities lists in normal form of the environmentstate identification engine. Is assigned to field profile_pool_sz of structure qsmm_actor_desc_s passed to function qsmm_actor_create when creating the engine.

[Field]int profile_pool_opt_szA non-negative size of the pool of probabilities lists in normal form of the instructionemitting engine. Is assigned to field profile_pool_sz of structure qsmm_actor_desc_s

passed to function qsmm_actor_create when creating the engine.

[Field]int compatThe compatibility level of algorithms used by the multinode model. Must be 0 or 1. Isassigned to field compat of structure qsmm_actor_desc_s passed to function qsmm_actor_

create when creating a pair of actors that correspond to the multinode model. Settinga value of this field to 1 is recommended for your new programs. This manual does notinclude outdated details, specific to original algorithms, which will be used when this fieldhas value 0.

[Field]double sparse_fill_maxThe maximum fill ratio for vectors that hold relative probabilities of output signals choice,on the basis of which engines of the multinode model decide when to use sparse vectorsinstead of ordinary vectors. Must be a number between 0 and 1 (inclusive). Is assigned tofield sparse_fill_max of structure qsmm_actor_desc_s passed to function qsmm_actor_

create when creating the engines.

Note: when field is_large_env and/or field is_large_opt have non-zerovalues or when loading large assembler programs, which specify sparseprobability profiles, into model nodes, forgetting to set field sparse_fill_

max to a positive value, e.g. to 0.2, will cause bad model performance.

Chapter 4: Multinode Model 81

[Field]qsmm_rng_t rngThe handle of a random number generator to be used by the multinode model. SeeSection 6.1 [Random Number Generators], page 212, for information on how to create,destroy random number generators, and perform other operations on them. Can be 0, inwhich case an instance of default random number generator is automatically created foruse by the multinode model and destroyed upon multinode model destruction.

[Field]struct qsmm_pair_sig_s * range_sig_env_la_pRanges of signal identifiers in a segment of extra signals in an action choice state that takepart in the identification of a new node state. Those ranges are used to check the validityof the segment, to reduce the memory footprint of flat storage if it is used by a small actor,which represents the environment state identification engine, and to reduce the numberof nodes in the multinode model of a large actor, which represents the environment stateidentification engine. In future versions of the package, the ranges can be used for otherpurposes. To reduce the memory footprint of the environment state identification engine,it is recommended to specify the ranges as precisely as possible.

This field must have zero value or be a pointer to an array of ngram_env_la_sz elements.Each array element is a pair (see Section 2.4 [Creating an Actor], page 14, for a descriptionof structure qsmm_pair_sig_s). Field first of the pair defines the minimum value ofsignal identifier and field second of the pair defines the maximum value of signal identifier.The value of first must be less than or equal to the value of second, and the value ofsecond must be less than a value specified in field nsig_ngram_env_la of this structure.If field range_sig_env_la_p has zero value, then it will be assumed that every segmentsignal can be in the range 0 to the value of field nsig_ngram_env_la (exclusive).

To improve compatibility with future versions of the library, an instance of structure qsmm_

desc_s, a pointer to which is passed to function qsmm_create, should be zeroed using functionmemset before setting values of structure fields.

Some parameters specified when creating a multinode model can be obtained later using thefollowing functions.

[Function]int qsmm_get_use_instr_class_weights (qsmm t model )This function returns a positive value if weights of output signals of an instruction emittingengine that corresponds to multinode model are set equal to weights of instruction classes ofa node being executed or returns 0 otherwise. The function returns a positive value if fielddont_use_instr_class_weights of structure qsmm_desc_s passed to function qsmm_create

has zero value when creating the multinode model. The function returns zero if that field hasa non-zero value when creating the multinode model. The function never returns negativevalues.

[Function]int qsmm_get_determ_opt (qsmm t model )This function returns a positive value if action emission matrices of all nodes of multinodemodel are restricted to defining deterministic choice of action for every node state. Thefunction returns a positive value if field is_determ_opt of structure qsmm_desc_s passed tofunction qsmm_create has a non-zero value when creating the multinode model. Otherwise,zero value is returned. This function never returns negative values.

[Function]int qsmm_get_nspur (qsmm t model )This function returns the number of spur types used in multinode model. It is a numberspecified in field nspur of structure qsmm_desc_s when creating the multinode model byfunction qsmm_create. The returned value is always positive.

Chapter 4: Multinode Model 82

[Function]int qsmm_get_stack_sz_max (qsmm t model )This function returns the maximum allowed number of frames in the node call stack ofmultinode model. It is a number specified in field stack_sz_max of structure qsmm_desc_s

when creating the multinode model by function qsmm_create. The returned value is alwayspositive.

[Function]int qsmm_get_ngram_env_la_sz (qsmm t model )This function returns the length of a segment of extra signals in an action choice stateof the environment state identification engine of multinode model, which take part in theidentification of a new node state. It is a number specified in field ngram_env_la_sz ofstructure qsmm_desc_s when creating the multinode model by function qsmm_create. Thereturned value is always non-negative.

[Function]int qsmm_get_nsig_ngram_env_la (qsmm t model )This function returns the number of signals, which are allowed to be placed into an actionchoice state of the environment state identification engine of multinode model at extra posi-tions, and which take part in the identification of a new node state. It is a number specifiedin field nsig_ngram_env_la of structure qsmm_desc_s when creating the multinode modelby function qsmm_create. The returned value is always non-negative.

4.3 Instruction Meta-class Definition

An instruction meta-class is specified by its name and an event handler function. The eventhandler function typically processes initialization of instruction classes derived from the instructi-on meta-class and invocation of instructions, which belong to those instruction classes, duringmodel execution.

4.3.1 Function Declaration

An instruction meta-class should normally be declared or defined using the following macro.

[Macro]QSMM_INSTR_META_CLASS (instr_meta_class_name )This macro declares a prototype for a function named instr meta class name, whichrepresents an instruction meta-class with the same name and is the event handlerfunction of that instruction meta-class. You can prepend the macro with the static

keyword to declare or define the static function. A pointer to the function has typeqsmm_instr_meta_class_func_t. The function is declared as having return type int andthe following arguments.

[Function argument]qsmm_t qsmmThe handle of a multinode model that contains the instruction meta-class.

[Function argument]int qsmm_evtThe type of an event that should be processed by the event handler function. Can be oneof these constants: QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE, QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, QSMM_EVT_ENGINE_INIT, QSMM_EVT_ENGINE_DONE,QSMM_EVT_ACTIVATE.

[Function argument]int qsmm_nodeThe identifier of a node being executed. Is a valid identifier for event QSMM_EVT_ACTIVATE.For other events is equal to −1.

[Function argument]void * qsmm_param_pA user parameter of the event handler function. Is equal to the value of the correspondingargument of function qsmm_reg_instr_meta_class called to register the instruction meta-class.

Chapter 4: Multinode Model 83

For example, a prototype for a static function, which represents instruction meta-class ‘move’,could be declared as follows:

static QSMM_INSTR_META_CLASS(move);

Static function ‘move’ could be defined as follows:

static QSMM_INSTR_META_CLASS(move) {

...

}

[Data type]qsmm_instr_meta_class_func_tThis is a type for a pointer to the event handler function of instruction meta-class, to whichthe following declaration corresponds:

typedef int (*qsmm_instr_meta_class_func_t)(

qsmm_t qsmm,

int qsmm_evt,

int qsmm_node,

void *qsmm_param_p);

See above, for a description of arguments of the event handler function. To improve compati-bility with future versions of the library, avoid declaring the event handler functions withsuch prototype explicitly, use macro QSMM_INSTR_META_CLASS instead.

4.3.2 Event Handling

The event handler function of an instruction meta-class can process the types of events, whichare represented by macros listed below. The type of event is passed to the event handler functionvia argument qsmm_evt.

[Macro]QSMM_EVT_ENT_INITInstruction meta-class initialization. This event is sent by function qsmm_reg_instr_meta_

class called to register the instruction meta-class.

You may put initial assignments to variables and allocation of resources, which are used bythe instruction meta-class, in a block of code that handles this event, together with otheruser code associated with the instruction meta-class.

[Macro]QSMM_EVT_ENT_DONEInstruction meta-class uninitialization. This event is sent to all registered instruction meta-class event handlers by function qsmm_destroy called to destroy the multinode model.

In a block of code, which handles the event, resources could be freed that were allocatedwhen processing event QSMM_EVT_ENT_INIT.

[Macro]QSMM_EVT_INSTR_CLASS_INITInstruction class initialization. This event is sent by function qsmm_reg_instr_class calledto register an instruction class which is a subclass of the instruction meta-class. Functionqsmm_reg_instr_class is usually called from the event handler function of an instructionclass set during processing event QSMM_EVT_ENT_INIT for the instruction class set, and theinstruction class is registered as belonging to that instruction class set.

A block of code, which handles the event, typically performs the following operations:

– set the instruction parameters string using function qsmm_set_eh_instr_param_str_f

if the instruction has parameters;

– set the number of instruction outcomes using function qsmm_set_eh_noutcome if theinstruction has more than one outcome or should behave depending on the outcome ofthe previous instruction invoked.

The functions mentioned above are described in detail further on in this section.

Chapter 4: Multinode Model 84

[Macro]QSMM_EVT_INSTR_CLASS_DONEInstruction class uninitialization. This event is sent for registered instruction classes upon uni-nitialization of the instruction meta-class or an instruction class set that contains them, whichis currently performed during destruction of multinode model by function qsmm_destroy.

In a block of code, which handles the event, a binary representation of instruction classparameters (see further on in this subsection) could be uninitialized, and additional resourcesassociated with the instruction class, which were allocated while processing event QSMM_EVT_INSTR_CLASS_INIT, could be freed.

[Macro]QSMM_EVT_ENGINE_INITInitialization of the model instance. This event is sent to all registered instruction meta-classevent handlers (in lexicographical order of names of instruction meta-classes) by functionqsmm_engine_create, called to create the model instance, at the end of execution of thatfunction.

In a block of code, which handles the event, initial assignments to user variables specific tothe model instance could be made, and additional resources specific to the model instancecould be allocated.

[Macro]QSMM_EVT_ENGINE_DONEUninitialization of the model instance. This event is sent by function qsmm_engine_destroy

to all registered instruction meta-class event handlers at the beginning of execution of thatfunction in order, which is reverse for order, in which event QSMM_EVT_ENGINE_INIT wassent. Function qsmm_engine_destroy can be called explicitly, but is also called automaticallywhen recreating the model instance by function qsmm_engine_create and when destroyingthe multinode model by function qsmm_destroy.

In a block of code, which handles the event, additional resources could be freed that wereallocated when processing event QSMM_EVT_ENGINE_INIT.

[Macro]QSMM_EVT_ACTIVATEInstruction invocation. A block of code, which handles the event, performs custom actionsassociated with the instruction class that change system or environment state. In that blockof code, the outcome of the instruction can be set using function qsmm_set_instr_outcome.See Section 4.9 [Handling Instruction Invocation], page 112, for more information.

Upon successful completion, the event handler function must return a non-negative value.Specific non-negative value will have no effect on system operation. On error, the event handlerfunction should return a negative value. Such negative value will cause a model error handlerto be invoked if it is set.

An instruction class may have parameters associated with it. Instruction class parametershave two forms: binary and textual. A textual form is derived from a binary form. Instructionclass parameters in textual form are printed after an instruction meta-class name and togetherthey make up the whole instruction class name. Instruction class parameters in binary formcan be specified when registering the instruction class by function qsmm_reg_instr_class. Thepurpose of the following function is to fetch binary instruction class parameters to a buffer,which could be a variable or a structure instance, in the event handler function of instructionmeta-class.

[Function]int qsmm_get_eh_instr_param (qsmm t model, int bufsz, void *bufp )This function copies a binary representation of parameters of an instruction class, associatedwith an event processed, to buffer bufp of size bufsz. The function can be called from theevent handler function of an instruction meta-class of multinodemodel while processing eventsQSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, and QSMM_EVT_ACTIVATE.

Chapter 4: Multinode Model 85

Size bufsz of the buffer in bytes must be greater than or equal to the size of the binaryrepresentation of instruction class parameters specified when registering the instruction classusing function qsmm_reg_instr_class. If bufsz is greater than the size of the binaryrepresentation of the instruction class parameters, then remaining contents of buffer bufpwill be left intact.

On success, the function returns a non-negative number equal to the size in bytes of thebinary representation of instruction class parameters copied to buffer bufp. On failure, anegative error code is returned. Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The function was not called from the event handler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_

CLASS_DONE, or QSMM_EVT_ACTIVATE.

QSMM_ERR_INVAL

The value of bufsz is less than the size of the binary representation of instructionclass parameters specified when registering the instruction class using functionqsmm_reg_instr_class.

Because a binary representation of instruction class parameters is needed when processingseveral types of events, it is reasonable to fetch the parameters at the beginning of the eventhandler function when processing those types of events. To prevent raising error QSMM_ERR_

UNTIMELY and possible invocation of model error handler because of an inappropriate eventtype, the following macro can be used to check whether the type of event is appropriate to callfunction qsmm_get_eh_instr_param.

[Macro]QSMM_HAS_INSTR_CLASS (evt )This macro is expanded to:

((evt)==QSMM_EVT_INSTR_CLASS_INIT ||

(evt)==QSMM_EVT_INSTR_CLASS_DONE ||

(evt)==QSMM_EVT_ACTIVATE)

This macro is intended for checking whether an instruction class is associated with type evtof an event processed by the event handler function, and it is safe to call function qsmm_get_

eh_instr_param and other functions that use instruction class context.

For example, to fetch a binary representation of instruction class parameters at the begi-nning of the event handler function of instruction meta-class ‘move’, the instruction meta-classdefinition may be written as follows:

static QSMM_INSTR_META_CLASS(move) {

enum direct_e direct=0;

if (QSMM_HAS_INSTR_CLASS(qsmm_evt))

qsmm_get_eh_instr_param(qsmm,sizeof(direct),&direct);

...

}

To get the name of an instruction class set to which an instruction class belongs, a functi-on described below can be called when processing an event by the event handler function ofinstruction meta-class. The described function can also be used to get the name of an instructi-on class set when processing an event by the event handler function of the instruction classset.

[Function]int qsmm_get_eh_instr_class_set_name (qsmm t model, const char**instr_class_set_name_pp )

This function sets *instr class set name pp to the name of an instruction class set thatcorresponds to an event processed by an event handler function of multinode model. If

Chapter 4: Multinode Model 86

instr class set name pp is 0, then *instr class set name pp will not be set. If the function iscalled from the event handler function of instruction meta-class while processing events QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, and QSMM_EVT_ACTIVATE, then itwill retrieve the name of an instruction class set, to which an instruction class associatedwith the event belongs. If the function is called from the event handler function of instructi-on class set, then it will retrieve the name of that instruction class set.

On success, the function returns a non-negative value. If the function is not called from theevent handler function of instruction meta-class while processing event QSMM_EVT_INSTR_

CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, or QSMM_EVT_ACTIVATE, and is not called fromthe event handler function of instruction class set, then negative error code QSMM_ERR_

UNTIMELY will be returned.

4.3.3 Registering the Function

An event handler function of instruction meta-class can be registered using the following macro.

[Macro]QSMM_REG_INSTR_META_CLASS (model, instr_meta_class_name, paramp )This macro registers instruction meta-class instr meta class name for multinode model. Theinstruction meta-class should be previously defined using macro QSMM_INSTR_META_CLASS.Parameter paramp will be passed as a value of argument qsmm_param_p of the event handlerfunction of the instruction meta-class on processing all types of events.

This macro is expanded to:

qsmm_reg_instr_meta_class((model), #instr_meta_class_name,

&instr_meta_class_name, (paramp))

A function called by macro QSMM_REG_INSTR_META_CLASS is described below.

[Function]int qsmm_reg_instr_meta_class (qsmm t model, const char*instr_meta_class_name, qsmm instr meta class func tinstr_meta_class_func, void *paramp )

This function registers instruction meta-class instr meta class name for multinode model.Function instr meta class func will be used as an event handler function of the instructionmeta-class. Parameter paramp will be passed as a value of argument qsmm_param_p of theevent handler function on processing all types of events.

A string pointed by instr meta class name must begin with an English letter or an underscoreand must be followed by zero or more characters, where each character is an English letter,a decimal digit, or an underscore.

After registering an instruction meta-class, function qsmm_reg_instr_meta_class sendsevent QSMM_EVT_ENT_INIT to the event handler function of the instruction meta-class, whichcan perform initialization of the instruction meta-class.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance already exists, so changing model structure is not allowed.

QSMM_ERR_INVAL

A string pointed by instr meta class name has invalid format.

QSMM_ERR_EXIST

An instruction meta-class or instruction class set named instr meta class nameis already registered.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Chapter 4: Multinode Model 87

To get a pointer to the event handler function of an instruction meta-class, the followingfunction can be used.

[Function]int qsmm_get_instr_meta_class_handler (qsmm t model, const char*instr_meta_class_name, qsmm instr meta class func t*instr_meta_class_func_p, void **param_pp )

This function retrieves parameters, which are associated with the event handler functi-on of instruction meta-class instr meta class name registered for multinode model. Ifinstr meta class func p is not 0, then *instr meta class func p will be set to a pointer tothe event handler function. If param pp is not 0, then *param pp will be set to a value ofargument qsmm_param_p of that function when it is called to process an event.

This function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction meta-class instr meta class name not found.

QSMM_ERR_TYPE

An entity named instr meta class name is not an instruction meta-class. Theentity is an instruction class set.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

4.3.4 Setting the Instruction Parameters String

An instruction class parameters string is a textual representation of binary instruction classparameters. If an instruction class has parameters, then the instruction class parameters stringmust be set by the event handler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_INIT. Setting the parameters string can be done using the following function.

[Function]int qsmm_set_eh_instr_param_str_f (qsmm t model, const char *fmt,...)

This function sets a textual representation of parameters of an instruction class associatedwith an event processed. The function is to be called from the event handler function of aninstruction meta-class of multinode model while processing event QSMM_EVT_INSTR_CLASS_INIT. The textual representation of instruction class parameters is formatted according toargument fmt and subsequent arguments, the meaning of which is the same as in functionprintf. A formatted textual representation of instruction class parameters is then convertedto normal form according to rules described further on in this subsection.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The function was not called from the event handler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_INIT.

QSMM_ERR_INVAL

A textual representation of instruction class parameters has invalid format. Seebelow for a description of the format.

QSMM_ERR_ILSEQ

A textual representation of instruction class parameters cannot be converted toa wide string according to the current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Chapter 4: Multinode Model 88

For example, setting a textual representation of parameters of an instruction class, which isa subclass of instruction meta-class ‘move’, could be done using the following block of code:

const char *ccp=0;

switch (direct) {

case DIRECT_NORTH: ccp="north"; break;

case DIRECT_EAST: ccp="east"; break;

case DIRECT_SOUTH: ccp="south"; break;

case DIRECT_WEST: ccp="west"; break;

}

if (ccp) qsmm_set_eh_instr_param_str_f(qsmm,"%s",ccp);

It is assumed that the contents of direct were obtained using a call to qsmm_get_eh_instr_

param at the beginning of the event handler function.

A textual representation of instruction class parameters may contain string literals. Stringliterals must be enclosed in double quotes. Character ‘\’ within a string literal is an escapecharacter that starts an escape sequence. The escape character can be followed by a three-digitoctal character code, or by character ‘x’ and by a two-digit hexadecimal character code, or byone of the following characters: ‘a’, ‘b’, ‘f’, ‘n’, ‘r’, ‘t’, ‘v’, ‘’’, ‘"’, ‘\’. The meaning of theseescape sequences is the same as in C language.

When setting a textual representation of instruction class parameters using function qsmm_

set_eh_instr_param_str_f, an instruction class parameters string is automatically convertedto normal form. All instruction classes in an instruction class set, which are subclasses of aninstruction meta-class, must have distinct normalized strings of instruction class parameters.The process of normalization consists in the following steps.

1. A source string is converted to a wide string according to the current locale.

2. All characters in the wide string starting from the first character L‘;’ not within a stringliteral are considered a comment and are discarded.

3. All whitespace characters not within string literals are discarded.

4. All string literals are reformatted by converting them to arrays of wide characters andformatting the arrays according to the following rules.

a. Wide characters L‘\a’, L‘\b’, L‘\f’, L‘\n’, L‘\r’, L‘\t’, L‘\v’, L‘"’, L‘\\’ are replacedwith corresponding escape sequences.

b. Other wide characters with codes less than 32 are replaced with corresponding octalescape sequences.

c. All other wide characters are copied to the formatted string as is.

d. The resulting formatted string is enclosed in double quotes.

To get in an event handler function of instruction meta-class a normalized textualrepresentation of instruction class parameters, the following function can be used.

[Function]int qsmm_get_eh_instr_param_str (qsmm t model, const char**param_str_pp )

This function sets *param str pp to a normalized textual representation of parameters of aninstruction class associated with an event processed. A pointer returned in *param str ppwill be valid until the next call to function qsmm_get_eh_instr_param_str or qsmm_get_

instr_class_param_str (see Section 4.4.4 [Registering Instruction Classes], page 94) for thatinstruction class. If param str pp is 0, then *param str pp will not be set. The function canbe called from the event handler function of an instruction meta-class of multinode modelwhile processing events QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, andQSMM_EVT_ACTIVATE.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 4: Multinode Model 89

QSMM_ERR_UNTIMELY

The function was not called from the event handler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_

CLASS_DONE, or QSMM_EVT_ACTIVATE.

QSMM_ERR_ILSEQ

A normalized textual representation of instruction class parameters cannot beconverted to a multibyte string according to the current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

4.3.5 Setting the Number of Instruction Outcomes

To an instruction class the number of instruction outcomes corresponds. Instructions that belongto the instruction class can return those outcomes. The outcomes returned may affect furtherexecution of an assembler program.

The number of instruction outcomes must be non-negative. Special value 0 indicates that aninstruction may analyze an outcome of the previous instruction invoked, use that outcome as itsown outcome, or change it to a non-negative value less than the maximum number of outcomesof instruction classes that belong to the instruction class set. The default number of outcomesof instruction class is equal to 1.

The purpose of the following function is to set the number of instruction outcomes whi-le processing event QSMM_EVT_INSTR_CLASS_INIT by the event handler function of instructionmeta-class.

[Function]int qsmm_set_eh_noutcome (qsmm t model, int noutcome )This function sets the number of outcomes of an instruction class associated with an eventprocessed. The function is to be called from the event handler function of an instructionmeta-class of multinode model while processing event QSMM_EVT_INSTR_CLASS_INIT.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The function was not called from the event handler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_INIT.

QSMM_ERR_INVAL

The value of noutcome is negative.

To get the number of outcomes of an instruction class associated with an event processed bythe event handler function of instruction meta-class, the following function can be used.

[Function]int qsmm_get_eh_noutcome (qsmm t model )This function returns the number of outcomes of an instruction class associated with anevent processed. The function can be called from the event handler function of an instructionmeta-class of multinode model while processing events QSMM_EVT_INSTR_CLASS_INIT, QSMM_EVT_INSTR_CLASS_DONE, and QSMM_EVT_ACTIVATE.

On success, a non-negative value is returned. If the function is not called from the eventhandler function of instruction meta-class while processing event QSMM_EVT_INSTR_CLASS_

INIT, QSMM_EVT_INSTR_CLASS_DONE, or QSMM_EVT_ACTIVATE, then negative error code QSMM_ERR_UNTIMELY will be returned.

Chapter 4: Multinode Model 90

4.3.6 Function Layout

Below there is given a template for the event handler function of instruction meta-class.

QSMM_INSTR_META_CLASS(instr_meta_class_name) {

struct param_s param;

// structure "param_s" is used to hold instruction parameters in a

// binary form

// TODO: declare (and possibly initialize) other automatic variables.

if (QSMM_HAS_INSTR_CLASS(qsmm_evt))

qsmm_get_eh_instr_param(qsmm,sizeof(param),&param);

switch (qsmm_evt) {

case QSMM_EVT_ENT_INIT:

// TODO: handle the instruction meta-class initialization

// event.

break;

case QSMM_EVT_ENT_DONE:

// TODO: handle the instruction meta-class uninitialization

// event.

break;

case QSMM_EVT_INSTR_CLASS_INIT:

qsmm_set_eh_instr_param_str_f(

qsmm, fmt, param.field, ...);

// set a textual representation of binary parameters of

// the instruction class

qsmm_set_eh_noutcome(qsmm,noutcome);

// set the number of outcomes of the instruction class if

// it is not equal to 1

// TODO: perform other initialization procedures for the

// instruction class.

break;

case QSMM_EVT_INSTR_CLASS_DONE:

// TODO: handle the instruction class uninitialization event.

break;

case QSMM_EVT_ENGINE_INIT:

// TODO: handle the model instance initialization event.

break;

case QSMM_EVT_ENGINE_DONE:

// TODO: handle the model instance uninitialization event.

break;

case QSMM_EVT_ACTIVATE:

// TODO: handle instruction invocation.

qsmm_set_instr_outcome(qsmm,outcome);

// set an instruction outcome if the instruction class has

// multiple outcomes

break;

}

return 0;

}

Chapter 4: Multinode Model 91

4.4 Instruction Class Set Definition

An instruction class set is specified by its name and an event handler function. The event handlerfunction typically processes initialization of the instruction class set, transferring control to nodesof a node class represented by the instruction class set, and returning control from them.

4.4.1 Function Declaration

You should normally declare or define an instruction class set using the following macro.

[Macro]QSMM_INSTR_CLASS_SET (instr_class_set_name )This macro declares a prototype for a function named instr class set name, which representsan instruction class set with the same name and is an event handler function of that instructi-on class set. The macro can be prepended with the static keyword to declare or define thestatic function. A pointer to the function has type qsmm_instr_class_set_func_t. Thefunction is declared as having return type int and the following arguments.

[Function argument]qsmm_t qsmmThe handle of a multinode model that contains the instruction class set.

[Function argument]int qsmm_evtThe type of an event that should be processed by the event handler function. Can be oneof these constants: QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE, QSMM_EVT_ENGINE_INIT,QSMM_EVT_ENGINE_DONE, QSMM_EVT_NODE_ENTER, QSMM_EVT_NODE_LEAVE.

[Function argument]int qsmm_nodeThe identifier of a node, to which control has just been transferred, or which returnscontrol. Is a valid identifier for events QSMM_EVT_NODE_ENTER and QSMM_EVT_NODE_LEAVE.For other events is equal to −1.

[Function argument]void * qsmm_param_pA user parameter of the event handler function. For events QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE, QSMM_EVT_ENGINE_INIT, and QSMM_EVT_ENGINE_DONE is equal to the valueof the corresponding argument of function qsmm_reg_instr_class_set called to registerthe instruction class set. For events QSMM_EVT_NODE_ENTER and QSMM_EVT_NODE_LEAVE isequal to the value of the corresponding argument of function qsmm_node_call_default

using which the node was called.

For example, a prototype for a static function, which represents instruction class set ‘walker’,could be declared as follows:

static QSMM_INSTR_CLASS_SET(walker);

Static function ‘walker’ could be defined as follows:

static QSMM_INSTR_CLASS_SET(walker) {

...

}

[Data type]qsmm_instr_class_set_func_tThis is a type for a pointer to the event handler function of instruction class set, to whichthe following declaration corresponds:

typedef int (*qsmm_instr_class_set_func_t)(

qsmm_t qsmm,

int qsmm_evt,

int qsmm_node,

void *qsmm_param_p);

Chapter 4: Multinode Model 92

See above, for a description of arguments of the event handler function. To improve compati-bility with future versions of the library, avoid declaring the event handler functions withsuch prototype explicitly, use macro QSMM_INSTR_CLASS_SET instead.

4.4.2 Event Handling

The event handler function of an instruction class set can process the types of events, which arerepresented by macros listed below. The type of event is passed to the event handler functionvia argument qsmm_evt.

[Macro]QSMM_EVT_ENT_INITInstruction class set initialization. Function qsmm_reg_instr_class_set called to registerthe instruction class set sends this event.

A block of code, which handles the event, typically performs a subset of the following operati-ons:

– register instruction classes, which belong to the instruction class set, using macros QSMM_REG_INSTR_CLASS and QSMM_REG_INSTR_CLASS_PARAM;

– register controlled probability variables of the instruction class set using macro QSMM_

REG_VAR_PROB; that macro is described in Section 5.9.2 [Controlled Variables], page 172;

– set the maximum number of states of nodes, which belong to a node class representedby the instruction class set, using function qsmm_set_nstate_max (see further on in thissection);

– create nodes, which belong to a node class represented by the instruction class set, usingmacro QSMM_NODE_CREATE;

– set the number of states of each created node to a required value using function qsmm_

set_node_nstate.

See Section 4.5 [Creating Nodes], page 102, for a description of macro QSMM_NODE_CREATE

and function qsmm_set_node_nstate.

[Macro]QSMM_EVT_ENT_DONEInstruction class set uninitialization. This event is sent to all registered event handlers ofinstruction class sets by function qsmm_destroy called to destroy the multinode model.

In a block of code, which handles the event, additional resources could be freed that wereallocated when processing event QSMM_EVT_ENT_INIT.

[Macro]QSMM_EVT_ENGINE_INITInitialization of the model instance. This event is sent to all registered event handlers ofinstruction class sets (in lexicographical order of names of instruction class sets) by functionqsmm_engine_create, called to create the model instance, at the end of execution of thatfunction.

In a block of code, which handles the event, setting up probability profiles for nodes couldbe performed, initial assignments to user variables specific to the model instance could bemade, and additional resources specific to the model instance could be allocated.

[Macro]QSMM_EVT_ENGINE_DONEUninitialization of the model instance. This event is sent by function qsmm_engine_destroy

to all registered event handlers of instruction class sets at the beginning of execution of thatfunction in order, which is reverse to order, in which event QSMM_EVT_ENGINE_INIT was sent.Function qsmm_engine_destroy can be called explicitly, but is also called automaticallywhen recreating the model instance by function qsmm_engine_create and when destroyingthe multinode model by function qsmm_destroy.

In a block of code, which handles the event, additional resources could be freed that wereallocated when processing event QSMM_EVT_ENGINE_INIT.

Chapter 4: Multinode Model 93

[Macro]QSMM_EVT_NODE_ENTERTransferring control to a node that belongs to a node class represented by the instructionclass set. Function qsmm_node_call_default, which calls a node, sends this event. Anidentifier of the node is passed to the event handler function via argument qsmm_node, and auser parameter specified when calling the node is passed via argument qsmm_param_p. Beforesending this event to the event handler function, a frame in the system stack and a frame inthe user stack (if this stack is used) are created.

In a block of code, which handles the event, initialization of the user stack frame could beperformed. Fields of the user stack frame could be set in accordance with a value of argumentqsmm_param_p.

To conserve memory and speed up program operation when a model contains many nodes,some of which will turn to be never called at all, a probability profile can be loaded into anode while processing this event on the first call to the node.

[Macro]QSMM_EVT_NODE_LEAVEReturning control from a node that belongs to a node class represented by the instructionclass set. Function qsmm_node_call_default, which calls a node, sends this event. Anidentifier of the node is passed to the event handler function via argument qsmm_node, and auser parameter specified when calling the node is passed via argument qsmm_param_p. Theframe in the system stack and the frame in the user stack (if this stack is used) are destroyedafter sending this event to the instruction class set.

In a block of code, which handles the event, uninitialization of the user stack frame could beperformed. Before the uninitialization, a value pointed by argument qsmm_param_p could beset in accordance with the contents of the user stack frame.

Upon successful completion, the event handler function must return a non-negative value.Specific non-negative value will have no effect on system operation. On error, the event handlerfunction should return a negative value; this will cause a model error handler to be invoked if itis set.

The name of an instruction class set and the name of its event handler function can be notthe same in special cases. In the general case, to get the name of an instruction class set whileprocessing an event by the event handler function of the instruction class set, function qsmm_get_

eh_instr_class_set_name can be used. That function is described in detail in Section 4.3.2[Instruction Meta-class Event Handling], page 83.

4.4.3 Registering the Function

An event handler function of instruction class set can be registered using the following macro.

[Macro]QSMM_REG_INSTR_CLASS_SET (model, instr_class_set_name, paramp )This macro registers instruction class set instr class set name for multinode model. Theinstruction class set should be previously defined using macro QSMM_INSTR_CLASS_SET.Parameter paramp will be passed for a value of argument qsmm_param_p of an event handlerfunction of the instruction class set when the event handler function is called to processevents QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE, QSMM_EVT_ENGINE_INIT, and QSMM_EVT_

ENGINE_DONE.

This macro is expanded to:

qsmm_reg_instr_class_set((model), #instr_class_set_name,

&instr_class_set_name, (paramp))

A function called by macro QSMM_REG_INSTR_CLASS_SET is described below.

Chapter 4: Multinode Model 94

[Function]int qsmm_reg_instr_class_set (qsmm t model, const char*instr_class_set_name, qsmm instr class set func t instr_class_set_func,void *paramp )

This function registers instruction class set instr class set name for multinode model model.Function instr class set func will be used as an event handler function of the instruction classset. Parameter paramp will be passed for a value of argument qsmm_param_p of the eventhandler function on processing events QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE, QSMM_EVT_ENGINE_INIT, and QSMM_EVT_ENGINE_DONE.

After registering an instruction class set, function qsmm_reg_instr_class_set sends eventQSMM_EVT_ENT_INIT to the event handler function of the instruction class set, which canperform initialization of the instruction class set.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance already exists, so changing model structure is not allowed.

QSMM_ERR_EXIST

An instruction class set or an instruction meta-class named instr class set nameis already registered.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To get a pointer to the event handler function of an instruction class set, the followingfunction can be used.

[Function]int qsmm_get_instr_class_set_handler (qsmm t model, const char*instr_class_set_name, qsmm instr class set func t*instr_class_set_func_p, void **param_pp )

This function retrieves parameters associated with the event handler function of instructionclass set instr class set name registered for multinode model. If instr class set func p isnot 0, then *instr class set func p will be set to a pointer to the event handler function.If param pp is not 0, then *param pp will be set to a value of argument qsmm_param_p ofthat function when it is called to process events QSMM_EVT_ENT_INIT, QSMM_EVT_ENT_DONE,QSMM_EVT_ENGINE_INIT, and QSMM_EVT_ENGINE_DONE.

This function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name not found.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

4.4.4 Registering Instruction Classes

Every instruction class is an entity related to two other entities: an instruction meta-class andan instruction class set. An instruction class is a subclass of an instruction meta-class and is anelement of an instruction class set. Identical subclasses of an instruction meta-class can be theelements of several instruction class sets.

To register an instruction class, the following function can be used.

Chapter 4: Multinode Model 95

[Function]int qsmm_reg_instr_class (qsmm t model, const char*instr_class_set_name, const char *instr_meta_class_name, intinstr_param_sz, const void *instr_param_p )

This function registers an instruction class of multinode model. The instruction class isregistered as being a subclass of instruction meta-class instr meta class name and an elementof instruction class set instr class set name. Arguments instr param p and instr param szspecify the contents and the size in bytes of a buffer with a binary representation of instructionclass parameters. If instr param sz is 0, then instr param p can be 0.

When registering the instruction class, function qsmm_reg_instr_class sends event QSMM_EVT_INSTR_CLASS_INIT to the event handler function of the instruction meta-class, whichmight set a textual representation of instruction class parameters using function qsmm_set_

eh_instr_param_str_f and the number of instruction outcomes using function qsmm_set_

eh_noutcome.

On success, the function returns a non-negative number that uniquely identifies the registeredinstruction class in the instruction class set. On failure, the function returns a negative errorcode. Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance already exists, so changing model structure is not allowed.

QSMM_ERR_NOTFOUND

Instruction meta-class named instr meta class name or instruction class setnamed instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr meta class name is not an instruction meta-class, or anentity named instr class set name is not an instruction class set.

QSMM_ERR_EXIST

An instruction class with the same binary or textual representation of parametersis already registered for pair <instr meta class name, instr class set name>. Thebinary representation is passed via arguments instr param p and instr param sz.The textual representation might be set in the event handler function of instructi-on meta-class instr meta class name while processing event QSMM_EVT_INSTR_

CLASS_INIT, which is sent by function qsmm_reg_instr_class.

QSMM_ERR_VIOLNODE

There exist nodes that belong to a node class represented by instruction class setinstr class set name. Therefore, changing the instruction class set is not allowed.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To register an instruction class, which belongs to an instruction class set, in the event handlerfunction of the instruction class set during processing event QSMM_EVT_ENT_INIT, the followingmacros can be used.

[Macro]QSMM_REG_INSTR_CLASS (instr_meta_class_name )This macro registers an instruction class which is a subclass of instruction meta-classinstr meta class name and which has no binary parameters.

The macro is expanded to:

qsmm_reg_instr_class((qsmm), __FUNCTION__,

#instr_meta_class_name, 0, 0)

Chapter 4: Multinode Model 96

[Macro]QSMM_REG_INSTR_CLASS_PARAM (instr_meta_class_name, instr_param )This macro registers an instruction class which is a subclass of instruction meta-classinstr meta class name and which has binary parameters specified in variable instr param.

The macro is expanded to:

qsmm_reg_instr_class((qsmm), __FUNCTION__, #instr_meta_class_name,

sizeof(instr_param), &(instr_param))

These macros are to be expanded from the event handler function of an instruction class set.The name of the event handler function must coincide with the name of the instruction classset, and normally it does coincide. There must be variable qsmm, which is a handle of multinodemodel, defined in a function from which the macros are expanded. Normally, that variable is anargument of the event handler function.

A binary representation of parameters of an instruction class to be registered using macroQSMM_REG_INSTR_CLASS_PARAM must be a variable, not a constant. It is because the size ofthe binary representation has to be determined, and it is done using the sizeof operator forthe variable. If you need to specify a constant for a binary representation of instruction classparameters, then assign that constant to a variable of appropriate type and use that variable asan argument of macro QSMM_REG_INSTR_CLASS_PARAM.

For example, to use element DIRECT_NORTH of enumeration direct_e as a binary parameterof an instruction class which is a subclass of instruction meta-class ‘move’, the following lines ofcode could be used:

enum direct_e direct=DIRECT_NORTH;

QSMM_REG_INSTR_CLASS_PARAM(move,direct);

An instruction class is uniquely identified in an instruction class set by a non-negative number.That number cannot be greater than or equal to the total number of instruction classes containedin the instruction class set. To get the total number of instruction classes in the set, the followingfunction can be used.

[Function]int qsmm_get_instr_class_set_sz (qsmm t model, const char*instr_class_set_name )

This function returns the number of instruction classes contained in instruction class setinstr class set name of multinode model.

On success, a non-negative value is returned. On failure, a negative error code is returned.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To get a non-negative number that uniquely identifies an instruction class with a specifiedname in an instruction class set, the following functions can be used.

[Function]int qsmm_find_instr_class_in_set_f (qsmm t model, const char*instr_class_set_name, const char *fmt, ...)

[Function]int qsmm_find_instr_class_in_set_fv (qsmm t model, const char*instr_class_set_name, const char *fmt, va list ap )

These functions return a number that uniquely identifies an instruction class in instructionclass set instr class set name of multinode model. The instruction class is specified by its

Chapter 4: Multinode Model 97

name which is the name of instruction meta-class followed by an optional textual representati-on of instruction class parameters after one or more whitespace characters.

Function qsmm_find_instr_class_in_set_f formats the name of instruction class accordingto argument fmt and subsequent arguments, the meaning of which is the same as in functionprintf. Function qsmm_find_instr_class_in_set_fv formats the name of instruction classaccording to arguments fmt and ap, the meaning of which is the same as in function vprintf.

Before searching the instruction class in the set, the formatted name is converted to a canoni-cal form: extra whitespace characters before and after the name of instruction meta-class areremoved, and textual representation of instruction class parameters is normalized accordingto rules described in Section 4.3.4 [Setting the Instruction Parameters String], page 87.

On success, the functions return a non-negative value. On failure, a negative error code isreturned. Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist or the instruction classnot found in the instruction class set.

QSMM_ERR_INVAL

The name of instruction class has invalid format.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_ILSEQ

The name of instruction class cannot be converted to a wide string according tothe current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To get information about an instruction class specified by a number, which uniquely identifiesit in an instruction class set, the following functions can be used.

[Function]int qsmm_get_instr_class_name (qsmm t model, const char*instr_class_set_name, int instr_class, const char**instr_class_name_pp )

This function sets *instr class name pp to a canonicalized name of instruction class which isthe name of instruction meta-class followed by an optional normalized textual representationof instruction class parameters after a whitespace character. If instr class name pp is 0,then *instr class name pp will not be set. A pointer returned in *instr class name pp willbe valid until the next call to this function. The instruction class is specified by non-negativenumber instr class that uniquely identifies it in instruction class set instr class set name ofmultinode model.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in instruction class set instr class set name.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

Chapter 4: Multinode Model 98

QSMM_ERR_ILSEQ

The canonicalized name of instruction class cannot be converted to a multibytestring according to the current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_get_instr_class_meta_name (qsmm t model, const char*instr_class_set_name, int instr_class, const char**instr_meta_class_name_pp )

This function sets *instr meta class name pp to the name of instruction meta-class of aninstruction class. If instr meta class name pp is 0, then *instr meta class name pp will notbe set. The instruction class is specified by non-negative number instr class that uniquelyidentifies it in instruction class set instr class set name of multinode model.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in instruction class set instr class set name.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_get_instr_class_param_str (qsmm t model, const char*instr_class_set_name, int instr_class, const char **param_str_pp )

This function sets *param str pp to a normalized textual representation of parameters of aninstruction class. If param str pp is 0, then *param str pp will not be set. A pointer returnedin *param str pp will be valid until the next call to function qsmm_get_instr_class_param_

str or qsmm_get_eh_instr_param_str for that instruction class. If param str pp is not 0,and the instruction class does not have textual parameters, then *param str pp will be setto 0. The instruction class is specified by non-negative number instr class that uniquelyidentifies it in instruction class set instr class set name of multinode model.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in instruction class set instr class set name.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_ILSEQ

A normalized textual representation of instruction class parameters cannot beconverted to a multibyte string according to the current locale.

Chapter 4: Multinode Model 99

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_get_instr_class_param (qsmm t model, const char*instr_class_set_name, int instr_class, const void **buf_pp )

This function retrieves a binary representation of parameters of an instruction class. Theinstruction class is specified by non-negative number instr class that uniquely identifies itin instruction class set instr class set name of multinode model. If buf pp is not 0, then*buf pp will be set to a pointer to a binary representation of parameters of the instructionclass. If the instruction class does not have binary parameters (i.e. their size is 0), and buf ppis not 0, then *buf pp will be set to 0.

On success, the function returns a non-negative size in bytes of a binary representation ofparameters of the instruction class. On failure, the function returns a negative error code.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in instruction class set instr class set name.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_get_instr_class_noutcome (qsmm t model, const char*instr_class_set_name, int instr_class )

This function returns the number of instruction outcomes for an instruction class. Theinstruction class is specified by non-negative number instr class that uniquely identifies itin instruction class set instr class set name of multinode model. The number of outcomesequal to 0 has special meaning described in Section 4.3.5 [Setting the Number of InstructionOutcomes], page 89.

On success, a non-negative value is returned. On failure, a negative error code is returned.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in instruction class set instr class set name.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

4.4.5 Setting the Number of States

Every node of a multinode model has a certain number of states, one of which is current nodestate. Current state of a node is changed automatically according to the input from the instructi-on execution environment. The input is conveyed in the form of an identifier of the last invoked

Chapter 4: Multinode Model 100

instruction, an outcome of that instruction, and the contents of the look-ahead signal segmentif the multinode model uses this segment.

A prerequisite for the synthesis of an assembler program of tolerable quality for a node isthat the node must have a sufficient number of states. At the same time, the more states a nodehas the more instructions need to be executed by the node for the synthesis of an assemblerprogram of tolerable quality.

When creating a node, its number of states is inherited from the number of states specifiedfor a node class the node belongs to. The node class is represented by an instruction class set.The number of states specified for a node class is the default number of states for newly creatednodes and, at the same time, the maximum allowed number of states of nodes of the node class.After creating a node, its number of states can be changed to a value less than the maximumallowed one.

To retrieve or set the maximum number of states for a node class, which is also the defaultnumber of states for newly created nodes that belong to the node class, the following functionscan be used.

[Function]int qsmm_get_nstate_max (qsmm t model, const char*instr_class_set_name )

This function returns the maximum allowed number of states of nodes that belong to a nodeclass of multinode model. The returned number is also the default number of states of newlycreated nodes that belong to the node class.

The node class is represented by instruction class set instr class set name.

On success, a positive value is returned. On failure, a negative error code is returned.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_set_nstate_max (qsmm t model, const char*instr_class_set_name, int nstate )

This function sets the maximum allowed number of states of nodes, which belong to a nodeclass of multinode model, to nstate. That number will also be the default number of statesof newly created nodes that belong to the node class.

The node class is represented by instruction class set instr class set name.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of nstate is less than 2.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

Chapter 4: Multinode Model 101

QSMM_ERR_VIOLAP

The model instance exists and the value of nstate is greater than the number ofstates of the environment state identification engine. When creating the modelinstance, that engine is created as having the number of states equal to the maxi-mum value among maximum numbers of states specified using function qsmm_

set_nstate_max for instruction class sets registered for the multinode model.

QSMM_ERR_VIOLNODE

The value of nstate is less than the number of states of one or more alreadycreated nodes that belong to a node class represented by instruction class setinstr class set name.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The default number of states for newly registered instruction class sets is equal to 2.

4.4.6 Function Layout

Below there is given a template for the event handler function of instruction class set.

static QSMM_INSTR_CLASS_SET(instr_class_set_name) {

struct stack_frame_s *stack_frame_p=0;

// structure "stack_frame_s" represents a user stack frame

// TODO: declare (and possibly initialize) other automatic variables.

switch (qsmm_evt) {

case QSMM_EVT_ENT_INIT:

// Register instruction classes.

QSMM_REG_INSTR_CLASS(meta_class_1);

QSMM_REG_INSTR_CLASS(meta_class_2);

// ...

QSMM_REG_INSTR_CLASS_PARAM(meta_class_a,var_a);

QSMM_REG_INSTR_CLASS_PARAM(meta_class_b,var_b);

// ...

qsmm_set_nstate_max(qsmm,__FUNCTION__,nstate);

// set the maximum allowed and the default number of

// states for nodes that belong to this node class

// Create the nodes.

QSMM_NODE_CREATE(node1);

QSMM_NODE_CREATE(node2);

// ...

// TODO: perform other initialization procedures.

break;

case QSMM_EVT_ENT_DONE:

// TODO: handle the instruction class set uninitialization

// event.

break;

case QSMM_EVT_ENGINE_INIT:

// TODO: handle the model instance initialization event.

break;

case QSMM_EVT_ENGINE_DONE:

// TODO: handle the model instance uninitialization event.

break;

Chapter 4: Multinode Model 102

case QSMM_EVT_NODE_ENTER:

qsmm_get_stack_frame(qsmm,0,(void **) &stack_frame_p);

// TODO: initialize *stack_frame_p, possibly according to the

// contents of a structure pointed by qsmm_param_p.

break;

case QSMM_EVT_NODE_LEAVE:

qsmm_get_stack_frame(qsmm,0,(void **) &stack_frame_p);

// TODO: set the contents of a structure pointed by

// qsmm_param_p according to *stack_frame_p and

// uninitialize *stack_frame_p.

break;

}

return 0;

}

4.5 Creating Nodes

To create a node, which belongs to a particular node class represented by an instruction classset, the following function can be used.

[Function]int qsmm_node_create (qsmm t model, const char*instr_class_set_name, int node )

This function creates a node of multinode model. The node will belong to a node classrepresented by instruction class set instr class set name. If node is non-negative, then thenode will have identifier node.

If node is equal to −1, then the function will try to find an unused identifier for the node.If the model instance does not exist, then an identifier found will be an unused identifier inthe range 0 to a value returned by function qsmm_get_nnode inclusive. If the model instanceexists, then an identifier found will be an unused identifier in the range 0 to a value returnedby function qsmm_get_nnode exclusive.

On success, the function returns a non-negative identifier of created node. On failure, thefunction returns a negative error code. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of node is less than −1 or is greater than QSMM_SIG_MAX.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_EXIST

A node with identifier node already exists.

QSMM_ERR_VIOLAP

Creating a node with identifier node will violate parameters of already createdmodel instance. To be able to create nodes with greater identifiers after creatingthe model instance, call function qsmm_node_reserve before creating the modelinstance. That function is described further on in this section.

QSMM_ERR_MNODE

The value of node is equal to −1, the model instance exists, but there are nounused node identifiers.

Chapter 4: Multinode Model 103

QSMM_ERR_NOMEM

There was not enough memory to create a node.

To create a node from within an event handler function of an instruction class set, where thename of the function is the name of the instruction class set, the following macro can be used.

[Macro]QSMM_NODE_CREATE (node )This macro is expanded to:

qsmm_node_create((qsmm), __FUNCTION__, (node))

The macro is intended for creating a model node with identifier node from within an eventhandler function of an instruction class set that represents a node class to which the creatednode will belong. The name of the event handler function must coincide with the name ofthe instruction class set, and normally it does coincide. There must be variable qsmm, whichis a handle of the multinode model, defined in a function from which the macro is expanded.Normally, that variable is an argument of the event handler function.

The created nodes are destroyed upon destruction of the whole multinode model, which isperformed by function qsmm_destroy. Starting from QSMM version 1.15 there is supporteddynamic node destruction using the following function.

[Function]int qsmm_node_destroy (qsmm t model, int node )This function destroys a node with identifier node contained in multinode model. Thatidentifier becomes the unused one. All statistics, which might have been collected for thenode, is cleared.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_PROFSRCP

A node with identifier node is the source of probability profile for other nodes.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, formore information on this mode.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing a reasonof the error, the operation can be repeated, and if the function succeeds or raisesQSMM_ERR_NOTFOUND, then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indetermi-nate state, then after removing a reason of the error, the operation can berepeated, and if the function succeeds or raises QSMM_ERR_NOTFOUND, then themodel instance state will become determinate.

To get the name of the node class of a node, the function described below can be used. Thisfunction can also be used to test whether a node with given identifier exists.

[Function]const char * qsmm_get_node_class_name (qsmm t model, int node )This function returns the name of an instruction class set that represents the node class of anode with identifier node contained in multinode model. If the node does not exist, then thefunction will return 0.

Chapter 4: Multinode Model 104

To reserve node identifiers to allow creating nodes with greater identifiers after making themodel instance, a function described below can be used. Without reserving, after making themodel instance, nodes can be created with identifiers not greater than the highest identifier ofa node created before making the model instance. The default number of reserved nodes is 1.

[Function]int qsmm_node_reserve (qsmm t model, int node )This function ensures that the internal array of nodes of multinodemodel is capable of holdingnodes with identifiers up to node inclusively. If necessary, the array is reallocated. Increasingarray length can be performed when the model instance is not yet created. The length of thearray is used as a parameter for creating the environment state identification engine and theinstruction emitting engine that correspond to the model instance.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of node is negative or is greater than QSMM_SIG_MAX.

QSMM_ERR_UNTIMELY

The length of an internal array, which holds nodes, needs to be increased, butthe model instance has already been created.

QSMM_ERR_NOMEM

There was not enough memory to perform reallocation of an internal array thatholds nodes.

To get the length of the internal array, the following function can be used.

[Function]int qsmm_get_nnode (qsmm t model )This function returns the length of the internal array that holds nodes of multinode model.Not all elements of the array may really contain nodes, some of them can have NULL values.The length of the array can be increased by functions qsmm_node_create and qsmm_node_

reserve. A value returned by this function is always positive.

A newly created node will have the number of states equal to the maximum allowed number ofstates of nodes that belong to a node class represented by an instruction class set specified whencreating the node. See Section 4.4.5 [Setting the Number of States], page 99, for a description offunctions qsmm_get_nstate_max and qsmm_set_nstate_max using which that maximum allowednumber of states can be retrieved or modified. When the environment state identification engineis represented by a small actor or the model contains multiple nodes, the number of states ofthe node can later be changed to other value.

To retrieve or set the number of states of a node, the following functions can be used.

[Function]int qsmm_get_node_nstate (qsmm t model, int node )This function returns the number of states of a node of multinode model.

On success, a positive value is returned. If node does not exist, then negative error codeQSMM_ERR_NOTFOUND will be returned.

[Function]int qsmm_set_node_nstate (qsmm t model, int node, int nstate )This function sets the number of states of a node of multinode model to nstate.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of nstate is less than 2 or is greater than the maximum allowed numberof states of nodes of a node class a node with identifier node belongs to.

Chapter 4: Multinode Model 105

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_NOSTATE

A node with identifier node has a probability profile loaded, and nstate is lessthan the minimum number of states a node must have to hold the probabilityprofile.

QSMM_ERR_PROFSRCU

A node with identifier node is a user of a source probability profile provided byanother node. See Section 5.12 [Memory Efficient Cloning a Probability Profile],page 191, for more information on this mode.

QSMM_ERR_NOSYS

The following conditions are true at once:

1. The environment state identification engine is represented by a large actor.This mode is specified using field is_large_env of structure qsmm_desc_s

when creating the multinode model.

2. The model contains a single node with identifier 0. Function qsmm_get_

nnode will return 1.

Use function qsmm_set_nstate_max to set the number of states of the node.

4.6 Creating the Model Instance

A multinode model can have an instance that represents model parameters specific to a singleinteraction of a system with an external entity or to a single run of the system against inputdata. That is, a model represents system structure, and the model instance is a system of thatstructure created to carry out a particular process of interaction or computation or, in otherwords, model execution. After finishing the process of model execution, the model instance canbe destroyed or recreated to perform a new process of model execution.

Creating the model instance implies creating the environment state identification engine andthe instruction emitting engine and also initializing the instruction execution environment. Todetermine parameters necessary to create the pair of engines, all instruction class sets registeredfor the model are scanned, and the engines are set up using parameters that comply with everyregistered instruction class set and every existing node.

New instruction class sets, instruction meta-classes, and instruction classes cannot be regi-stered for a model when its instance exists. New nodes cannot be created if they have identifiersgreater than the highest node identifier reserved before making the model instance. The highestnode identifier can be reserved explicitly, but is also reserved implicitly when creating a newnode with an identifier greater than identifiers of all previously created nodes.

To create the model instance, the following function can be used.

[Function]int qsmm_engine_create (qsmm t model )This function creates the instance of multinode model. A model instance corresponds toa particular process of interaction or computation performed using a model of a certainstructure. If there exists a model instance already created, then it will be destroyed first.

The function returns a non-negative value on success or a negative error code on failure increating a model instance. Currently, the following error codes can be returned.

QSMM_ERR_BIGMDL

The multinode model has too many variants of the contents of the look-aheadsignal segment or contains too many nodes or an instruction class set with toobig maximum number of states or which has too many instruction classes oroutcomes of those instruction classes.

Chapter 4: Multinode Model 106

QSMM_ERR_NOIC

There was encountered an instruction class set that does not contain instructionclasses.

QSMM_ERR_NOMEM

There was not enough memory to create the model instance.

To destroy the model instance, the following function can be used.

[Function]void qsmm_engine_destroy (qsmm t model )This function destroys the instance of multinode model. Destruction of the instance impliesdestruction of the environment state identification engine and the instruction emitting engineand removing all statistics they might have collected. If the model instance does not exist,then the function will do nothing. Destruction of the model instance removes restrictions onchanging model structure, which are imposed when creating the instance.

The pair of engines, which correspond to the model instance, is represented by an objectcalled actor pair. An actor pair is referred to by an actor pair handle.

[Data type]qsmm_actpair_tThis is a type for an actor pair handle. It is a pointer, so variables of this type can havezero value. The handle of an actor pair, which corresponds to a model instance, can beobtained using function qsmm_get_actpair (see below). The handle will be valid until themodel instance is destroyed.

To get the handle of an actor pair associated with the model instance, the following functioncan be used.

[Function]qsmm_actpair_t qsmm_get_actpair (qsmm t model )This function returns the handle of an actor pair associated with the instance of multinodemodel. The handle will be valid until the model instance is destroyed. If the model instancedoes not exist, then the function will return 0.

Handles of actors, which comprise an actor pair and represent the engines, can be obtainedusing functions described below.

[Function]qsmm_actor_t qsmm_get_actpair_actor_env (qsmm actpair t actpair )This function returns the handle of an actor of actor pair actpair that represents the envi-ronment state identification engine. This function never returns 0.

[Function]qsmm_actor_t qsmm_get_actpair_actor_opt (qsmm actpair t actpair )This function returns the handle of an actor of actor pair actpair that represents the instructi-on emitting engine. This function never returns 0.

For the certainty and full awareness of model operating conditions by the developer, it isrecommended to explicitly set all key parameters of both engines just after creating the modelinstance. If the handle of multinode model is stored in variable qsmm, then to assign to variableactor_env the handle of the environment state identification engine and to assign to variableactor_opt the handle of the instruction emitting engine, the following lines of code could beused:

qsmm_actor_t actor_env, actor_opt;

qsmm_actpair_t actpair=qsmm_get_actpair(qsmm);

actor_env=qsmm_get_actpair_actor_env(actpair);

actor_opt=qsmm_get_actpair_actor_opt(actpair);

For each of two engines, the following parameters are to be set.

Chapter 4: Multinode Model 107

1. The type of a function that returns a relative probability of output signal choice. Thisparameter is set using a call to qsmm_set_actor_relprob_type. If necessary, a helperfunction must be provided using a call to qsmm_set_actor_relprob_helper.

2. A spur type that corresponds to the automatic spur. This parameter is set using functionqsmm_set_actor_auto_spur_type. By default, the environment state identification engineuses automatic spur of type 0, and this can be turned off. Spur of type 0 then can be reusedfor another purpose.

3. Ways of perception for all supported spur types. The way of spur perception is set usingfunction qsmm_set_actor_spur_perception. By default, mode QSMM_SPUR_PERCEPTION_

NORMAL is used for all spur types.

4. Weights for all supported spur types. The weights are set using function qsmm_set_actor_

spur_weight.

5. The temperature of an engine. This parameter is set using function qsmm_set_actor_

ktemperature.

For a small actor, types of time for all supported spur types are to be set using calls toqsmm_set_actor_spur_time.

If an engine is represented by a large actor, say, referred to by handle actor, then the handleof a small actor associated with the large actor can be obtained by expression

qsmm_get_actpair_actor_env(

qsmm_get_actpair(qsmm_get_actor_large_model(actor)))

The following parameters are to be additionally set for that small actor.

1. A spur type that corresponds to the automatic spur. This parameter is set by a callto qsmm_set_actor_auto_spur_type for an actor, which handle was obtained using theabove expression. By default, that actor uses automatic spur of type 0, and this mode canbe turned off. Spur of type 0 of the small actor then can be reused for another purpose. Tospur of type 0 of the small actor there corresponds spur of type −1 of the large actor.

2. The way of perception for spur of type 0. This parameter is set by a call to qsmm_set_

actor_spur_perception either for an actor, which handle was obtained using the aboveexpression, passing 0 for spur type, or for the large actor, passing −1 for spur type. Bydefault, mode QSMM_SPUR_PERCEPTION_NORMAL is used.

3. Weight for spur type 0. This parameter is set by a call to qsmm_set_actor_spur_weight

either for an actor, which handle was obtained using the above expression, passing 0 forspur type, or for the large actor, passing −1 for spur type.

4.7 Incrementing Time and Spur

To convey to the instance of multinode model information that a period of continuous time haspassed, the following function can be used.

[Function]int qsmm_time_delta (qsmm t model, double time_delta )This function increments the values of continuous time associated with the environment stateidentification engine and the instruction emitting engine that correspond to the instance ofmultinode model. The values of continuous time are incremented by time delta.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of time delta is not finite, or the incremented value of continuous timeassociated with one or both engines becomes non-finite or negative.

QSMM_ERR_UNTIMELY

The model instance does not exist.

Chapter 4: Multinode Model 108

When the environment state identification engine is represented by a small actor, spur typessupported by the model have zero-based indices. Spur type 0 of the model normally correspondsto the automatic spur. This spur is used only by the environment state identification engine ofthe model. Spur type 0 of the environment state identification engine normally corresponds tothe automatic spur. The value of the automatic spur ordinarily not changed by a program thatuses the model.

When the environment state identification engine is represented by a large actor, the modelsupports special spur type −1 that corresponds to the automatic spur of a small actor associatedwith the large actor. The value of this spur ordinarily not changed by a program that uses themodel.

Spur types of the model with indices greater than 0 correspond to user spur supplied by aprogram that uses the model. Spur types of the environment state identification engine withindices greater than 0 correspond to user spur. The instruction emitting engine has the numberof supported spur types equal to the number of spur types specified when creating the modelminus 1. All supported spur types of that engine correspond to user spur. Spur type i of theinstruction emitting engine corresponds to spur type i+1 of the environment state identificationengine and the model.

To increment the value of the spur of given type for a model instance, the following functioncan be used.

[Function]int qsmm_spur_delta (qsmm t model, int spur_type, doublespur_delta )

This function increments by spur delta the value of the spur of type spur type of the envi-ronment state identification engine and possibly of the instruction emitting engine associatedwith the instance of multinode model. The value of spur delta can be negative. If spur typeis equal to 0 or −1, then only the value of the spur of type 0 or −1 the environment stateidentification engine keeps track of will be incremented. If spur type is equal to j > 0,then the value of the spur of type j of the environment state identification engine will beincremented, and the value of the spur of type j − 1 of the instruction emitting engine willbe incremented.

Spur type 0 corresponds to the automatic spur of the environment state identification engine,the value of which usually not changed by the application program. If the environment stateidentification engine is represented by a large actor (which is specified using field is_large_

env of structure qsmm_desc_s when creating a multinode model), then spur type −1 willcorrespond to the automatic spur of a small actor associated with the large actor, the valueof which usually not changed by the application program too. The number of spur typessupported by a multinode model (excluding that special spur type −1) is returned by functionqsmm_get_nspur.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

One of the following conditions is met:

– the environment state identification engine is represented by a small actorand spur type is negative;

– the environment state identification engine is represented by a large actorand spur type is less than −1;

– the value of spur type is greater than or equal to the number of spur typesspecified when creating the multinode model;

– the value of spur delta is not finite;

– the incremented value of the spur for one or both engines becomes non-finite.

Chapter 4: Multinode Model 109

QSMM_ERR_UNTIMELY

The model instance does not exist.

4.8 Transferring Control Between Nodes

Currently, transferring control to a node can only be performed by calling the node. A result oftransferring control to the node is node activation (if the node is not already active) and nodeexecution. When the node returns control to the caller, and the node is not called recursively,the node becomes the inactive one. Initially, when all nodes are inactive, activation of one ofthem is performed by a system that has created the multinode model. If there exist active nodes,then one of them will possess control and can call another node by transferring control to it.When calling a node, current state of the called node is reset to the initial one.

To transfer control to a node, the following function can be used.

[Function]int qsmm_node_call_default (qsmm t model, int node, void *paramp )This function transfers control to a node of multinode model, executes the node, and exitswhen the node returns control to the caller.

Transferring control to a node begins with sending event QSMM_EVT_NODE_ENTER to aninstruction class set, which is a node class of the node, and passing parameter paramp to theevent handler function. If the node does not have a probability profile specified, the envi-ronment state identification engine and/or the instruction emitting engine are representedby large actors, and the model contains multiple nodes, then a default uniform probabilityprofile will be loaded into the node. During the execution of the node, events QSMM_EVT_

ACTIVATE are sent to meta-classes of instruction classes, which identifiers were generated bythe instruction emitting engine. At the end of execution of the node, before returning controlto the caller, event QSMM_EVT_NODE_LEAVE is sent to the instruction class set with passingparameter paramp to the event handler function.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_NOCHOICE

There are no positive weights assigned to instruction classes of an instructi-on class set which is a node class of node. The weights can be specified usi-ng functions qsmm_set_instr_class_weight, qsmm_set_instr_class_weight_by_name_f, and qsmm_set_instr_meta_class_weight. The error will leave themultinode model in indeterminate state.

QSMM_ERR_NOPROF

A default uniform probability profile cannot be generated and loaded into node,because action emission matrices of all nodes are restricted to defining determi-nistic choice of action for every node state (which is specified using field is_

determ_opt of structure qsmm_desc_s when creating the multinode model), butan instruction class set, which is a node class of the node, contains multipleinstruction classes. It is necessary to load a probability profile into the nodemanually.

QSMM_ERR_MPROF

There is no room in the pool of probabilities lists in normal form of a large actorthat represents the environment state identification engine or the instruction

Chapter 4: Multinode Model 110

emitting engine when loading a default uniform probability profile into node.Sizes of the pools are specified in fields profile_pool_env_sz and profile_

pool_opt_sz of structure qsmm_desc_s when creating the multinode model.

QSMM_ERR_OUTCOME

During the invocation of instruction, an instruction outcome was not set whenit ought to be set, or an invalid instruction outcome was set. This will leave themultinode model in indeterminate state.

QSMM_ERR_STACKOVR

The number of frames in the node call stack will exceed the maximum allowedvalue. That value is specified in field stack_sz_max of structure qsmm_desc_s

when creating the multinode model and is returned by function qsmm_get_stack_

sz_max.

QSMM_ERR_UNSUPPLA

A default uniform probability profile cannot be loaded into node because themultinode model has positive length of the look-ahead signal segment. Thatlength is specified in field ngram_env_la_sz of structure qsmm_desc_s whencreating the multinode model.

QSMM_ERR_ILSEQ

A textual representation of instruction class parameters cannot be converted toa multibyte string according to the current locale. Such conversion is neededwhen filling structure qsmm_except_outcome_s that corresponds to error codeQSMM_ERR_OUTCOME returned by this function. See Section 4.19 [Error Handlingfor a Multinode Model], page 130, for more information on that structure. Theerror will leave the multinode model in indeterminate state.

QSMM_ERR_STORAGE

An Actor API function did return error QSMM_ERR_STORAGE. This could leave themultinode model in indeterminate state.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themultinode model in indeterminate state.

To get the number of times a node was called since the model instance had been created, thefollowing function can be used.

[Function]int qsmm_get_node_fq (qsmm t model, int node, long *fq_p )This function sets *fq p to the number of times a node of multinode model was called sincethe model instance had been created. If the model instance does not exist, then the functionwill set *fq p to 0. If fq p is 0, then *fq p will not be set.

On success, the function returns a non-negative value. If a node with identifier node doesnot exist, then the function will return negative error code QSMM_ERR_NOTFOUND.

To get the number of nested calls to a node, the function described below can be used.The function might be used, e.g. to prevent calling already active nodes if the system does notsupport recursive node calls.

[Function]int qsmm_get_node_recurs (qsmm t model, int node )On successful completion, this function returns the non-negative number of times control hasbeen transferred to node of multinode model and is not yet returned. Value 0 means thatthe node is inactive. Values greater than 0 mean that the node is active. If the node doesnot exist, then the function will return negative error code QSMM_ERR_NOTFOUND.

Chapter 4: Multinode Model 111

When a multinode model contains at least one active node, we can say the model is beingexecuted. After finishing the process of modeling, e.g. when all input data are processed, modelexecution should be terminated. That is, all active nodes should return control and becomeinactive ones (the node call stack should become empty).

There is a flag associated with a multinode model, which is when set to a non-zero value,indicates that the process of modeling should be continued, and when set to zero value, indicatesthat the process of modeling should be successfully terminated. When creating the modelinstance, the flag is initialized to a non-zero value. To query or set the value of the flag, thefollowing functions can be used.

[Function]int qsmm_get_continue (qsmm t model )This function returns a flag that specifies whether the process of execution of multinodemodel should be continued or terminated. If the function returns a positive value, thenthe process of model execution should be continued. If the function returns zero, then theprocess of model execution should be terminated. If the model instance does not exist, thenthe function will return negative error code QSMM_ERR_UNTIMELY.

[Function]int qsmm_set_continue (qsmm t model, int flag )This function sets a flag that specifies whether the process of execution of multinode modelshould be continued or terminated. If flag is non-zero, then the process of model executionshould be continued. If flag is zero, then the process of model execution should be terminated.

On success, the function returns a non-negative value. If the model instance does not exist,then the function will return negative error code QSMM_ERR_UNTIMELY.

The flag, when has zero value, should cause to return from all nested calls to function qsmm_

node_call_default. The flag is automatically checked at the beginning of execution of thatfunction, and if it has zero value, the function exits immediately. The flag is also automaticallychecked after sending event QSMM_EVT_NODE_ENTER to the instruction class set and after everyinstruction invocation, and if the flag is zero, function qsmm_node_call_default exits. The flagcan be explicitly analyzed using function qsmm_get_continue after a call to qsmm_node_call_

default when processing event QSMM_EVT_ACTIVATE by the event handler function of instructionmeta-class to perform immediate exit from the event handler function when model execution isterminated.

To set the flag to zero, the following macro can also be used.

[Macro]QSMM_TERMINATE ()This macro is expanded to:

qsmm_set_continue((qsmm), 0)

You can use this macro to terminate execution of a multinode model from within an eventhandler function that has argument qsmm equal to the handle of the multinode model.

For example, this macro can be called in a block of code that handles invocation of aninstruction (i.e. where event QSMM_EVT_ACTIVATE is processed by the event handler function ofinstruction meta-class) to terminate execution of a multinode model when all input data of themodel are fetched by the instruction.

To return just from the last call to qsmm_node_call_default, the following function can beused.

[Function]void qsmm_return_to_caller_node (qsmm t model )This function sets a flag for multinode model, which causes function qsmm_node_call_

default to exit. The flag is reset before triggering event QSMM_EVT_NODE_ENTER for theinstruction class set to process transfer of control to the node and before triggering event

Chapter 4: Multinode Model 112

QSMM_EVT_ACTIVATE for an instruction meta-class to process invocation of instruction bythe node. The flag is checked after processing event QSMM_EVT_NODE_ENTER by the eventhandler function of instruction class set and after processing event QSMM_EVT_ACTIVATE bythe event handler function of instruction meta-class. If function qsmm_return_to_caller_

node is called during processing instruction invocation, then an instruction outcome, whichmight be set, will be ignored.

4.9 Handling Instruction Invocation

During system operation, nodes of multinode model execute instructions. When a node has toinvoke an instruction, the node triggers event QSMM_EVT_ACTIVATE of an instruction meta-classthe instruction belongs to.

When triggering event QSMM_EVT_ACTIVATE, an identifier of the node is passed to the eventhandler function of instruction meta-class via argument qsmm_node. The event handler functionmay fetch a binary representation of parameters of the instruction class using a call to qsmm_

get_eh_instr_param. The name of an instruction class set the instruction class belongs to canbe obtained using a call to qsmm_get_eh_instr_class_set_name. Number idx that uniquelyidentifies the instruction class in the instruction class set can be fetched from the current frameof the system stack (see Section 4.12 [Working with System and User Stacks], page 117) usingcall

qsmm_get_stack_instr_class(qsmm,0,&idx);

While processing event QSMM_EVT_ACTIVATE, the event handler function of instruction meta-class may call nodes of multinode model using function qsmm_node_call_default.

After performing custom actions associated with an instruction class, which change system orenvironment state, the event handler function may set an instruction outcome. The instructionoutcome affects which state is a new state of the node after instruction invocation.

To get or set an instruction outcome, the following functions can be used.

[Function]void qsmm_get_instr_outcome (qsmm t model, int *outcome_p )This function sets *outcome p to an instruction outcome associated with multinode model. Ifoutcome p is 0, then *outcome p will not be set. An instruction outcome associated with themultinode model is the last instruction outcome set using a call to qsmm_set_instr_outcomewhile processing the instruction invocation event. If function qsmm_set_instr_outcome isnot called, and the instruction class has a positive number of outcomes, then the instructionoutcome returned will be equal to −1. If function qsmm_set_instr_outcome is not called, andthe instruction class has zero number of outcomes, then the instruction outcome returnedwill be the outcome of the previous instruction invoked by a node since control has beentransferred to the node or 0 if there is no such instruction.

[Function]int qsmm_set_instr_outcome (qsmm t model, int outcome )This function sets an instruction outcome, associated with multinode model, to outcome.The function performs only a preliminary check on the validity of the outcome. Final checksare performed after a return from the event handler function of instruction meta-class, and ifthe outcome is invalid, then error QSMM_ERR_OUTCOME will be raised by function qsmm_node_

call_default.

On success, the function returns a non-negative value. If outcome is less than −1, thennegative error code QSMM_ERR_INVAL will be returned.

The number of instruction outcomes is specified using function qsmm_set_eh_noutcome duri-ng instruction class initialization. The default number of instruction outcomes, which will beused when that function is not called, is equal to 1. The number of instruction outcomes equalto 0 has special meaning.

Chapter 4: Multinode Model 113

Before calling the event handler function of instruction meta-class to process event QSMM_

EVT_ACTIVATE, an instruction outcome associated with the multinode model is set to −1 if theinstruction class has a positive number of outcomes. If the instruction class has zero number ofoutcomes, then an instruction outcome associated with the multinode model will be set to theoutcome of the previous instruction invoked by the node since control has been transferred toit or to 0 if there is no such instruction.

After calling the event handler function of instruction meta-class to process event QSMM_EVT_ACTIVATE, if an instruction outcome associated with the multinode model is equal to −1, andthe number of outcomes of the instruction class is equal to 1, then outcome 0 will be usedwhen choosing the next node state. Such default behavior allows not to call function qsmm_set_

instr_outcome at all for instruction classes that have only one possible instruction outcome.

If after calling the event handler function an instruction outcome associated with the multi-node model is equal to −1, and the number of outcomes of the instruction class is not equal to 1,then error QSMM_ERR_OUTCOME will be raised by function qsmm_node_call_default. Such checkcompels to set an instruction outcome using function qsmm_set_instr_outcome if the numberof outcomes of the instruction class is greater than 1.

If the instruction class has zero number of outcomes, then while processing event QSMM_EVT_ACTIVATE by the event handler function of instruction meta-class, function qsmm_get_instr_

outcome can be called to analyze the outcome of the previous instruction invoked by the nodesince control has been transferred to it. That outcome can be left intact or can be changedto a non-negative value less than the maximum number among the numbers of outcomes ofinstruction classes, which belong to an instruction class set that represents a node class of thenode.

In QSMM version 1.16 there are added functions for retrieving a probability of the laststate transition performed and a probability of the last instruction invoked in a state. Theprobabilities have type QSMM_PROB_AGGR and are contained in corresponding cells of the statetransition matrix and the action emission matrix of the node. The functions can be called duringprocessing event QSMM_EVT_ACTIVATE by the event handler function of instruction meta-class,e.g. to compute the time when the instruction has to take effect.

[Function]double qsmm_get_prob_goto (qsmm t model )This function returns the probability of state transition performed just before invoking thelast instruction by a node of multinode model. The probability has type QSMM_PROB_AGGR

and is stored in a cell of the state transition matrix of the node. The returned value is alwaysin the range 0 to 1 (inclusive). If nodes of the model did not invoke instructions yet, thenthe function returns 0.

[Function]double qsmm_get_prob_action (qsmm t model )This function returns the probability of the last instruction invoked in a state of a node ofmultinode model just after performing the state transition. The probability has type QSMM_

PROB_AGGR and is stored in a cell of the action emission matrix of the node. The returnedvalue is always in the range 0 to 1 (inclusive). If nodes of the model did not invoke instructionsyet, then the function returns 0.

4.10 Setting Look-ahead Signals

Look-ahead signals are the ones, which along with an identifier of instruction class and aninstruction outcome are used after instruction invocation to determine a new node state. Maybe“look-ahead” is not a correct adjective chosen to denote those signals, it only indicates that insome situations those signals can convey look-ahead information. For example, when processinga sequence of symbols from left to right, look-ahead symbols can be passed to the multinode

Chapter 4: Multinode Model 114

model in the form of look-ahead signals. In other situations, those signals can be used to passeven look-back information to the model.

The length of the look-ahead signal segment of a multinode model and ranges of signals,which can be assigned to elements of that segment, are specified using fields ngram_env_la_

sz, nsig_ngram_env_la, and range_sig_env_la_p of structure qsmm_desc_s when creatingthe multinode model by function qsmm_create. Those parameters can be retrieved later usingfunctions qsmm_get_ngram_env_la_sz and qsmm_get_nsig_ngram_env_la called for the multi-node model and using function qsmm_get_actor_range_sig called for the environment stateidentification engine that corresponds to the multinode model.

An important limitation imposed on a model when its look-ahead signal segment has positivelength is that assembler programs cannot be loaded into nodes of such model. This limitationis also pertinent to loading default uniform probability profiles into nodes of the model usingimplicitly generated assembler programs when the model contains multiple nodes and the envi-ronment state identification engine and/or the instruction emitting engine are represented bylarge actors. When the look-ahead signal segment has positive length, such probability profilescannot be loaded into nodes of the model, and the nodes cannot be called. Therefore, when youneed to use a look-ahead signal segment of positive length for a model, one or both engines ofwhich are represented by large actors, use a single-node model that contains only a node withidentifier 0.

To get or set signals of the look-ahead signal segment at given positions, the following functi-ons can be used.

[Function]int qsmm_get_la_sig (qsmm t model, int pos, qsmm sig t *sigp )This function sets *sigp to an element of the look-ahead signal segment of multinode modelat position pos. If sigp is 0, then *sigp will not be set.

On success, the function returns a non-negative value. If pos is negative or is greater thanor equal to the length of the look-ahead signal segment, then negative error code QSMM_ERR_INVAL will be returned.

[Function]int qsmm_set_la_sig (qsmm t model, int pos, qsmm sig t sig )This function sets an element of the look-ahead signal segment of multinode model at positionpos to sig.

On success, the function returns a non-negative value. If pos is negative or is greater thanor equal to the length of the look-ahead signal segment, or sig does not fall into a range ofallowed signal identifiers at position pos of the look-ahead signal segment, then negative errorcode QSMM_ERR_INVAL will be returned.

Functions qsmm_get_la_sig and qsmm_set_la_sig can be called at any point after creatinga multinode model. For example, they can be called when processing event QSMM_EVT_NODE_

ENTER by the event handler function of instruction class set or when processing event QSMM_EVT_ACTIVATE by the event handler function of instruction meta-class.

If field range_sig_env_la_p of structure qsmm_desc_s has zero value, then function qsmm_

create will initialize elements of the look-ahead signal segment to 0. If that field has a non-zerovalue, then function qsmm_create will initialize elements of the look-ahead signal segment tovalues of field first of corresponding elements of array range_sig_env_la_p.

4.11 Setting Instruction Classes Weights

If field dont_use_instr_class_weights of structure qsmm_desc_s passed to function qsmm_

create when creating a multinode model has zero value, then nodes of the model may have

Chapter 4: Multinode Model 115

weights assigned to instruction classes that can be executed by the nodes1. Those weightsare multipliers for optimal probabilities of invocation of instruction classes. The multipliedprobabilities are renormalized and become probabilities that are actually used when stochasti-cally choosing which instruction class to invoke. In fact, the weights are assigned using functionqsmm_set_actor_sig_weight to output signals of the instruction emitting engine. Functionqsmm_node_create initializes weights of all instruction classes, which can be executed by thenode, to 1.

To retrieve or set the weight of an instruction class, which is specified by a number thatuniquely identifies it in an instruction class set, the following functions can be used.

[Function]int qsmm_get_instr_class_weight (qsmm t model, int node, intinstr_class, double *weight_p )

This function retrieves the weight of an instruction class that can be executed by node ofmultinode model. The instruction class is specified by number instr class that uniquelyidentifies it in an instruction class set which is a node class of node. If weight p is not 0,then *weight p will be set to the retrieved weight.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_INVAL

The value of instr class is negative or is greater than or equal to the number ofinstruction classes in an instruction class set which is a node class of node.

QSMM_ERR_NOSYS

The multinode model does not allow to assign weights to instruction classes.

[Function]int qsmm_set_instr_class_weight (qsmm t model, int node, intinstr_class, double weight )

This function sets to weight the weight of an instruction class that can be executed by nodeof multinode model. The instruction class is specified by number instr class that uniquelyidentifies it in an instruction class set which is a node class of node.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_INVAL

The value of weight is not finite or is negative, or the value of instr class isnegative or is greater than or equal to the number of instruction classes in aninstruction class set which is a node class of node.

QSMM_ERR_NOSYS

The multinode model does not allow to assign weights to instruction classes.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To retrieve or set the weight of an instruction class, which is specified by its name thatconsists of an instruction meta-class name and an optional textual representation of instructionclass parameters, the following functions can be used.

1 Here and below “invocation/execution of an instruction class” actually means “invocation/execution of aninstruction that belongs to the instruction class.”

Chapter 4: Multinode Model 116

[Function]int qsmm_get_instr_class_weight_by_name_f (qsmm t model, intnode, double *weight_p, const char *fmt, ...)

This function retrieves the weight of an instruction class that can be executed by node ofmultinodemodel. The instruction class is specified by its name, which is the name of instructi-on meta-class followed by an optional textual representation of instruction class parametersafter one or more whitespace characters. The name of instruction class is formatted accordingto argument fmt and subsequent arguments, the meaning of which is the same as in functionprintf. If weight p is not 0, then *weight p will be set to the retrieved weight.

Before searching the instruction class in an instruction class set which is a node class ofnode, the formatted name is converted to a canonical form: extra whitespace charactersbefore and after the name of instruction meta-class are removed, and textual representationof instruction class parameters is normalized according to rules described in Section 4.3.4[Setting the Instruction Parameters String], page 87.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist or the instruction class not found inan instruction class set which is a node class of node.

QSMM_ERR_INVAL

The name of instruction class has invalid format.

QSMM_ERR_ILSEQ

The name of instruction class cannot be converted to a wide string according tothe current locale.

QSMM_ERR_NOSYS

The multinode model does not allow to assign weights to instruction classes.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_set_instr_class_weight_by_name_f (qsmm t model, intnode, double weight, const char *fmt, ...)

This function sets to weight the weight of an instruction class that can be executed by node ofmultinodemodel. The instruction class is specified by its name, which is the name of instructi-on meta-class followed by an optional textual representation of instruction class parametersafter one or more whitespace characters. The name of instruction class is formatted accordingto argument fmt and subsequent arguments, the meaning of which is the same as in functionprintf.

Before searching the instruction class in an instruction class set which is a node class ofnode, the formatted name is converted to a canonical form: extra whitespace charactersbefore and after the name of instruction meta-class are removed, and textual representationof instruction class parameters is normalized according to rules described in Section 4.3.4[Setting the Instruction Parameters String], page 87.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist or the instruction class not found inan instruction class set which is a node class of node.

QSMM_ERR_INVAL

The value of weight is not finite or is negative, or the name of instruction classhas invalid format.

Chapter 4: Multinode Model 117

QSMM_ERR_ILSEQ

The name of instruction class cannot be converted to a wide string according tothe current locale.

QSMM_ERR_NOSYS

The multinode model does not allow to assign weights to instruction classes.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

For example, to set the weight of instruction class ‘move north’ to 0 to disable moving anagent in the north direction, use a line of code like this:

qsmm_set_instr_class_weight_by_name_f(qsmm,node,0,"move north");

To set weights of all instruction classes of a node, which are derived from an instructionmeta-class, to the same value, the following function can be used.

[Function]int qsmm_set_instr_meta_class_weight (qsmm t model, const char*instr_meta_class_name, int node, double weight )

This function sets weights of all instruction classes, which belong to instruction meta-classinstr meta class name and which can be executed by node of multinode model, to a valueequal to weight divided by the number of those instruction classes.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of weight is not finite or is negative.

QSMM_ERR_NOTFOUND

Instruction meta-class instr meta class name not found, or a node with identifiernode does not exist, or no instruction classes derived from instruction meta-classinstr meta class name are found in an instruction class set which is a node classof node.

QSMM_ERR_TYPE

An entity named instr meta class name is not an instruction meta-class. Theentity is an instruction class set.

QSMM_ERR_NOSYS

The multinode model does not allow to assign weights to instruction classes.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

4.12 Working with System and User Stacks

The system stack of called nodes contains information on active nodes, i.e. nodes to which controlhad been transferred and which did not return it yet. A node can occur in several frames ofthe stack when the node is called recursively. The number of frames in the stack is limited bya value specified in field stack_sz_max of structure qsmm_desc_s when creating the multinodemodel, which is returned by function qsmm_get_stack_sz_max. The current number of framesin the stack can be retrieved using the following function.

[Function]int qsmm_get_stack_sz (qsmm t model )This function returns the current number of frames in the stack of called nodes of multinodemodel. The returned value is always non-negative.

To get an identifier of called node stored in the system stack at given depth, the followingfunction can be used.

Chapter 4: Multinode Model 118

[Function]int qsmm_get_stack_node (qsmm t model, int depth )This function returns a non-negative identifier of called node stored in the system stack ofmultinode model at specified depth. The value of depth must be non-negative and less thana value returned by function qsmm_get_stack_sz. The value of depth equal to 0 correspondsto current stack frame, the value of depth equal to 1 corresponds to the previous stack frame,and so on.

On failure, the function returns a negative error code. Currently, the following error codescan be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of framesin the node call stack, which is returned by function qsmm_get_stack_sz.

To every node in the node call stack there corresponds a node state, on the basis of which aninstruction was invoked or is to be invoked by the node. The node state can be obtained usingthe following function.

[Function]int qsmm_get_stack_state (qsmm t model, int depth )This function returns a non-negative node state index stored in the system stack of multinodemodel at specified depth. It is a state determined by the environment state identificationengine. If the state is not determined yet, then the returned value will be equal to 0.

The value of depth must be non-negative and less than a value returned by function qsmm_

get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the valueof depth equal to 1 corresponds to the previous stack frame, and so on.

On failure, the function returns a negative error code. Currently, the following error codescan be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of framesin the node call stack, which is returned by function qsmm_get_stack_sz.

To a node there might correspond an instruction class of the last instruction invoked by thenode. To fetch that information from the node call stack, the following function can be used.

[Function]int qsmm_get_stack_instr_class (qsmm t model, int depth, int*idx_p )

This function sets *idx p to the index of an instruction class of the last instruction invoked bya node. That instruction class index is fetched from a frame of the system stack of multinodemodel at specified depth. If idx p is 0, then *idx p will not be set. If there are no instructionsinvoked by the node since the corresponding frame in the stack is created, and idx p is not0, then *idx p will be set to −1.The value of depth must be non-negative and less than a value returned by function qsmm_

get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the valueof depth equal to 1 corresponds to the previous stack frame, and so on.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The node call stack is empty.

Chapter 4: Multinode Model 119

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of framesin the node call stack, which is returned by function qsmm_get_stack_sz.

For the means of obtaining information on an instruction class represented by its index, seeSection 4.4.4 [Registering Instruction Classes], page 94.

Besides the system stack, a multinode model can maintain a user stack, which contai-ns application-specific information associated with called nodes. Ordinarily, that informationincludes values of variables used by instruction classes, and those values make up the executioncontext of a node.

A frame of the user stack is typically an instance of a structure or a union defined in anapplication program. The purpose of functions described below is to query or set the size of theframe. Setting the size of the frame should be performed before creating the model instance byfunction qsmm_engine_create.

[Function]int qsmm_get_stack_frame_sz (qsmm t model )This function returns the size in bytes of user stack frame of multinode model. If the userstack is not used, then 0 will be returned. This function never returns negative values.

[Function]int qsmm_set_stack_frame_sz (qsmm t model, int sz )This function sets the size of user stack frame of multinode model to sz bytes. Size equal to0 indicates that the user stack is not used.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance already exists.

QSMM_ERR_INVAL

The value of sz is negative.

Function qsmm_create initializes the size of user stack frame to 0.

When control is transferred to a node, a new frame in the system stack is created. If the sizeof user stack frame is greater than 0, then a new frame in the user stack will be also created,and the total number of frames in each stack will be equal to a value returned by functionqsmm_get_stack_sz. After creating a new frame in the user stack, the frame is initialized withzero bytes.

Event QSMM_EVT_NODE_ENTER is triggered for an instruction class set which is a node class ofthe node. The event handler function of the instruction class set may process that event andperform application-specific initialization of a newly created user stack frame. For example, thefunction may allocate dynamic arrays or copy parameters of calling the node to the frame. Theparameters are usually passed via a memory block pointed by argument qsmm_param_p of theevent handler function.

When the node returns control, event QSMM_EVT_NODE_LEAVE is triggered for the instructionclass set. The contents of the current stack frame, which might have been changed while processi-ng events QSMM_EVT_ACTIVATE by event handler functions of instruction meta-classes, can beused to compute results of node invocation. Those results are usually returned via a memoryblock pointed by argument qsmm_param_p of the event handler function of instruction class set.If necessary, the event handler function must perform application-specific uninitialization of theframe, e.g. free allocated memory.

To get a pointer to a frame of the user stack, the following function can be used.

Chapter 4: Multinode Model 120

[Function]int qsmm_get_stack_frame (qsmm t model, int depth, void **frame_pp )This function sets *frame pp to a pointer to a frame of the user stack of multinode model atspecified depth. If frame pp is 0, then *frame pp will not be set.

The value of depth must be non-negative and less than a value returned by function qsmm_

get_stack_sz. The value of depth equal to 0 corresponds to current stack frame, the valueof depth equal to 1 corresponds to the previous stack frame, and so on.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOUSTACK

The user stack is not used. Most likely, a positive size of user stack frame was notset by function qsmm_set_stack_frame_sz before creating the model instance.

QSMM_ERR_UNTIMELY

The user stack is empty.

QSMM_ERR_INVAL

The value of depth is negative or is greater than or equal to the number of framesin the user stack, which is returned by function qsmm_get_stack_sz.

If a user stack frame is stored in structure stack_frame_s, then the size of the frame can beset by this call:

qsmm_set_stack_frame_sz(qsmm,sizeof(struct stack_frame_s));

To get a pointer to current stack frame, use lines of code like these:

struct stack_frame_s *stack_frame_p=0;

qsmm_get_stack_frame(qsmm,0,(void **) &stack_frame_p);

4.13 Dumping a State Transition Matrix

The state transition matrix of a node contains transition probabilities of supported types alongwith other numeric information. Rows of the matrix correspond to quadruples, each consisti-ng of a source state, a user or mixed type instruction invoked in that state, the outcome ofthat instruction, and the contents of the look-ahead signal segment. Columns of the matrixcorrespond to target transition states. To dump a state transition matrix to a stream, thefollowing function can be used.

[Function]int qsmm_mat_goto_dump (qsmm t model, int node, structqsmm dump mat goto desc s *desc_p, FILE *filep )

This function dumps a state transition matrix of node of multinode model to stream filep. Ifnode is equal to −1, then state transition matrices of all nodes of the multinode model willbe dumped. Dumping is performed according to parameters specified in *desc p. If desc pis 0, then default parameters will be used.

In the current implementation, if desc p is not 0, then *desc p will not be modified as aresult of the function call. However, in future versions of the package the contents of *desc pcould be modified by the function, e.g. statistics on the dumping process could be writtenthere.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_INVAL

The value of desc p is not 0, and parameters specified in *desc p are invalid.

Chapter 4: Multinode Model 121

QSMM_ERR_NOTFOUND

The value of node is not −1, and a node with identifier node does not exist.

QSMM_ERR_STORAGE

An Actor API function did return error QSMM_ERR_STORAGE. This could leave themodel instance in indeterminate state.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state.

A structure, which specifies parameters of dumping, is described below.

[Structure]qsmm_dump_mat_goto_desc_sThis structure specifies parameters of dumping the state transition matrix of a node. Itcontains the following fields.

[Field]char do_print_prob[QSMM_PROB_COUNT]An array that specifies probabilities of which types to dump. Indices of the array are theelements of enumeration qsmm_prob_e (except for the last element) described in Section 2.8[Generating an Optimal Action], page 29. If an element of the array has a non-zero value,then probabilities of the corresponding type will be dumped. The default is to dumpprobabilities of all types.

[Field]int indentLeft indent, i.e. the number of spaces to print at the beginning of each line of output.Must be a non-negative value. The default is to use indent 0.

[Field]int prob_precThe number of digits after the decimal point to print for probabilities. If is a positivenumber, then use fixed-point notation. If is a negative number, then use exponentialnotation with the number of digits after the decimal point equal to the absolute value ofthe field. If is zero, then use exponential notation with 15 digits after the decimal point,which is the default mode.

[Field]long fq_minThe minimum value of field fq of an instance of structure qsmm_cycle_s, whichcorresponds to the intersection of a row and a column of the matrix. Information oninstances with lesser value of field fq, i.e. which have lesser frequency, will not be includedin the output. The default is to use value 0 for the minimum frequency.

To improve compatibility with future versions of the library, an instance of structure qsmm_

dump_mat_goto_desc_s, a pointer to which is passed to function qsmm_mat_goto_dump, shouldbe zeroed using function memset before setting values of structure fields.

Below there is shown a fragment of a dump. When creating the dump, only element QSMM_PROB_LEARNT of field do_print_prob of structure qsmm_dump_mat_goto_desc_s was set to anon-zero value. To make lines of the example shorter, fractional parts of numbers in exponentialnotation were truncated, and the numbers were rounded.* State 83

A0 |mn| O7 L0 : tmd0=183117, tmc0=6E+4, state_next=45, spur[0].val0=-4E+5, spur[1].val0=4E+2

S45 : pl=1.0E+00, spur[0].ds=-3E+05, spur[1].ds=4E+02, fq=376, ps_d=148416, ps_c=5E+04

S79 : pl=4.2E-267, spur[0].ds=-4E+04, spur[1].ds=1E+01, fq=3, ps_d=23976, ps_c=8E+03

S92 : pl=9.1E-283, spur[0].ds=-2E+04, spur[1].ds=4E+00, fq=2, ps_d=9516, ps_c=3E+03

A0 |mn| O7 L1 : tmd0=183219, tmc0=6E+4, state_next=120, spur[0].val0=-4E+5, spur[1].val0=4E+2

Chapter 4: Multinode Model 122

S63 : pl=2.2E-245, spur[0].ds=-4E+04, spur[1].ds=1E+01, fq=5, ps_d=22740, ps_c=8E+03

S87 : pl=2.0E-292, spur[0].ds=-3E+02, spur[1].ds=0E+00, fq=1, ps_d=156, ps_c=5E+01

S120 : pl=1.0E+00, spur[0].ds=-3E+05, spur[1].ds=4E+02, fq=119, ps_d=160185, ps_c=5E+04

Below there is a key for the dump. For information on fields of structures referenced, seeSection 3.2 [Structures for Accessing Storage], page 58.

Ai An instruction invoked by the node in a source transition state. Index i is a numberthat uniquely identifies the instruction, i.e. the instruction class, in an instructionclass set which is a node class of the node. Starting from QSMM version 1.15, thename of the instruction class is dumped after token Ai between characters ‘|’.

Li Look-ahead signal i that was in the look-ahead signal segment of multinode modelwhen the node was in a source transition state. The number of tokens Li is equal tothe length of the look-ahead signal segment of multinode model. Positions of tokensLi are equal to positions of look-ahead signals in the look-ahead signal segment.

Oi Outcome i of an instruction invoked by the node in a source transition state.

Si The description of a transition to target state i. Starting from QSMM version 1.15,if the state has a name assigned by an argument of stt assembler instruction, thenthat name will be dumped after token Si in quotes.

RST This keyword can replace tokens ‘Ax |name| Oy ’ for source transition state 0. Thekeyword indicates that one of specified transitions to target states will be madewhen control is just transferred to the node. In such situation the node did notinvoke instructions yet, so values x and y are unknown.

fq The value of field fq of structure qsmm_cycle_s.

pa The probability of type QSMM_PROB_AGGR.

pf The probability of type QSMM_PROB_FQ.

pl The probability of type QSMM_PROB_LEARNT.

pp The probability of type QSMM_PROB_PROFILE.

ps_c The value of field period_sum_c of structure qsmm_cycle_s.

ps_d The value of field period_sum_d of structure qsmm_cycle_s.

spur[i].ds

The value of field delta_sum of structure qsmm_cspur_s for spur type i. Spur type0 usually corresponds to the automatic spur.

spur[i].val0

The value of field val0 of structure qsmm_sspur_s for spur type i. Spur type 0usually corresponds to the automatic spur.

State The index of a source transition state. Starting from QSMM version 1.15, if thestate has a name assigned by an argument of stt assembler instruction, then thatname will be dumped after the index of the state in quotes.

state_next

The index of target state of the last transition made from a source state.Corresponds to the value of field sig_cycle_next of structure qsmm_state_s.Special value ‘N’ corresponds to value QSMM_SIG_INVALID of that field.

tmc0 The value of field tmc0 of structure qsmm_state_s.

tmd0 The value of field tmd0 of structure qsmm_state_s.

Chapter 4: Multinode Model 123

Descriptions only of those transitions to target states are dumped, information on which isheld in storage. Omitting transitions, information on which is absent in storage, reduces thelength of the output when dumping a sparse state transition matrix.

When not all descriptions of transitions are dumped, either because of a positive value of fieldfq_min of structure qsmm_dump_mat_goto_desc_s or because information on some transitionsis absent in storage, the sum of probabilities (of a specific type) of transitions to target states ina row of the matrix may be less than 1. If field fq_min has zero value, then every transition thatwas not dumped will have a probability equal to (1− p)/n, where p is the sum of probabilitiesof transitions, which were dumped, and n is the number of transitions that were not dumped.

4.14 Dumping an Action Emission Matrix

The action emission matrix of a node contains probabilities of emitting each action of the nodein each state of the node. The actions are instruction classes of instruction class set of the node.To dump an action emission matrix to a stream, the following function can be used.

[Function]int qsmm_mat_action_dump (qsmm t model, int node, structqsmm dump mat action desc s *desc_p, FILE *filep )

This function dumps the action emission matrix of node of multinode model to stream filep.If node is equal to −1, then action emission matrices of all nodes of the multinode model willbe dumped. Dumping is performed according to parameters specified in *desc p. If desc pis 0, then default parameters will be used.

In the current implementation, if desc p is not 0, then *desc p will not be modified as aresult of the function call. However, in future versions of the package the contents of *desc pcould be modified by the function, e.g. statistics on the dumping process could be writtenthere.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_INVAL

The value of desc p is not 0, and parameters specified in *desc p are invalid.

QSMM_ERR_NOTFOUND

The value of node is not −1, and a node with identifier node does not exist.

QSMM_ERR_STORAGE

An Actor API function did return error QSMM_ERR_STORAGE. This could leave themodel instance in indeterminate state.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state.

A structure, which specifies parameters of dumping, is described below.

[Structure]qsmm_dump_mat_action_desc_sThis structure specifies parameters of dumping the action emission matrix of a node. Itcontains the following fields.

[Field]char do_print_prob[QSMM_PROB_COUNT]An array that specifies probabilities of which types to dump. Indices of the array are theelements of enumeration qsmm_prob_e (except for the last element) described in Section 2.8[Generating an Optimal Action], page 29. If an element of the array has a non-zero value,

Chapter 4: Multinode Model 124

then probabilities of the corresponding type will be dumped. The default is to dumpprobabilities of all supported types.

[Field]int indentLeft indent, i.e. the number of spaces to print at the beginning of each line of output.Must be a non-negative value. The default is to use indent 0.

[Field]int prob_precThe number of digits after the decimal point to print for probabilities. If is a positivenumber, then use fixed-point notation. If is a negative number, then use exponentialnotation with the number of digits after the decimal point equal to the absolute value ofthe field. If is zero, then use exponential notation with 15 digits after the decimal point,which is the default mode.

[Field]long fq_minThe minimum value of field fq of an instance of structure qsmm_cycle_s, whichcorresponds to the intersection of a row and a column of the matrix. Information oninstances with lesser value of field fq, i.e. which have lesser frequency, will not be includedin the output. The default is to use value 0 for the minimum frequency.

To improve compatibility with future versions of the library, an instance of structure qsmm_

dump_mat_action_desc_s, a pointer to which is passed to function qsmm_mat_action_dump,should be zeroed using function memset before setting values of structure fields.

Below there is shown a fragment of a dump. When creating the dump, only element QSMM_PROB_LEARNT of field do_print_prob of structure qsmm_dump_mat_action_desc_s was set to anon-zero value. To make lines of the example shorter, some digits in fractional parts of numbersin exponential notation were replaced with ellipses.

* State 1 : tmd0=2711, tmc0=1.205...E+03, action_next=0, spur[0].val0=4.000...E+00

A0 |me| : pl=9.9306...E-01, spur[0].ds=4.0...E+00, fq=43, ps_d=1965, ps_c=8.22...E+02

A1 |ms| : pl=3.4713...E-03, spur[0].ds=0.0...E+00, fq=49, ps_d=147, ps_c=9.80...E+01

A2 |mw| : pl=3.4713...E-03, spur[0].ds=0.0...E+00, fq=36, ps_d=108, ps_c=7.20...E+01

Below there is a key for the dump. For information on fields of structures referenced, seeSection 3.2 [Structures for Accessing Storage], page 58.

Ai The description of an action with index i for a state. Starting from QSMM version1.15, the name of an instruction class that corresponds to the action is dumped aftertoken Ai between characters ‘|’.

action_next

The index of the last action emitted in a state. Corresponds to the value of fieldsig_cycle_next of structure qsmm_state_s. Special value ‘N’ corresponds to valueQSMM_SIG_INVALID of that field.

fq The value of field fq of structure qsmm_cycle_s.

pa The probability of type QSMM_PROB_AGGR.

pf The probability of type QSMM_PROB_FQ.

pl The probability of type QSMM_PROB_LEARNT.

pp The probability of type QSMM_PROB_PROFILE.

ps_c The value of field period_sum_c of structure qsmm_cycle_s.

ps_d The value of field period_sum_d of structure qsmm_cycle_s.

spur[i].ds

The value of field delta_sum of structure qsmm_cspur_s for spur type i.

Chapter 4: Multinode Model 125

spur[i].val0

The value of field val0 of structure qsmm_sspur_s for spur type i.

State The description of a state. Starting from QSMM version 1.15, if the state has aname assigned by an argument of stt assembler instruction, then that name will bedumped after the index of the state in quotes.

tmc0 The value of field tmc0 of structure qsmm_state_s.

tmd0 The value of field tmd0 of structure qsmm_state_s.

Starting from QSMM version 1.14, descriptions only of those actions for an action choice stateare dumped, information on which is held in storage. Omitting actions, information on whichis absent in storage, reduces the length of the output when dumping a sparse action emissionmatrix.

When not all descriptions of actions are dumped, either because of a positive value of fieldfq_min of structure qsmm_dump_mat_action_desc_s or because information on some actions isabsent in storage, the sum of probabilities (of a specific type) of actions for an action choicestate may be less than 1. If field fq_min has zero value, then every action that was not dumpedwill have a probability equal to (1− p)/n, where p is the sum of probabilities of actions, whichwere dumped, and n is the number of actions that were not dumped.

4.15 Controlling Random Behavior

A random number generator used by a multinode model, either supplied when creating the modelor, if not supplied, an instance of default random number generator allocated automatically, canbe obtained using the following function.

[Function]qsmm_rng_t qsmm_get_rng (qsmm t model )This function returns the handle of a random number generator used by the environmentstate identification engine and the instruction emitting engine of multinode model. Thisfunction never returns 0.

The handle of a random number generator returned is typically used to seed the generatorafter creating the multinode model or the model instance. See Section 6.1 [Random NumberGenerators], page 212, for information on how to seed a random number generator and performother operations on it.

A useful approach to test the efficiency of operation of a multinode model developed usingthe QSMM framework is to compare a measure of efficiency calculated for the model duringits normal operation with a measure of efficiency calculated when an optimization mechanismprovided by the QSMM framework is switched off. The greater is the difference between thosevalues the more optimization mechanism provided by the QSMM framework increases overalloptimality of operation of the model.

To switch the model instance to nonoptimal or normal behavior, the following function canbe used.

[Function]int qsmm_set_random (qsmm t model, int flag )This function switches the current mode of behavior of the instance of multinode model toa nonoptimal or an optimal (normal) mode. If flag is non-zero, then the current mode willbe switched to the nonoptimal one. If flag is zero, then the current mode will be switchedto the optimal one. In the nonoptimal mode actors, which represent the environment stateidentification engine and the instruction emitting engine, use equal probabilities of actionchoice, to which profile probabilities and action weights are applied.

On success, the function returns a non-negative value. If the model instance does not exist,then negative error code QSMM_ERR_UNTIMELY will be returned.

Chapter 4: Multinode Model 126

Function qsmm_engine_create initializes the current mode of behavior of the model instanceto the optimal (normal) one.

4.16 Associating Parameters with a Model

When an application creates a multinode model, user variables of the model can be declared asglobal (or static global) ones and accessed from event handler functions as normal C variables.However, when an application creates several multinode models, there may arise a need toassociate a number of variables with a particular model.

There can be a number of pointers associated with a multinode model. They could pointto statically or dynamically allocated memory blocks, possibly instances of structures in whichvariables specific to the model are stored. The pointers are accessed by indices. The set ofindices could be defined using the enum keyword.

To get a pointer associated with a model or associate a pointer with the model, the followingfunctions can be used.

[Function]void * qsmm_get_ptr (qsmm t model, int ptr_idx )This function returns a pointer with index ptr idx associated with multinode model. If apointer with that index is not associated with the model, or the pointer is NULL, then 0 willbe returned.

[Function]int qsmm_set_ptr (qsmm t model, int ptr_idx, void *ptr_p )This function associates pointer ptr p with multinode model. The pointer can be fetchedlater by index ptr idx.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of ptr idx is negative.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Starting from QSMM version 1.15 there is supported associating pointers not only with thewhole multinode model, but also with its particular nodes. To get a pointer associated with anode or associate a pointer with the node, the following functions can be used.

[Function]void * qsmm_get_node_ptr (qsmm t model, int node, int ptr_idx )This function returns a pointer with index ptr idx associated with a node of multinodemodel.If the node does not exist, or a pointer with that index is not associated with the node, orthe pointer is NULL, then 0 will be returned.

[Function]int qsmm_set_node_ptr (qsmm t model, int node, int ptr_idx, void*ptr_p )

This function associates pointer ptr p with a node of multinode model. The pointer can befetched later by index ptr idx.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of ptr idx is negative.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Chapter 4: Multinode Model 127

4.17 Enumerating Entities

An instruction meta-class and an instruction class set are two special types of entities that canbe stored within a multinode model. There are also several other types of entities that can bestored there. The notion of entity was introduced primarily to enable passing an entity typeand an entity identifier to an error handler function as parameters of an error occurred. Thatnotion has nothing to do with logical entities represented by nodes of the model.

Entity types are declared using the following enumeration.

[Enumeration]qsmm_ent_eThis is an enumeration for categorizing entities stored within a multinode model. It containsthe following elements.

QSMM_ENT_INVALID

Invalid entity type, which is currently used to indicate unknown entity type or atype of non-existent entity.

QSMM_ENT_INSTR_CLASS_SET

An instruction class set. Is identified by name. See Section 4.1 [Principle ofOperation], page 75, for more information.

QSMM_ENT_INSTR_META_CLASS

An instruction meta-class. Is identified by name. See Section 4.1 [Principle ofOperation], page 75, for more information.

QSMM_ENT_INSTR_CLASS

An instruction class. A human-readable identifier of the instruction class consistsof an instruction meta-class name and, optionally, a whitespace character and astring representation of instruction parameters. See Section 4.1 [Principle ofOperation], page 75, for more information.

QSMM_ENT_NODE

A node of multinode model. Is identified by a non-negative integer.

QSMM_ENT_VAR_PROB

A controlled or output probability variable. Is identified by name. See Section 5.9[Using Probability Variables], page 171, for more information.

QSMM_ENT_ARRAY_PROB

[New in QSMM 1.16] An output probabilities array. Is identified by name.See Section 5.10.3 [Getting Output Probabilities Arrays], page 185, for moreinformation.

QSMM_ENT_NODE_CLASS

A synonym for QSMM_ENT_INSTR_CLASS_SET.

Entities of types QSMM_ENT_INSTR_CLASS_SET and QSMM_ENT_INSTR_META_CLASS share thesame namespace and must not have duplicate names. That was made because to each of thoseentities an event handler function with the same name usually corresponds, and function namesmust be unique.

The identifier of an entity can be stored in a union that contains fields for holding a stringor numeric identifier.

[Union]qsmm_ent_uThis union holds an identifier of an entity of one of the types defined by enumeration qsmm_

ent_e. The union contains the following fields.

Chapter 4: Multinode Model 128

[Field]char *nameA string identifier of the entity. Is applicable to entities of types QSMM_ENT_INSTR_CLASS_SET, QSMM_ENT_INSTR_META_CLASS, QSMM_ENT_INSTR_CLASS, QSMM_ENT_VAR_PROB, QSMM_ENT_ARRAY_PROB, and QSMM_ENT_NODE_CLASS.

[Field]int idA numeric identifier of the entity. Is applicable to entities of type QSMM_ENT_NODE.

To enumerate entities of given type stored within a multinode model, the following functioncan be used.

[Function]int qsmm_enum_ent (qsmm t model, enum qsmm ent e ent_type,qsmm enum ent callback func t callback_func, void *paramp )

This function enumerates all entities of type ent type stored in multinode model. The processof enumeration is a repeated calling callback function callback func, to which an entity type,an entity identifier, and user parameter paramp are passed. If the callback function returnsa positive value, then the process of enumeration will be continued. If the callback functionreturns zero, then the process of enumeration will be terminated, and function qsmm_enum_

ent will report success. If the callback function returns a negative value, then the process ofenumeration will be terminated, and function qsmm_enum_ent will report failure.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of ent type is not QSMM_ENT_INSTR_META_CLASS, QSMM_ENT_INSTR_CLASS_SET, QSMM_ENT_NODE_CLASS, and QSMM_ENT_NODE.

QSMM_ERR_CALLBACK

The callback function did return an error.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

The type of a pointer to a callback function, which is called for every enumerated entity, isdescribed below.

[Data type]qsmm_enum_ent_callback_func_tThis is a type of callback function pointer, to which the following declaration corresponds:

typedef int (*qsmm_enum_ent_callback_func_t)(

qsmm_t model,

enum qsmm_ent_e ent_type,

const union qsmm_ent_u *ent_p,

void *paramp);

The callback function is called for every enumerated entity of multinode model. The typeof an entity is passed via argument ent type, and an identifier of the entity is passed viaargument ent p. A user parameter is passed via argument paramp.

The callback function may return a positive value if the process of enumeration should becontinued, zero if the process of enumeration should be terminated, or a negative value onerror.

To get an entity type by an entity name, the following function can be used.

Chapter 4: Multinode Model 129

[Function]enum qsmm_ent_e qsmm_get_ent_type_by_name (qsmm t model, constchar *ent_name )

This function returns the type of an entity named ent name stored in multinodemodel. Thereare supported and can be returned entity types QSMM_ENT_INSTR_CLASS_SET and QSMM_ENT_

INSTR_META_CLASS. If the entity does not exist or has another type, then value QSMM_ENT_

INVALID will be returned.

4.18 Tracing Model Execution

The QSMM framework provides facilities for tracing events related to a multinode model. Typesof events, which are dumped to the trace log, can be specified using a bitmask defined as asubset of the following macros merged by bitwise “or.”

[Macro]QSMM_TRACE_APIMultinode model API calls entry and exit. For every call, the name of an API function, namesand values of arguments of the function, and a value returned by the function are dumped.

[Macro]QSMM_TRACE_EVTThe start and the end of processing every model event by event handler functions. Eventparameters are also dumped.

[Macro]QSMM_TRACE_CTRLCalling nodes, returning control from nodes, instruction invocations and outcomes of thoseinvocations.

To get or set a bitmask of types of events, which are dumped to the trace log, the followingfunctions can be used.

[Function]unsigned int qsmm_get_trace_flags (qsmm t model )This function returns a bitmask of types of events related to multinode model, which aredumped to the trace log. It is a bitmask set by the last call to function qsmm_set_trace_

flags or the default bitmask if that function is not called yet.

[Function]void qsmm_set_trace_flags (qsmm t model, unsigned int flags )This function sets to flags the bitmask of types of events related to multinode model, whichare dumped to the trace log. The function does not check the correctness of the bitmask.

Function qsmm_create initializes the bitmask of types of events, which are dumped to thetrace log, to 0.

After setting the bitmask of event types, the events will not be written to the trace log unlessa stream that represents the trace log is specified for the multinode model. To get or set astream for the trace log, the following functions can be used.

[Function]FILE * qsmm_get_trace_stream (qsmm t model )This function returns a stream that represents the trace log of multinode model. If the streamis not set, then the function will return 0.

[Function]void qsmm_set_trace_stream (qsmm t model, FILE *filep )This function sets to filep a stream that represents the trace log of multinode model. If filepis 0, then event tracing will be disabled for the multinode model.

To write a custom formatted message to the trace log, the following functions can be used.

Chapter 4: Multinode Model 130

[Function]void qsmm_trace_f (qsmm t model, const char *fmt, ...)[Function]void qsmm_trace_fv (qsmm t model, const char *fmt, va list ap )

These functions write a formatted message to the trace log of multinode model. Character‘\n’ is appended to the message and the stream buffer is flushed. If the trace log is not set,then the functions will do nothing. The meaning of argument fmt and subsequent argumentsof function qsmm_trace_f is the same as in function printf. The meaning of arguments fmtand ap of function qsmm_trace_fv is the same as in function vprintf.

4.19 Error Handling for a Multinode Model

A multinode model can have an error handler assigned to it. An error handler is a function,which is called in case of error raised by any QSMM API function that takes an argument oftype qsmm_t and can return an error code. The default error handler function of multinodemodel prints information on an error occurred to stderr and calls exit(2). If there is noerror handler function assigned to the model or an error handler function assigned to the modeldoes not terminate program execution and returns, then an API function, where the error hasoccurred, will return corresponding error code.

To get or set an error handler for a multinode model, the following functions can be used.

[Function]void qsmm_get_err_handler (qsmm t model, qsmm err handler func t*func_p, void **param_pp )

This function retrieves information on an error handler assigned to multinode model. Iffunc p is not 0, then *func p will be set to a pointer to an error handler function assignedto the model or to 0 if there is no such function assigned to the model. If param pp is not 0,then *param pp will be set to the user parameter of that error handler function.

[Function]void qsmm_set_err_handler (qsmm t model, qsmm err handler func tfunc, void *paramp )

This function assigns an error handler to multinode model. Argument func specifies an errorhandler function, and argument paramp specifies a user parameter of that function. If funcis 0, then no error handler will be used for the model.

An error handler function may receive extended information for some types of errors occurred.

[Data type]qsmm_err_handler_func_tThis is a type of a pointer to an error handler function. To this type the following declarationcorresponds:

typedef void (*qsmm_err_handler_func_t)(

qsmm_t model,

struct qsmm_except_s *except_p,

void *paramp);

The handle of a multinode model, to which an error pertains to, is passed via argumentmodel.Information on the error is passed via argument except p. A user parameter, specified whensetting the error handler function for the model, is passed via argument paramp.

Below there is a description of a structure that contains information on an error occurred.

[Structure]qsmm_except_sThis structure is used to convey to the error handler function of multinode model informationabout an error occurred. The structure contains the following fields.

[Field]const char * func_nameThe name of a function within the QSMM library that has raised the error.

Chapter 4: Multinode Model 131

[Field]int codeAn error code that will be returned by the QSMM API function after return from the errorhandler function.

[Field]union qsmm_except_u eeExtended information on the error occurred. A list of error codes, for which this fieldalways contains the extended information, is given in the description of union qsmm_

except_u.

A union that contains extended error information, which depends on the error code, is descri-bed below.

[Union]qsmm_except_uThis union contains fields that correspond to error codes for which extended error informationis provided.

[Field]char * noicExtended information for error code QSMM_ERR_NOIC. A description of the error code is“instruction class set does not contain instruction classes.” This field contains the nameof an instruction class set that does not contain instruction classes.

[Field]int callbackExtended information for error code QSMM_ERR_CALLBACK. A description of the error codeis “callback function returned an error.” This field contains an error code returned by thecallback function.

[Field]int noprofExtended information for error code QSMM_ERR_NOPROF. A description of the error codeis “node has no probability profile specified.” This field contains the identifier of a nodethat has no probability profile specified.

[Field]int violnodeExtended information for error code QSMM_ERR_VIOLNODE. A description of the error codeis “the change violates parameters of an already created node.” This field contains theindex of a node, which parameters are violated.

[Field]int mprofExtended information for error code QSMM_ERR_MPROF. A description of the error codeis “no room in the pool of probabilities lists in normal form.” This field contains themaximum possible number of probabilities lists in normal form that can be stored in thepool.

[Field]int mnodeExtended information for error code QSMM_ERR_MNODE. A description of the error codeis “too many nodes.” This field contains the maximum allowed number of nodes in themodel.

[Field]qsmm_msglist_t prgExtended information for error code QSMM_ERR_PRG. A description of the error code is“invalid program.” This field contains a message list that hands over information onerrors in the program.

[Field]qsmm_storage_t storageExtended information for error code QSMM_ERR_STORAGE. A description of the error codeis “storage failure.” This field contains a reference to existing storage the failure pertainsto.

Chapter 4: Multinode Model 132

[Field]struct qsmm_except_notfound_s notfoundExtended information for error code QSMM_ERR_NOTFOUND. A description of the error codeis “entity not found.”

[Field]struct qsmm_except_type_s typeExtended information for error code QSMM_ERR_TYPE. A description of the error code is“invalid entity type.”

[Field]struct qsmm_except_exist_s existExtended information for error code QSMM_ERR_EXIST. A description of the error code is“entity already exists.”

[Field]struct qsmm_except_outcome_s outcomeExtended information for error code QSMM_ERR_OUTCOME. A description of the error codeis “invalid instruction outcome.”

[Field]struct qsmm_except_evthndlr_s evthndlrExtended information for error code QSMM_ERR_EVTHNDLR. A description of the error codeis “event handler function returned an error.”

[Field]struct qsmm_except_nostate_s nostateExtended information for error code QSMM_ERR_NOSTATE. A description of the error codeis “not enough node states to hold the probability profile.”

[Field]struct qsmm_except_nosamenc_s nosamencExtended information for error code QSMM_ERR_NOSAMENC. A description of the error codeis “node classes are not the same.”

[Field]struct qsmm_except_profsrcp_s profsrcpExtended information for error code QSMM_ERR_PROFSRCP. A description of the error codeis “node is the source of probability profile for other nodes.”

[Field]struct qsmm_except_profsrcu_s profsrcuExtended information for error code QSMM_ERR_PROFSRCU. A description of the error codeis “node is a user of a source probability profile provided by another node.”

[Field]struct qsmm_except_psumgt1_s psumgt1Extended information for error code QSMM_ERR_PSUMGT1. A description of the error codeis “the sum of probabilities will exceed 1.”

There exists an API function that dumps the contents of structure qsmm_except_s to astream in a human-readable form. This function is described below.

[Function]void qsmm_except_dump (qsmm t model, int indent, const structqsmm except s *except_p, FILE *filep )

This function dumps error information contained in *except p to stream filep in a human-readable form. To dump parameters of a node associated with the error (if such node exists),the function uses the value of argument model that must be the handle of a multinode modelto which the error pertains to. Argument indent, which must be non-negative, specifies leftindent, i.e. the number of spaces to print at the beginning of each line of output.

In the rest of this section, there are described structures that are the fields of union qsmm_

except_u. In some of those structures, fields of types enum qsmm_ent_e and union qsmm_ent_u

are used. See Section 4.17 [Enumerating Entities], page 127, for a description of these types.

Chapter 4: Multinode Model 133

[Structure]qsmm_except_notfound_sThis structure provides extended information for error code QSMM_ERR_NOTFOUND. A descri-ption of the error code is “entity not found.” The structure contains the following fields.

[Field]enum qsmm_ent_e typeThe type of an entity that was not found.

[Field]union qsmm_ent_u entThe name or the identifier of an entity that was not found.

[Structure]qsmm_except_type_sThis structure provides extended information for error code QSMM_ERR_TYPE. A descriptionof the error code is “invalid entity type.” The structure contains the following fields.

[Field]enum qsmm_ent_e typeAn invalid type of entity.

[Field]enum qsmm_ent_e type_requiredThe required type for the entity.

[Field]union qsmm_ent_u entThe name or the identifier of an entity that has an invalid type.

[Structure]qsmm_except_exist_sThis structure provides extended information for error code QSMM_ERR_EXIST. A descriptionof the error code is “entity already exists.” The structure contains the following fields.

[Field]enum qsmm_ent_e typeThe type of an entity that cannot be created, because an entity with the same name oridentifier already exists.

[Field]union qsmm_ent_u entThe name or the identifier of an entity that cannot be created.

[Structure]qsmm_except_outcome_sThis structure provides extended information for error code QSMM_ERR_OUTCOME. A descri-ption of the error code is “invalid instruction outcome.” The structure contains the followingfields.

[Field]char * instr_meta_class_nameThe name of meta-class of an instruction that has an invalid outcome.

[Field]char * instr_param_str_pThe textual representation of parameters of an instruction that has an invalid outcome or0 if the instruction has no parameters.

[Field]int nodeThe identifier of a node that has invoked the instruction.

[Field]int outcomeAn instruction outcome which is invalid.

[Structure]qsmm_except_evthndlr_sThis structure provides extended information for error code QSMM_ERR_EVTHNDLR. A descri-ption of the error code is “event handler function returned an error.” The structure containsthe following fields.

Chapter 4: Multinode Model 134

[Field]int rcA negative return value of the event handler function.

[Field]int evtThe type of an event for which the event handler function was called (one of constantsdefined by QSMM_EVT_* macros).

[Field]int nodeThe identifier of a node for which the event handler function was called. If there is nonode associated with the event, then the identifier will be equal to −1.

[Field]enum qsmm_ent_e typeThe type of an entity, which events are handled by the event handler function.

[Field]union qsmm_ent_u entThe name of an entity, which events are handled by the event handler function.

[Structure]qsmm_except_nostate_sThis structure provides extended information for error code QSMM_ERR_NOSTATE. A descripti-on of the error code is “not enough node states to hold the probability profile.” The structurecontains the following fields.

[Field]int nodeThe identifier of a node that has or would have the number of states less than it is requiredto hold the probability profile.

[Field]int nstate_requiredThe minimum number of states the node must have to hold the probability profile.

[Structure]qsmm_except_nosamenc_sThis structure provides extended information for error code QSMM_ERR_NOSAMENC. A descri-ption of the error code is “node classes are not the same.” The structure contains the followingfields.

[Field]char * node_class_name_1The name of the first node class (i.e. instruction class set).

[Field]char * node_class_name_2The name of the second node class (i.e. instruction class set).

[Structure]qsmm_except_profsrcp_sThis structure provides extended information for error code QSMM_ERR_PROFSRCP. A descri-ption of the error code is “node is the source of probability profile for other nodes.” Thestructure contains the following fields.

[Field]int node_providerThe identifier of a node that acts as a source of probability profile for other nodes.

[Field]int n_profile_userThe number of nodes, which are users of the probability profile.

[Structure]qsmm_except_profsrcu_sThis structure provides extended information for error code QSMM_ERR_PROFSRCU. A descri-ption of the error code is “node is a user of a source probability profile provided by anothernode.” The structure contains the following fields.

Chapter 4: Multinode Model 135

[Field]int node_providerThe identifier of a node that acts as a source of probability profile.

[Field]int node_userThe identifier of a node, which is a user of the probability profile.

[Structure]qsmm_except_psumgt1_sThis structure provides extended information for error code QSMM_ERR_PSUMGT1. A descri-ption of the error code is “the sum of probabilities will exceed 1.” The structure contains thefollowing fields.

[Field]char * var_nameThe name of a controlled probability variable, after assignment to which the sum ofprobabilities of case instructions in a choice instruction block or the sum of elements ofa probabilities list used by a casels instruction will exceed 1.

[Field]int nodeThe identifier of a node that contains a state to which the choice instruction block or thecasels instruction corresponds.

[Field]int stateThe index of a node state to which the choice instruction block or the casels instructioncorresponds.

4.20 Example of Working in Large-scale Mode

The large-scale mode of working with a multinode model is the one when an environmentstate identification engine and an instruction emitting engine that correspond to the model arerepresented by large actors. The use of large actors is controlled by fields is_large_env andis_large_opt of structure qsmm_desc_s passed to function qsmm_create when creating themultinode model.

The large scalability consists in the possibility to support large numbers of signals and statesby utilizing relatively slow processing units and memory, which in principle could be distributedones. When using a default uniform probability profile, the large-scale mode does not requirepossibly time-consuming initialization of working memory only if a single-node model (specialcase of multinode model) is used. To speed up program operation, if there is a need to workwith many nodes, they can be emulated by creating multiple single-node models.

In the example, an agent has to find the gold in a labyrinth represented in Figure 4.4 andthen exit from the labyrinth. The agent does not know its precise location in the labyrinth.The agent receives only limited amount of information about current location, as when a personwalking in a labyrinth sees only some signs that got into his eyes and has to reconstruct partsof the labyrinth in his memory without assistance.

The labyrinth is represented by a set of sites connected in various ways. The agent can movefrom a site in four possible directions. The moves are performed by instructions ‘move north’,‘move east’, ‘move south’, and ‘move west’. At specific sites only subsets of those moves areallowed, and when the agent tries to perform a disallowed move, that action will be ignored.

After an attempt to perform a move, the agent receives one of the following items of informati-on:

– an indication that a move cannot be performed because of an obstacle;

– a bitmask of four bits, which indicate whether a move in corresponding direction is allowedfrom current site or there is an obstacle in that direction;

– an indication whether current site had contained the gold and the gold was taken; the goldis located at site 31;

Chapter 4: Multinode Model 136

– an indication whether current site is an exit from the labyrinth.

No other information on the configuration of the labyrinth is received by the agent.

To learn the configuration of the labyrinth, the agent visits the labyrinth the number of timesdefined by macro NVISIT. A visit is considered finished when the agent moves to the labyrinthexit site.

Figure 4.4: a test labyrinth

At the end of its run, the sample program prints information on the last path of visiting thelabyrinth. Every element of the path contains either letter ‘x’, which indicates that a move wasnot performed because of an obstacle, or the index of a site (the agent is unaware of that index)and a combination of letters ‘N’, ‘E’, ‘S’, and ‘W’ that specify whether a move in the correspondingdirection is possible from the site. If the site had contained the gold and the gold was taken,then ‘(***)’ is printed after that combination of letters.

After the last visiting path there are printed the total number of visits of the labyrinth forwhich the gold was found, the total length of all traversed visiting paths, and the average amountof gold found per one successful move in the labyrinth. File ‘mat_goto’ with a state transitionmatrix and file ‘mat_action’ with an action emission matrix are created in the current directory.The matrices are dumped rather slowly, and if you do not need them, you can press CTRL-Cto stop that process prematurely.

A random seed can be specified as a program argument. If the random seed is non-negative,then the agent will operate normally. If the random seed is negative, then the agent will move

Chapter 4: Multinode Model 137

in the labyrinth completely randomly. You could compare the program output for these twomodes of program execution.

The source code of the example is provided in file ‘samples/maze.c’ in the package distri-bution and is also given below.

#include <assert.h>

#include <stdlib.h>

#include <string.h>

#include <qsmm/qsmm.h>

#define NVISIT 400

#define NSTATE 148

#define ERREXIT(fmt, ...) \

do { \

fprintf(stderr,(fmt), ## __VA_ARGS__); \

fprintf(stderr,"\n"); \

goto Exit; \

} \

while (0)

enum direct_e {

DIRECT_NORTH=0,

DIRECT_EAST =1,

DIRECT_SOUTH=2,

DIRECT_WEST =3

};

static int visit, n_gold_found=0, path_len=0;

static int opaque_maze(enum direct_e direct,

unsigned char *percept_p) {

static char is_gf=0;

static int node_curr=-1;

static int maze[][4]={

{21, 1, -1, -1}, // 0

{24, 0, -1, 11}, // 1

{-1, 9, -1, -1}, // 2

{ 7, 4, -1, 8}, // 3

{-1, -1, -1, 3}, // 4

{-1, 6, -1, -1}, // 5

{-1, 12, 7, 5}, // 6

{14, -1, 3, 6}, // 7

{10, -1, 3, 20}, // 8

{12, 13, 2, -1}, // 9

{ 8, -1, -1, -1}, // 10

{-1, -1, -1, 1}, // 11

{-1, 15, 9, 6}, // 12

{-1, -1, 9, -1}, // 13

{-1, -1, 7, -1}, // 14

{25, 16, 12, -1}, // 15

{-1, -1, -1, 15}, // 16

{21, -1, -1, -1}, // 17

{23, -1, -1, -1}, // 18

{-1, 20, -1, -1}, // 19

{26, 8, -1, 19}, // 20

{23, 17, 0, -1}, // 21

{-1, 24, -1, -1}, // 22

{28, 18, 21, -1}, // 23

Chapter 4: Multinode Model 138

{-1, 25, 22, 1}, // 24

{35, -1, 15, 24}, // 25

{32, 27, 20, -1}, // 26

{33, 36, -1, 26}, // 27

{30, 29, 23, -1}, // 28

{-1, -1, -1, 28}, // 29

{28, 31, -1, 34}, // 30

{-1, -1, -1, 30}, // 31

{26, -1, -1, -1}, // 32

{-1, -1, 27, -1}, // 33

{-1, -1, 30, -1}, // 34

{-1, -1, 25, -1}, // 35

{-1, -1, -1, 27} // 36

};

unsigned char percept=0;

int ii, result=0, node_new=(node_curr>=0?maze[node_curr][direct]:0);

if (node_new<0) {

percept=16;

result=3;

if (visit==NVISIT-1) printf(" x");

}

else {

node_curr=node_new;

assert(node_curr<sizeof(maze)/sizeof(*maze));

for (ii=0; ii<4; ii++)

if (maze[node_curr][ii]>=0) percept|=1 << ii;

if (node_curr==31) {

if (!is_gf) {

is_gf=1;

result=1;

}

}

else if (node_curr==36) {

is_gf=0;

result=2;

}

if (visit==NVISIT-1)

printf(" %d:%s%s%s%s%s", node_curr,

(percept & (1 << DIRECT_NORTH))?"N":"",

(percept & (1 << DIRECT_EAST ))?"E":"",

(percept & (1 << DIRECT_SOUTH))?"S":"",

(percept & (1 << DIRECT_WEST ))?"W":"",

result==1?"(***)":"");

if (result==2) node_curr=-1;

}

if (percept_p) *percept_p=percept;

return result;

}

static QSMM_INSTR_META_CLASS(move) {

const char *ccp;

int rc;

enum direct_e direct=0;

if (QSMM_HAS_INSTR_CLASS(qsmm_evt))

qsmm_get_eh_instr_param(qsmm,sizeof(direct),&direct);

switch (qsmm_evt) {

case QSMM_EVT_INSTR_CLASS_INIT:

switch (direct) {

case DIRECT_NORTH: ccp="north"; break;

case DIRECT_EAST: ccp="east"; break;

case DIRECT_SOUTH: ccp="south"; break;

case DIRECT_WEST: ccp="west"; break;

default: assert(0);

}

Chapter 4: Multinode Model 139

qsmm_set_eh_instr_param_str_f(qsmm,"%s",ccp);

qsmm_set_eh_noutcome(qsmm,17);

break;

case QSMM_EVT_ACTIVATE: {

unsigned char percept=0;

rc=opaque_maze(direct,&percept);

qsmm_time_delta(qsmm,1);

switch (rc) {

case 0:

case 3:

break;

case 1:

qsmm_set_la_sig(qsmm,0,1);

n_gold_found++;

break;

case 2: {

qsmm_sig_t sig_la=0;

qsmm_get_la_sig(qsmm,0,&sig_la);

if (sig_la) qsmm_spur_delta(qsmm,1,1);

qsmm_return_to_caller_node(qsmm);

break;

}

default:

assert(0);

}

if (rc!=2) {

if (rc!=3) path_len++;

qsmm_set_instr_outcome(qsmm,percept);

}

break;

}

}

return 0;

}

static QSMM_INSTR_CLASS_SET(walker) {

switch (qsmm_evt) {

case QSMM_EVT_ENT_INIT: {

enum direct_e direct;

direct=DIRECT_NORTH, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_EAST, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_SOUTH, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_WEST, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

qsmm_set_nstate_max(qsmm,__FUNCTION__,NSTATE);

QSMM_NODE_CREATE(0);

break;

}

case QSMM_EVT_NODE_ENTER: {

unsigned char percept=0;

qsmm_set_la_sig(qsmm,0,0);

opaque_maze(DIRECT_NORTH,&percept);

break;

}

}

return 0;

}

int main(int argc, char **argv) {

const char *ccp;

int rc, seed=0, exit_code=1;

qsmm_t qsmm=0;

FILE *file_mat_goto_p=0, *file_mat_action_p=0;

struct qsmm_desc_s desc;

Chapter 4: Multinode Model 140

struct qsmm_dump_mat_goto_desc_s dump_mat_goto_desc;

memset(&desc,0,sizeof(desc));

desc.dont_use_instr_class_weights=1;

desc.is_large_env=1;

desc.is_large_opt=1;

desc.nspur=2;

desc.stack_sz_max=1;

desc.ngram_env_la_sz=1;

desc.nsig_ngram_env_la=2;

desc.sparse_fill_max=0.2;

desc.compat=1;

if ((rc=qsmm_create(&desc,&qsmm))<0)

ERREXIT("qsmm_create: %s",qsmm_err_str(rc));

QSMM_REG_INSTR_META_CLASS(qsmm,move,0);

QSMM_REG_INSTR_CLASS_SET(qsmm,walker,0);

qsmm_engine_create(qsmm);

if (argc>1 && (seed=atoi(argv[1]))<0) {

qsmm_set_random(qsmm,1);

seed=-seed;

}

qsmm_rng_seed(qsmm_get_rng(qsmm),seed);

for (visit=0; visit<NVISIT; visit++) qsmm_node_call_default(qsmm,0,0);

printf("\nn_gold_found=%d\npath_len=%d\nn_gold_found/path_len=%.8f\n",

n_gold_found, path_len, (double) n_gold_found/path_len);

if (!(file_mat_goto_p=fopen(ccp="mat_goto","w")) ||

!(file_mat_action_p=fopen(ccp="mat_action","w")))

ERREXIT("%s: failed to open the file for writing",ccp);

memset(&dump_mat_goto_desc,0,sizeof(dump_mat_goto_desc));

dump_mat_goto_desc.do_print_prob[QSMM_PROB_LEARNT]=1;

qsmm_mat_goto_dump(qsmm,0,&dump_mat_goto_desc,file_mat_goto_p);

qsmm_mat_action_dump(qsmm,0,0,file_mat_action_p);

exit_code=0;

Exit:

qsmm_destroy(qsmm);

if (file_mat_action_p) fclose(file_mat_action_p);

if (file_mat_goto_p) fclose(file_mat_goto_p);

return exit_code;

}

Below there is given sample program output for the completely random mode of operationof the program.

$ ./maze -1

0:NE 21:NES 23:NES 21:NES x 17:N 21:NES x 23:NES 28:NES 30:NEW x x 34

:S x x x x x x x x x x 30:NEW 34:S x x x 30:NEW 34:S x 30:NEW 28:NES 3

0:NEW x x 31:W(***) x 30:NEW 31:W 30:NEW 34:S x 30:NEW 34:S x x x x x

x x x x x x x x x x x x 30:NEW x x x 31:W x x x x 30:NEW x 31:W 30:NEW

x 34:S x x x x x x x x x x x x x 30:NEW x x 28:NES 29:W 28:NES x 30:N

EW 31:W x x x x x x x x x x 30:NEW 31:W x x 30:NEW 31:W x x x x 30:NEW

x 28:NES 29:W x 28:NES 30:NEW x 34:S x x 30:NEW 31:W x 30:NEW 28:NES

23:NES x 18:N 23:NES 18:N x x 23:NES 28:NES x 29:W x x 28:NES 23:NES 1

8:N x x x x x x x x x x x x 23:NES 18:N x x x x x x 23:NES 28:NES 29:W

28:NES 29:W 28:NES 30:NEW 31:W x x 30:NEW 28:NES x 30:NEW x 28:NES 29

:W 28:NES x 23:NES x 18:N x 23:NES 21:NES x 17:N x x x x x 21:NES 0:NE

1:NEW 11:W x x x x x x x 1:NEW x x 0:NE x 1:NEW x 11:W x x x 1:NEW 11

:W 1:NEW 24:ESW 25:NSW x 15:NES 25:NSW 15:NES 16:W x 15:NES 12:ESW 15:

NES 12:ESW 15:NES 16:W x x x x x x x 15:NES x 16:W x x 15:NES x x 16:W

15:NES 16:W 15:NES x x 16:W x x x x x 15:NES x 16:W x x 15:NES 16:W x

x x x x x 15:NES x 12:ESW 15:NES 16:W x x x x x x x 15:NES 12:ESW 15:

NES 16:W x 15:NES 16:W x x x 15:NES 25:NSW 35:S x x x x 25:NSW 24:ESW

22:E x x x 24:ESW 25:NSW 35:S x x 25:NSW 24:ESW 22:E x x x 24:ESW 22:E

x 24:ESW 1:NEW 24:ESW 1:NEW 0:NE x 21:NES 23:NES 18:N x x x 23:NES x

28:NES 23:NES 21:NES 23:NES 28:NES 30:NEW 34:S x x x x x 30:NEW 31:W x

x 30:NEW x 28:NES 23:NES 21:NES 23:NES 18:N x x x x x x x x x x 23:NE

S 21:NES 0:NE x 1:NEW 0:NE x 1:NEW 0:NE x 1:NEW 24:ESW 25:NSW 24:ESW 2

Chapter 4: Multinode Model 141

5:NSW 35:S x x 25:NSW x x x 35:S x x x x x x x x x x 25:NSW 35:S 25:NS

W x 15:NES 12:ESW x 9:NES x x 12:ESW 9:NES 13:S 9:NES 12:ESW 15:NES 12

:ESW 15:NES 12:ESW x 15:NES 12:ESW 15:NES 25:NSW 35:S 25:NSW x 15:NES

16:W x x x x 15:NES 25:NSW 35:S x 25:NSW 15:NES x 25:NSW 15:NES 25:NSW

24:ESW 25:NSW 35:S x 25:NSW 35:S 25:NSW 35:S x x x x x 25:NSW 15:NES

x 25:NSW 24:ESW 1:NEW 24:ESW 22:E x x x x x x x 24:ESW 25:NSW 15:NES x

x 25:NSW x 35:S x x x x x x x x x x x x 25:NSW x 24:ESW 1:NEW 11:W 1:

NEW 11:W x x x x x 1:NEW 11:W 1:NEW 24:ESW x 1:NEW 11:W x x x x x x x

1:NEW x 11:W x x 1:NEW x 24:ESW 25:NSW 24:ESW x x 1:NEW x 11:W 1:NEW x

24:ESW 22:E x x x x 24:ESW 22:E x x x x x x x 24:ESW 1:NEW x 11:W x 1

:NEW 0:NE 21:NES 17:N 21:NES 17:N x x x x x x 21:NES x 23:NES 21:NES 2

3:NES 21:NES x 0:NE x x x 1:NEW 24:ESW 1:NEW 11:W x x 1:NEW 24:ESW 25:

NSW 24:ESW x 1:NEW 11:W 1:NEW x 0:NE x 21:NES 17:N x 21:NES x 17:N 21:

NES x x x 17:N x x 21:NES 23:NES 18:N x x x x x x x 23:NES 21:NES 0:NE

x x 1:NEW 0:NE x 1:NEW 11:W x x x x 1:NEW 24:ESW 25:NSW 24:ESW x 1:NE

W 11:W 1:NEW 11:W x x x x x x x 1:NEW 11:W 1:NEW 11:W 1:NEW 24:ESW 22:

E x x x x x x x x x x x x x x 24:ESW x 22:E x x x x 24:ESW 25:NSW 24:E

SW 25:NSW 24:ESW x x 22:E 24:ESW 22:E x x x x x x x x x 24:ESW 1:NEW 2

4:ESW x 25:NSW x 24:ESW 22:E 24:ESW 1:NEW 11:W x x 1:NEW 11:W x x x 1:

NEW 24:ESW x x x 1:NEW x 0:NE 21:NES 17:N x x x x x x x x x x x 21:NES

x 23:NES x 18:N 23:NES 18:N 23:NES 28:NES 30:NEW x 31:W x 30:NEW 28:N

ES 23:NES 28:NES x 30:NEW 28:NES 29:W 28:NES x x 23:NES 21:NES 0:NE x

x x 1:NEW 24:ESW 25:NSW 35:S x x x 25:NSW 35:S x x x x x x x x 25:NSW

15:NES 25:NSW 35:S x 25:NSW 35:S 25:NSW 15:NES 16:W x x 15:NES 16:W x

x x x 15:NES 12:ESW 9:NES 13:S x x x x x 9:NES 13:S x 9:NES 13:S 9:NES

13:S x x x x x x x x x x x 9:NES 13:S x 9:NES 2:E x x x x x x x x x x

x x x 9:NES x 12:ESW 6:ESW x 7:NSW 6:ESW 5:E x x x x 6:ESW x 5:E 6:ES

W 12:ESW 15:NES 12:ESW 15:NES 12:ESW 15:NES 16:W x x x x x x x x x x x

15:NES 16:W x 15:NES x x 25:NSW 15:NES 12:ESW x 6:ESW 5:E x x x 6:ESW

5:E x x x 6:ESW 5:E x x x x 6:ESW 12:ESW 9:NES x 2:E x x 9:NES 2:E x

x x 9:NES 12:ESW x 6:ESW x 12:ESW x 15:NES x 12:ESW 6:ESW x 12:ESW 15:

NES 12:ESW x 15:NES x 12:ESW x 9:NES 2:E x x x x x x x 9:NES 2:E 9:NES

12:ESW 15:NES 12:ESW 9:NES 12:ESW 6:ESW x 12:ESW 6:ESW x 5:E x x 6:ES

W 12:ESW 6:ESW 12:ESW 9:NES 12:ESW 9:NES 2:E x 9:NES 12:ESW 9:NES 12:E

SW x 6:ESW 12:ESW 15:NES 25:NSW x 15:NES 25:NSW 35:S 25:NSW 24:ESW 1:N

EW x 24:ESW x x 22:E x x x 24:ESW 1:NEW 11:W x x 1:NEW 24:ESW 1:NEW 24

:ESW 25:NSW 35:S x x x x 25:NSW 35:S 25:NSW 24:ESW 22:E 24:ESW 1:NEW x

0:NE x x x x 1:NEW 0:NE 1:NEW x 11:W 1:NEW x x 24:ESW 25:NSW 35:S x 2

5:NSW 24:ESW 25:NSW x x 15:NES 16:W x x x 15:NES 16:W x x x x x x x x

15:NES 16:W x x x x x x x x x 15:NES 25:NSW x x 15:NES 12:ESW 9:NES 2:

E 9:NES 2:E x x x x x 9:NES 13:S x x x 9:NES x 2:E 9:NES x 12:ESW 9:NE

S x x 2:E x x x 9:NES 2:E x x 9:NES 2:E x x 9:NES 13:S x x 9:NES 12:ES

W x 6:ESW 12:ESW 15:NES x 25:NSW 15:NES x 25:NSW 15:NES x x x 16:W 15:

NES 16:W x x x x 15:NES 12:ESW 9:NES 12:ESW 9:NES 2:E x x x 9:NES 12:E

SW 9:NES x x 2:E x 9:NES x 12:ESW 15:NES 12:ESW 9:NES 13:S x 9:NES 12:

ESW 9:NES x 12:ESW x 9:NES 2:E x 9:NES x 2:E x x 9:NES 2:E 9:NES x 13:

S x x x x 9:NES 13:S x x x x 9:NES 13:S x x x x 9:NES 13:S x 9:NES 12:

ESW 9:NES 12:ESW 9:NES 13:S x x x x x x x x x 9:NES 12:ESW x x 6:ESW 7

:NSW 6:ESW 5:E x 6:ESW 7:NSW x 6:ESW 12:ESW 15:NES 25:NSW x 15:NES 12:

ESW 15:NES 12:ESW 9:NES 2:E 9:NES 12:ESW 9:NES 13:S x 9:NES 13:S x 9:N

ES 13:S x x 9:NES 12:ESW x x 9:NES 13:S 9:NES 13:S x 9:NES 13:S 9:NES

12:ESW 15:NES 16:W 15:NES 25:NSW x x 35:S 25:NSW 35:S x x 25:NSW x x 2

4:ESW 22:E x x 24:ESW 22:E x 24:ESW 22:E x x 24:ESW 25:NSW 15:NES 16:W

x 15:NES 25:NSW x 35:S x 25:NSW 35:S 25:NSW 35:S x 25:NSW x 15:NES 16

:W 15:NES 16:W x x x 15:NES 16:W x x x 15:NES 12:ESW 9:NES 2:E 9:NES x

2:E x 9:NES 13:S x x x x x x x x x 9:NES 12:ESW 6:ESW 7:NSW 14:S x x

x 7:NSW x 3:NEW 7:NSW 6:ESW 7:NSW 14:S x x x x x x x x x x x 7:NSW 6:E

SW 5:E x x x 6:ESW 12:ESW x x 9:NES x 12:ESW x 9:NES 12:ESW 9:NES x 13

:S x 9:NES x 13:S x x x 9:NES 12:ESW 9:NES 13:S 9:NES 2:E x x x 9:NES

2:E 9:NES 13:S x x x 9:NES 13:S x 9:NES 2:E x 9:NES 13:S x x x 9:NES x

13:S 9:NES 12:ESW 15:NES x 12:ESW 9:NES x 12:ESW x 9:NES 13:S x 9:NES

x 13:S x x 9:NES x 13:S x x x x x x 9:NES x 12:ESW 6:ESW 7:NSW x 3:NE

W 8:NSW x 3:NEW 4:W x x x x 3:NEW x 7:NSW 3:NEW 8:NSW 3:NEW 4:W x x x

x x x x 3:NEW 4:W x x x x x x x x x x x x x x x x x x x x x x x 3:NEW

4:W x x x x x x 3:NEW 4:W x 3:NEW 4:W x x x x x 3:NEW x x 8:NSW x 3:NE

Chapter 4: Multinode Model 142

W 8:NSW 10:N x x x 8:NSW 10:N x x x x x x x 8:NSW 3:NEW 8:NSW 3:NEW 8:

NSW 20:NEW 19:E x x x 20:NEW x x 8:NSW 10:N x 8:NSW 10:N x 8:NSW 3:NEW

4:W 3:NEW 7:NSW x 14:S x x x x 7:NSW 6:ESW 5:E 6:ESW 12:ESW x 9:NES x

13:S x x x x 9:NES 13:S x x x x x x 9:NES 13:S x 9:NES 12:ESW 9:NES 2

:E x x 9:NES 12:ESW x 6:ESW 7:NSW 6:ESW 12:ESW x x x 9:NES x 12:ESW 6:

ESW 7:NSW 6:ESW 12:ESW 15:NES 16:W 15:NES 12:ESW 15:NES 12:ESW 9:NES 1

2:ESW 9:NES 13:S 9:NES 2:E 9:NES 2:E x 9:NES x x 2:E x x x x x x x x 9

:NES x 2:E x x x x x x 9:NES 13:S 9:NES x 12:ESW 9:NES 2:E x x 9:NES 1

3:S x x x 9:NES 12:ESW 9:NES 13:S x x 9:NES x 12:ESW 15:NES 12:ESW x 6

:ESW 7:NSW 14:S x x x x x x x x x x x x x 7:NSW 3:NEW x 7:NSW 6:ESW 7:

NSW 14:S x x 7:NSW 6:ESW x 7:NSW 3:NEW 8:NSW x 20:NEW x 8:NSW x 10:N x

x x x x 8:NSW 10:N x x x x x x 8:NSW 20:NEW 26:NES 32:N 26:NES x x 32

:N x 26:NES 27:NEW 33:S 27:NEW 33:S x x x x x 27:NEW 36:W

n_gold_found=297

path_len=257582

n_gold_found/path_len=0.00115303

Below there is given sample program output for the normal mode of operation of the program.$ ./maze 1

0:NE x 21:NES x 23:NES x x 21:NES 23:NES 28:NES 29:W x x 28:NES x 23:

NES 28:NES 30:NEW 34:S x x x 30:NEW 28:NES x x 30:NEW 31:W(***) 30:NEW

31:W 30:NEW 34:S x x x x x x 30:NEW 31:W 30:NEW 28:NES 23:NES x 21:NE

S x 17:N x x x x x 21:NES 0:NE x 1:NEW x x 24:ESW x 25:NSW 35:S x x x

x x 25:NSW 15:NES 16:W x x x x x 15:NES 16:W 15:NES x 12:ESW 6:ESW x x

5:E 6:ESW x 7:NSW 14:S x x x 7:NSW 3:NEW 8:NSW 20:NEW 26:NES 27:NEW x

x 26:NES 27:NEW 36:W

n_gold_found=398

path_len=37254

n_gold_found/path_len=0.01068342

Results of invocation of the sample program using random seeds in the range 1 to 20 (normalmode of operation) and in the range −20 to −1 (completely random mode of operation) arerepresented in the table below.

SEED NGF PATH_LEN NGF/PATH_LEN SEED NGF PATH_LEN NGF/PATH_LEN

------ --- -------- ------------ ------ --- -------- ------------

1 398 37254 0.01068342 -1 297 257582 0.00115303

2 400 55424 0.00721709 -2 310 254296 0.00121905

3 399 49060 0.00813290 -3 282 238204 0.00118386

4 389 35382 0.01099429 -4 285 245584 0.00116050

5 400 34992 0.01143118 -5 284 238040 0.00119308

6 398 117074 0.00339956 -6 290 227870 0.00127266

7 395 41422 0.00953600 -7 288 229944 0.00125248

8 399 46858 0.00851509 -8 287 243174 0.00118022

9 399 41146 0.00969718 -9 280 238668 0.00117318

10 396 53364 0.00742073 -10 299 230718 0.00129595

11 394 37840 0.01041226 -11 297 228010 0.00130257

12 399 34672 0.01150784 -12 284 237060 0.00119801

13 399 58556 0.00681399 -13 286 233272 0.00122604

14 397 47514 0.00835543 -14 274 239664 0.00114327

15 400 37706 0.01060839 -15 272 235452 0.00115522

16 398 42292 0.00941076 -16 296 234588 0.00126179

17 393 52206 0.00752787 -17 284 219864 0.00129171

18 398 30352 0.01311281 -18 297 230014 0.00129123

19 395 50552 0.00781374 -19 285 245476 0.00116101

20 399 75942 0.00525401 -20 288 243924 0.00118070

------ --- -------- ------------ ------ --- -------- ------------

AVG 397 48980 [0.00811039] AVG 288 237570 [0.00121333]

STDDEV 2.8 19221 0.00231747 STDDEV 9.0 9114 0.00005491

As it can be seen from the table, the average amount of gold found per one move in thelabyrinth for 20 invocations of the sample program in the normal mode of operation is about 7times greater than in the completely random mode of operation.

Chapter 5: Assembler Programs 143

5 Assembler Programs

In QSMM, assembler programs are in the first place the means of specifying probability profilesof nodes of multinode model in the algorithmic form. In the second place, they are the meansof printing and analyzing learned state models of the nodes. In the third place, they are themeans of fetching learned probabilities from the state models.

The use of assembler programs relies heavily on instruction meta-classes, instruction classsets, and instruction classes registered for a multinode model. An instruction meta-class nameand a textual representation of instruction class parameters are used to code an assemblerinstruction in an assembler program.

5.1 Basic Datatypes

A memory representation of an assembler program is referred to by a program handle.

[Data type]qsmm_prg_tThis is a type for a program handle. It is a pointer, so variables of this type can have zerovalue. Functions qsmm_node_disasm and qsmm_parse_asm_source_* allocate a new programhandle. Function qsmm_prg_destroy frees an existing program handle. After allocating aprogram handle, it can be passed to API functions that take argument qsmm_prg_t until thehandle is freed.

To destroy a memory representation of an assembler program, the following function can beused.

[Function]void qsmm_prg_destroy (qsmm prg t prg )This function destroys a memory representation of an assembler program specified by programhandle prg. After the destruction, the program handle must not be used. If prg is 0, thenthe function will do nothing.

The QSMM framework provides limited capabilities to work with instructions that are contai-ned in a memory representation of an assembler program. An assembler instruction is referredto by an instruction handle.

[Data type]qsmm_instr_tThis is a type for an instruction handle. It is a pointer, so variables of this type can have zerovalue. The handle of an existing instruction can be obtained by functions qsmm_get_prg_

instr and qsmm_get_instr_nested (see Section 5.5 [Inspecting an Assembler Program],page 158).

5.2 Assembler Program Syntax

An assembler program consists of lines. Empty lines can be used to decorate the program.Characters on a line, which start with the first character ‘;’ not within a string literal (that literalcan be a part of instruction parameters), are considered a comment. For proper identificationof continuation of multiline comments, align characters ‘;’, which start every line of a multilinecomment, one under another.

If the first character on a line is not a whitespace character, then it must be the start of alabel definition. There are two types of labels supported: location labels, which definitions endwith character ‘:’, and data labels, which definitions do not end with that character. The firstcharacter of a label must be a letter or ‘_’. Every subsequent character of the label (exceptfor the last character ‘:’ in the definition of location label) must be a letter, a digit, or ‘_’. Adefinition of a location label can be on a separate line or can be followed by an instruction after

Chapter 5: Assembler Programs 144

one or more whitespace characters. A definition of a data label must be followed by a ‘prob’,‘probeq’, or ‘probls’ keyword after one or more whitespace characters.

If the line starts with one or more whitespace characters, then they can be followed byan instruction. An instruction consists of an instruction name followed by optional instructi-on parameters after one or more whitespace characters. Whitespace characters in instructionparameters not within string literals are ignored.

Below there is given a sample assembler program.

L1: stt

jprob 0.5, L2 ; jump with probability 0.5

user 0 ; a user instruction

jmp L1

L2: user 1 ; a user instruction

jmp L1

There are two types of sections that can be used in an assembler program: ‘.data’ section and‘.code’ section. In a ‘.data’ section probability variables and probabilities lists can be defined(see Section 5.9 [Using Probability Variables], page 171 and Section 5.10 [Using ProbabilitiesLists], page 183). To every probability variable or a probabilities list a data label corresponds.In a ‘.code’ section there can be program instructions. Sections are marked by ‘.data’ and‘.code’ keywords that must be on lines of their own (after one or more whitespace charactersat the beginning of lines). There can be several ‘.data’ and ‘.code’ sections defined in anassembler program. They are merged into a single ‘.data’ section and a single ‘.code’ section.By default, it is assumed that an assembler program starts with a ‘.code’ section.

The assembler supports the ‘line’ directive, which can be programmed explicitly or generatedby the assembler preprocessor (see Section 5.14 [Using the Assembler Preprocessor], page 195).That directive can change current line number in the source file, the name of the source file, thestack of include locations, and the stack of macro expansion locations tracked by the assembler.However, changing the stack of include locations and the stack of macro expansion locations isnot documented in this manual, because the corresponding syntax of the ‘line’ directive willlikely be changed in future versions of the QSMM package. Information changed by the ‘line’directive is used when printing error, warning, and note messages.

The directive must be placed on a separate line (after one or more whitespace characters atthe beginning of the line) and should be in one of the following formats:

line line_number

line line_number, file_name

In the first case, the directive changes the number of the next line in the current sourcefile to line number. In the second case, the directive changes the number of the next line toline number and the name of current source file to file name. The value of file name must be a(quoted) string literal.

5.3 Assembler Instructions

In QSMM, assembler instructions are divided into three categories: built-in instructions, userinstructions, and mixed type instructions. The assembler understands the built-in instructionswithout prior definition of corresponding instruction classes and meta-classes. The built-ininstructions are case, casels, choice, end, jmp, joe, jprob, and stt. The built-in instructionsdo not necessarily induce code that is to be executed by some kind of a machine: they can beinterpreted as control words that affect the structure of the machine.

User instructions must be declared in an application program using corresponding instructi-on classes and meta-classes. Execution of actions associated with user instructions has to beimplemented in event handler functions of corresponding instruction meta-classes.

Chapter 5: Assembler Programs 145

Instructions abort, lookup, nop, and nop1 are ones of mixed type. Instructions abort,lookup, and nop1 can be generated by the disassembler, but assembling them requires definingcorresponding instruction classes and meta-classes, which implementation can be specific toyour application program. In certain cases nop instructions can be implicitly generated by theassembler, but the assembling will fail if there is no corresponding instruction class or meta-classdefined.

5.3.1 jmp Instruction

The instruction has syntax

jmp loc_label

and specifies that control has to be transferred to location label loc label. The location labelhas to be defined elsewhere as follows:

loc_label:

5.3.2 jprob Instruction

The instruction must be written in one of the following forms:

jprob number, loc_label

jprob var_name, loc_label

The instruction specifies that the control has to be transferred to location label loc label withprobability number, which must be in the range 0 to 1 (inclusive), or with probability storedin variable var name. Probability number must be specified either in fixed-point or exponentialnotation.

The instruction effectively sets a profile probability in an action emission matrix or one ormore profile probabilities in a state transition matrix. If a contiguous block of jprob instructionsis prepended with an stt instruction, then those jprob instructions will set profile probabilitiesin the action emission matrix. If a contiguous block of jprob instructions is not prependedwith an stt instruction, then those jprob instructions will set profile probabilities in the statetransition matrix. See Section 5.3.6 [stt Instruction], page 147, for more information.

If the assembler considers that a user instruction should be assembled at a particular place,but it encounters a contiguous block of jprob instructions there, then the assembler will assemblea nop instruction and treat that contiguous block as possible transitions to states made afterinvocation of that nop instruction.

Let us consider a block of jprob instructions like this:

jprob prob1, L1

jprob prob2, L2

jprob prob3, L3

Jump to location label L1 will be made with probability prob1. Jump to the second jprob

instruction will be made with probability 1–prob1. Jump to location label L2 will be made withprobability (1–prob1)*prob2. Jump to the third jprob instruction will be made with probability(1–prob1)*(1–prob2). Jump to location label L3 will be made with probability (1–prob1)*(1–prob2)*prob3. Jump to an instruction that follows the third jprob instruction will be madewith probability (1–prob1)*(1–prob2)*(1–prob3).

5.3.3 choice Instruction Block

The instruction block has format

choice

case ...

case ...

...

end choice

Chapter 5: Assembler Programs 146

It consists of a choice instruction, one or more case instructions, and an end choice instruction.Instructions case and end choice must not be prepended with location labels.

Each case instruction must be written in one of the following forms:

case number, loc_label

case var_name, loc_label

The instruction specifies that the control has to be transferred to location label loc label withprobability number, which must be in the range 0 to 1 (inclusive), or with probability storedin variable var name. Probability number must be specified either in fixed-point or exponentialnotation. If there is a location label defined at the beginning of a choice instruction block, thenyou must not use that label in case instructions within the block.

The instruction block effectively sets profile probabilities in an action emission matrix ora state transition matrix. If a choice instruction block is prepended with an stt instruction,then the instruction block will set profile probabilities in the action emission matrix. If a choiceinstruction block is not prepended with an stt instruction, then the instruction block will setprofile probabilities in the state transition matrix. See Section 5.3.6 [stt Instruction], page 147,for more information.

If the assembler considers that a user instruction should be assembled at a particular place,but it encounters a choice instruction block there, then the assembler will assemble a nop

instruction and treat the choice instruction block as possible transitions to states made afterinvocation of that nop instruction.

As opposed to a contiguous block of jprob instructions, a choice instruction block allows tospecify jump probabilities in a direct way. Let us consider a choice instruction block like this:

choice

case prob1, L1

case prob2, L2

case prob3, L3

end choice

Jump to location label L1 will be made with probability prob1. Jump to location label L2 willbe made with probability prob2. Jump to location label L3 will be made with probability prob3.Jump to an instruction that follows the choice instruction block will be made with probability1–prob1–prob2–prob3. Compare this example to the corresponding example with a block ofjprob instructions in the previous subsection.

5.3.4 casels Instruction

The instruction has syntax

casels list_name, loc_label_1, ..., loc_label_N

and specifies that control has to be transferred to one of location labels loc label 1, ...,loc label N with probabilities, which are elements of probabilities list list name. The numberof location labels must be equal to the length of the probabilities list. See Section 5.10 [UsingProbabilities Lists], page 183, for more information. If there is a location label assigned to acasels instruction, then you must not use that label in arguments of the casels instructions.

The list of parameters of a casels instruction can be splitted into multiple lines. To indicatethat a line of parameters list is continued on the next line, terminate a line, which is continued,with a comma after the name of probabilities list or a location label. This is shown in thefollowing example:

casels ls,

L1, L2, L3, L4, L5,

L6, L7, L8, L9, L10

Chapter 5: Assembler Programs 147

A casels instruction effectively sets profile probabilities in an action emission matrix or astate transition matrix. If a casels instruction is prepended with an stt instruction, thenthe casels instruction will set profile probabilities in the action emission matrix. If a casels

instruction is not prepended with an stt instruction, then the casels instruction will set profileprobabilities in the state transition matrix. See Section 5.3.6 [stt Instruction], page 147, for moreinformation.

If the assembler considers that a user instruction should be assembled at a particular place,but it encounters a casels instruction there, then the assembler will assemble a nop instructi-on and treat the casels instruction as a specification of possible transitions to states afterinvocation of that nop instruction.

5.3.5 joe Instruction

The instruction has syntax

joe outcome, loc_label

and specifies that control has to be transferred to location label loc label if an outcome of the lastinstruction invoked is equal to outcome. The total number of instruction outcomes is specifiedby the event handler function of instruction meta-class during initialization of the instructionclass.

If the assembler considers that a user instruction should be assembled at a particular place,but it encounters a contiguous block of joe instructions there, then the assembler will assemblea nop instruction, which normally does not change the outcome of the last instruction invoked,and treat the contiguous block as a place where analysis of that outcome is performed.

5.3.6 stt Instruction

The instruction must be written in one of the following forms:

stt

stt state_name

The instruction marks the beginning of a state of an assembler program. The statecorresponds to a state of a node, into which that assembler program can be loaded. Thestate might have a name specified by (quoted) string literal state name. An assembler programmust not contain states with duplicate names. See Section 5.8 [Loading a Parsed Program intoa Node], page 166, for a description of functions that retrieve the name of a node state by itsindex and retrieve the index of a node state by its name.

An stt instruction indicates in which matrix of a node probabilities specified by otherinstructions of the assembler program should be stored: in the action emission matrix or thestate transition matrix. If a node is assembled with a restriction that the action emission matrixmust define deterministic choice of instruction for every state of the node, and there is no needto assign a name to a state of an assembler program, then an stt instruction, which marks thestart of the state, can be safely omitted in the assembler program. Probabilities specified byjprob, case, and casels instructions that follow a place where the stt instruction was omittedwill be stored in the state transition matrix of the node.

If a node is assembled without a restriction that its action emission matrix must definedeterministic choice of instruction for every node state, then omitting stt instructions in theassembler program will cause the first unassembled instruction encountered while assemblingto become the start of the next state. However, assembling a node is not always performedby consecutive processing the instructions of an assembler program from its beginning to theend, and the best practice is to specify stt instructions for all states, so the programmer willknow exactly where each state begins. To support this approach, the assembler may generatea warning where it has to begin assembling a state, but it encounters no stt instruction there.

Chapter 5: Assembler Programs 148

Note that inserting stt instructions into an assembler program may require rearranging theprogram.

There are four possible places where an stt instruction can be inserted.

1. Before a user instruction or a mixed type instruction:

stt [state_name]

user or mixed type instruction

This means that in a state marked by the stt instruction a specified user or mixed typeinstruction will be invoked. Effectively, the action emission matrix will define deterministicchoice of the instruction in the state: it will contain profile probability 1 for that state andthat instruction and profile probability 0 for that state and all other instructions. If youneed to mark the start of a state, but there is no user or a mixed type instruction to insertafter the stt instruction, then you may insert two instructions at the start of the state:stt and nop, or stt and nop1. A user or mixed type instruction after the stt instructionmust not have a location label defined, to which a jump from elsewhere is made.

2. Before a block of jprob instructions:

stt [state_name]

jprob prob1, L1

jprob prob2, L2

...

jprob probN, LN

user or mixed type instruction

...

L1: user or mixed type instruction

...

L2: user or mixed type instruction

...

LN: user or mixed type instruction

...

This means that in a state marked by the stt instruction one of specified user or mixedtype instructions will be invoked. All those instructions must have different combinationsof instruction name and instruction parameters. Effectively, the action emission matrixwill contain profile probabilities of invocation of the instructions in that state. However, inthe general case, the profile probabilities will not be equal to those specified in the jprob

instructions (see Section 5.3.2 [jprob Instruction], page 145, for more information). Noneof the jprob instructions just after the stt instruction must have location labels defined,to which jumps from elsewhere are made.

3. Before a choice instruction block:

stt [state_name]

choice

case prob1, L1

case prob2, L2

...

case probN, LN

end choice

user or mixed type instruction

...

L1: user or mixed type instruction

...

Chapter 5: Assembler Programs 149

L2: user or mixed type instruction

...

LN: user or mixed type instruction

...

This means that in a state marked by the stt instruction one of specified user or mixedtype instructions will be invoked. All those instructions must have different combinationsof instruction name and instruction parameters. Effectively, the action emission matrixwill contain profile probabilities of invocation of the instructions in that state. The profi-le probabilities, except for the profile probability of an instruction just after the choice

instruction block, will be equal to those specified in case instructions. A choice instructi-on after the stt instruction must not have a location label defined, to which a jump fromelsewhere is made.

4. Before a casels instruction:

stt [state_name]

casels list_name, L1, L2, ..., LN

user or mixed type instruction

...

L1: user or mixed type instruction

...

L2: user or mixed type instruction

...

LN: user or mixed type instruction

...

This means that in a state marked by the stt instruction one of specified user or mixedtype instructions will be invoked. All those instructions must have different combinationsof instruction name and instruction parameters. Effectively, the action emission matrixwill contain profile probabilities of invocation of the instructions in that state. The profi-le probabilities, except for the profile probability of an instruction just after the casels

instruction, will be equal to those contained in probabilities list list name. A casels

instruction after the stt instruction must not have a location label defined, to which ajump from elsewhere is made.

When inserting stt instructions into a program, adhere to the following program structure.A user or mixed type instruction can be followed by a contiguous block of joe instructions whichanalyze an outcome of that instruction. Every joe instruction should specify a conditional jumpto a contiguous block of jprob instructions or to a choice instruction block or to a casels

instruction or to another state directly. The contiguous block of joe instructions should befollowed by a contiguous block of jprob instructions or a choice instruction block or a casels

instruction or by a jmp instruction that transfers control to another state. The contiguous blocksof jprob instructions or contiguous blocks of case instructions within the choice instructionblocks or the casels instructions should specify probabilities of transitions to other states(stored in the state transition matrix). Every contiguous block of jprob instructions or achoice instruction block or a casels instruction should be followed by a jmp instruction thattransfers control to another state or should be followed by another state directly. Such programstructure is represented by the following example.

user or mixed type instruction

; A contiguous block of ‘joe’ instructions.

; Each of labels L1, L2, ..., LN may be defined at the start of a

; contiguous block of ‘jprob’ instructions or at the start of a

; ‘choice’ instruction block or at a ‘casels’ instruction or at

Chapter 5: Assembler Programs 150

; the start of a state.

joe outcome1, L1

joe outcome2, L2

...

joe outcomeN, LN

joe outcomeN1, LN1 ; Conditional jump to a sample

; ‘casels’ instruction.

joe outcomeN2, LN2 ; Conditional jump to a sample

; ‘choice’ instruction block.

joe outcomeN3, LN3 ; Conditional jump to a sample

; contiguous block of ‘jprob’

; instructions.

; An optional contiguous block of ‘jprob’ instructions (may also

; be a ‘choice’ instruction block or a ‘casels’ instruction)

; followed by a ‘jmp’ instruction. Each of labels SA1, SA2, ...,

; SAN, SANN should be defined at the start of a state.

jprob probA1, SA1

jprob probA2, SA2

...

jprob probAN, SAN

jmp SANN

; A sample ‘casels’ instruction that specifies probabilities of

; transitions to states for a source state, in which the user or

; mixed type instruction is invoked, for that instruction, and

; for its outcome outcomeN1. Probabilities list list_name, which

; contains N probabilities, should be defined in the ‘.data’

; section of the assembler program. Each of labels SB1, SB2, ...,

; SBN, SBNN should be defined at the start of a state.

LN1: casels list_name, SB1, SB2, ..., SBN

jmp SBNN

; A sample ‘choice’ instruction block that specifies

; probabilities of transitions to states for a source state, in

; which the user or mixed type instruction is invoked, for that

; instruction, and for its outcome outcomeN2. Each of labels SC1,

; SC2, ..., SCN, SCNN should be defined at the start of a state.

LN2: choice

case probC1, SC1

case probC2, SC2

...

case probCN, SCN

end choice

jmp SCNN

Chapter 5: Assembler Programs 151

; A sample contiguous block of ‘jprob’ instructions that

; specifies probabilities of transitions to states for a source

; state, in which the user or mixed type instruction is invoked,

; for that instruction, and for its outcome outcomeN3. Each of

; labels SD1, SD2, ..., SDN, SDNN should be defined at the start

; of a state.

LN3: jprob probD1, SD1

jprob probD2, SD2

...

jprob probDN, SDN

jmp SDNN ; This instruction will not be needed

; if it specifies a jump to a state

; that goes just after the

; instruction.

After a user instruction or a mixed type instruction there can be no joe instructions at all.In this case, the instruction should be immediately followed by a contiguous block of jprobinstructions or a choice instruction block or a casels instruction or by a jmp instructionthat transfers control to another state or should be followed by another state directly. Sucharrangement of instructions is represented by the example below.

user or mixed type instruction

; An optional contiguous block of ‘jprob’ instructions (may also

; be a ‘choice’ instruction block or a ‘casels’ instruction) that

; specifies probabilities of transitions to states for a source

; state, in which the user or mixed type instruction is invoked,

; and for that instruction. Each of labels S1, S2, ..., SN, SNN

; should be defined at the start of a state.

jprob prob1, S1

jprob prob2, S2

...

jprob probN, SN

jmp SNN ; This instruction will not be needed

; if it specifies a jump to a state

; that goes just after the

; instruction.

; The start of another state.

Adherence to the above structure of an assembler program will simplify understanding howyour assembler program is converted to a probability profile stored in the state transition matrixand the action emission matrix of a node. Such understanding may be necessary to develop anassembler program that can be trained efficiently.

5.3.7 nop and nop1 Instructions

Mixed type instruction nopmust have the corresponding instruction meta-class explicitly definedin the application program. The instruction is supposed to do nothing and not to change theoutcome of the previous instruction invoked by a node. The instruction meta-class can be definedusing the following block of code:

static QSMM_INSTR_META_CLASS(nop) {

switch (qsmm_evt) {

Chapter 5: Assembler Programs 152

case QSMM_EVT_INSTR_CLASS_INIT:

qsmm_set_eh_noutcome(qsmm,0);

break;

}

return 0;

}

The instruction can be explicitly inserted into an assembler program after stt instructionswhere needed. The instruction can also be generated implicitly while assembling the program,in which case the corresponding warning will be produced.

Ideally, there should be no implicitly generated nop instructions in your assembler program.You have to analyze warnings produced while assembling and remove instructions, which donothing useful, or insert stt instructions where needed, rearranging your program if necessary,or insert nop instructions into appropriate places explicitly.

Mixed type instruction nop1 is supposed to have a single outcome and do nothing. Theinstruction meta-class can be defined using the following block of code:

static QSMM_INSTR_META_CLASS(nop1) {

return 0;

}

This instruction (instead of a nop instruction) can be explicitly inserted after an stt instructi-on when there is no need to preserve the outcome of the previous instruction invoked by a nodeand the outcome should be reset to 0. The use of the nop1 instruction instead of the nop

instruction reduces the number of profile probabilities written to the state transition matrix,making it simpler and decreasing the amount of memory needed to store the matrix (if mapstorage is used). This instruction can be generated by the disassembler at the beginning of anassembler program.

5.3.8 lookup Instruction

The instruction is the mixed type one, which can be generated when disassembling a node ofa multinode model that has positive length of the look-ahead signal segment. That length isspecified when creating the multinode model and can be retrieved using function qsmm_get_

ngram_env_la_sz.

The instruction has syntax

lookup position

The instruction sets the outcome to a look-ahead signal at given zero-based position.

When the length of the look-ahead signal segment of a multinode model is positive, assemblerprograms cannot be loaded into nodes of the multinode model. Therefore, if you need to assemblea program that contains lookup instructions (e.g. generated by the disassembler), you have tocreate a model with the zero-length look-ahead signal segment. You have to define instructionmeta-class ‘lookup’ that fetches signals at given positions from an array used as a substitute forthe look-ahead signal segment. You also need to register necessary instruction classes derivedfrom instruction meta-class ‘lookup’, the number of which is equal to the number of possiblevalues of position.

5.3.9 abort Instruction

The instruction is the mixed type one, which can be generated by the disassembler after a userinstruction when the disassembler has no information what should be executed after that userinstruction. The information is typically absent when the user instruction was executed onlyonce and did not return control, or when subsequent instructions were discarded according toparameters of disassembling.

Chapter 5: Assembler Programs 153

When you need to assemble programs generated by the disassembler that contain abort

instructions, the following approach can be used. First, make the disassembler generate a singleabort instruction at the program end, to which there are jumps from other places of the program.After an abort instruction at the end of the program there will be a jump to the start of theprogram. Second, implement the abort instruction as the nop1 instruction that does nothing.The control will be transferred to the program start when it is not known what to execute.Maybe such looping will be appropriate in your situation.

5.3.10 User Instructions

An assembler program can contain user instructions, which correspond to instruction classesthat are held in the instruction class set of a node and perform application-specific operations.

The parameters string of a user instruction can be splitted into multiple lines at positions ofcommas contained not within string literals. To indicate that a line of the parameters string iscontinued on the next line, terminate a line, which is continued, with a comma.

Before searching an instruction class in the set, the parameters string is normalized accordingto rules described in Section 4.3.4 [Setting the Instruction Parameters String], page 87.

5.4 Disassembling a Node

The state transition matrix and the action emission matrix of a node can be converted toa representation in the form of an assembler program. This conversion process is called di-sassembling a node.

In practice, disassembling a node is typically performed after training the node. Before thetraining, an assembler program, which specifies a probability profile for the state transitionmatrix and the action emission matrix of the node, could be loaded into the node. In this case,to simplify the analysis of results of training the node, it is often desirable for a developer toobtain a disassembled program, which is an assembler program previously loaded into the node,but with profile probabilities in jprob and case instructions changed to probabilities learnedwhile training the node. This mode of disassembling a node is implemented starting from QSMM

version 1.15 and is called disassembling using an assembler program template. To turn this modeon, pass the QSMM_ASM_TEMPLATE flag to function qsmm_node_asm when loading an assemblerprogram into a node that will be disassembled later (see Section 5.8 [Loading a Parsed Programinto a Node], page 166). If an assembler program was not previously loaded into a node or wasloaded without specification of the QSMM_ASM_TEMPLATE flag, then disassembling the node canonly be performed in a classic mode, which was the only mode implemented in QSMM beforeversion 1.15.

To disassemble a node, the following function can be used.

[Function]int qsmm_node_disasm (qsmm t model, int node, structqsmm disasm desc s *desc_p, qsmm prg t *prg_p )

This function disassembles node of multinode model according to parameters specified in*desc p and stores an allocated handle of disassembled program in *prg p. If desc p is 0,then default disassembling parameters will be used.

If node is previously assembled with the QSMM_ASM_TEMPLATE flag or if node uses a sourceprobability profile provided by another node assembled with the QSMM_ASM_TEMPLATE flag,then the disassembled program will be an assembler program stored in a node assembled wi-th the QSMM_ASM_TEMPLATE flag as the template assembler program. In the disassembledprogram profile probabilities in jprob and case instructions of the template assemblerprogram are replaced with probabilities of type desc_p->prob_type (if desc p is not 0)or of type QSMM_PROB_AGGR (if desc p is 0).

In the current implementation, if desc p is not 0, then *desc p will not be modified as a resultof the function call. However, in future versions of the package the contents of *desc p could

Chapter 5: Assembler Programs 154

be modified by the function, e.g. statistics on the disassembling process could be writtenthere.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Either argument prg p is 0 or parameters specified in *desc p (if desc p is not0) are invalid.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state.

A structure, a pointer to which is an argument of function qsmm_node_disasm, is describedbelow.

[Structure]qsmm_disasm_desc_sThis structure specifies parameters of disassembling. It contains the following fields.

[Field]char use_stt_startIf not 0, then generate an stt instruction at the beginning of an assembler program whenthe program starts with a lookup instruction, and generate stt and nop1 instructions atthe beginning of a program when the program starts with a jprob instruction or a choiceinstruction block. The default is not to generate. The value of this field is ignored if anode is disassembled using an assembler program template.

[Field]char use_stt_stateIf not 0, then generate stt instructions at the beginnings of states. The default is not togenerate. The value of this field is ignored if a node is disassembled using an assemblerprogram template.

[Field]char use_stt_lookupIf not 0, then generate stt instructions before lookup instructions. The default is not togenerate. The value of this field is ignored if a node is disassembled using an assemblerprogram template.

[Field]char use_stt_abortIf not 0, then generate stt instructions before abort instructions. This will not bevery useful unless there is not more than one abort instruction in the program, whichis controlled by field use_abort_1. The default is not to generate. The value of this fieldis ignored if a node is disassembled using an assembler program template.

[Field]char use_choiceIf not 0, then generate a choice instruction block instead of a contiguous block of jprobinstructions when the number of jprob instructions in the block is greater than one. Thedefault is to generate. The value of this field is ignored if a node is disassembled using anassembler program template.

Chapter 5: Assembler Programs 155

[Field]char use_abort_1If is 0, then generate each time an abort instruction just after a user instruction whenit is not known what to execute after the user instruction. If not 0, then generate eachtime a jump after such user instruction to a single abort instruction at the end of theprogram and generate a jump to the program start after that abort instruction. If not0 and there are no jumps to an abort instruction at the end of the program, then thatabort instruction followed by a jump to the program start will not be generated. Thedefault is to generate an abort instruction just after a user instruction. The value of thisfield is ignored if a node is disassembled using an assembler program template.

[Field]char do_retain_goto_1If not 0, then retain the most probable transition to another state for a quadruple thatconsists of a source state, a user or mixed type instruction invoked, an outcome of thatinstruction, and the contents of the look-ahead signal segment when discarding transitionswith probabilities less than specified in field prob_goto_min. This ensures that for everyquadruple there remains at least one transition to another state. Field prob_type specifiesa type of probabilities being analyzed. The default is not to retain the most probabletransition. The value of this field is ignored if a node is disassembled using an assemblerprogram template.

[Field]char do_retain_action_1If not 0, then retain the most probable user or mixed type instruction that can be executedin a state when discarding instructions with probabilities less than specified in field prob_

action_min. This ensures that for every state there remains at least one user or mixedtype instruction that can be executed in the state, i.e. the state will not be removedbecause it does not contain user or mixed type instructions. Field prob_type specifies atype of probabilities being analyzed. The default is not to retain the most probable useror mixed type instruction. The value of this field is ignored if a node is disassembled usingan assembler program template.

[Field]char do_calc_prob[QSMM_PROB_COUNT]An array that specifies additional types of probabilities to calculate for jprob and case

instructions, which can be printed in comments for those instructions. Indices of the arrayare the elements of enumeration qsmm_prob_e (except for the last element) described inSection 2.8 [Generating an Optimal Action], page 29. If an element of the array has a non-zero value, then probabilities of the corresponding type will be calculated and stored inthe instructions. Probabilities of a type specified in field prob_type are calculated always,regardless of the value of field do_calc_prob. The default is not to calculate probabilitiesof additional types.

[Field]long fq_goto_minThe minimum frequency of transition to another state for a quadruple that consists of asource state, a user or mixed type instruction invoked, an outcome of that instruction,and the contents of the look-ahead signal segment. Transitions with lesser frequenciesare discarded out of hand. The frequencies might not be incremented for transitionsperformed deterministically. It is not recommended to set this field to a positive valuewhen disassembling a node, into which an assembler program was loaded, because theassembler program might define deterministic transitions, which frequencies could be zeroand which would be discarded. The default minimum frequency is 0. The value of thisfield is ignored if a node is disassembled using an assembler program template.

[Field]long fq_action_minThe minimum frequency of invocation of user or mixed type instruction in a state.Instructions invoked lesser number of times are discarded out of hand. The frequenci-

Chapter 5: Assembler Programs 156

es might not be incremented for instruction invocations performed deterministically. Itis not recommended to set this field to a positive value when disassembling a node, intowhich an assembler program was loaded, because the assembler program might definedeterministic instruction invocations which frequencies could be zero. The default mini-mum frequency is 0. The value of this field is ignored if a node is disassembled using anassembler program template.

[Field]double prob_goto_minWhen disassembling a node using an assembler program template, this field specifies theminimum probability in jprob and case instructions that correspond to the state transi-tion matrix of the node. Instructions with lesser probabilities will be removed from thedisassembled program, although they are present in the assembler program template.

When disassembling a node without using an assembler program template, this field speci-fies the minimum probability of transition to another state for a quadruple that consists ofa source state, a user or mixed type instruction invoked, an outcome of that instruction,and the contents of the look-ahead signal segment. Transitions with lesser probabilitiesare discarded after discarding transitions with frequencies less than a frequency specifiedin field fq_goto_min and after renormalizing transition probabilities. When discardingtransitions with lesser probabilities, if do_retain_goto_1 is not 0, then the most probabletransition will be retained.

Field prob_type specifies a type of probabilities being analyzed. The default minimumprobability is 0.

[Field]double prob_action_minWhen disassembling a node using an assembler program template, this field specifies theminimum probability in jprob and case instructions that correspond to the action emi-ssion matrix of the node. Instructions with lesser probabilities will be removed from thedisassembled program, although they are present in the assembler program template.

When disassembling a node without using an assembler program template, this field speci-fies the minimum probability of invocation of user or mixed type instruction in a state.Instructions with lesser invocation probabilities are discarded after discarding instructionswith frequencies less than a frequency specified in field fq_action_min and after renormali-zing the invocation probabilities. When discarding instructions with lesser invocationprobabilities, if do_retain_action_1 is not 0, then the most probable instruction will beretained.

Field prob_type specifies a type of probabilities being analyzed. The default minimumprobability is 0.

[Field]enum qsmm_prob_e prob_typeA type of probabilities to calculate for jprob and case instructions.

When disassembling a node using an assembler program template, those probabilities arecompared with probabilities in fields prob_goto_min and prob_action_min to determinewhether to discard specific jprob and case instructions.

When disassembling a node without using an assembler program template, this field speci-fies the type of probability, by which jprob and case instructions within correspondinginstruction blocks are sorted in descending order. This field also specifies the type ofprobabilities of transitions to other states and the type of probabilities of invocation ofuser and mixed type instructions, which are compared with probabilities in fields prob_goto_min and prob_action_min to perform discarding when necessary.

See Section 2.8 [Generating an Optimal Action], page 29, for a description of elements ofenumeration qsmm_prob_e. The default type of probabilities is QSMM_PROB_AGGR.

Chapter 5: Assembler Programs 157

An instance of structure qsmm_disasm_desc_s, a pointer to which is passed to functionqsmm_node_disasm, should be zeroed using function memset before setting values of structurefields.

When disassembling a node without using an assembler program template, the followingcomments are generated for instructions in a disassembled program.

• At the beginnings of states: the index of a state and the number of times control wastransferred to the state.

• For user and mixed type instructions: the number of instruction invocations (calls).

• For jmp, joe, jprob, and case instructions: the number of jumps performed.

Note the following regarding the frequencies.

• Frequencies less than 2 are not printed in comments.

• If an assembler program, which defines deterministic state transitions and/or instructioninvocations, is loaded into the node, then frequencies printed in comments will be inaccurate.

• Frequencies printed in comments may be inconsistent among themselves if some instructionsare discarded according to parameters of disassembling.

• Probabilities of type QSMM_PROB_FQ are calculated on the basis of frequencies of non-deterministic choices made and sometimes can be less by 1 than the values expected due tothe of way how the frequencies are incremented.

When disassembling a node without using an assembler program template, to generate themost probable completely deterministic program, set fields prob_goto_min, prob_action_min,do_retain_goto_1, and do_retain_action_1 of structure qsmm_disasm_desc_s to 1.

Below there is given an example of calling function qsmm_node_disasm to generate a programfor subsequent assembling. It is assumed that there is no assembler program loaded into a nodefor which function qsmm_node_disasm is called.

qsmm_prg_t prg=0;

struct qsmm_disasm_desc_s disasm_desc;

memset(&disasm_desc,0,sizeof(disasm_desc));

// Insert ‘stt’ instructions at appropriate places.

disasm_desc.use_stt_start=1;

disasm_desc.use_stt_state=1;

disasm_desc.use_stt_lookup=1;

disasm_desc.use_stt_abort=1;

// Make probabilistic jumps to look intelligible.

disasm_desc.use_choice=1;

// Simplify handling unexplored control paths.

disasm_desc.use_abort_1=1;

// Do not produce code that was never executed.

disasm_desc.fq_goto_min=1;

disasm_desc.fq_action_min=1;

// Do not generate probabilistic jumps with

// rounded probabilities less than 1%.

disasm_desc.prob_goto_min=0.005;

disasm_desc.prob_action_min=0.005;

qsmm_node_disasm(qsmm,node,&disasm_desc,&prg);

To disassemble a node assembled with the QSMM_ASM_TEMPLATE flag, the above example canbe reduced to the lesser number of lines because assignments to other fields are ignored in thismode.

qsmm_prg_t prg=0;

Chapter 5: Assembler Programs 158

struct qsmm_disasm_desc_s disasm_desc;

memset(&disasm_desc,0,sizeof(disasm_desc));

// Remove ‘jprob’ and ‘case’ instructions with

// rounded probabilities less than 1%.

disasm_desc.prob_goto_min=0.005;

disasm_desc.prob_action_min=0.005;

qsmm_node_disasm(qsmm,node,&disasm_desc,&prg);

5.5 Inspecting an Assembler Program

To get the number of instructions contained in an assembler program, the following functioncan be used.

[Function]int qsmm_get_prg_ninstr (qsmm prg t prg )This function returns the number of instructions contained in program prg. The returnedvalue is always non-negative.

To get an instruction contained in an assembler program, the following function can be used.

[Function]qsmm_instr_t qsmm_get_prg_instr (qsmm prg t prg, int instr_idx )This function returns the handle of an instruction contained in program prg at zero-basedindex instr idx.

If instr idx is negative or is greater than or equal to the number of instructions in the program,then 0 will be returned.

A type of an assembler instruction is specified using the following enumeration.

[Enumeration]qsmm_instr_eThis enumeration specifies a type of an assembler instruction. It contains the followingelements.

QSMM_INSTR_USER

A user or mixed type instruction.

QSMM_INSTR_JMP

A jmp instruction.

QSMM_INSTR_JPROB

A jprob instruction.

QSMM_INSTR_CASE

A case instruction (within a choice instruction block).

QSMM_INSTR_CHOICE

A choice instruction.

QSMM_INSTR_CASELS

A casels instruction.

QSMM_INSTR_JOE

A joe instruction.

QSMM_INSTR_STT

An stt instruction.

QSMM_INSTR_END

An end choice instruction (at the end of a choice instruction block).

To get the type of an assembler instruction, the following function can be used.

Chapter 5: Assembler Programs 159

[Function]enum qsmm_instr_e qsmm_get_instr_type (qsmm instr t instr )This function returns the type of instruction instr.

Function qsmm_get_prg_instr does not return instructions of types QSMM_INSTR_CASE andQSMM_INSTR_END. It can return an instruction of type QSMM_INSTR_CHOICE instead, whichrepresents a choice instruction block that contains nested case and end choice instructions.To get the number of instructions, nested in a choice instruction block, the following functioncan be used.

[Function]int qsmm_get_instr_nnested (qsmm instr t instr )This function returns the number of instructions nested in instruction instr of type QSMM_

INSTR_CHOICE. For instructions of other types, the function returns 0. The returned valueis always non-negative.

To get the handle of a nested case or end choice instruction, the following function can beused.

[Function]qsmm_instr_t qsmm_get_instr_nested (qsmm instr t instr, intnested_idx )

This function returns the handle of an instruction nested in instruction instr of type QSMM_

INSTR_CHOICE. A zero-based index of nested instruction is specified by nested idx.

If instruction instr is not of type QSMM_INSTR_CHOICE, or nested idx is negative or is greaterthan or equal to the number of instructions nested in instruction instr, then 0 will be returned.

An instruction can have location labels assigned to it, which are normally placed to theleft of the instruction. A location label assigned to a casels instruction can be used to fetchprobabilities, which correspond to jump labels specified in arguments of that instruction. Alocation label assigned to a choice instruction block can be used to fetch probabilities thatcorrespond to case instructions within the block. The fetched probabilities could be learnedduring the node training. To get the number of location labels assigned to an instruction, thefollowing function can be used.

[Function]int qsmm_get_instr_nlabel (qsmm instr t instr )This function returns the number of location labels assigned to instruction instr, which arenormally placed to the left of instruction. The returned value is always non-negative.

To get a location label by a location label index, the following function can be used.

[Function]const char * qsmm_get_instr_label (qsmm instr t instr, intlabel_idx )

This function returns a location label at zero-based index label idx assigned to instructioninstr. That label is normally placed to the left of instruction. If label idx is negative or isgreater than or equal to the number of location labels assigned to the instruction, then 0 willbe returned.

To get the name of a probabilities list associated with an instruction, a function describedbelow can be used. See Section 5.10 [Using Probabilities Lists], page 183, for more informationon probabilities lists.

[Function]const char * qsmm_get_instr_ls_name (qsmm instr t instr )This function returns the name of a probabilities list associated with instruction instr of typeQSMM_INSTR_CASELS. If instruction instr has a type other than QSMM_INSTR_CASELS, then 0will be returned.

Chapter 5: Assembler Programs 160

The purpose of the function described below is to get the number of elements in a probabilitieslist defined in an assembler program. The retrieved number of elements can be used to allocatean array for fetching probabilities learned during the node training that correspond to jumplabels specified in arguments of a casels instruction.

[Function]int qsmm_get_prg_ls_nprob (qsmm prg t prg, const char *ls_name )This function returns the number of elements in probabilities list ls name defined in programprg.

On success, a positive value is returned. If program prg does not contain probabilities listls name, then negative error code QSMM_ERR_NOTFOUND will be returned.

5.6 Printing an Assembler Program

To get a string representation of an instruction of an assembler program, the following functioncan be used.

[Function]int qsmm_instr_str (char *bufp, int bufsz, qsmm instr t instr, structqsmm dump instr desc s *desc_p )

This function stores in buffer bufp of size bufsz bytes a string representation of instructioninstr generated according to parameters specified in *desc p. If desc p is 0, then defaultparameters of generating the string representation will be used. The function may changeeither *desc p or the instance of structure qsmm_dump_instr_desc_s where the defaultparameters are stored (when desc p is 0).

On success, the function returns a non-negative number of bytes required for a stringrepresentation of the instruction, not counting trailing byte 0. The returned value greaterthan or equal to bufsz indicates that the string representation was truncated. If bufsz isgreater than 0, then the truncated string representation of length bufsz–1 bytes will be wri-tten to bufp and terminated with byte 0. It is allowed to pass 0 for both bufp and bufsz todetermine the length of the string representation of an instruction.

On failure, the function returns a negative error code. Currently, the following error codescan be returned.

QSMM_ERR_INVAL

The value of bufsz is less than 0, or the value of bufsz is greater than 0 and bufpis 0, or desc p is not 0 and parameters specified in *desc p are invalid, or desc pis 0 and the default parameters are invalid.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

There is an instance of structure qsmm_dump_instr_desc_s defined within the library, wherethe default parameters of generating a string representation of instruction are stored. To get apointer to that instance, the following function can be used.

[Function]struct qsmm_dump_instr_desc_s *qsmm_get_default_dump_instr_desc ()

This function returns a pointer to default parameters of generating a string representation ofan assembler instruction. The parameters can be changed using that pointer. The functionnever returns 0.

A structure, which specifies parameters of generating a string representation of instruction,is described below.

[Structure]qsmm_dump_instr_desc_sThis structure specifies parameters of generating a string representation of an assemblerinstruction. It contains the following fields.

Chapter 5: Assembler Programs 161

[Field]char is_line_after_comment_aboveIf not 0, then if there is a comment above the instruction stored with the instruction andfield do_print_comment_above has a non-zero value, then insert an empty line after thecomment and before the instruction. This field is also used in a similar way to determinewhether to insert an empty line after a comment above a definition of a probability variableor a probabilities list in an assembler program and before the definition. The default is toinsert an empty line.

[Field]char is_line_after_multiline_comment_rightIf not 0 and field do_print_comment_right has a non-zero value, then insert an emptyline after an instruction, a jump label (in arguments of casels instruction), the definitionof a probability variable, a probabilities list, or its element that has a multiline commentto the right if the next line in the assembler program contains a comment to the right.The default is to insert an empty line.

[Field]char is_space_after_commaIf not 0, then insert a space after every comma not within string literals in instructionparameters. This field is also used in a similar way to determine whether to insert a spaceafter every comma in definitions of probabilities lists in an assembler program. The defaultis to insert a space.

[Field]char do_print_labelIf not 0 and the instruction has a location label defined, then print the location label tothe left of the instruction. If there are several location labels defined for the instruction,then all the labels except for the last one will be printed on separate lines. If there isno room between the last label and an instruction name, then the last label will also beprinted on a separate line. The default is to print location labels.

[Field]char do_print_nameIf not 0, then print an instruction name. The default is to print.

[Field]char do_print_paramIf not 0, then print instruction parameters. The default is to print.

[Field]char do_print_comment_aboveIf not 0 and there is a comment above the instruction stored with the instruction, thenprint that comment. This field is also used in a similar way to determine whether to printcomments above definitions of probability variables and probabilities lists in an assemblerprogram. The default is to print the comments.

[Field]char do_print_comment_rightIf not 0 and there is a comment to the right of an instruction or a jump label (in argumentsof casels instruction) stored with the instruction or the jump label, then print thatcomment. This field is also used in a similar way to determine whether to print commentsto the right of definitions of probability variables, probabilities lists and their elements inan assembler program. The default is to print the comments.

[Field]char do_print_varIf not 0, then if there is a name of probability variable stored in a jprob or a case

instruction and the value of field prob_type is equal to QSMM_PROB_PROFILE, then printthat name of variable. Otherwise, print a probability. This field also determines whetherto print names of probability variables in definitions of probabilities lists in an assemblerprogram where those names were provided in the program source text. The default is toprint names of probability variables when possible.

Chapter 5: Assembler Programs 162

[Field]char do_print_state_nameIf not 0, then if there is a state name stored with an stt instruction and field do_print_

param has a non-zero value, then print the state name in that instruction. The default isto print state names.

[Field]char do_print_prob[QSMM_PROB_COUNT]An array that specifies additional types of probabilities to print in comments for jproband case instructions to the right. Indices of the array are the elements of enumerationqsmm_prob_e (except for the last element) described in Section 2.8 [Generating an OptimalAction], page 29. If an element of the array has a non-zero value, the index of the elementis not equal to the value of field prob_type, and the value of field do_print_comment_

right is non-zero, then probabilities of the corresponding type will be printed in thecomments. When dumping an instruction of a program disassembled using an assemblerprogram template, if that instruction is used in the template in an ambiguous context,then ‘?’ will be printed for the probabilities. The default is not to print probabilities inthe comments.

[Field]int prob_precThe number of digits after the decimal point to print for probabilities in jprob and case

instructions and comments for those instructions to the right according to the value offield do_print_prob. It is also the number of digits after the decimal point to print forprobabilities in definitions of probability variables, probabilities lists and their elementsin an assembler program. If is a non-negative number, then fixed-point notation will beused. If is a negative number, then exponential notation with the number of digits afterthe decimal point equal to the absolute value of the field will be used. The default numberof digits to print after the decimal point is equal to 2.

[Field]int col_nameIf is a positive number, then a column to align the start of instruction name to. If not apositive number, then do not perform the alignment. This field also indicates a column toalign the start of ‘.data’ and ‘.code’ directives, a column to align the start of commentsabove instructions, definitions of probability variables and probabilities lists, a columnto align the start of a tail comment in an assembler program if the assembler programcontains that comment. If not a positive number, then ‘.data’ and ‘.code’ directives andthe comments will be aligned to column 1. The default is to align to column 9.

[Field]int col_paramIf is a positive number, then a column to align the start of instruction parameters to.If not a positive number, then do not perform the alignment. The default is to align tocolumn 17.

[Field]int col_commentIf is a positive number, then a column to align the start of a comment to the right ofinstruction to. If not a positive number, then do not perform the alignment. The defaultis to align to column 33.

[Field]int margin_rightIf is a positive number, then a right margin column to use for comments. Longer commentswill be splitted into multiple lines. If not a positive number, then do not split commentsinto multiple lines based on a right margin column. The default is not to split.

[Field]int margin_right_paramIf is a positive number, then a right margin column to use for lists of arguments of userand casels instructions. Longer lists will be splitted into multiple lines. Commas not

Chapter 5: Assembler Programs 163

within string literals (those literals can be parts of arguments of user instructions) areused as places, at which splitting can be performed. If not a positive number, then donot split the lists into multiple lines based on a right margin column. The default rightmargin column is 30.

[Field]int nline_comment_rightFunction qsmm_instr_str sets the value of this field. The function writes here the numberof lines in a comment to the right of the instruction or the last jump label in argumentsof a casels instruction. If field do_print_comment_right has zero value, the instructionor the last jump label does not have a comment to the right, or the instruction is a userinstruction, which arguments list was splitted into multiple lines and which has a commentto the right with the number of lines less than the number of lines of the arguments list,then 0 will be written here. If field do_print_comment_right has a non-zero value andthe instruction or the last jump label has a comment to the right, which was splitted intomultiple lines according to the value of field margin_right, then a value greater than1 will be written here (with the exception of a user instruction with a comment to theright that occupies the number of lines less than the number of lines of arguments list ofthe instruction). The value of this field is used by function qsmm_prg_dump to insert anempty line after an instruction that has a multiline comment to the right when the nextinstruction has a comment to the right.

[Field]int nline_paramFunction qsmm_instr_str sets the value of this field. The function writes here the numberof lines of arguments list of an instruction printed. The value of this field is used by functionqsmm_prg_dump to determine whether to insert empty lines around multiline instructions.

[Field]enum qsmm_prob_e prob_typeA type of probabilities to print in jprob and case instructions. See Section 2.8 [Generatingan Optimal Action], page 29, for a description of elements of enumeration qsmm_prob_e.When dumping an instruction of a program disassembled using an assembler programtemplate, if that instruction is used in the template in an ambiguous context, then ‘?’ willbe printed for the probability. The default type of probabilities is QSMM_PROB_AGGR.

Note: when converting a disassembled program or its specific instructions to a stri-ng representation, be sure to set fields do_print_prob and prob_type of structureqsmm_dump_instr_desc_s to values consistent with values of fields do_calc_proband prob_type of structure qsmm_disasm_desc_s used when disassembling theprogram. Otherwise, zero probabilities will be printed.

To dump a program to a stream, the following function can be used.

[Function]int qsmm_prg_dump (qsmm prg t prg, struct qsmm dump prg desc s*desc_p, FILE *filep )

This function dumps program prg to stream filep according to parameters specified in *desc p.If desc p is 0, then default parameters of dumping a program will be used.

In the current implementation, *desc p (if desc p is not 0) or the instance of structure qsmm_dump_prg_desc_s where the default parameters are stored (if desc p is 0), are not modifiedas a result of the function call. However, in future versions of the package those variablescould be modified by the function, e.g. statistics on the dumping process could be writtenthere.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 5: Assembler Programs 164

QSMM_ERR_INVAL

Argument desc p is not 0 and parameters specified in *desc p are invalid, ordesc p is 0 and default parameters, a pointer to which is returned by functionqsmm_get_default_dump_prg_desc, are invalid.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

There is an instance of structure qsmm_dump_prg_desc_s defined within the library, wherethe default parameters of dumping a program are stored. To get a pointer to that instance, thefollowing function can be used.

[Function]struct qsmm_dump_prg_desc_s * qsmm_get_default_dump_prg_desc()

This function returns a pointer to default parameters of dumping an assembler program. Theparameters can be changed using that pointer. The function never returns 0.

A structure, which specifies parameters of dumping a program, is described below.

[Structure]qsmm_dump_prg_desc_sThis structure specifies parameters of dumping an assembler program. It contains the followi-ng fields.

[Field]char do_print_varsIf not 0 and the program contains definitions of probability variables and/or probabilitieslists, then dump a ‘.data’ section with those definitions. The default is to dump.

[Field]char is_line_before_labelIf not 0, then insert an empty line before a line with a location label definition. If aninstruction has several location labels defined (which are dumped on separate lines), thenan empty line will be inserted only before a line with the first location label definition.The default is to insert.

[Field]char is_line_before_isolated_commentIf not 0, then insert an empty line before a comment above an instruction or a definitionof a probability variable or a probabilities list if the instruction or the definition has thatcomment, and insert an empty line before a comment at the end of the program if theprogram contains that comment and field do_print_comment_tail has a non-zero value.The default is to insert.

[Field]char are_lines_around_choiceIf not 0, then insert empty lines before and after choice instruction blocks. The defaultis to insert.

[Field]char are_lines_around_multiline_paramIf not 0, then insert empty lines before and after multiline user and casels instructions.The default is to insert.

[Field]char do_print_comment_tailIf not 0 and the program contains a comment at the end, then dump that comment. Thedefault is to dump.

[Field]int col_var_typeIf is a positive number, then a column to align the start of ‘prob’, ‘probeq’, and ‘probls’keywords to. If not a positive number, then do not perform the alignment. The default isto align to column 17.

Chapter 5: Assembler Programs 165

[Field]int col_var_valIf is a positive number, then a column to align the start of a probability variable orprobabilities list value to. If not a positive number, then do not perform the alignment.The default is to align to column 25.

[Field]int col_var_commentIf is a positive number, then a column to align the start of a comment to the right ofdefinition of a probability variable, a probabilities list, or its element. If not a positivenumber, then do not perform the alignment. The default is to align to column 33.

[Field]int margin_right_lsIf is a positive number, then a right margin column to use for probabilities lists definedwith the help of ‘probls’ keywords. Longer lists will be splitted into multiple lines. If nota positive number, then do not split the lists into multiple lines based on a right margincolumn. The default right margin column is 30.

[Field]struct qsmm_dump_instr_desc_s * dump_instr_desc_pIf not 0, then parameters of dumping instructions of the program. If is 0, then use defaultparameters returned by function qsmm_get_default_dump_instr_desc.

5.7 Parsing an Assembler Program

The QSMM framework supports parsing an assembler program provided in a string buffer, in a fi-le, or which should be read from a stream. The program is converted to a memory representationthat can be inspected, printed, or loaded into a node.

[Function]int qsmm_parse_asm_source_buf (const char *in_p, const char *cwd_p,unsigned int flags, void *rez1, void *rez2, qsmm msglist t msglist,qsmm prg t *prg_p )

[Function]int qsmm_parse_asm_source_stream (FILE *filep, const char *cwd_p,unsigned int flags, void *rez1, void *rez2, qsmm msglist t msglist,qsmm prg t *prg_p )

Function qsmm_parse_asm_source_buf parses an assembler program, the source text of whi-ch is given using argument in p in the form of a NULL-terminated string. Function qsmm_

parse_asm_source_stream parses an assembler program, the source text of which is readfrom stream filep. The functions store an allocated handle of the memory representation ofthe program in *prg p.

If msglist is not 0, then error, warning, and note messages generated during parsing willbe written to message list msglist. If flags has a bit specified by mask QSMM_PARSE_ASM_

PREPROCESS set, then the source program text will be first preprocessed by the assemblerpreprocessor. If cwd p is not 0, then cwd p will be used for the name of current workingdirectory by the assembler preprocessor when resolving ‘include’ directives. If cwd p is 0,then the actual current working directory will be used when resolving ‘include’ directives.Arguments rez1 and rez2 are reserved for future use and must be equal to 0.

The functions return a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument prg p is 0.

QSMM_ERR_PRG

One or more errors were encountered in the source program text.

QSMM_ERR_ILSEQ

The source text of the assembler program cannot be converted to a wide stringaccording to the current locale.

Chapter 5: Assembler Programs 166

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_parse_asm_source_file (const char *fln, unsigned int flags,void *rez1, void *rez2, qsmm msglist t msglist, qsmm prg t *prg_p )

This function parses an assembler program, the source text of which is provided in a filenamed fln, and stores an allocated handle of the memory representation of the program in*prg p. If msglist is not 0, then error, warning, and note messages generated during parsingwill be written to message list msglist. If flags has a bit specified by mask QSMM_PARSE_ASM_

PREPROCESS set, then the source program text will be first preprocessed by the assemblerpreprocessor. Arguments rez1 and rez2 are reserved for future use and must be equal to 0.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument prg p is 0.

QSMM_ERR_LIBC

When accessing file fln, the operating system has returned an error. Variableerrno holds the error code.

QSMM_ERR_PRG

One or more errors were encountered in the source program text.

QSMM_ERR_ILSEQ

The source text of the assembler program cannot be converted to a wide stringaccording to the current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

See Section 6.3.1 [Creating a Message List], page 218, for a description of functions usingwhich an empty message list can be created to pass it to functions qsmm_parse_asm_source_*to possibly fill it with messages and finally destroyed. See Section 6.3.4 [Dumping a MessageList], page 221, for a description of a function using which that message list can be dumped toa stream.

5.8 Loading a Parsed Program into a Node

An assembler program specifies a probability profile that can be loaded into nodes of multinodemodel. Loading a probability profile, which is specified by a parsed assembler program, into anode of multinode model is called assembling a node for short. The node must belong to a nodeclass represented by an instruction class set that contains instruction classes for all user andmixed type instructions used in the assembler program. Parsed assembler programs can only beloaded into nodes of a multinode model that has the look-ahead signal segment of zero length.

Functions described further on in this section take argument flags that specifies modes ofprocessing a parsed assembler program. This argument was introduced in QSMM version 1.15.The argument is a bitmask that can be defined as a subset of macros described below mergedby bitwise “or.”

[Macro]QSMM_ASM_DETERM_OPTImpose the following restriction on an action emission matrix that corresponds to theassembler program: for every node state the action emission matrix must define determi-nistic choice of an instruction class, which can be emitted in that node state. This modewill be turned on implicitly if field is_determ_opt of structure qsmm_desc_s has a non-zero value when creating the multinode model. In this mode, when processing the memory

Chapter 5: Assembler Programs 167

representation of an assembler program, states are assumed to begin just before user andmixed type instructions, and there is no need to mark unnamed states by stt instructions.If the assembler program contains stt instructions, they cannot be located just before jproband casels instructions and choice instruction blocks.

[Macro]QSMM_ASM_TEMPLATEWhen converting the memory representation of an assembler program to the state transitionmatrix and the action emission matrix of a node, store that memory representation in thenode as an assembler program template. The template will be automatically used whendisassembling the node by function qsmm_node_disasm. A disassembled program will be thetemplate program for which profile probabilities in jprob and case instructions are replacedwith probabilities of a type specified in field prob_type of structure qsmm_disasm_desc_s

passed to function qsmm_node_disasm or of type QSMM_PROB_AGGR if default disassemblingparameters are used. Field prob_goto_min of structure qsmm_disasm_desc_s specifies theminimum probability in jprob and case instructions that correspond to the state transitionmatrix. Field prob_action_min of structure qsmm_disasm_desc_s specifies the minimumprobability in jprob and case instructions that correspond to the action emission matrix.Instructions with lesser probabilities are removed from the disassembled program, althoughthey are present in the template program. Additional probabilities of types specified infield do_calc_prob of structure qsmm_disasm_desc_s can be calculated and then printed incomments for jprob and case instructions.

When storing an assembler program template into a node, casels instructions encounteredin the memory representation of the assembler program are converted to choice instructionblocks or jprob instructions. If a casels instruction uses a probabilities list that containsmore than one element, the instruction is converted to a choice instruction block. Otherwise,the instruction is converted to a jprob instruction. Such conversion makes possible obtainingprobabilities associated with jump labels of casels instructions when disassembling the node.

[Macro]QSMM_ASM_VAR_OUTCollect information on output probability variables and arrays in the assembler program.They all can be used to obtain probabilities learned during the node training. Outputprobability variables can be used to obtain probabilities that correspond to jprob andcase instructions. Output probabilities arrays can be used to obtains probabilities thatcorrespond to casels instructions and choice instruction blocks. See Section 5.9.3 [OutputVariables], page 177, and Section 5.10.3 [Getting Output Probabilities Arrays], page 185, formore information.

[Macro]QSMM_ASM_VAR_AUXPermit the use of auxiliary probability variables in the assembler program. Auxiliary probabi-lity variables are probability variables that are neither controlled nor output ones. Auxiliaryprobability variables are used merely for convenience in jprob and case instructions anddefinitions of probabilities lists and are replaced with their actual values in the process ofassembling the node. See Section 5.9.4 [Auxiliary Variables], page 183, for more information.

To load the memory representation of an assembler program into a node, the followingfunction can be used.

[Function]int qsmm_node_asm (qsmm t model, int node, unsigned int flags,qsmm prg t prg, qsmm msglist t msglist )

This function loads a probability profile, specified by program prg, into node of multinodemodel, i.e. assembles the node. Modes of assembling the node are specified using bitmaskflags (see above for a description of macros that correspond to bits of the bitmask takeninto account). If msglist is not 0, then warning messages generated during the assembling

Chapter 5: Assembler Programs 168

will be written to msglist. The function clears statistics on the event history that mighthave been collected for the node. If the node already has a probability profile loaded, thenthat profile will be first unloaded. To clear statistics on the event history and to unloadthe profile, function qsmm_node_unload described in Section 5.13 [Unloading a ProbabilityProfile], page 194 is implicitly called.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_NOSTATE

A node with identifier node does not have enough states.

QSMM_ERR_MPROF

No room in the pool of probabilities lists in normal form of a large actor thatrepresents the environment state identification engine or the instruction emi-tting engine. Sizes of the pools are specified in fields profile_pool_env_sz

and profile_pool_opt_sz of structure qsmm_desc_s passed to function qsmm_

create when creating the multinode model.

QSMM_ERR_PROFSRCP

A node with identifier node is the source of probability profile for other nodes.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, formore information on this mode.

QSMM_ERR_PRG

An error was encountered in program prg.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

To successfully load a program into a node, the node must have the sufficient number ofstates. Otherwise, error QSMM_ERR_NOSTATE will be raised. The number of states of a node canbe set using function qsmm_set_node_nstate, but it must not exceed the maximum numberof states of nodes of instruction class set, which is specified using function qsmm_set_nstate_

max. To determine, which number of states to pass to functions qsmm_set_node_nstate andqsmm_set_nstate_max, the following function can be used.

Chapter 5: Assembler Programs 169

[Function]int qsmm_get_prg_nstate (qsmm t model, const char*instr_class_set_name, unsigned int flags, qsmm prg t prg, qsmm msglist tmsglist )

This function calculates the minimum number of states required for nodes of multinode modelto successfully load program prg into them. Calculating is performed for nodes that belongto a node class represented by instruction class set instr class set name. Modes of assemblingthe nodes are specified using bitmask flags (see the beginning of this section for a descriptionof macros that correspond to bits of the bitmask taken into account). For a certainty, thevalue of flags passed to this function must be equal to the value of argument flags that willbe passed to function qsmm_node_asm when loading program prg into particular nodes of themodel. If msglist is not 0, then warning messages generated during the calculating will bewritten to msglist.

On success, the function returns a non-negative number of states. On failure, a negative errorcode is returned. Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_PRG

An error was encountered in program prg.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Functions qsmm_node_asm and qsmm_get_prg_nstate may generate the following warningmessages.

‘nop’ instruction has been insertedA nop instruction has been inserted at the beginning of an implicitly defined statebecause the state does not start with a user or mixed type instruction.

a replacement ‘nop’ instruction has been generatedAfter a jprob instruction, which has a jump probability greater than 0, there is ajmp instruction with a jump to that jprob instruction, and the jump location of thejprob instruction is not the next instruction. The jprob instruction was replacedwith the nop instruction, and the address of the next instruction, which will beexecuted after that nop instruction, has been set to the jump location of the jprobinstruction.

all valid outcomes have already been testedControl will never reach an instruction after a joe instruction block because allpossible outcomes of a user or mixed type instruction have already been tested inthat block.

instruction does nothing and was replaced with the ‘nop’ instructionThe jump location of a jprob instruction, which has a jump probability less than1, is that jprob instruction, or the jump location of a jprob or a joe instruction isthe next instruction. The instruction was replaced with the nop instruction.

Chapter 5: Assembler Programs 170

list element at index idx has no effectA jump label at zero-based index idx in arguments of a casels instruction specifiesthe transfer of control to the next instruction after the casels instruction. Thejump label was ignored.

nested instruction at index idx: instruction does nothingThe jump location of a case instruction at zero-based index idx within a choice

instruction block is the next instruction after that choice instruction block. Thecase instruction was ignored.

state is not marked by an ‘stt’ instructionThe assembler wants to start assembling a state at this location, but there is nostt instruction specified here. This causes the state to be defined implicitly. Thewarning message will not be generated if field is_determ_opt of structure qsmm_

desc_s has a non-zero value when creating the multinode model or if the node isassembled with the QSMM_ASM_DETERM_OPT flag.

test for outcome num is ignored, because the outcome has already been testedA joe instruction, which performs a jump on outcome num, is ignored, becausethere was another joe instruction before that instruction, which also performs ajump on outcome num.

test for outcome num is ignored, because the outcome is out of rangeA joe instruction, which performs jump on outcome num, has been ignored, becausea user or mixed type instruction, which outcome is being tested, has the number ofpossible outcomes less than or equal to num.

unreachable stateControl will never reach the state. This warning can only be generated if fieldis_determ_opt of structure qsmm_desc_s has a non-zero value when creating themultinode model or if the node is assembled with the QSMM_ASM_DETERM_OPT flag orif the state is marked by an stt instruction.

An assembler program might have names assigned to its states by arguments of stt instructi-ons. After loading the assembler program into a node, the index of a node state, whichcorresponds to the name of the state, can be retrieved using the following function.

[Function]int qsmm_get_node_state_by_name (qsmm t model, const char*state_name, int node, int *state_p )

This function sets *state p equal to the index of a state of a node of multinode model. Thestate is specified by name state name assigned by the argument of an stt instruction in anassembler program loaded into the node. If state p is 0, then *state p will not be set. Ifstate p is not 0, and there is no assembler program loaded into the node or the assemblerprogram does not contain a state named state name, then *state p will be set to −1.If node uses a source probability profile provided by another node, then the function wi-ll retrieve the index of node state for an assembler program loaded into the latter node.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, for a detaileddescription of this mode.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_ILSEQ

The name of node state cannot be converted to a wide string according to thecurrent locale.

Chapter 5: Assembler Programs 171

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To retrieve the name of a node state by its index, the following function can be used.

[Function]int qsmm_get_node_state_name (qsmm t model, int node, int state,const char **state_name_pp )

This function sets *state name pp to a state name specified by the argument of an stt

instruction in an assembler program loaded into a node of multinode model. The state namecorresponds to state of the node. If state name pp is 0, then *state name pp will not beset. If state name pp is not 0, and there is no name assigned to the state in the assemblerprogram, then *state name pp will be set to 0.

If node uses a source probability profile provided by another node, then the function wi-ll retrieve the state name specified in an assembler program loaded into the latter node.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, for a detaileddescription of this mode.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of state is negative or is greater than or equal to the number of statesof a node with identifier node.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_ILSEQ

The name of node state cannot be converted to a multibyte string according tothe current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

5.9 Using Probability Variables

Probability variables are the means of changing a probability profile loaded into a node, retrievingprobabilities learned during the node training, and parametrizing instructions and probabilitieslists used in an assembler program. There are three kinds of variables supported: controlled,output, and auxiliary. Output and auxiliary probability variables were introduced in QSMM

version 1.15.

5.9.1 Variables in an Assembler Program

Probability variables must be defined in a ‘.data’ section of an assembler program. Everydefinition of a probability variable consists of a data label, which is the name of the variable,followed by the ‘prob’ keyword after one or more whitespace characters and by a variable value inthe range 0 to 1 (inclusive) after one or more whitespace characters. Fixed-point and exponentialnotations of specifying values of the variables are supported. A ‘.data’ section followed by a‘.code’ section may look like this:

.data

var_name_1 prob val1

var_name_2 prob val2

...

var_name_N prob valN

Chapter 5: Assembler Programs 172

.code

There can be multiple ‘.data’ sections defined in the program, e.g. within macros that areexpanded by the assembler preprocessor.

Names of probability variables previously defined in a ‘.data’ section can be used in jprob

and case instructions instead of fixed probability values:

jprob var_name, loc_label

case var_name, loc_label

For example, a choice instruction block may look like this:

choice

case var1, L1

case var2, L2

case 0.25, L3

case var1, L4

end choice

Names of probability variables can also be used in ‘probeq’ and ‘probls’ directives that defineprobabilities lists. See Section 5.10 [Using Probabilities Lists], page 183, for more informationon probabilities lists.

In a ‘probeq’ directive, which defines a probabilities list that contains equal elements, aprobability variable can be used as a second argument:

ls_name probeq length, var_name

In a ‘probls’ directive, which defines a probabilities list that contains specific elements,probability variables can be used as the elements of the list. An example ‘probls’ directive withsome list elements equal to values of probability variables may look like this:

ls1 probls var1, var1, var2, var2,

var3, var3, 0.05, 0.05

After converting the text of an assembler program to a memory representation of the program,the number of probability variables defined in the program can be obtained using the followingfunction.

[Function]int qsmm_get_prg_nvar (qsmm prg t prg )This function returns the number of probability variables defined in program prg using ‘prob’directives. The returned value is always non-negative.

To get the name of a probability variable by its index in the memory representation of anassembler program, the following function can be used.

[Function]const char * qsmm_get_prg_var_name (qsmm prg t prg, int var_idx )This function returns the name of a probability variable with index var idx in program prg.If var idx is negative or is greater than or equal to the number of probability variables definedin the program using ‘prob’ directives, then 0 will be returned.

5.9.2 Controlled Variables

Controlled probability variables are the means of changing a probability profile loaded intoa node. For example, the changing could be performed as a result of reasoning or self-programming.

Controlled probability variables that correspond to profile probabilities in the state transitionmatrix can only be used when the environment state identification engine is represented by asmall actor, which will take place when field is_large_env of structure qsmm_desc_s passed tofunction qsmm_create has zero value. Controlled probability variables that correspond to profile

Chapter 5: Assembler Programs 173

probabilities in the action emission matrix can only be used when the instruction emitting engineis represented by a small actor, which will take place when field is_large_opt of structureqsmm_desc_s has zero value.

Controlled probability variables must be registered in an instruction class set that representsa node class of the node. After registering the variables in the instruction class set, an assemblerprogram, which contains references to a subset of those variables in its text, can be loaded intothe node. Later, the application may change values of controlled probability variables of thenode, thus changing its probability profile. Changing values of the variables can be performedwhen processing invocation of specific instructions by event handler functions of instructionmeta-classes.

When changing the value of a controlled probability variable via API function calls, profi-le probabilities in the state transition matrix and/or in the action emission matrix, whichcorrespond to occurrences of jprob and case instructions, where that variable is used for aprobability, and to jump labels in arguments of casels instructions, for which that variablespecifies a probability, are updated accordingly.

To register a controlled probability variable in an instruction class set, the following functioncan be used.

[Function]int qsmm_reg_var_prob (qsmm t model, const char*instr_class_set_name, const char *var_name, int rez1 )

This function registers a controlled probability variable named var name in instruction classset instr class set name of multinode model. Argument rez1 is reserved for future use andmust be equal to 0.

On success, the function returns a non-negative index of the variable registered in theinstruction class set. On failure, a negative error code is returned. Currently, the followingerror codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_EXIST

Probability variable var name is already registered in instruction class setinstr class set name.

QSMM_ERR_VIOLNODE

There exist nodes that belong to a node class represented by instruction class setinstr class set name. Therefore, changing the structure of the instruction classset is not allowed.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOSYS

The environment state identification engine and the instruction emitting engineare represented by large actors.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

Currently, there are no QSMM API functions that take as an argument an index of variablereturned by function qsmm_reg_var_prob. Instead, functions, which query and set values of

Chapter 5: Assembler Programs 174

controlled probability variables, take the name of variable as an argument. To speed up queryingand setting values of the variables, in future versions of the library counterpart functions can beintroduced, to which the index of a variable instead of the name of the variable is passed.

To register a controlled probability variable when processing event QSMM_EVT_ENT_INIT bythe event handler function of instruction class set, the following macro can be used.

[Macro]QSMM_REG_VAR_PROB (var_name )This macro registers controlled probability variable var name. The macro is expanded to:

qsmm_reg_var_prob((qsmm), __FUNCTION__, (var_name), 0)

The macro is to be expanded from the event handler function of an instruction class set.The name of the event handler function must coincide with the name of the instruction classset, and normally it does coincide. There must be variable qsmm, which is a handle of themultinode model, defined in a function from which the macro is expanded. Normally, thatvariable is an argument of the event handler function.

To get names of controlled probability variables registered in an instruction class set, thefollowing function can be used.

[Function]int qsmm_enum_var_prob (qsmm t model, const char*instr_class_set_name, qsmm enum ent callback func t callback_func,void *paramp )

This function enumerates controlled probability variables that are registered in instructionclass set instr class set name of multinode model. The process of enumeration is a repeatedcalling callback function callback func, to which entity type QSMM_ENT_VAR_PROB, the nameof a controlled probability variable, and user parameter paramp are passed. The type of thecallback function is described in Section 4.17 [Enumerating Entities], page 127.

If the callback function returns a positive value, then the process of enumeration will becontinued. If the callback function returns zero, then the process of enumeration will beterminated, and function qsmm_enum_var_prob will report success. If the callback functionreturns a negative value, then the process of enumeration will be terminated, and functionqsmm_enum_var_prob will report failure.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

Instruction class set instr class set name does not exist.

QSMM_ERR_TYPE

An entity named instr class set name is not an instruction class set. The entityis an instruction meta-class.

QSMM_ERR_CALLBACK

The callback function did return an error.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To query or set the value of a controlled probability variable from an application program,the following functions can be used.

[Function]int qsmm_get_node_var_prob (qsmm t model, const char *var_name, intnode, double *valp )

This function sets *valp to the value of controlled probability variable var name of node ofmultinode model. If valp is 0, then *valp will not be set.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 5: Assembler Programs 175

QSMM_ERR_NOTFOUND

A node with identifier node or a controlled probability variable named var namedoes not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_set_node_var_prob (qsmm t model, const char *var_name, intnode, double val )

This function sets the value of controlled probability variable var name of a node of multinodemodel to val. However, the actual update of profile probabilities in the state transition matrixand/or in the action emission matrix of the node is not performed until function qsmm_node_

var_realize (described further on in this subsection) is called.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of val is not finite or is negative or is greater than 1.

QSMM_ERR_NOTFOUND

A node with identifier node or a probability variable named var name does notexist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

After loading an assembler program into a node, controlled probability variables associatedwith the node take on initial values defined in the assembler program.

It is allowed to set values of controlled probability variables declared in an instruction class set,but not defined in the assembler program. It is also allowed to set values of controlled probabilityvariables for a node, to which an assembler program was not loaded. Such assignments tovariables do not cause changing profile probabilities in the state transition matrix and theaction emission matrix of the node.

After assigning values to controlled probability variables by function qsmm_set_node_var_

prob, the actual update of profile probabilities in the state transition matrix and the actionemission matrix of the node can be performed using the following function.

[Function]int qsmm_node_var_realize (qsmm t model, int node, int rez1 )This function updates the state transition matrix and/or the action emission matrix of anode of multinode model according to assignments to controlled probability variables of thenode, which were previously made using function qsmm_set_node_var_prob, and then clearsthe queue of pending updates. Argument rez1 is reserved for future use and must be equalto 0.

For affected cycle types, values of field profile of structure qsmm_cycle_s are updated. Foraffected action choice states, values of fields nsig_pos and nsig_ctrl of structure qsmm_

state_s are updated.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

Chapter 5: Assembler Programs 176

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_PSUMGT1

The sum of probabilities of case instructions in a choice instruction block or thesum of elements of a probabilities list used by a casels instruction will exceed 1.This could leave the model instance in indeterminate state. If the model instanceis in indeterminate state, then after removing a reason of the error, the operationcan be repeated, and if the function succeeds, then the model instance state willbecome determinate.

QSMM_ERR_PROFSRCP

A node with identifier node is the source of probability profile for other nodes.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, formore information on this mode.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

To prevent relying on a rather weak concept of the mean number of actor’s output signalsdescribed in Section 2.13 [Other Parameters of an Actor], page 48, it is recommended to usecontrolled probability variables in a somewhat restricted way when they specify either determini-stic choices or do not change the number of choice alternatives if it is greater than 1. To achievethis, it is recommended to use jprob instructions when the potential number of choice alternati-ves is equal to 2 and use choice instruction blocks or casels instructions when the potentialnumber of choice alternatives is greater than 2. At all places in the assembler program wherethe choice is not deterministic, there should be used certain fixed number of choice alternativesgreater than 1.

Consider the following example with a jprob instruction:

user 0 ; a user instruction

jprob var0, L1

jmp L2

If the number of alternatives of non-deterministic choices at all places in the assemblerprogram is equal to 2, then correct values of controlled probability variable var0 will be 0,0.5, and 1. Value 0 specifies deterministic jump to location label L2, value 1 specifies determini-stic jump to location label L1, and value 0.5 provides two jump alternatives, which correspondsto the actual number of actor’s output signals equal to 2. The concept of the actual number ofoutput signals is described in Section 2.13 [Other Parameters of an Actor], page 48.

Consider the following example with a choice instruction block:

Chapter 5: Assembler Programs 177

user 0 ; a user instruction

choice

case var1, L1

case 0.25, L2

case var3, L3

case var4, L4

case var5, L5

case var6, L6

case var7, L7

end choice

jmp L8

Correct sets of values of controlled probability variables var1, var3, var4, var5, var6, andvar7 are the sets in which exactly two or three variables have values 0.25 and all other variableshave values 0. Such sets correspond to the actual number of actor’s output signals equal to4, which should be the number of alternatives of every non-deterministic choice made in theassembler program.

5.9.3 Output Variables

Output probability variables are used to retrieve probabilities learned during training a node.Variables of this kind need not be registered in the instruction class set. Information on outputprobability variables is automatically fetched from the memory representation of an assemblerprogram when loading the assembler program into a node by function qsmm_node_asm, to whi-ch the QSMM_ASM_VAR_OUT flag is passed. An output probability variable can be a controlledprobability variable.

Not every probability variable encountered in the memory representation of an assemblerprogram will be registered as an output probability variable of the node. The first restriction isthat the variable must be used in only one jprob or case instruction. The second restriction isthat the variable must be used in unambiguous context. If a probability variable violates at leastone of these restrictions, but is registered in the instruction class set as a controlled probabilityvariable, then it will be only a controlled probability variable. If the QSMM_ASM_VAR_AUX flagis passed to function qsmm_node_asm, a probability variable violates at least one of the aboverestrictions and is not registered in the instruction class set as a controlled probability variable,then it will be treated as an auxiliary variable. If the QSMM_ASM_VAR_AUX flag is not passed tofunction qsmm_node_asm, a probability variable violates at least one of the above restrictionsand is not registered in the instruction class set as a controlled probability variable, then anerror will be reported.

Every output probability variable corresponds either to the state transition matrix or to theaction emission matrix of a node. The type of a matrix is defined using an enumeration describedbelow. The enumeration is introduced in QSMM version 1.16.

[Enumeration]qsmm_mat_eThis enumeration specifies a type of matrix. It contains the following elements.

QSMM_MAT_GOTO

The state transition matrix.

QSMM_MAT_ACTION

The action emission matrix.

To get the type of a matrix, to which an output probability variable corresponds, a functiondescribed below can be used. The function is introduced in QSMM version 1.16.

Chapter 5: Assembler Programs 178

[Function]int qsmm_get_node_var_prob_mat (qsmm t model, const char *var_name,int node, enum qsmm mat e *mat_p )

This function sets *mat p to the type of a matrix, to which output probability variablevar name of node of multinode model corresponds. If mat p is 0, then *mat p will not beset. If node uses a source probability profile provided by another node, then there will beretrieved the type of a matrix of the output probability variable of the latter node.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node or an output probability variable named var namedoes not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To calculate the value of an output probability variable, there are calculated relative probabi-lities of all choice alternatives that include an alternative to which the probability variablecorresponds. After that, the relative probabilities are normalized to obtain values of outputprobability variables that correspond to the choice alternatives. Calculated values are cached.

An output probability variable might correspond to many cells of the state transition matrixof a node. When a type of probability to retrieve for the variable is QSMM_PROB_FQ, then fora relative probability, the sum of frequencies of transitions to target states stored in the cellswill be taken. When a type of probability to retrieve is not QSMM_PROB_FQ, then for a relativeprobability, the weighted mean of output probabilities in those cells will be taken. The weightsare the frequencies of transitions to target states stored in the cells. A situation when an outputprobability variable corresponds to several cells of the state transition matrix is illustrated bythe following fragment of an assembler program.

stt "s0"

test 3 ; user instruction with 3 outcomes

jprob var0, L2

stt "s1"

...

L2: stt "s2"

Instruction ‘test 3’ has three outcomes, but in the above fragment of an assembler programthey all are processed in the same way. The state transition matrix has rows for all outcomes ofthe instruction and columns for states ‘s0’, ‘s1’, and ‘s2’. The fragment of the state transitionmatrix is represented in Figure 5.1. There p denotes an output probability, ν denotes a frequencyof transition, and pp denotes a profile probability.

To calculate the value of output probability variable var0 of type QSMM_PROB_FQ, relativeprobabilities ν0,1+ν1,1+ν2,1 and ν0,2+ν1,2+ν2,2 are calculated, and ratio (ν0,2+ν1,2+ν2,2)/(ν0,1+ν1,1+ν2,1+ν0,2+ν1,2+ν2,2) is taken for the value. To calculate the value of the variable of a typeother than QSMM_PROB_FQ, relative probabilities (p0,1ν0,1+p1,1ν1,1+p2,1ν2,1)/(ν0,1+ν1,1+ν2,1) and(p0,2ν0,2+p1,2ν1,2+p2,2ν2,2)/(ν0,2+ν1,2+ν2,2) are calculated, and the second relative probabilitydivided by the sum of both relative probabilities is taken for the value.

Chapter 5: Assembler Programs 179

Figure 5.1: a fragment of state transition matrix for calculating the value of a variable

It should be noted that when an output probability variable corresponds to more than onecell of the state transition matrix, calculating output probabilities of types QSMM_PROB_LEARNTand QSMM_PROB_AGGR is performed by a rather bogus algorithm. Therefore, it is recommendedto avoid calculating output probabilities of those types or to use output probability variablesthat correspond to single cells of the state transition matrix. In many cases, output probabilitiesQSMM_PROB_LEARNT and QSMM_PROB_AGGR can be approximated by output probabilities QSMM_

PROB_FQ.

As it was said before, a probability variable used in more than one jprob or case instructioncannot be an output probability variable. The following fragment of an assembler programillustrates this.

L1: user 0 ; user instruction

jprob var0, L1 ; the first occurrence of variable ‘var0’

L2: user 1 ; user instruction

jprob var0, L2 ; the second occurrence of variable

; ‘var0’;

; encountering this occurrence means that

; variable ‘var0’ cannot be an output

; probability variable

jmp L1

As it was mentioned above, a probability variable used once, but in an ambiguous context,cannot be an output probability variable too. In the current implementation of the assembler,only jprob instructions can have ambiguous context. The context of a jprob instruction isambiguous when the instruction is included in blocks of jprob instructions that have differentstart addresses. Such situation is illustrated by the following fragment of an assembler program.

L1: user 0

jprob 0.5, L3

L2: jprob var0, L1

user 1

L3: user 2

jmp L2

After invoking instruction ‘user 0’, the selection of the next instruction to execute isperformed by a block that contains two instructions: ‘jprob 0.5, L3’ and ‘jprob var0, L1’.However, after invoking instruction ‘user 2’, the selection of the next instruction to execute isperformed only by the last instruction of that block. In the first case, the block begins withinstruction ‘jprob 0.5, L3’, and in the second case the block begins with instruction ‘jprob

Chapter 5: Assembler Programs 180

var0, L1’ (it contains only this instruction). That is, the blocks have different start addresses,a ‘jprob var0, L1’ instruction they contain occurs in the ambiguous context, and, therefore,variable var0 cannot be an output probability variable.

It is recommended to replace fixed profile probability values with output probability variablesonly in assembler programs for which no warnings are generated when loading them into nodes.Such assembler programs do not contain instructions used in ambiguous contexts. When theQSMM_ASM_VAR_OUT flag is passed to function qsmm_node_asm, all probability variables used onlyonce in such assembler programs become output probability variables.

To get names of output probability variables of a node, the following function can be used.

[Function]int qsmm_enum_var_prob_out (qsmm t model, int node,qsmm enum ent callback func t callback_func, void *paramp )

This function enumerates output probability variables defined in an assembler program loadedinto a node of multinode model. If node uses a source probability profile provided by anothernode, then there will be enumerated output probability variables of the latter node.

The process of enumeration is a repeated calling callback function callback func, to whi-ch entity type QSMM_ENT_VAR_PROB, the name of an output probability variable, and userparameter paramp are passed. See Section 4.17 [Enumerating Entities], page 127, for adescription of the type of the callback function.

If the callback function returns a positive value, then the process of enumeration will be conti-nued. If the callback function returns zero, then the process of enumeration will be termi-nated, and function qsmm_enum_var_prob_out will report success. If the callback functionreturns a negative value, then the process of enumeration will be terminated, and functionqsmm_enum_var_prob_out will report failure.

Function qsmm_enum_var_prob_out does not enumerate output probabilities arrays of thenode. An example program that enumerates those arrays for the memory representationof an assembler program is given in Section 5.10.3 [Getting Output Probabilities Arrays],page 185.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_CALLBACK

The callback function did return an error.

To retrieve the value of an output probability variable, the following function can be used.

[Function]int qsmm_get_node_var_prob_out (qsmm t model, const char *var_name,int node, enum qsmm prob e prob_type, double *valp )

This function sets *valp to a value of output probability variable var name of node of multi-node model. If valp is 0, then *valp will not be set. If valp is not 0, then value *valpretrieved will be a probability of type prob type. See Section 2.8 [Generating an OptimalAction], page 29, for a description of the elements of enumeration qsmm_prob_e.

If node uses a source probability profile provided by another node, then information on howto calculate the value of probability variable var name will be obtained from the latter node.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, for a detaileddescription of this mode.

If valp is not 0, and variable var name is a controlled or auxiliary probability variable usedmore than once in an assembler program loaded into node or into a node, which acts as asource of probability profile for node, or used in an ambiguous context in that assemblerprogram, then *valp will be set to −1.

Chapter 5: Assembler Programs 181

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of prob type is not a valid element of enumeration qsmm_prob_e.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist, or probability variable namedvar name is not defined in an assembler program loaded into node or into anode that acts as a source of probability profile for node.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

Output probabilities, which correspond to case instructions in choice instruction blocks, canbe retrieved via output probability variables used in case instructions or as output probabilitiesarrays referenced by location labels assigned to choice instruction blocks. The contents ofoutput probabilities arrays, which correspond to casels instructions and choice instructionblocks, are fetched by function qsmm_get_node_array_prob_out described in Section 5.10.3[Getting Output Probabilities Arrays], page 185.

In QSMM version 1.16, there are introduced functions for fetching aggregate statistics forcycle types that correspond to output probability variables and elements of output probabilitiesarrays. The statistics are aggregate in the sense that when an output probability variable or anelement of output probabilities array correspond to the state transition matrix of a node, thestatistics are composed of statistics for cycle types in all matrix cells, which are associated withthe variable or the array element. When an output probability variable or an element of outputprobabilities array correspond to the action emission matrix of a node, aggregate statistics aresimply the statistics for a cycle type in a matrix cell associated with the variable or the arrayelement.

To fetch aggregate statistics for cycle types associated with an output probability variable, afunction described below can be used. For a description of a function for fetching aggregate stati-stics for cycle types associated with an element of output probabilities array, see Section 5.10.3[Getting Output Probabilities Arrays], page 185.

[Function]int qsmm_get_node_var_prob_cycle (qsmm t model, const char*var_name, int node, struct qsmm cycle s *cycle_p, struct qsmm cspur s*cspur_p )

This function fetches aggregate statistics on cycle types that correspond to output probabilityvariable var name of node of multinode model. If cycle p is not 0, then *cycle p will be set

Chapter 5: Assembler Programs 182

to aggregate statistics on the cycle types. If cspur p is not 0, then *cspur p will be set toaggregate statistics on spur types for the cycle types. Structures qsmm_cycle_s and qsmm_

cspur_s are described in Section 3.2 [Structures for Accessing Storage], page 58.

If cspur p is not 0 and the output probability variable corresponds to the state transitionmatrix of the node, then array cspur p must be capable of holding the number of elementsreturned for the multinode model by function qsmm_get_nspur. If cspur p is not 0 and theoutput probability variable corresponds to the action emission matrix of the node, thenarray cspur p must be capable of holding the number of elements returned by functionqsmm_get_nspur minus 1. The type of a matrix, to which the output probability variablecorresponds, can be obtained using function qsmm_get_node_var_prob_mat described earlierin this subsection.

Aggregate statistics on the cycle types are computed in the following way. Values of fieldsfq, period_sum_d, and period_sum_c of *cycle p are the sums of values of those fields ininstances of structure qsmm_cycle_s, which correspond to cycle types associated with theoutput probability variable. The value of cycle p->profile is computed by calling functionqsmm_get_node_var_prob_out and passing QSMM_PROB_PROFILE for a type of probability toretrieve. Values of field delta_sum of elements of array cspur p are the sums of values ofthat field of corresponding elements, which contain statistics on spur types for cycle typesassociated with the output probability variable.

If node uses a source probability profile provided by another node, then information on howto calculate the aggregate statistics will be obtained from the latter node. See Section 5.12[Memory Efficient Cloning a Probability Profile], page 191, for a detailed description of thismode.

On success, the function returns a non-negative number of cycle types that were used to makeup the aggregate statistics. On failure, the function returns a negative error code. Currently,the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node or an output probability variable named var namedoes not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

When retrieving values of particular output probability variables, values of associated outputprobability variables can be implicitly calculated. All values of output probability variablescalculated for a node are stored in a values cache created within the node. The cache is destroyedautomatically by functions qsmm_node_call_default (see Section 4.8 [Transferring Control

Chapter 5: Assembler Programs 183

Between Nodes], page 109) and qsmm_node_unload (see Section 5.13 [Unloading a ProbabilityProfile], page 194) invoked for the node, after disassembling the node if it is assembled with theQSMM_ASM_TEMPLATE flag, and when destroying the model instance. For conserving memory, thecache can be destroyed manually by the following function.

[Function]int qsmm_node_var_out_forget (qsmm t model, int node )This function destroys the cache of values of output probability variables and arrays of node ofmultinode model. The cache is used by functions qsmm_get_node_var_prob_out and qsmm_

get_node_array_prob_out to speed up fetching output probability variables and arrays ofthe node.

On success, a non-negative value is returned. If a node with identifier node does not exist,then negative error code QSMM_ERR_NOTFOUND will be returned.

5.9.4 Auxiliary Variables

Auxiliary probability variables are probability variables, which are neither controlled nor outputones and which are used in assembler programs merely for convenience purposes. Auxiliaryprobability variables are replaced with their values specified in ‘prob’ directives at the time ofloading an assembler program into a node. Information on auxiliary probability variables is notstored in a node, and they cannot be accessed after loading an assembler program into the node.

To load the memory representation of an assembler program, which contains auxiliaryprobability variables, into a node, you need to pass the QSMM_ASM_VAR_AUX flag to functionqsmm_node_asm. The use of a probability variable in an assembler program will not raise anerror if the probability variable is the controlled and/or the output one, or if the QSMM_ASM_VAR_AUX flag is passed to function qsmm_node_asm. Note that controlled probability variables mustbe registered in the instruction class set, and to enable the use of output probability variables,you need to pass the QSMM_ASM_VAR_OUT flag to function qsmm_node_asm.

5.10 Using Probabilities Lists

Probabilities lists are syntactical constructions that help to reduce clutter in assembler programsby making them shorter and simpler. To a probabilities list used in a casels instruction theremay correspond an output probabilities array, with the help of which learned probabilitiesassociated with profile probabilities specified by elements of the probabilities list can be fetchedafter training a node. Probabilities lists were introduced in QSMM version 1.15.

5.10.1 Defining Probabilities Lists

Probabilities lists are defined in a ‘data’ section of an assembler program.

A definition of probabilities list might contain names of controlled probability variables.Names of such variables can be present in the definition of a probabilities list used in casels

instructions, which specify profile probabilities in the state transition matrix, only when theenvironment state identification engine is represented by a small actor. Names of controlledprobability variables can be present in the definition of a probabilities list used in casels

instructions, which specify profile probabilities in the action emission matrix, only when theinstruction emitting engine is represented by a small actor.

A probabilities list, which contains equal probabilities, can be defined using a ‘probeq’ di-rective that must be written in one of the following forms:

ls_name probeq length

ls_name probeq length, fixed_prob

ls_name probeq length, var_name

All three forms define a probabilities list named ls name that contains length elements.The first form defines the probabilities list with all elements equal to 1/(length+1). The

Chapter 5: Assembler Programs 184

second form defines the probabilities list with all elements equal to number fixed prob, wherelength*fixed prob must be less than or equal to 1. Number fixed prob must be specified eitherin fixed-point or exponential notation. The third form defines the probabilities list with allelements equal to the value of a probability variable named var name that must be previouslydefined using a ‘prob’ directive.

Probability variable var name might be a controlled or auxiliary probability variable.Expression length*var name must be less than or equal to 1 for an initial value of probabi-lity variable var name specified in the ‘prob’ directive. If var name is a controlled probabilityvariable, to which a value is assigned that makes expression length*var name be greater than1, then function qsmm_node_var_realize will raise error QSMM_ERR_PSUMGT1 when trying toupdate profile probabilities, which correspond to a casels instruction that uses probabilitieslist ls name.

A probabilities list, which contains explicitly specified probabilities, can be defined using a‘probls’ directive that has the following syntax:

ls_name probls prob1, prob2, ..., probN

The probabilities list will have name ls name and contain elements prob1, prob2, ..., probN,where each element can be a number or the name of a probability variable previously definedusing a ‘prob’ directive. Numeric elements of probabilities list can be specified either in fixed-point or exponential notation.

The elements list can be splitted into multiple lines. To indicate that a line of elements listis continued on the next line, terminate a line, which is continued, with a comma after the lastelement on the line. This is shown in the following example:

ls2 probls 0.04, var1, 0.02, 0.02,

0.08, 0.08, var2, var2,

var3, 0.06, 0.06, 0.04

The sum of elements of a probabilities list, which contains explicitly specified probabilities,should be less than or equal to 1. If the sum of an element of a probabilities list and elementslocated earlier in the list exceeds 1, then the element will be discarded when parsing the assemblerprogram. If an element is the name of a probability variable, then for the value of the elementthere will be taken an initial value of the variable specified in the ‘prob’ directive.

As for the ‘probeq’ directive, probability variables used in arguments of the ‘probls’ directivecan be controlled or auxiliary probability variables. If to controlled probability variables, whichare used as elements of a probabilities list, there are assigned values that make the sum of allelements of the probabilities list be greater than 1, then function qsmm_node_var_realize willraise error QSMM_ERR_PSUMGT1 when trying to update profile probabilities, which correspond toa casels instruction that references the probabilities list.

5.10.2 Referencing Probabilities Lists

Probabilities lists are used in casels instructions. See Section 5.3.4 [casels Instruction], page 146,for more information. For example, a casels instruction, which uses probabilities list ls2 definedin the previous subsection, might look like this:

casels ls2,

L1, L2, L3, L4, L5, L6,

L7, L8, L9, L10, L11, L12

If the QSMM_ASM_TEMPLATE flag is passed to function qsmm_node_asm, then to support includi-ng in a disassembled program the values of output probabilities, which correspond to jumplabels in arguments of casels instructions, all those instructions encountered in the memoryrepresentation of the assembler program will be converted to choice instruction blocks. Theexception is that when a casels instruction uses a probabilities list, which contains only oneelement, the instruction will be converted to a jprob instruction.

Chapter 5: Assembler Programs 185

5.10.3 Getting Output Probabilities Arrays

An output probabilities array, which corresponds to a casels instruction or a choice instructionblock, is referenced using one of location labels assigned to the instruction or the instructionblock. A casels instruction and a choice instruction block with such location labels assignedmight look like these:

LS1: casels ls1, L1, L2, L3, L4, L5, L6, L7, L8

LS2: choice

case 0.15, L1

case 0.05, L2

case 0.10, L3

case 0.20, L4

end choice

In these examples there are defined two output probabilities arrays: LS1 and LS2. Array elementscorrespond to jump labels specified in arguments of the casels instruction and to case instructi-ons within the choice instruction block.

Every output probabilities array corresponds either to the state transition matrix or to theaction emission matrix of a node. To get the type of a matrix, to which an output probabilitiesarray corresponds, a function described below can be used. The function is introduced in QSMM

version 1.16.

[Function]int qsmm_get_node_array_prob_mat (qsmm t model, const char *label,int node, enum qsmm mat e *mat_p )

This function sets *mat p to the type of a matrix, to which an output probabilities array ofnode of multinode model corresponds. A location label assigned to a casels instruction or achoice instruction block specifies the array. If mat p is 0, then *mat p will not be set. SeeSection 5.9.3 [Output Variables], page 177, for a description of the elements of enumerationqsmm_mat_e. If node uses a source probability profile provided by another node, then therewill be retrieved the type of a matrix of the output probabilities array of the latter node.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node or output probabilities array label does not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

To get the contents of a segment of output probabilities array, the following function can beused.

[Function]int qsmm_get_node_array_prob_out (qsmm t model, const char *label,int node, int from, int to, enum qsmm prob e prob_type, double *prob_p )

This function fetches the contents of an output probabilities array of node of multinodemodel.A location label assigned to a casels instruction or a choice instruction block specifies thearray. If prob p is not 0, then output probabilities of type prob type will be copied fromthe array to a buffer pointed by prob p. See Section 2.8 [Generating an Optimal Action],page 29, for a description of the elements of enumeration qsmm_prob_e.

Chapter 5: Assembler Programs 186

Arguments from and to can be both zero (which is not recommended) or may specify indicesof the first element (inclusive) and of the last element (exclusive) of a segment of outputprobabilities array, the contents of which should be fetched to buffer prob p. If to is 0, thenthe length of the output probabilities array will be used as an index (incremented by 1) ofthe last element of the segment. A special element of the output probabilities array at indexequal to the length of the array corresponds to a choice alternative just after the casels

instruction or the choice instruction block, to which control is transferred when no jumpto one of location labels specified in the casels instruction or case instructions within thechoice instruction block is made.

If node uses a source probability profile provided by another node, then information on howto fetch the contents of output probabilities array label will be obtained from the latter node.See Section 5.12 [Memory Efficient Cloning a Probability Profile], page 191, for a detaileddescription of this mode.

On success, the function returns a non-negative number of elements written to buffer prob p.On failure, a negative error code is returned. Currently, the following error codes can bereturned.

QSMM_ERR_INVAL

The value of prob type is not a valid element of enumeration qsmm_prob_e, orthe value of from is negative or is greater than or equal to an index (incrementedby 1) of the last element of the segment of the output probabilities array, or thevalue of to is negative or is greater than the length of the output probabilitiesarray plus 1.

QSMM_ERR_NOTFOUND

A node with identifier node or output probabilities array label does not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

In QSMM version 1.16 there is introduced a function for fetching aggregate statistics on cycletypes associated with an element of output probabilities array. A description of the function isgiven below. See Section 5.9.3 [Output Variables], page 177, for a description of the correspondi-ng function for fetching aggregate statistics on cycle types associated with an output probabilityvariable and for additional information on the concept of aggregate statistics.

Chapter 5: Assembler Programs 187

[Function]int qsmm_get_node_array_prob_cycle (qsmm t model, const char*label, int node, int offs, struct qsmm cycle s *cycle_p, struct qsmm cspur s*cspur_p )

This function fetches aggregate statistics on cycle types that correspond to an element of anoutput probabilities array of node of multinode model. A location label assigned to a casels

instruction or a choice instruction block specifies the array.

The index of the element of the array is specified by offs. A special element of the arrayat index equal to the length of the array corresponds to a choice alternative just after thecasels instruction or the choice instruction block, to which control is transferred when nojump to one of location labels specified in the casels instruction or case instructions withinthe choice instruction block is made.

If cycle p is not 0, then *cycle p will be set to aggregate statistics on the cycle types. Ifcspur p is not 0, then *cspur p will be set to aggregate statistics on spur types for the cycletypes. Structures qsmm_cycle_s and qsmm_cspur_s are described in Section 3.2 [Structuresfor Accessing Storage], page 58.

If cspur p is not 0 and the output probabilities array corresponds to the state transitionmatrix of the node, then array cspur p must be capable of holding the number of elementsreturned for the multinode model by function qsmm_get_nspur. If cspur p is not 0 and theoutput probabilities array corresponds to the action emission matrix of the node, then arraycspur p must be capable of holding the number of elements returned by function qsmm_get_

nspur minus 1. The type of a matrix, to which the output probabilities array corresponds,can be obtained using function qsmm_get_node_array_prob_mat described earlier in thissubsection.

Aggregate statistics on the cycle types is computed in the following way. Values of fieldsfq, period_sum_d, and period_sum_c of *cycle p are the sums of values of those fields ininstances of structure qsmm_cycle_s, which correspond to cycle types associated with theelement of output probabilities array. The value of cycle p->profile is computed by callingfunction qsmm_get_node_array_prob_out for the element of output probabilities array andpassing QSMM_PROB_PROFILE for a type of probability to retrieve. Values of field delta_sum

of elements of array cspur p are the sums of values of that field of corresponding elements,which contain statistics on spur types for cycle types associated with the element of outputprobabilities array.

If node uses a source probability profile provided by another node, then information on howto calculate the aggregate statistics will be obtained from the latter node. See Section 5.12[Memory Efficient Cloning a Probability Profile], page 191, for a detailed description of thismode.

On success, the function returns a non-negative number of cycle types that were used to makeup the aggregate statistics. On failure, the function returns a negative error code. Currently,the following error codes can be returned.

QSMM_ERR_INVAL

The value of offs is negative or is greater than the length of the output probabi-lities array.

QSMM_ERR_NOTFOUND

A node with identifier node or output probabilities array label does not exist.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

Chapter 5: Assembler Programs 188

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

When retrieving the contents of a segment of output probabilities array of a node, expli-citly and implicitly calculated probability values are stored in the values cache created wi-thin the node. In certain situations, the cache is destroyed automatically, but it can also bedestroyed manually by function qsmm_node_var_out_forget. See Section 5.9.3 [Output Vari-ables], page 177, for more information on the cache of values of output probability variables andarrays of node.

If there is a need to dump the contents of all output probabilities arrays defined in anassembler program, then only instructions of types QSMM_INSTR_CHOICE and QSMM_INSTR_

CASELSmust be considered. The type of an instruction specified by its handle can be obtained byfunction qsmm_get_instr_type. If the instruction has at least one location label assigned, thenthere will be an output probabilities array associated with that instruction. The first locationlabel, which identifies the output probabilities array, can be retrieved by call qsmm_get_instr_label(instr,0), where instr is an instruction handle. When 0 is returned, the instructiondoes not have location labels assigned.

For an instruction of type QSMM_INSTR_CHOICE, the length of an output probabilities arrayassociated with the instruction is equal to a value returned by function qsmm_get_instr_

nnested for that instruction minus 1 (the last nested instruction is the ‘end choice’ instruction).For an instruction of type QSMM_INSTR_CASELS, the length of the output probabilities array isequal to the length of probabilities list returned by function qsmm_get_prg_ls_nprob. Thename of probabilities list, which should be passed to that function, can be retrieved by functionqsmm_get_instr_ls_name for the instruction handle.

An example function that dumps the contents of all output probabilities arrays of a node

into which assembler program prg was loaded is given below. The function returns 0 on successor −1 on out of memory error.

#include <stdlib.h>

#include <qsmm/qsmm.h>

static int dump_prob_out_arrays(qsmm_t qsmm,

int node,

qsmm_prg_t prg,

enum qsmm_prob_e prob_type) {

int ii, jj, ninstr, prob_allo=1, result=-1;

double *probp=calloc(prob_allo,sizeof(*probp));

if (!probp) goto Exit;

ninstr=qsmm_get_prg_ninstr(prg);

for (ii=0; ii<ninstr; ii++) {

const char *label;

int nprob;

qsmm_instr_t instr=qsmm_get_prg_instr(prg,ii);

Chapter 5: Assembler Programs 189

if (!(label=qsmm_get_instr_label(instr,0))) continue;

switch (qsmm_get_instr_type(instr)) {

case QSMM_INSTR_CHOICE:

nprob=qsmm_get_instr_nnested(instr)-1;

break;

case QSMM_INSTR_CASELS:

nprob=qsmm_get_prg_ls_nprob(

prg, qsmm_get_instr_ls_name(instr));

break;

default:

continue;

}

if (prob_allo<nprob) {

double *newp;

if (!(newp=realloc(probp,nprob*sizeof(*newp)))) goto Exit;

prob_allo=nprob;

probp=newp;

}

qsmm_get_node_array_prob_out(qsmm, label, node, 0, nprob,

prob_type, probp);

for (jj=0; jj<nprob; jj++)

printf("%s[%d]=%.15E\n",label,jj,probp[jj]);

}

result=0;

Exit:

if (probp) free(probp);

return result;

}

5.11 Cloning a Probability Profile

When there is a need to load the same probability profile into multiple nodes, an assemblerprogram can be loaded into one node, and then the probability profile can be copied to othernodes. In QSMM, the process of copying a probability profile from a node to another one iscalled cloning a probability profile. Cloning a probability profile from a node to other nodes isfaster than loading the same assembler program into them.

To clone a probability profile, the following function can be used.

[Function]int qsmm_node_profile_clone (qsmm t model, int node_from, intnode_to, unsigned int flags )

This function copies a probability profile from node node from of multinode model to nodenode to of the model. The function clears statistics on the event history that might havebeen collected for node node to. If node node to already has a probability profile loaded,then that profile along with additional information, which might be copied by this function(see a description of argument flags below), will be first unloaded. To clear statistics on theevent history and to unload the profile, function qsmm_node_unload described in Section 5.13[Unloading a Probability Profile], page 194 is implicitly called. Probability profiles manuallywritten to storage without prior calling function qsmm_node_asm cannot be copied by functionqsmm_node_profile_clone.

Argument flags is a bitmask, which specifies types of additional information that should becopied from node node from to node node to along with the probability profile. Bits of the

Chapter 5: Assembler Programs 190

bitmask, which are taken into account, are represented by the following macros that can bemerged by bitwise “or.”

[Macro]QSMM_NODE_CLONE_VARSCopy definitions of controlled and output probability variables and arrays, so values ofcontrolled probability variables of node node to can be set, and values of output probabi-lity variables and arrays of that node can be retrieved, as they can be set and retrievedfor node node from. Before copying the definitions of controlled probability variables,function qsmm_node_var_realize is implicitly called for node node from if that node hasuncommitted assignments to those variables.

[Macro]QSMM_NODE_CLONE_STATE_NAMESCopy names assigned to node states by arguments of stt instructions. You will be ableto retrieve that information for node node to by functions qsmm_get_node_state_name

and qsmm_get_node_state_by_name and use that information when disassembling nodenode to and dumping the state transition matrix and the action emission matrix of nodenode to.

[Macro]QSMM_NODE_CLONE_TEMPLATEIf node node from has an assembler program template associated with it, then copy thattemplate. The template will be used when disassembling node node to.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of node from is equal to the value of node to.

QSMM_ERR_NOTFOUND

A node with identifier node from or node to does not exist.

QSMM_ERR_NOSTATE

A node with identifier node to has the number of states less than it is requiredto hold the probability profile of a node with identifier node from.

QSMM_ERR_NOSAMENC

Instruction class sets that represent node classes, to which nodes node from andnode to belong, are not the same.

QSMM_ERR_NOPROF

A probability profile is not loaded into a node with identifier node from.

QSMM_ERR_PROFSRCU

A node with identifier node from is a user of a source probability profile providedby another node.

QSMM_ERR_PROFSRCP

One of the following conditions is met:

– a node with identifier node to is a source of probability profile for othernodes;

– function qsmm_node_var_realize was implicitly called, and it turned outthat a node with identifier node from is a source of probability profile forother nodes.

QSMM_ERR_PSUMGT1

Function qsmm_node_var_realize was implicitly called for node node from, andit turned out that the sum of probabilities of case instructions in a choice

Chapter 5: Assembler Programs 191

instruction block or the sum of elements of a probabilities list used by a casels

instruction will exceed 1 if assignments to controlled probability variables arecommitted. This could leave the model instance in indeterminate state. If themodel instance is in indeterminate state, then after removing a reason of theerror, the operation can be repeated, and if the function succeeds, then themodel instance state will become determinate.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

5.12 Memory Efficient Cloning a Probability Profile

The QSMM framework supports a mechanism of deferred copying a probability profile fromone node to another node when no memory is consumed during the copying operation itself.The deferred copying operation only sets a correspondence between two nodes, where one nodebecomes a source of a probability profile and another node becomes a user of that probabilityprofile. A node can be a source of probability profile for multiple other nodes. Applyingdeferred copying operation makes sense when the memory is allocated dynamically, i.e. whenthe multinode model uses map storage for holding statistics collected over the event history.The longer gets the event history the same efficiency of memory consumption is provided in casewhen there is no probability profile loaded into a node and in case when the node is a user of asource probability profile provided by another node.

The deferred copying mechanism works in the following way. Information on a probabilityprofile is stored in instances of structures qsmm_state_s and qsmm_cycle_s as described inSection 3.2 [Structures for Accessing Storage], page 58. Statistics collected over the event historyis also stored in those instances. However, initially there is no statistics collected for a node,which acts as a user of probability profile1, so the default statistics can be used when needed.Information on a probability profile for that node can be obtained using redirection, i.e. takenfrom another part of storage that corresponds to a node, which serves as a source of probabilityprofile. When the event history gets longer, and there is a need to update statistics for aparticular action choice state or cycle type, the corresponding instance of structure qsmm_state_s or qsmm_cycle_s is allocated in storage. Information on a probability profile is copied therefrom another part of storage, and updated statistics is written there. Later, the information ona probability profile will be read from the allocated instance directly.

Values of controlled probability variables defined in an assembler program loaded into a nodethat serves as a source of a probability profile can be changed for a node, which acts as a user of

1 Statistics is automatically unloaded from a node, which becomes a user of probability profile, when there isset a correspondence for that node with a node, which acts as a source of probability profile.

Chapter 5: Assembler Programs 192

that probability profile, in the ordinary way. Information on how elements of the state transitionmatrix and the action emission matrix of the latter node should be updated when changing thevalues of controlled probability variables for that node is taken from the former node. Changingvalues of probability variables causes allocation of corresponding instances of structures qsmm_state_s and qsmm_cycle_s in storage for the latter node if they are not allocated yet.

The following information stored in a node, which serves as a source of a probability profile,becomes automatically available for a node, which acts as a user of that probability profile.

• Information on output probability variables and arrays collected when loading an assemblerprogram into the former node. That information will be used by functions qsmm_

get_node_var_prob_out, qsmm_get_node_array_prob_out, qsmm_get_node_var_prob_

cycle, qsmm_get_node_array_prob_cycle, qsmm_get_node_var_prob_mat, qsmm_get_

node_array_prob_mat, and qsmm_enum_var_prob_out called for the latter node.

• Names assigned to states of an assembler program loaded into the former node. Informationabout state names can be retrieved by functions qsmm_get_node_state_name and qsmm_

get_node_state_by_name called for the latter node and can be used when disassemblingthat node and dumping the state transition matrix and the action emission matrix of thelatter node.

• An assembler program template, which might have been associated with the former node.The template will be automatically applied when disassembling the latter node.

The following operations cannot be performed on a node that serves as a source of probabilityprofile for other nodes:

– loading an assembler program into the node by function qsmm_node_asm;

– copying a probability profile to the node by function qsmm_node_profile_clone;

– setting the node as a user of a probability profile provided by another node using functionqsmm_set_node_profile_source;

– unloading a probability profile from the node by function qsmm_node_unload;

– destroying the node by function qsmm_node_destroy;

– committing assignments to probability variables of the node by function qsmm_node_var_

realize.

The following operations cannot be performed on a node that acts as a user of a probabilityprofile provided by another node:

– setting the node as the source of probability profile for other nodes;

– cloning a probability profile from the node to another node by function qsmm_node_

profile_clone;

– setting the number of node states by function qsmm_set_node_nstate.

When dumping the state transition matrix or the action emission matrix, or when disassembli-ng a node, which is a user of a probability profile provided by another node, keep in mind thatnot all probabilities of type QSMM_PROB_PROFILE may yet be copied from a node, which servesas a source of the probability profile. Because the collection of probabilities can be incomplete,calculating probabilities of that type for a node, which is a user of probability profile, is notrecommended.

When the deferred copying mechanism is used for some nodes of a multinode model, thisslows down all access operations to storage, which is used by the model, approximately twice(even for other nodes of the model).

To set a correspondence between two nodes of a multinode model, where one node becomesthe source of a probability profile and another node becomes a user of that probability profile,the following function can be used.

Chapter 5: Assembler Programs 193

[Function]int qsmm_set_node_profile_source (qsmm t model, int node_from, intnode_to, int rez1 )

This function sets node node from of multinode model as the source of a probability profileand sets node node to of the model as a user of that probability profile. Argument rez1 isreserved for future use and must be equal to 0.

The function clears statistics on the event history that might have been collected for nodenode to. If node node to has a probability profile loaded, then that profile along withinformation, which depends on the profile, will be unloaded. To clear statistics on the eventhistory and to unload the profile, function qsmm_node_unload described in the next sectionis implicitly called.

If node node from has uncommitted assignments to controlled probability variables, thenfunction qsmm_node_var_realize will be implicitly called for that node.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of node from is equal to the value of node to.

QSMM_ERR_NOTFOUND

A node with identifier node from or node to does not exist.

QSMM_ERR_NOSTATE

A node with identifier node to has the number of states less than it is requiredto hold the probability profile of a node with identifier node from.

QSMM_ERR_NOSAMENC

Instruction class sets that represent node classes, to which nodes node from andnode to belong, are not the same.

QSMM_ERR_NOPROF

A probability profile is not loaded into a node with identifier node from.

QSMM_ERR_PROFSRCU

A node with identifier node from is a user of a source probability profile providedby another node.

QSMM_ERR_PROFSRCP

One of the following conditions is met:

– a node with identifier node to is a source of probability profile for othernodes;

– function qsmm_node_var_realize was implicitly called, and it turned outthat a node with identifier node from is already a source of probability profilefor other nodes.

QSMM_ERR_PSUMGT1

Function qsmm_node_var_realize was implicitly called for node node from, andit turned out that the sum of probabilities of case instructions in a choice

instruction block or the sum of elements of a probabilities list used by a casels

instruction will exceed 1 if assignments to controlled probability variables arecommitted. This could leave the model instance in indeterminate state. If themodel instance is in indeterminate state, then after removing a reason of theerror, the operation can be repeated, and if the function succeeds, then themodel instance state will become determinate.

QSMM_ERR_UNTIMELY

The model instance does not exist.

Chapter 5: Assembler Programs 194

QSMM_ERR_UNSUPPLA

The multinode model has positive length of the look-ahead signal segment.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

A correspondence between a node, which is the source of a probability profile, and a node,which is a user of that probability profile, can be broken off by function qsmm_node_unload

described in the next section.

5.13 Unloading a Probability Profile

To unload statistics and a probability profile from a node, the following function can be used.

[Function]int qsmm_node_unload (qsmm t model, int node )This function performs the following operations on node of multinode model:

– if node is a user of probability profile, then break off a correspondence with a node,which is the source of probability profile;

– unload statistics collected over the event history for the node;

– unload a node probability profile;

– if an assembler program is loaded into the node, then unload information on controlledand output probability variables defined in the assembler program;

– if an assembler program is loaded into the node, then unload information about namesassigned to states of the assembler program;

– unload an assembler program template used for disassembling;

– destroy the cache of values of output probability variables.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_NOTFOUND

A node with identifier node does not exist.

QSMM_ERR_PROFSRCP

A node with identifier node is a source of probability profile for other nodes.

QSMM_ERR_UNTIMELY

The model instance does not exist.

QSMM_ERR_STORAGE

Statistics storage failure. This could leave the model instance in indeterminatestate. If the model instance is in indeterminate state, then after removing areason of the error, the operation can be repeated, and if the function succeeds,then the model instance state will become determinate.

Chapter 5: Assembler Programs 195

QSMM_ERR_NOMEM

There was not enough memory to perform the operation. This could leave themodel instance in indeterminate state. If the model instance is in indeterminatestate, then after removing a reason of the error, the operation can be repeated,and if the function succeeds, then the model instance state will become determi-nate.

5.14 Using the Assembler Preprocessor

The assembler preprocessor, which is part of the QSMM framework, was primarily developed toprovide the means of encapsulating similar blocks of assembler source code in macros that canbe reused in an assembler program. Macros can define nested control transfer structures andproduce unique location labels when expanded. The preprocessor also provides the means ofincluding other files in an assembler source file.

The assembler preprocessor returns a single output buffer with a text of preprocessedprogram. The contents of all included source files are copied explicitly to the preprocessedoutput. The preprocessed output might contain ‘line’ directives that describe source locations,which could be indicated in error, warning, and note messages generated by the assembler. Thepreprocessor also merges string literals on a line, which go one after another and are delimitedby zero or more whitespace characters, into a single string literal.

When performing transformations of the source text, the assembler preprocessor may breakalignment of multiline comments. This may prevent proper detection by the assembler whethera multiline comment is continued on the next line, and comments may be assigned to someinstructions incorrectly. At present, this cannot be generally avoided.

The assembler preprocessor provides only basic features necessary to work with symbols andmacros. If you need more sophisticated features to produce the source text of an assemblerprogram, then either generate input to the preprocessor using an auxiliary function, program,or a script, or create an assembler program, which does not require preprocessing, by thosemeans directly. Example C programs that generate input to the assembler preprocessor, whichis then converted to an assembler program and loaded into a node, are described in Section 7.8[asmat], page 255, Section 7.9 [tohuff-test], page 256, and Section 7.11 [predict-test], page 262.

5.14.1 Changing Line Number and File Name

To change current line number and possibly the name of the current source file beingpreprocessed, which are tracked by the assembler preprocessor, with emitting a correspondi-ng ‘line’ directive to the preprocessed output for subsequent interpreting by the assembler, usethe ‘line’ directive of the assembler preprocessor. Additionally, information changed by the‘line’ directive is used when generating error and note messages by the assembler preprocessor.

The directive must be placed on a separate line (after one or more whitespace characters atthe beginning of the line) and must be in one of the following formats:

line line_number

line line_number, file_name

In the first case, the directive changes the number of the next line in the current sourcefile to line number. In the second case, the directive changes the number of the next line toline number and the name of current source file to file name. The value of file name must be a(quoted) string literal.

5.14.2 Including Other Source Files

To include another source file in an assembler source file, use the ‘include’ directive:

include string_literal

Chapter 5: Assembler Programs 196

Argument string literal specifies a (quoted) full or relative path to an included file. A relativepath is interpreted by using for the base directory a directory that contains a file with the‘include’ directive, a base directory specified as a parameter of preprocessing if the name ofthat file is unknown, or current working directory if the base directory is not specified as aparameter of preprocessing. The directive must be written on a separate line after one or morewhitespace characters. The directive must not occur within a macro definition. The maximumnesting level of ‘include’ directives is equal to 100.

5.14.3 Defining Symbols

To define or redefine a symbol, use the ‘def’ directive:

name def value

This statement defines or redefines symbol name to value. A symbol name must start at thebeginning of a line. A symbol value must not contain commas not within string literals.

There are two possible scopes of a symbol: global and local. Global symbols are those definednot within macros. If the ‘def’ directive within a macro is used for symbol name, which hasbeen defined as a global one, then that global symbol will be redefined to a new value.

Local symbols are those defined within macros. Macro arguments are also got implicitlydefined as local symbols. Local symbols are not visible outside of macros where they weredefined. If the ‘def’ directive within a macro is used for symbol name, which has been definedas a local one, then that local symbol will be redefined to a new value.

If the name of a symbol occurs as a token in the text in the scope of that symbol, then thattoken will be replaced with a symbol value. If the symbol value has to be concatenated withadjacent tokens, then prepend and/or append characters ‘##’ to the symbol name token.

For example, source text

st def 01

choice

case a##st##_00, l##st##_00

case a##st##_01, l##st##_01

end choice

jmp l##st##_02

will be preprocessed to text

choice

case a01_00, l01_00

case a01_01, l01_01

end choice

jmp l01_02

When a symbol value is a verbatim text, to convert the symbol value to a string literal,prepend character ‘#’ to the symbol name token. For example, source text

id def 5

s##id: stt #id

will be preprocessed to text

s5: stt "5"

Names of symbols may occur in a value to which a symbol is defined or redefined. Afterexpanding those symbols, the value of the symbol must reduce either to verbatim text, whichdoes not contain commas, or to a string literal.

Chapter 5: Assembler Programs 197

The assembler preprocessor supports predefined symbol ‘__UNIQUE__’, which is expanded toverbatim text in the form of the next element from the sequence of natural numbers. Thatsymbol can be used to generate unique location labels in macros.

5.14.4 Defining Macros

A macro definition looks like this:

name macro arg1, arg2, ...

text

end macro

The above block of code defines macro name with arguments arg1, arg2, . . . A macro may haveno arguments at all. Names of macro arguments work as names of local symbols that can beused within a macro.

If a macro has a long list of arguments, then the list can be splitted into multiple lines. Toindicate that a line of arguments list is continued on the next line, terminate a line, which iscontinued, with a comma after the name of an argument. This is shown in the following example:

mac1 macro arg1, arg2, arg3, arg4,

arg5, arg6, arg7, arg8

...

end macro

Below there is given an example of a macro that can represent a state linked to another statein a chain of state transitions:

g1 macro id, ll

s##id: stt #id

regst ; register passing the state

jmp ll

end macro

Macro definitions cannot be nested. However, a macro can expand another macro, whichexpands another macro, and so on. The maximum supported nesting level of macro expansionsis equal to 65535.

To expand macro name defined earlier in source text and use arg1, arg2, . . . for values ofmacro arguments, write a line like this:

name arg1, arg2, ...

The name of expanded macro must be written on a line after one or more whitespacecharacters. The name can be prepended with a location label definition. No substitutionsof symbol names with symbol values are performed in names of macros to expand. However,the substitutions are performed in values of macro arguments. After substituting, the value ofevery macro argument must reduce either to verbatim text, which does not contain commas, orto a string literal.

If a macro is expanded using a long list of arguments, then the list can be splitted intomultiple lines. To indicate that a line of arguments list is continued on the next line, terminatea line, which is continued, with a comma after the value of an argument. This is shown in thefollowing example:

mac1 "alpha", 0.1, "beta", 0.2,

"gamma", 0.3, "delta", 0.4

Chapter 5: Assembler Programs 198

5.14.5 Generating Unique Location Labels

Macros should often contain definitions of location labels that must not duplicate when a macrois expanded several times in the source text. When there is a number of location labels usedlocally in a macro, local symbols can be defined for them using lines of code like these:

lu0 def u##__UNIQUE__

lu1 def u##__UNIQUE__

lu2 def u##__UNIQUE__

The above directives define symbols lu0, lu1, and lu2, values of which have form ui , wherei is an increasing integer number. When the macro is expanded the first time, symbols lu0, lu1,and lu2 take values u1, u2, u3 (if there are no other symbols defined using predefined symbol‘__UNIQUE__’). When the macro is expanded the second time, symbols lu0, lu1, and lu2 takevalues u4, u5, u6, and so on. Thus, values of symbols lu0, lu1, and lu2 will never duplicate, andthose symbols can be used for location labels within macros that are expanded several times.This is illustrated by the following example of a macro:

.data

ls2 probeq 2

.code

emit_ch macro

lu0 def u##__UNIQUE__

lu1 def u##__UNIQUE__

lu2 def u##__UNIQUE__

casels ls2, lu0, lu1

emit "A"

jmp lu2

lu0: emit "B"

jmp lu2

lu1: emit "C"

lu2:

end macro

This macro emits character ‘A’, ‘B’, or ‘C’ by corresponding user instruction emit. The macrocan be safely expanded an arbitrary number of times, and this should not cause problems withduplicate location labels. For example, to emit a sequence of two characters, expand the macrotwice:

...

emit_ch

emit_ch

...

5.14.6 Specifying State Transition Networks

A researcher may want to investigate the behavior of a state transition network that operatesunder the control of QSMM. The network can be defined by an assembler program that containsa number of macro definitions. Every expanded macro might correspond to a state, from which

Chapter 5: Assembler Programs 199

there can be transitions to other states. The text of macro g1 that can represent a state linked toanother state in a chain of state transitions was already given in Section 5.14.4 [Defining Macros],page 197. Along with instruction regst that macro might contain other user instructions, whichperform custom operations upon entering a state.

Below there is given the text of macro g2 that defines a state with two possible transitionsto states specified by arguments of the macro. To every transition a probability corresponds,according to which user spur increment is made. The probabilities are specified by argumentsof the macro. User instruction incspr increments user spur by the logarithm of a probabilityspecified as an instruction argument.

g2 macro id, l1,p1, l2,p2

lu def u##__UNIQUE__

s##id: stt #id

regst

jprob 0.5, lu

incspr p2

jmp l2

lu: incspr p1

jmp l1

end macro

Below there is represented an example state transition network. The initial state is encircledby the thick line.

Figure 5.2: an example state transition network

The state transition network can be described by the following assembler program fragmentlocated after definitions of macros g1 and g2.

g2 0, s1, 0.5, s5, 0.5

g2 1, s2, 0.5, s3, 0.5

g1 2, s4

g1 3, s4

g2 4, s1, 0.5, s9, 0.5

Chapter 5: Assembler Programs 200

g2 5, s6, 0.9, s7, 0.1

g1 6, s8

g1 7, s8

g2 8, s5, 0.5, s9, 0.5

g1 9, s0

Note that when a state is connected to just one other state, the state transition is performeddeterministically. When the environment state identification engine is represented by a smallactor, the use of a state transition network with states connected to several different numbers(greater than 1) of other states will imply relying on a rather weak concept of the mean numberof actor’s output signals (described in Section 2.13 [Other Parameters of an Actor], page 48) thatbiuniquely correspond to states. Therefore, it is recommended either to use a state transitionnetwork with states, where each state is connected to just one other state and/or to certain fixednumber of other states, or to use a large actor for the environment state identification engine thatdoes not have such deficiency. In the latter case, the number of output signals of a small actorassociated with the large actor is fixed and is equal to the arity of Huffman tree. The same ispertinent to invocation of instructions in action choice states: if in different action choice statesthere can be invoked instructions from the sets of user and mixed type instructions of differentsizes greater than 1, it is recommended to use the instruction emitting engine represented by alarge actor.

Another peculiarity a researcher should keep in mind is that the auto-increment of theautomatic spur is not well-defined when the state transition network has transitions performeddeterministically. Such transitions can appear not only between principal states of the network,but also between user and mixed type instructions within definitions of those states. Moreover,it is often useful to increment the automatic spur only during transitions between a subset ofstates defined by an assembler program. Therefore, it is generally recommended switching offthe auto-increment of the automatic spur for assembler programs, especially when they definedeterministically performed state transitions. In this case, automatic spur (or spur of otherkind used instead of it) can be incremented manually by a well-defined algorithm supplied bythe researcher during invocation of user instructions from an instruction set provided by theresearcher.

5.14.7 Getting a Preprocessed Output

Functions qsmm_parse_asm_source_* described in Section 5.7 [Parsing an Assembler Program],page 165 can automatically call the assembler preprocessor to preprocess a source program textif the QSMM_PARSE_ASM_PREPROCESS flag is passed to those functions. However, sometimes itmight be necessary to obtain a preprocessed source text directly. To accomplish this task, thefollowing functions can be used.

[Function]int qsmm_preprocess_asm_source_buf (const char *in_p, const char*cwd_p, int rez1, void *rez2, void *rez3, qsmm msglist t msglist, char**out_pp )

[Function]int qsmm_preprocess_asm_source_stream (FILE *filep, const char*cwd_p, int rez1, void *rez2, void *rez3, qsmm msglist t msglist, char**out_pp )

Function qsmm_preprocess_asm_source_buf preprocesses a source program text, which isprovided using argument in p in the form of a NULL-terminated string. Function qsmm_

preprocess_asm_source_stream preprocesses a source program text, which the functionreads from stream filep.

On success, the functions set *out pp to a pointer to an allocated NULL-terminated stringthat contains the preprocessed output. If the preprocessor produces the zero-length output,

Chapter 5: Assembler Programs 201

then *out pp will be set to 0. If out pp is 0, then *out pp will not be set. If after successfulfunction completion *out pp is not 0, then a memory block pointed by *out pp should befreed by function free when its contents are not needed any longer.

If msglist is not 0, then messages generated during preprocessing will be written to messagelist msglist. If cwd p is not 0, then cwd p will be used for the name of current workingdirectory when resolving ‘include’ directives. If cwd p is 0, then the actual current workingdirectory will be used when resolving ‘include’ directives. Arguments rez1, rez2, and rez3are reserved for future use and must be equal to 0.

On success, the functions return a non-negative number of bytes in the preprocessed outputor constant INT_MAX. If out pp is not 0 and that number is greater than 0 (and less thanINT_MAX), then it will be the number of bytes in a string pointed by *out pp, not countingtrailing byte 0. When the functions return INT_MAX, the number of bytes in a string pointedby *out pp (if out pp is not 0) is greater than or equal to INT_MAX. On failure, a negativeerror code is returned. Currently, the following error codes can be returned.

QSMM_ERR_PRG

One or more errors were encountered in the source program text.

QSMM_ERR_ILSEQ

The source program text cannot be converted to a wide string according to thecurrent locale or the preprocessed output cannot be converted to a multibytestring according to the current locale.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

[Function]int qsmm_preprocess_asm_source_file (const char *fln, int rez1, void*rez2, void *rez3, qsmm msglist t msglist, char **out_pp )

This function preprocesses a source program text provided in a file named fln. On success,the function sets *out pp to a pointer to an allocated NULL-terminated string that containsthe preprocessed output. If the preprocessor produces the zero-length output, then *out ppwill be set to 0. If out pp is 0, then *out pp will not be set. If after successful functioncompletion *out pp is not 0, then a memory block pointed by *out pp should be freed byfunction free when its contents are not needed any longer.

If msglist is not 0, then messages generated during preprocessing will be written to messagelist msglist. Arguments rez1, rez2, and rez3 are reserved for future use and must be equal to0.

On success, the function returns a non-negative number of bytes in the preprocessed outputor constant INT_MAX. If out pp is not 0 and that number is greater than 0 (and less thanINT_MAX), then it will be the number of bytes in a string pointed by *out pp, not countingtrailing byte 0. When the function returns INT_MAX, the number of bytes in a string pointedby *out pp (if out pp is not 0) is greater than or equal to INT_MAX. On failure, a negativeerror code is returned. Currently, the following error codes can be returned.

QSMM_ERR_LIBC

When accessing file fln, the operating system has returned an error. Variableerrno holds the error code.

QSMM_ERR_PRG

One or more errors were encountered in the source program text.

QSMM_ERR_ILSEQ

The source program text cannot be converted to a wide string according to thecurrent locale or the preprocessed output cannot be converted to a multibytestring according to the current locale.

Chapter 5: Assembler Programs 202

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

5.15 Example of Working with an Assembler Program

In the example of working with an assembler program, an agent controlled by the sample programhas to find a path to the gold in a labyrinth and then to an exit from the labyrinth. As insample program ‘samples/labyr2.c’ described in Section 2.14 [Example of Using the ActorAPI], page 51, the image of the labyrinth is encoded in the C source program text using asubset of ASCII characters that look like pseudographics. You can change the image to test thebehavior of the agent for various configurations of the labyrinth.

To learn the configuration of the labyrinth, the agent visits the labyrinth the number of timesdefined by macro NVISIT. A visit is considered finished when the agent moves to a cell wherethe labyrinth exit is located.

Each labyrinth cell is a rectangle 4x3. Maximum zero-based indices of a column and arow of labyrinth cell are defined by macros MAX_X and MAX_Y. Coordinates of the entry cellof the labyrinth relative to its upper left corner are defined by macros ENTRY_X and ENTRY_Y.Characters ‘*’ at cell corners denote a cell with the gold. Characters ‘#’ at cell corners denotea labyrinth exit.

Space characters denote allowed movement paths, and other characters denote places towhich movement is impossible. If a cell is reachable from the labyrinth entry, then it must havetwo spaces in the middle. Every reachable cell must also have two spaces or two non-spaces atthe top and at the bottom (in the middle), which indicates whether movement is allowed to anadjacent cell located at the north and/or the south. When modifying the image of the labyrinth,make sure that cells are properly aligned and connected, and there are no paths outside of thelabyrinth, otherwise an assertion failure will occur.

Although the sample program uses a picture of labyrinth encoded in its source text, inother respects this program works much like as sample program ‘samples/maze.c’ described inSection 4.20 [Example of Working in Large-scale Mode], page 135. That is, in a default mode ofprogram operation, the agent does not know its precise location in the labyrinth and receives onlylimited amount of information about current location. However, as opposed to sample program‘samples/maze.c’, an agent controlled by the program described in this section receives eitheran indication whether current cell is an exit from the labyrinth or, if the current cell is not anexit from the labyrinth, a union of the following pieces of information:

– an indication that a move was successfully performed or could not be performed because ofan obstacle;

– a bitmask of four bits, which indicate whether a move in corresponding direction is allowedfrom current cell or there is an obstacle in that direction;

– an indication whether the agent has taken the gold at current visit of the labyrinth.

In the default mode of program operation, the number of tracked environment states isdefined by macro NSTATE. This number is about 3.5 times greater than in sample program‘samples/maze.c’, which along with much greater amount of information about current condi-tion of visiting the labyrinth received by the agent considerably decreases the probability ofinfinite looping during program execution. Otherwise, such infinite loopings would occur oncein a while for some reason.

After its invocation, the sample program prints the number of tracked environment states.Then, after every visit of the labyrinth, the sample program prints an index number of the visit,the number of times the agent found the gold since the beginning of program execution, thelength of all traversed visiting paths, and the average amount of gold found per one move inthe labyrinth. In the default mode of program operation for the default configuration of the

Chapter 5: Assembler Programs 203

labyrinth, after starting the program, the agent visits the labyrinth a number of times withouttaking the gold, until at some point the agent usually “understands” how to take the gold, andthen it finds the gold at almost every visit of the labyrinth.

At the last visit of the labyrinth, the sample program switches the terminal to the full-screenmode and shows the picture of the labyrinth. After a user presses SPACE, the sample programshows movements of the agent in the labyrinth. An indication whether the agent took the goldand current length of visiting path are printed. After the agent finds an exit from the labyrinth,the user can press Q to turn off the full-screen terminal mode and quit the sample program withdumping to file ‘prg_disasm’ in the current directory a learned assembler program according towhich the agent operates.

A random seed can be specified as the first program argument. If the random seed is non-negative, then the agent will operate normally. If the random seed is negative, then the agentwill move in the labyrinth completely randomly. You could compare the program output forthese two modes of program execution.

A special mode of operation of the sample program, as opposed to the default mode, isthe use of a profile assembler program that helps the agent to do its job more efficiently. Thename of a file with the profile assembler program should be specified as the second programargument. A single node of the model is assembled with the QSMM_ASM_TEMPLATE flag set, sowhen disassembling the node at the end of execution of the sample program, a disassembledprogram will be the input assembler program, in which profile probabilities are replaced withlearned probabilities.

The source text of the profile assembler program is provided in file ‘samples/prg_maze’ inthe package distribution and is also given below. That assembler program is intended for usewith labyrinths that have up to 10 cells in width and height. It actually provides tracking aprecise location of the agent in the labyrinth, which is why the agent will find the gold at almostall visits of the labyrinth. The final visiting path shown in the full-screen terminal mode atthe end of execution of the sample program does not have vacillations that take place when theprofile assembler program is not used.

.data

ls_a probeq 3

.code

reloc macro l_repeat, new_row, new_col

l_g0 def g0_r##new_row##_c##new_col

l_g1 def g1_r##new_row##_c##new_col

joe 0, l_g0

joe 1, l_g0

joe 2, l_g0

joe 3, l_g0

joe 4, l_g0

joe 5, l_g0

joe 6, l_g0

joe 7, l_g0

joe 8, l_g0

joe 9, l_g0

joe 10, l_g0

joe 11, l_g0

joe 12, l_g0

joe 13, l_g0

joe 14, l_g0

joe 15, l_g0

joe 32, l_g1

Chapter 5: Assembler Programs 204

joe 33, l_g1

joe 34, l_g1

joe 35, l_g1

joe 36, l_g1

joe 37, l_g1

joe 38, l_g1

joe 39, l_g1

joe 40, l_g1

joe 41, l_g1

joe 42, l_g1

joe 43, l_g1

joe 44, l_g1

joe 45, l_g1

joe 46, l_g1

joe 47, l_g1

jmp l_repeat

end macro

state macro is_gf, row, col,

row_north, row_south, col_west, col_east

repeat def u##__UNIQUE__

m_north def u##__UNIQUE__

m_east def u##__UNIQUE__

m_south def u##__UNIQUE__

g##is_gf##_r##row##_c##col:

repeat: stt

casels ls_a,

m_north,

m_east,

m_south

mv west

reloc repeat, row, col_west

m_south:

mv south

reloc repeat, row_south, col

m_east: mv east

reloc repeat, row, col_east

m_north:

mv north

reloc repeat, row_north, col

end macro

strow macro is_gf, row, row_north, row_south

state is_gf, row, 0, row_north, row_south, 9, 1

state is_gf, row, 1, row_north, row_south, 0, 2

state is_gf, row, 2, row_north, row_south, 1, 3

state is_gf, row, 3, row_north, row_south, 2, 4

state is_gf, row, 4, row_north, row_south, 3, 5

state is_gf, row, 5, row_north, row_south, 4, 6

state is_gf, row, 6, row_north, row_south, 5, 7

state is_gf, row, 7, row_north, row_south, 6, 8

state is_gf, row, 8, row_north, row_south, 7, 9

state is_gf, row, 9, row_north, row_south, 8, 0

Chapter 5: Assembler Programs 205

end macro

strows macro is_gf

strow is_gf, 0, 9, 1

strow is_gf, 1, 0, 2

strow is_gf, 2, 1, 3

strow is_gf, 3, 2, 4

strow is_gf, 4, 3, 5

strow is_gf, 5, 4, 6

strow is_gf, 6, 5, 7

strow is_gf, 7, 6, 8

strow is_gf, 8, 7, 9

strow is_gf, 9, 8, 0

end macro

strows 0

strows 1

The source code of the sample program is provided in file ‘samples/maze_asm.c’ in thepackage distribution and is also given below. Command make builds the sample program ifthe QSMM package is configured by the ‘configure’ script to use the Curses library. See file‘INSTALL’ at the root of the package distribution, for information on the ‘configure’ script.

#include <assert.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#if defined(HAVE_CURSES_H)

# include <curses.h>

#elif defined(HAVE_NCURSES_CURSES_H)

# include <ncurses/curses.h>

#endif

#include <qsmm/qsmm.h>

#define NVISIT 400

#define NSTATE 512

#define MAX_X 8

#define MAX_Y 8

#define ENTRY_X 1

#define ENTRY_Y 8

#define ERREXIT(fmt, ...) \

do { \

fprintf(stderr,(fmt), ## __VA_ARGS__); \

fprintf(stderr,"\n"); \

goto Exit; \

} \

while (0)

#define CHK_FAIL(func, ...) \

do { \

int rc=func(__VA_ARGS__); \

if (rc<0) ERREXIT( #func ": %s", qsmm_err_str(rc)); \

} \

while (0)

Chapter 5: Assembler Programs 206

enum direct_e {

DIRECT_NORTH=0,

DIRECT_EAST =1,

DIRECT_SOUTH=2,

DIRECT_WEST =3

};

static char is_gold_found;

static int visit, n_gold_found=0, path_len=0;

static qsmm_prg_t prg_asm=0;

static qsmm_msglist_t msglist=0;

static unsigned char get_percept(const char **picture_pp, int xx, int yy) {

unsigned char result=0;

int col=xx*3+1, row=yy*2+1;

assert(picture_pp[row][col]==’ ’ && picture_pp[row][col+1]==’ ’);

assert((picture_pp[row-1][col]==’ ’ &&

picture_pp[row-1][col+1]==’ ’) ||

(picture_pp[row-1][col]!=’ ’ &&

picture_pp[row-1][col+1]!=’ ’));

assert((picture_pp[row+1][col]==’ ’ &&

picture_pp[row+1][col+1]==’ ’) ||

(picture_pp[row+1][col]!=’ ’ &&

picture_pp[row+1][col+1]!=’ ’));

if (picture_pp[row-1][col]==’ ’ && picture_pp[row-1][col+1]==’ ’)

result|=1 << DIRECT_NORTH;

if (picture_pp[row][col+2]==’ ’) result|=1 << DIRECT_EAST;

if (picture_pp[row+1][col]==’ ’ && picture_pp[row+1][col+1]==’ ’)

result|=1 << DIRECT_SOUTH;

if (picture_pp[row][col-1]==’ ’) result|=1 << DIRECT_WEST;

return result;

}

static int opaque_maze(enum direct_e direct,

unsigned char *percept_p) {

static const char *picture[]={

// 0 1 2 3 4 5 6 7 8

"x-----+--x--#..#--x--------+",

"| | | | |", // 0

"+--+ | | #--# | + + |",

"| | | | | | | |", // 1

"| +--+ | +--+ +--+ * *",

"| | | | | |", // 2

"x--+ +--x-----+ x--+ *--*",

"| | | | |", // 3

"| +--+ + + + | +--+ |",

"| | | | | |", // 4

"| +--+ +--+ | | +--+ |",

"| | | | | | |", // 5

"x--+ +--x--+ +--x-----+ |",

"| | | | |", // 6

"+--+ + | +--+ +--+ +--+",

"| | | | |", // 7

"| +--+ | +--+ +--+ +--+",

"| | | | |", // 8

"+--+..+--x-----+--x--------+"

};

static char is_gf=0;

static int path_len, xx=-1, yy=-1;

char ss[128];

unsigned char percept;

Chapter 5: Assembler Programs 207

int col, row, result=0;

if (xx<0 || yy<0) {

if (visit==NVISIT-1) {

if (!initscr()) exit(2);

noecho();

for (row=0; row<=(MAX_Y+1)*2+1; row++)

mvaddstr(row,0,picture[row]);

row=(MAX_Y+1)*2+3;

mvaddstr(row,0,"Press [Space] to start moving");

while (getch()!=’ ’) ;

sprintf(ss,"%64s","");

mvaddstr(row,0,ss);

}

xx=ENTRY_X;

yy=ENTRY_Y;

path_len=0;

}

assert(xx>=0 && xx<=MAX_X);

assert(yy>=0 && yy<=MAX_Y);

if (get_percept(picture,xx,yy) & (1 << direct)) {

col=xx*3+1;

row=yy*2+1;

switch (direct) {

case DIRECT_NORTH: yy--; break;

case DIRECT_EAST: xx++; break;

case DIRECT_SOUTH: yy++; break;

case DIRECT_WEST: xx--; break;

default: assert(0);

}

percept=get_percept(picture,xx,yy);

path_len++;

if (visit==NVISIT-1) mvaddstr(row,col," ");

col=xx*3+1;

row=yy*2+1;

if (visit==NVISIT-1) {

int picture_w=strlen(picture[0]);

mvaddstr(row,col,"[]");

sprintf(ss," Gold found: %d",is_gf);

mvaddstr(1,picture_w+2,ss);

sprintf(ss,"Path length: %d",path_len);

mvaddstr(3,picture_w+2,ss);

move((MAX_Y+1)*2+3,0);

refresh();

usleep(125000);

}

if (picture[row-1][col-1]==’*’ && picture[row-1][col+2]==’*’ &&

picture[row+1][col-1]==’*’ && picture[row+1][col+2]==’*’) {

if (!is_gf) {

is_gf=1;

result=1;

}

}

else if (picture[row-1][col-1]==’#’ && picture[row-1][col+2]==’#’ &&

picture[row+1][col-1]==’#’ && picture[row+1][col+2]==’#’) {

is_gf=0;

result=2;

xx=-1;

yy=-1;

if (visit==NVISIT-1) {

row=(MAX_Y+1)*2+3;

mvaddstr(row,0,"Press [Q] to exit");

while (1) {

int key=getch();

if (key==’q’ || key==’Q’) break;

}

Chapter 5: Assembler Programs 208

endwin();

}

}

}

else {

percept=get_percept(picture,xx,yy)+16;

result=3;

}

if (is_gf) percept+=32;

if (percept_p) *percept_p=percept;

return result;

}

static QSMM_INSTR_META_CLASS(mv) {

const char *ccp;

int rc;

enum direct_e direct=0;

if (QSMM_HAS_INSTR_CLASS(qsmm_evt))

qsmm_get_eh_instr_param(qsmm,sizeof(direct),&direct);

switch (qsmm_evt) {

case QSMM_EVT_INSTR_CLASS_INIT:

switch (direct) {

case DIRECT_NORTH: ccp="north"; break;

case DIRECT_EAST: ccp="east"; break;

case DIRECT_SOUTH: ccp="south"; break;

case DIRECT_WEST: ccp="west"; break;

default: assert(0);

}

qsmm_set_eh_instr_param_str_f(qsmm,"%s",ccp);

qsmm_set_eh_noutcome(qsmm,64);

break;

case QSMM_EVT_ACTIVATE: {

unsigned char percept=0;

rc=opaque_maze(direct,&percept);

qsmm_time_delta(qsmm,1);

switch (rc) {

case 0:

case 3:

break;

case 1:

is_gold_found=1;

n_gold_found++;

break;

case 2:

if (is_gold_found) qsmm_spur_delta(qsmm,1,1);

qsmm_return_to_caller_node(qsmm);

break;

default:

assert(0);

}

if (rc!=2) {

if (rc!=3) path_len++;

qsmm_set_instr_outcome(qsmm,percept);

}

break;

}

}

return 0;

}

static QSMM_INSTR_CLASS_SET(walker) {

switch (qsmm_evt) {

case QSMM_EVT_ENT_INIT: {

Chapter 5: Assembler Programs 209

int nstate;

enum direct_e direct;

direct=DIRECT_NORTH, QSMM_REG_INSTR_CLASS_PARAM(mv,direct);

direct=DIRECT_EAST, QSMM_REG_INSTR_CLASS_PARAM(mv,direct);

direct=DIRECT_SOUTH, QSMM_REG_INSTR_CLASS_PARAM(mv,direct);

direct=DIRECT_WEST, QSMM_REG_INSTR_CLASS_PARAM(mv,direct);

if (prg_asm)

nstate=qsmm_get_prg_nstate(qsmm, __FUNCTION__,

QSMM_ASM_TEMPLATE, prg_asm, 0);

else nstate=NSTATE;

printf("nstate = %d\n",nstate);

qsmm_set_nstate_max(qsmm,__FUNCTION__,nstate);

QSMM_NODE_CREATE(0);

break;

}

case QSMM_EVT_ENGINE_INIT:

if (prg_asm) qsmm_node_asm(qsmm, 0, QSMM_ASM_TEMPLATE,

prg_asm, msglist);

break;

case QSMM_EVT_NODE_ENTER: {

unsigned char percept=0;

is_gold_found=0;

opaque_maze(DIRECT_NORTH,&percept);

break;

}

}

return 0;

}

int main(int argc, char **argv) {

const char *ccp;

int seed=0, exit_code=1;

qsmm_t qsmm=0;

qsmm_prg_t prg_disasm=0;

FILE *file_disasm_p=0;

struct qsmm_desc_s desc;

struct qsmm_disasm_desc_s disasm_desc;

if (argc>2) {

CHK_FAIL(qsmm_msglist_create,&msglist);

CHK_FAIL(qsmm_parse_asm_source_file, argv[2],

QSMM_PARSE_ASM_PREPROCESS, 0, 0, msglist, &prg_asm);

}

memset(&desc,0,sizeof(desc));

desc.dont_use_instr_class_weights=1;

desc.is_large_env=1;

desc.is_large_opt=1;

desc.nspur=2;

desc.stack_sz_max=1;

desc.profile_pool_env_sz=2;

desc.profile_pool_opt_sz=2;

desc.compat=1;

desc.sparse_fill_max=0.2;

CHK_FAIL(qsmm_create,&desc,&qsmm);

QSMM_REG_INSTR_META_CLASS(qsmm,mv,0);

QSMM_REG_INSTR_CLASS_SET(qsmm,walker,0);

qsmm_engine_create(qsmm);

if (argc>1 && (seed=atoi(argv[1]))<0) {

qsmm_set_random(qsmm,1);

seed=-seed;

}

qsmm_rng_seed(qsmm_get_rng(qsmm),seed);

for (visit=0; visit<NVISIT; visit++) {

qsmm_node_call_default(qsmm,0,0);

printf("visit %d: ngf=%d, path_len=%d, ngf/path_len=%.8f\n",

Chapter 5: Assembler Programs 210

visit+1, n_gold_found, path_len,

(double) n_gold_found/path_len);

}

memset(&disasm_desc,0,sizeof(disasm_desc));

disasm_desc.use_stt_start=1;

disasm_desc.use_stt_state=1;

disasm_desc.use_stt_lookup=1;

disasm_desc.use_stt_abort=1;

disasm_desc.use_choice=1;

disasm_desc.use_abort_1=1;

disasm_desc.fq_goto_min=1;

disasm_desc.fq_action_min=1;

if (argc<3) {

disasm_desc.prob_goto_min=0.005;

disasm_desc.prob_action_min=0.005;

}

qsmm_node_disasm(qsmm,0,&disasm_desc,&prg_disasm);

if (!(file_disasm_p=fopen(ccp="prg_disasm","w")))

ERREXIT("%s: failed to open the file for writing",ccp);

CHK_FAIL(qsmm_prg_dump,prg_disasm,0,file_disasm_p);

exit_code=0;

Exit:

qsmm_prg_destroy(prg_disasm);

qsmm_prg_destroy(prg_asm);

qsmm_destroy(qsmm);

if (msglist) {

qsmm_msglist_dump(msglist,0,"BUFFER",0,stderr);

qsmm_msglist_destroy(msglist);

}

if (file_disasm_p) fclose(file_disasm_p);

return exit_code;

}

Here is given sample program output.

$ ./maze-asm -1

nstate = 512

visit 1: ngf=0, path_len=94, ngf/path_len=0.00000000

visit 2: ngf=0, path_len=800, ngf/path_len=0.00000000

...

visit 201: ngf=37, path_len=179608, ngf/path_len=0.00020600

visit 202: ngf=38, path_len=180284, ngf/path_len=0.00021078

...

visit 399: ngf=89, path_len=402678, ngf/path_len=0.00022102

visit 400: ngf=90, path_len=405574, ngf/path_len=0.00022191

$ ./maze-asm 1

nstate = 512

visit 1: ngf=0, path_len=94, ngf/path_len=0.00000000

visit 2: ngf=0, path_len=800, ngf/path_len=0.00000000

...

visit 200: ngf=175, path_len=98092, ngf/path_len=0.00178404

visit 201: ngf=176, path_len=98488, ngf/path_len=0.00178702

...

visit 399: ngf=373, path_len=180780, ngf/path_len=0.00206328

visit 400: ngf=374, path_len=181180, ngf/path_len=0.00206425

$ ./maze-asm -1 prg_maze

nstate = 200

visit 1: ngf=1, path_len=3086, ngf/path_len=0.00032404

Chapter 5: Assembler Programs 211

visit 2: ngf=1, path_len=3360, ngf/path_len=0.00029762

...

visit 200: ngf=43, path_len=192884, ngf/path_len=0.00022293

visit 201: ngf=43, path_len=193488, ngf/path_len=0.00022224

...

visit 399: ngf=84, path_len=381448, ngf/path_len=0.00022021

visit 400: ngf=84, path_len=382074, ngf/path_len=0.00021985

$ ./maze-asm 1 prg_maze

nstate = 200

visit 1: ngf=1, path_len=3086, ngf/path_len=0.00032404

visit 2: ngf=2, path_len=3138, ngf/path_len=0.00063735

...

visit 200: ngf=200, path_len=13434, ngf/path_len=0.01488760

visit 201: ngf=201, path_len=13486, ngf/path_len=0.01490435

...

visit 399: ngf=399, path_len=23782, ngf/path_len=0.01677739

visit 400: ngf=400, path_len=23834, ngf/path_len=0.01678275

As it can be seen from the above output, the average amount of gold found per one movein the labyrinth in a normal mode of operation of the sample program with random seed 1 andwithout using the profile assembler program is about 10 times greater than in the completelyrandom mode of operation. An average amount of gold found in a normal mode of operationwith random seed 1 and the use of the profile assembler program is about 80 times greater thanin the completely random mode of operation.

Chapter 6: Miscellaneous Topics 212

6 Miscellaneous Topics

In this chapter secondary topics are covered for which there was no place in other chapters ofthe manual.

6.1 Random Number Generators

Within the QSMM framework, a random number generator is used by an optimal action generati-on engine as a source of randomness when stochastically emitting output signals according totheir probabilities.

Standard random number generators used within the framework are actually pseudorandomnumber generators. A developer can also supply custom random number generators for usingby the framework. Those custom random number generators may actually be pseudorandomnumber generators or may provide real random numbers, e.g. obtained using some physicalprocess.

6.1.1 Creating a Random Number Generator

A random number generator is referred to by a handle.

[Data type]qsmm_rng_tThis is a type for a handle of random number generator. It is a pointer, so variables ofthis type can have zero value. Functions qsmm_rng_create and qsmm_rng_create_custom

allocate a new handle. Function qsmm_rng_destroy frees an existing handle.

After allocating a handle, it can be passed to API functions that take argument qsmm_rng_tuntil the handle is freed. An allocated handle can also be set as the value of field rng ofstructures that specify parameters of creating an actor or a multinode model. A lifetime ofthe allocated handle should be longer than a lifetime of the actor or the multinode model.

Function qsmm_get_actor_rng returns a handle of random number generator specified in fieldrng of structure qsmm_actor_desc_s when creating the actor, or the handle of an instance ofdefault random number generator allocated automatically if 0 is specified in that field. Functionqsmm_get_rng returns a handle of random number generator specified in field rng of structureqsmm_desc_s when creating the multinode model, or the handle of an instance of default randomnumber generator allocated automatically if 0 is specified in that field.

To create a random number generator, which is an instance of default random numbergenerator, the following function can be used.

[Function]int qsmm_rng_create (qsmm rng t *rng_p )This function creates a random number generator and stores its newly allocated handle in*rng p. The function creates either a random number generator, which type is defined bya user-supplied function qsmm_proxy_func_t and its parameter set by a call to qsmm_set_

rng_default (see Section 6.1.3 [Custom Random Number Generators], page 214, for moreinformation), or a random number generator of a standard type (defined when configuringthe package) if the user-supplied function is not set.

The function returns a non-negative value on success or a negative error code on failure increating a random number generator. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument rng p is 0.

QSMM_ERR_NOMEM

There was not enough memory to create a random number generator.

Chapter 6: Miscellaneous Topics 213

By default, the ‘configure’ script configures the package to use a pseudorandom numbergenerator implemented by function rand from the standard C library, as the standard randomnumber generator. This mode of operation does not require dependency on an external librarybut is not recommended. The recommended mode is to use a pseudorandom number generatorprovided by the GNU Scientific Library, as the standard random number generator. See file‘INSTALL’ at the root of the package distribution, for information on how to configure thepackage to use that library.

One of disadvantages of using a pseudorandom number generator implemented by functi-on rand from the standard C library is that only one instance of the pseudorandom numbergenerator exists, and different handles will actually correspond to a single pseudorandom numbergenerator. This will cause problems when seeding pseudorandom number generators representedby different handles.

A function described below can be used to create a random number generator on the basisof a user-supplied function.

[Function]int qsmm_rng_create_custom (qsmm proxy func t rng_func, void*paramp, qsmm rng t *rng_p )

This function creates a random number generator on the basis of function rng func and itsparameter paramp and stores a newly allocated handle of the random number generatorin *rng p. Function rng func must implement an interface for abstract random numbergenerator. See Section 6.1.3 [Custom Random Number Generators], page 214, for a descri-ption of the interface.

The function returns a non-negative value on success or a negative error code on failure increating a random number generator. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument rng p is 0.

QSMM_ERR_NOMEM

There was not enough memory to create a random number generator.

To destroy a random number generator, the following function can be used.

[Function]void qsmm_rng_destroy (qsmm rng t rng )This function destroys a random number generator specified by handle rng. After destructionof the random number generator, the handle must not be used. If rng is 0, then the functionwill do nothing.

An application program is only allowed to destroy random number generators, which it hascreated explicitly by function qsmm_rng_create or qsmm_rng_create_custom. For example,if the application program destroys a random number generator, which was automaticallycreated for a multinode model and returned by function qsmm_get_rng, then a segmentationfault will occur later.

6.1.2 Generating Random Numbers

To generate uniformly distributed random numbers, the following functions can be used.

[Function]int qsmm_rng_uniform_int (qsmm rng t rng, int nn )This function returns a new integer random number, uniformly distributed in the range 0(inclusive) to nn (exclusive), produced using random number generator rng. If nn is less than1, then negative error code QSMM_ERR_INVAL will be returned.

[Function]double qsmm_rng_uniform (qsmm rng t rng )This function returns a new random number, uniformly distributed in the range 0 (inclusive)to 1 (exclusive), produced using random number generator rng.

Chapter 6: Miscellaneous Topics 214

[Function]double qsmm_rng_uniform_pos (qsmm rng t rng )This function returns a new (positive) random number, uniformly distributed in the range 0to 1 (exclusive), produced using random number generator rng.

To seed a pseudorandom number generator, the following function can be used.

[Function]void qsmm_rng_seed (qsmm rng t rng, int seed )This function seeds pseudorandom number generator rng using seed. A seed specifies a streamof pseudorandom numbers produced by the generator. A pseudorandom number generatorcreated on the basis of a user-supplied function might not support seeding.

6.1.3 Custom Random Number Generators

The type of custom random number generator is defined by a user-supplied function qsmm_

proxy_func_t and its parameter. Instances of custom random number generator can be createdby function qsmm_rng_create_custom. The type of custom random number generator can be setas the default type of random number generator. Instances of default random number generatorare created by function qsmm_rng_create, which is implicitly called by functions qsmm_actor_create and qsmm_create when field rng of structure qsmm_actor_desc_s or qsmm_desc_s haszero value.

To retrieve or set a user-supplied function qsmm_proxy_func_t and its parameter, whichdefine the type of default random number generator, the following functions can be used.

[Function]void qsmm_get_rng_default (qsmm proxy func t *rng_func_p, void**param_pp )

This function retrieves the type of default random number generator, which is defined by auser-supplied function qsmm_proxy_func_t and its parameter. If rng func p is not 0, then*rng func p will be set to a pointer to the user-supplied function or to 0 if a standard randomnumber generator, which type is defined when configuring the package, is used as a defaultrandom number generator. If param pp is not 0, then *param pp will be set to a userparameter of function qsmm_proxy_func_t.

[Function]void qsmm_set_rng_default (qsmm proxy func t rng_func, void*paramp )

This function sets the type of default random number generator, which is defined by functionrng func and its parameter paramp. If rng func is 0, then a standard random numbergenerator, which type is defined when configuring the package, will be used as a defaultrandom number generator.

A function, which along with its user parameter defines the type of random number generator,has a prototype of an abstract proxy function that in future versions of the package may be usedto perform operations on other objects.

[Data type]qsmm_proxy_func_tThis is a type of a pointer to an abstract proxy function. To this type the following declarationcorresponds:

typedef int (*qsmm_proxy_func_t)(

int cmd,

int in_sz,

int out_sz,

const void *in_p,

void *out_p,

void *paramp);

A command identifier, which specifies an operation the proxy function should perform, isgiven via argument cmd. Input command parameters are given via buffer in p of length

Chapter 6: Miscellaneous Topics 215

in sz bytes. Output command parameters, i.e. results of command invocation, should bewritten to buffer out p of length out sz (or updated in that buffer). A user parameter,specified when setting the proxy function, is passed via argument paramp.

Upon successful completion, the proxy function must return a non-negative value. In thecase of error, the proxy function should return a negative value. Specific interpretation of avalue returned depends on an object the function represents and on an operation performedby the function.

Possible values of cmd and expected input parameters and invocation results of commandsof a proxy function that implements an interface for abstract random number generator aredescribed below.

[Macro]QSMM_RNG_CMD_CREATECreate a random number generator. A pointer to an object, which represents the randomnumber generator, should be written to buffer out p. The value of out sz is always equal tosizeof(void *). For example, to return pointer rng_state_p to an allocated instance ofstructure, in which the state of a created random number generator is stored, use a line ofcode like this:

*((void **) out_p)=rng_state_p;

The proxy function is permitted to return negative error code QSMM_ERR_NOMEM, indicatingthat there was not enough memory to allocate an object, which represents the random numbergenerator. This error code will be returned by function qsmm_rng_create or qsmm_rng_

create_custom called to create the random number generator.

[Macro]QSMM_RNG_CMD_DESTROYDestroy a random number generator. A pointer to an object, which represents the randomnumber generator, is passed via buffer in p. The value of in sz is always equal to sizeof(void*). For example, to obtain pointer rng_state_p to an allocated instance of structure, inwhich the state of a random number generator is stored, for subsequent destruction, use aline of code like this:

rng_state_p=*((void **) in_p);

The proxy function is only permitted to return a non-negative value.

[Macro]QSMM_RNG_CMD_GENERATEGenerate a random number. A pointer to an object, which represents a random numbergenerator, is passed via buffer in p. The value of in sz is always equal to sizeof(void *).A generated random number uniformly distributed in the range 0 (inclusive) to 1 (exclusive)must be written to buffer out p. The value of out sz is always equal to sizeof(double).For example, to return generated random number rnd, use a line of code like this:

*((double **) out_p)=rnd;

The proxy function is only permitted to return a non-negative value.

[Macro]QSMM_RNG_CMD_SEEDSeed a pseudorandom number generator. An instance of structure qsmm_rng_cmd_seed_in_s (see below), in which there are stored a random seed (the second argument of functionqsmm_rng_seed) and a pointer to an object, which represents the pseudorandom numbergenerator, is passed via buffer in p. The value of in sz is always equal to sizeof(struct

qsmm_rng_cmd_seed_in_s). To obtain seeding parameters, you might use lines of code likethese:

const struct qsmm_rng_cmd_seed_in_s *cmd_in_p=in_p;

rng_state_p=cmd_in_p->rng_object_p;

Chapter 6: Miscellaneous Topics 216

When the pseudorandom number generator does not support the seeding operation, the proxyfunction is permitted to return negative error code QSMM_ERR_NOSYS. However, this error codeis currently ignored, because function qsmm_rng_seed returns void.

The following structure is used to pass parameters of seeding operation.

[Structure]qsmm_rng_cmd_seed_in_sThis structure is used to pass input parameters of operation of seeding a pseudorandomnumber generator. It contains the following fields.

[Field]int seedA random seed value.

[Field]void * rng_object_pA pointer to an object that represents the pseudorandom number generator.

Below there is given the example source code of a proxy function that implements the interfacefor abstract random number generator.

#include <stdlib.h>

#include <qsmm/qsmm.h>

static int rng_proxy(int cmd,

int in_sz,

int out_sz,

const void *in_p,

void *out_p,

void *paramp) {

unsigned int *seed_p;

switch (cmd) {

case QSMM_RNG_CMD_CREATE:

if (!(seed_p=malloc(sizeof(*seed_p)))) return QSMM_ERR_NOMEM;

*seed_p=1;

*((void **) out_p)=seed_p;

break;

case QSMM_RNG_CMD_DESTROY:

free(*((void **) in_p));

break;

case QSMM_RNG_CMD_GENERATE:

seed_p=*((void **) in_p);

*seed_p=*seed_p*1103515245+12345;

*((double *) out_p)=(*seed_p/65536)%32768/32768.0;

break;

case QSMM_RNG_CMD_SEED: {

const struct qsmm_rng_cmd_seed_in_s *cmd_in_p=in_p;

seed_p=cmd_in_p->rng_object_p;

*seed_p=cmd_in_p->seed;

break;

}

}

return 0;

}

To set this proxy function as a default random number generator, use line of code

qsmm_set_rng_default(&rng_proxy,0);

Chapter 6: Miscellaneous Topics 217

6.2 Ordinary and Sparse Vectors

In QSMM, an ordinary or sparse vector is referred to by a vector handle.

[Data type]qsmm_vec_tThis is a type for a vector handle. It is a pointer, so variables of this type can have zerovalue. The handle of a vector, which holds probabilities of emitting output signals by anactor, is returned by function qsmm_get_actor_choice_sig_prob_vec. The handle of anewly allocated vector, which is a copy of another vector, is returned by function qsmm_vec_

clone. After using the copy, its handle should be freed by function qsmm_vec_destroy.

To get the number of accessible vector elements, the following function can be used.

[Function]int qsmm_get_vec_npos (qsmm vec t vec )This function returns the number of accessible elements of vector vec. The returned value isalways non-negative. For an ordinary vector, this number might be equal to the length of asegment of elements, which values were set for the vector. For a sparse vector, this numberis equal to the number of elements, which values were set for the vector. Normally, it is thenumber of non-zero elements in the sparse vector.

To get the value of an element of a vector, the following function can be used.

[Function]int qsmm_get_vec_elm_by_pos (qsmm vec t vec, int pos, double *valp )This function sets *valp to a value of an element of vector vec at position pos. If valp is 0,then *valp will not be set. The value of pos must be non-negative and less than the numberof accessible vector elements.

On success, the function returns a non-negative index of an element of the vector thatcorresponds to position pos. If pos is negative or is greater than or equal to a value returnedby function qsmm_get_vec_npos for the vector, then negative error code QSMM_ERR_NOTFOUNDwill be returned.

To get a position of an element of a vector by its index, the following function can be used.

[Function]int qsmm_get_vec_pos_by_idx (qsmm vec t vec, int idx )This function returns the position of an element of vector vec at index idx. The position is anon-negative number less than the number of accessible vector elements returned by functionqsmm_get_vec_npos for the vector.

On success, the function returns a non-negative position of an element of the vector thatcorresponds to index idx. If there is no such position, then negative error code QSMM_ERR_

NOTFOUND will be returned. When idx is non-negative and is less than the number of vectordimensions, this means that the value of the element at index idx is 0.

For example, to get the value of an element of vector vec at index idx, you might use a blockof code like this:

int rc;

double val=0; // value of the element

if ((rc=qsmm_get_vec_pos_by_idx(vec,idx))>=0)

qsmm_get_vec_elm_by_pos(vec,rc,&val);

To create a copy of a vector, the following function can be used.

[Function]int qsmm_vec_clone (qsmm vec t vec_src, qsmm vec t *vec_dst_p )This function creates a copy of vector vec src and stores its newly allocated vector handle in*vec dst p. The copy might occupy a lesser amount of memory than the original because,for an ordinary vector, there might be copied only a segment of elements, which values wereset for the vector.

Chapter 6: Miscellaneous Topics 218

The function returns a non-negative value on success or a negative error code on failure increating a copy of the vector. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument vec dst p is 0.

QSMM_ERR_NOMEM

There was not enough memory to create a copy of the vector.

To destroy a copy of a vector created using a call to qsmm_vec_clone, the following functioncan be used.

[Function]void qsmm_vec_destroy (qsmm vec t vec )This function destroys a vector specified by vector handle vec. After vector destruction, thevector handle must not be used. If vec is 0, then the function will do nothing.

An application program is only allowed to destroy vectors created by function qsmm_vec_

clone. If the application program destroys a vector, which handle was returned by functionqsmm_get_actor_choice_sig_prob_vec, then a segmentation fault will occur later.

6.3 Messages and Message Lists

Message lists are used within the QSMM framework to return error, warning, and note messagesthat can be part of a result of the following operations:

– access to statistics storage;

– preprocessing the source text of assembler program;

– parsing the source text of assembler program;

– assembling a parsed program.

Besides that, an API for working with messages and message lists can be used in applicationsyou develop to return lists of messages from functions.

6.3.1 Creating a Message List

A message list is referred to by a message list handle.

[Data type]qsmm_msglist_tThis is a type for a message list handle. It is a pointer, so variables of this type can havezero value. Function qsmm_msglist_create allocates a new message list handle. Functionqsmm_msglist_destroy frees an existing message list handle. After allocating a messagelist handle, it can be passed to API functions that take argument qsmm_msglist_t until thehandle is freed.

Use the following function to creates an empty message list, e.g. to pass the list to a functionthat can fill it with messages.

[Function]int qsmm_msglist_create (qsmm msglist t *msglist_p )This function creates an empty message list and stores its newly allocated handle in *msgli-st p.

The function returns a non-negative value on success or a negative error code on failure increating a message list. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument msglist p is 0.

QSMM_ERR_NOMEM

There was not enough memory to create a message list.

Chapter 6: Miscellaneous Topics 219

To destroy a message list and all the messages it contains, the following function can be used.

[Function]void qsmm_msglist_destroy (qsmm msglist t msglist )This function destroys a message list specified by message list handle msglist. After messagelist destruction, the message list handle must not be used. If msglist is 0, then the functionwill do nothing.

6.3.2 Creating Messages

The QSMM API has a special handle type for message objects that can be contained in a messagelist object. A message object is referred to by a message handle.

[Data type]qsmm_msg_tThis is a type for a message handle. It is a pointer, so variables of this type can have zerovalue. Functions qsmm_msg_create_f and qsmm_msg_create_fv allocate a new messagehandle. An existing message handle can be freed explicitly by function qsmm_msg_destroy

if the message is not added to a message list, or implicitly when clearing or destroying amessage list to which the message was added. After allocating a message handle, it can bepassed to API functions that take argument qsmm_msg_t until the handle is freed.

When creating a message object, a category of the message should be specified using thefollowing enumeration.

[Enumeration]qsmm_msg_eThis enumeration specifies the category of a message, which affects how the message will belabeled when dumping a message list that contains the message. The enumeration containsthe following elements.

QSMM_MSG_GENERAL

An uncategorized message. No category label will be printed before a messagetext.

QSMM_MSG_NOTE

A note message. Label ‘note: ’ will be printed before a message text.

QSMM_MSG_WARNING

A warning message. Label ‘warning: ’ will be printed before a message text.

QSMM_MSG_ERROR

An error message. Label ‘error: ’ will be printed before a message text.

To create and destroy a message object, the following functions can be used.

[Function]int qsmm_msg_create_f (qsmm msg t *msg_p, enum qsmm msg emsg_type, const char *fmt, ...)

[Function]int qsmm_msg_create_fv (qsmm msg t *msg_p, enum qsmm msg emsg_type, const char *fmt, va list ap )

These functions create a message of category msg type and store a newly allocated messagehandle in *msg p. Function qsmm_msg_create_f formats the text of the message accordingto argument fmt and subsequent arguments, the meaning of which is the same as in functi-on printf. Function qsmm_msg_create_fv formats the text of the message according toarguments fmt and ap, the meaning of which is the same as in function vprintf.

The functions return a non-negative value on success or a negative error code on failure increating a message. Currently, the following error codes can be returned.

QSMM_ERR_INVAL

Argument msg p is 0.

Chapter 6: Miscellaneous Topics 220

QSMM_ERR_NOMEM

There was not enough memory to create a message.

[Function]void qsmm_msg_destroy (qsmm msg t msg )This function destroys a message specified by message handlemsg. After message destruction,the message handle must not be used. If msg is 0, then the function will do nothing.

The function must not be used to destroy messages that were added to a message list.Those messages are automatically destroyed when clearing the message list by function qsmm_

msglist_clear or destroying the message list by function qsmm_msglist_destroy.

There can be a line number associated with a message. If the line number is positive and thename of an input file is specified when dumping the message list, then the name of the file andthe line number will be printed before a message text.

[Function]int qsmm_set_msg_lineno (qsmm msg t msg, int lineno )This function associates line number lineno with message msg. If lineno is non-negative andthe name of an input file is specified when dumping the message list, then the name of thefile will be printed before a message text. If lineno is positive and the name of an input fileis specified when dumping the message list, then line number lineno will be printed after thename of the file and before a message text. Thus, if lineno is 0, then only the name of aninput file will be printed before a message text, which may indicate that the message pertainsto the file in whole. If lineno is −1, then it means that no line number is actually associatedwith the message, and the name of an input file will not be printed.

The function returns a non-negative value on success or a negative error code on failure.Currently, the following error codes can be returned.

QSMM_ERR_INVAL

The value of lineno is less than −1.

QSMM_ERR_NOMEM

There was not enough memory to perform the operation.

6.3.3 Adding Messages to a Message List

To add a message to a message list, the following function can be used.

[Function]int qsmm_msglist_add_msg (qsmm msglist t msglist, qsmm msg t msg )This function adds message msg to message list msglist. After adding the message to themessage list, you must not explicitly destroy the message by function qsmm_msg_destroy. Themessage will be automatically destroyed by function qsmm_msglist_clear when clearing themessage list or by function qsmm_msglist_destroy when destroying the message list.

On success, the function returns a non-negative value. If there is not enough memory toperform the operation, then negative error code QSMM_ERR_NOMEM will be returned.

To append to a message list copies of all messages contained in another message list, thefollowing function can be used.

[Function]int qsmm_msglist_extend (qsmm msglist t msglist_dst, qsmm msglist tmsglist_src )

This function appends to message list msglist dst copies of all messages contained in messagelist msglist src, in the same order.

On success, the function returns a non-negative value. If there is not enough memory toperform the operation, then negative error code QSMM_ERR_NOMEM will be returned.

To clear a message list, the following function can be used.

Chapter 6: Miscellaneous Topics 221

[Function]void qsmm_msglist_clear (qsmm msglist t msglist )This function removes all messages from message list msglist and destroys them.

To get the number of messages contained in a message list, the following function can beused.

[Function]int qsmm_get_msglist_sz (qsmm msglist t msglist )This function returns the number of messages contained in message list msglist. The returnedvalue is always non-negative.

6.3.4 Dumping a Message List

To dump a message list to a stream, the following function can be used.

[Function]void qsmm_msglist_dump (qsmm msglist t msglist, const char*prg_name, const char *file_name, unsigned int flags, FILE *filep )

This function dumps all messages contained in message list msglist to stream filep. Ifprg name is not 0, then messages that do not have a line number assigned will be prependedwith prg name, which is supposed to be the name of an application program the user hasinvoked. If prg name is not 0 and flags has a bit specified by mask QSMM_MSG_DUMP_PRG_

NAME_ALL set, then all messages will be prepended with prg name. If file name is not 0, thenmessages that have a non-negative line number assigned will be prepended with file name,which is supposed to be the name of an input file those messages pertain to.

Thus, the function can dump user-created messages, contained in message lists, in formatslisted below. The text of a message might be prepended with a label that depends on a messagecategory defined using enumeration qsmm_msg_e when creating the message.

message text

program name: message text

input file name: message text

input file name:line number: message text

program name: input file name: message text

program name:input file name:line number: message text

When dumping message lists, which messages were created by QSMM API functions, specificmessages may be printed in other formats. For example, when dumping a list of messagesgenerated while parsing an assembler program, a message may be prepended with a stack oflocations in source assembler files. The stack may indicate places, where ‘include’ preprocessordirectives were used to include the contents of a source assembler file that contains an error.

6.4 Exchanging Data Packets in a Multithreaded Program

The QSMM framework provides a mechanism for exchanging data packets in multithreadedprograms. This mechanism can be helpful e.g. to organize interaction of a system you developwith the environment you model, each executing in a separate thread. When the whole programexecutes in a single thread, it is sometimes hard to set up communication between differentparts of the program.

The mechanism for exchanging data packets will be available if the QSMM package is confi-gured by the ‘configure’ script to use the POSIX threads API. See file ‘INSTALL’ at the rootof the package distribution, for information about the ‘configure’ script. Part of the QSMM

API, which represents the mechanism, is called Side API, because the mechanism allows multi-ple sides to take part in the interaction. Datatypes, functions, and macros of the Side API aredeclared in header file ‘qsmm/side.h’, which is installed in a directory for C header files set bythe ‘configure’ script.

Chapter 6: Miscellaneous Topics 222

6.4.1 Registering Interaction Sides

Before exchanging data packets, sides, which take part in the interaction, must be registered. Aregistered side is referred to by a side handle.

[Data type]qsmm_side_tThis is a type for a side handle. It is a pointer, so variables of this type can have zero value.Function qsmm_side_create allocates a new side handle. Function qsmm_side_destroy freesan existing side handle. After allocating a side handle, it can be passed to API functions thattake argument qsmm_side_t until the handle is freed.

To register and unregister an interaction side, the following functions can be used.

[Function]int qsmm_side_create (const char *name, qsmm side t *side_p )This function registers interaction side name and stores a newly allocated side handle in*side p. The value of name is used when dumping the trace of data packets exchange betweensides and must not be 0. The function creates a copy of name and stores it in the internalstructure.

The function returns a non-negative value on success or a negative error code on failure inregistering a side. Currently, the following error codes can be returned.

QSMM_SIDE_ERR_INVAL

Argument side p is 0.

QSMM_SIDE_ERR_PTHREAD

A POSIX threads API error.

QSMM_SIDE_ERR_NOMEM

There was not enough memory to register a side.

[Function]void qsmm_side_destroy (qsmm side t side )This function unregisters an interaction side specified by handle side. After unregistering theside, its handle must not be used. If side is 0, then the function will do nothing.

To get the name of an interaction side specified by a handle, the following function can beused.

[Function]const char * qsmm_get_side_name (qsmm side t side )This function returns the name of a side specified when creating the side. The returned valueis never 0.

6.4.2 Exchanging Data Packets Between Sides

The following function sends a data packet from one side to another.

[Function]int qsmm_side_send (qsmm side t side_from, qsmm side t side_to, intdata_sz, const void *data_p )

This function sends a data packet of size data sz bytes pointed by data p from side side fromto side side to. The data packet is appended to the end of the queue of received data packetsof side side to. If a thread, in which side side to is executed, waits for a new data packetusing function qsmm_side_recv, then the thread will resume execution, and that functionwill return the data packet just received.

On success, the function returns a non-negative value. If there is not enough memory toperform the operation, then negative error code QSMM_SIDE_ERR_NOMEM will be returned.

The following function receives a data packet.

Chapter 6: Miscellaneous Topics 223

[Function]int qsmm_side_recv (qsmm side t side, int bufsz, void *bufp )This function retrieves a data packet from the queue of received data packets of side. Thedata packet is retrieved to buffer bufp of size bufsz bytes. If bufsz is greater than the sizeof a data packet retrieved, then remaining contents of buffer bufp will be left intact. If thereis no data packet to retrieve, then the function will block until another thread sends a datapacket to side.

On success, the function returns a non-negative number equal to the size in bytes of a datapacket retrieved. If bufsz is less than the size of a data packet to be retrieved, or if bufszis positive and bufp is 0, then the function will return negative error code QSMM_SIDE_ERR_

INVAL.

To send a data packet from one side to another, it is recommended to use the followingmacro.

[Macro]QSMM_SIDE_SEND (from, to, msg )This macro sends data packet msg from side from to side to. The macro is expanded to:

qsmm_side_send((from), (to), sizeof(msg), &(msg))

Macro argument msg must be a variable, not a constant. For example, to send signal 1 fromone side to another, the following lines of code could be used:

qsmm_sig_t sig_out=1;

QSMM_SIDE_SEND(side_from,side_to,sig_out);

To receive a data packet, it is recommended to use the following macro.

[Macro]QSMM_SIDE_RECV (side, msgp )This macro retrieves a data packet from the queue of received data packets of side. The datapacket is retrieved to variable *msgp. The macro is expanded to:

qsmm_side_recv((side), sizeof(*(msgp)), (msgp))

For example, to receive a signal sent to a side, the following lines of code could be used:

qsmm_sig_t sig_in=QSMM_SIG_INVALID;

QSMM_SIDE_RECV(side,&sig_in);

6.4.3 Tracing Exchange of Data Packets

The QSMM framework provides facilities for tracing events related to an interaction side. Typesof events, which are dumped to the trace log, can be specified using a bitmask defined as asubset of the following macros merged by bitwise “or.”

[Macro]QSMM_SIDE_TRACE_APISide API calls entry and exit. For every call, the name of an API function, names and valuesof arguments of the function, and a value returned by the function are dumped.

[Macro]QSMM_SIDE_TRACE_MSGThe contents of data packets sent from the interaction side to other interaction sides.

To get or set a bitmask of types of events, which are dumped to the trace log, the followingfunctions can be used.

[Function]unsigned int qsmm_get_side_trace_flags (qsmm side t side )This function returns a bitmask of types of events related to side, which are dumped to thetrace log. It is a bitmask set by the last call to function qsmm_set_side_trace_flags or thedefault bitmask if that function is not yet called.

Chapter 6: Miscellaneous Topics 224

[Function]void qsmm_set_side_trace_flags (qsmm side t side, unsigned intflags )

This function sets a bitmask of types of events related to side, which are dumped to the tracelog, to flags. The correctness of the bitmask is not checked.

Function qsmm_side_create initializes a bitmask of types of events, which are dumped tothe trace log, to QSMM_SIDE_TRACE_MSG.

The events will not be written to the trace log unless a stream that represents the trace log isdefined for the interaction side. To get or set a stream for the trace log, the following functionscan be used.

[Function]FILE * qsmm_get_side_trace_stream (qsmm side t side )This function returns a stream that represents the trace log of side. If the stream is not set,then the function will return 0.

[Function]void qsmm_set_side_trace_stream (qsmm side t side, FILE *filep )This function sets a stream, which represents the trace log of side, to filep. If filep is 0, thenevent tracing will be disabled for the side.

To write a formatted message to the trace log, e.g. containing additional information on adata packet sent or received, the following functions can be used.

[Function]void qsmm_side_trace_f (qsmm side t side, const char *fmt, ...)[Function]void qsmm_side_trace_fv (qsmm side t side, const char *fmt, va list ap )

These functions write a formatted message to the trace log of side. Character ‘\n’ is appendedto the message and the stream buffer is flushed. If the trace log is not set, then the functionswill do nothing. The meaning of argument fmt and subsequent arguments of function qsmm_

side_trace_f is the same as in function printf. The meaning of arguments fmt and ap offunction qsmm_side_trace_fv is the same as in function vprintf.

6.4.4 Error Handling

To get a textual description of an error code returned by a Side API function, the followingfunction can be used.

[Function]const char * qsmm_side_err_str (int err )This function returns a textual description of error code err of the QSMM Side API. Forinvalid error codes, string "(invalid error code)" is returned.

An interaction side can have an error handler assigned to it. An error handler is a functioncalled in case of an error raised by any Side API function that takes an argument of typeqsmm_side_t and can return an error code. The default error handler function of interactionside prints information on an error occurred to stderr and calls exit(2). If there is no errorhandler function assigned to the interaction side or an error handler function assigned to theinteraction side does not terminate program execution and returns, then a Side API function,where the error has occurred, will return corresponding error code.

To get or set an error handler for an interaction side, the following functions can be used.

[Function]void qsmm_get_side_err_handler (qsmm side t side,qsmm side err handler func t *func_p, void **param_pp )

This function retrieves information on an error handler assigned to interaction side. If func pis not 0, then *func p will be set to a pointer to an error handler function assigned to theinteraction side or to 0 if there is no error handler function assigned to the interaction side.If param pp is not 0, then *param pp will be set to the user parameter of that error handlerfunction.

Chapter 6: Miscellaneous Topics 225

[Function]void qsmm_set_side_err_handler (qsmm side t side,qsmm side err handler func t func, void *paramp )

This function assigns an error handler to interaction side. Argument func specifies an errorhandler function, and argument paramp specifies a user parameter of that function. If funcis 0, then no error handler will be used for the interaction side.

The type of a pointer to an error handler function is described below.

[Data type]qsmm_side_err_handler_func_tThis is a type of a pointer to an error handler function. To this type the following declarationcorresponds:

typedef void (*qsmm_side_err_handler_func_t)(

qsmm_side_t side,

struct qsmm_side_except_s *except_p,

void *paramp);

The handle of an interaction side, to which an error pertains to, is passed via argument side.Information on the error occurred is passed via argument except p. A user parameter speci-fied when setting the error handler function for the interaction side is passed via argumentparamp.

A structure, which contains information on an error occurred, is described below.

[Structure]qsmm_side_except_sThis structure is used to convey to the error handler function of interaction side informationabout an error occurred. The structure contains the following fields.

[Field]const char * func_nameThe name of a function within the QSMM library that has raised the error.

[Field]int codeAn error code that will be returned by the Side API function after return from the errorhandler function.

6.4.5 Example Program that Exchanges Data Packets

An example program, which exchanges data packets, is the example program given inSection 4.20 [Example of Working in Large-scale Mode], page 135, rewritten using the POSIX

threads API and the QSMM Side API. For the same command-line arguments, the programsproduce the same output.

Every visit of the labyrinth is started with creating a thread, where function maze_thread

will execute. That thread represents the labyrinth, and the main thread of the program, whichrepresents the system that visits the labyrinth, communicates with the labyrinth thread usingthe Side API. At exit from the labyrinth, the labyrinth thread exits too.

The source code of the example is provided in file ‘samples/maze_mt.c’ in the packagedistribution and is also given below. Command make builds the program if the QSMM packageis configured by the ‘configure’ script to use the POSIX threads API. See file ‘INSTALL’ at theroot of the package distribution, for information on the ‘configure’ script.

#include <assert.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#include <qsmm/qsmm.h>

#include <qsmm/side.h>

Chapter 6: Miscellaneous Topics 226

#define NVISIT 400

#define NSTATE 148

#define ERREXIT(fmt, ...) \

do { \

fprintf(stderr,(fmt), ## __VA_ARGS__); \

fprintf(stderr,"\n"); \

goto Exit; \

} \

while (0)

enum direct_e {

DIRECT_NORTH=0,

DIRECT_EAST =1,

DIRECT_SOUTH=2,

DIRECT_WEST =3

};

struct comm_s {

int visit;

qsmm_side_t side_maze;

qsmm_side_t side_walker;

};

struct maze_response_s {

char is_obstacle;

char is_gold_found;

unsigned char percept;

};

static int n_gold_found=0, path_len=0;

static void *maze_thread(void *paramp) {

static int maze[][4]={

{21, 1, -1, -1}, // 0

{24, 0, -1, 11}, // 1

{-1, 9, -1, -1}, // 2

{ 7, 4, -1, 8}, // 3

{-1, -1, -1, 3}, // 4

{-1, 6, -1, -1}, // 5

{-1, 12, 7, 5}, // 6

{14, -1, 3, 6}, // 7

{10, -1, 3, 20}, // 8

{12, 13, 2, -1}, // 9

{ 8, -1, -1, -1}, // 10

{-1, -1, -1, 1}, // 11

{-1, 15, 9, 6}, // 12

{-1, -1, 9, -1}, // 13

{-1, -1, 7, -1}, // 14

{25, 16, 12, -1}, // 15

{-1, -1, -1, 15}, // 16

{21, -1, -1, -1}, // 17

{23, -1, -1, -1}, // 18

{-1, 20, -1, -1}, // 19

{26, 8, -1, 19}, // 20

{23, 17, 0, -1}, // 21

{-1, 24, -1, -1}, // 22

{28, 18, 21, -1}, // 23

Chapter 6: Miscellaneous Topics 227

{-1, 25, 22, 1}, // 24

{35, -1, 15, 24}, // 25

{32, 27, 20, -1}, // 26

{33, 36, -1, 26}, // 27

{30, 29, 23, -1}, // 28

{-1, -1, -1, 28}, // 29

{28, 31, -1, 34}, // 30

{-1, -1, -1, 30}, // 31

{26, -1, -1, -1}, // 32

{-1, -1, 27, -1}, // 33

{-1, -1, 30, -1}, // 34

{-1, -1, 25, -1}, // 35

{-1, -1, -1, 27} // 36

};

char do_dump_path;

int ii, node_curr=0;

qsmm_side_t side_maze, side_walker;

enum direct_e direct;

struct comm_s *comm_p=paramp;

struct maze_response_s response;

memset(&response,0,sizeof(response));

do_dump_path=(comm_p->visit==NVISIT-1);

side_maze=comm_p->side_maze;

side_walker=comm_p->side_walker;

QSMM_SIDE_RECV(side_maze,&direct);

while (1) {

int node_new;

if (response.percept) {

if (do_dump_path) printf(" x");

}

else {

for (ii=0; ii<4; ii++)

if (maze[node_curr][ii]>=0) response.percept|=1 << ii;

if (do_dump_path)

printf(" %d:%s%s%s%s", node_curr,

(response.percept & (1 << DIRECT_NORTH))?"N":"",

(response.percept & (1 << DIRECT_EAST ))?"E":"",

(response.percept & (1 << DIRECT_SOUTH))?"S":"",

(response.percept & (1 << DIRECT_WEST ))?"W":"");

if (node_curr==31 && !response.is_gold_found) {

if (do_dump_path) printf("(***)");

response.is_gold_found=1;

}

if (node_curr==36) break;

}

QSMM_SIDE_SEND(side_maze,side_walker,response);

QSMM_SIDE_RECV(side_maze,&direct);

node_new=(node_curr>=0?maze[node_curr][direct]:0);

if (node_new<0) {

response.is_obstacle=1;

response.percept=16;

}

else {

response.is_obstacle=0;

response.percept=0;

node_curr=node_new;

}

assert(node_curr>=0 && node_curr<sizeof(maze)/sizeof(*maze));

}

response.percept=-1;

QSMM_SIDE_SEND(side_maze,side_walker,response);

if (do_dump_path) fflush(stdout);

return 0;

}

Chapter 6: Miscellaneous Topics 228

static QSMM_INSTR_META_CLASS(move) {

const char *ccp;

enum direct_e direct=0;

if (QSMM_HAS_INSTR_CLASS(qsmm_evt))

qsmm_get_eh_instr_param(qsmm,sizeof(direct),&direct);

switch (qsmm_evt) {

case QSMM_EVT_INSTR_CLASS_INIT:

switch (direct) {

case DIRECT_NORTH: ccp="north"; break;

case DIRECT_EAST: ccp="east"; break;

case DIRECT_SOUTH: ccp="south"; break;

case DIRECT_WEST: ccp="west"; break;

default: assert(0);

}

qsmm_set_eh_instr_param_str_f(qsmm,"%s",ccp);

qsmm_set_eh_noutcome(qsmm,17);

break;

case QSMM_EVT_ACTIVATE: {

qsmm_side_t side_walker;

struct comm_s *comm_p=qsmm_get_ptr(qsmm,0);

struct maze_response_s maze_response;

side_walker=comm_p->side_walker;

QSMM_SIDE_SEND(side_walker,comm_p->side_maze,direct);

QSMM_SIDE_RECV(side_walker,&maze_response);

qsmm_time_delta(qsmm,1);

qsmm_set_la_sig(qsmm,0,maze_response.is_gold_found);

if (maze_response.percept==(unsigned char) -1) {

if (maze_response.is_gold_found) {

qsmm_spur_delta(qsmm,1,1);

n_gold_found++;

}

qsmm_return_to_caller_node(qsmm);

}

else {

if (!maze_response.is_obstacle) path_len++;

qsmm_set_instr_outcome(qsmm,maze_response.percept);

}

break;

}

}

return 0;

}

static QSMM_INSTR_CLASS_SET(walker) {

enum direct_e direct;

switch (qsmm_evt) {

case QSMM_EVT_ENT_INIT: {

direct=DIRECT_NORTH, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_EAST, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_SOUTH, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

direct=DIRECT_WEST, QSMM_REG_INSTR_CLASS_PARAM(move,direct);

qsmm_set_nstate_max(qsmm,__FUNCTION__,NSTATE);

QSMM_NODE_CREATE(0);

break;

}

case QSMM_EVT_NODE_ENTER: {

qsmm_side_t side_walker;

struct comm_s *comm_p=qsmm_get_ptr(qsmm,0);

struct maze_response_s maze_response;

qsmm_set_la_sig(qsmm,0,0);

side_walker=comm_p->side_walker;

direct=DIRECT_NORTH;

QSMM_SIDE_SEND(side_walker,comm_p->side_maze,direct);

Chapter 6: Miscellaneous Topics 229

QSMM_SIDE_RECV(side_walker,&maze_response);

break;

}

}

return 0;

}

int main(int argc, char **argv) {

int rc, seed=0, exit_code=1;

qsmm_t qsmm=0;

pthread_t thread_maze;

struct comm_s comm;

struct qsmm_desc_s desc;

memset(&comm,0,sizeof(comm));

if ((rc=qsmm_side_create("maze",&comm.side_maze)<0) ||

(rc=qsmm_side_create("walker",&comm.side_walker)<0))

ERREXIT("qsmm_side_create: %s",qsmm_side_err_str(rc));

memset(&desc,0,sizeof(desc));

desc.dont_use_instr_class_weights=1;

desc.is_large_env=1;

desc.is_large_opt=1;

desc.nspur=2;

desc.stack_sz_max=1;

desc.ngram_env_la_sz=1;

desc.nsig_ngram_env_la=2;

desc.sparse_fill_max=0.2;

desc.compat=1;

if ((rc=qsmm_create(&desc,&qsmm))<0)

ERREXIT("qsmm_create: %s",qsmm_err_str(rc));

qsmm_set_ptr(qsmm,0,&comm);

QSMM_REG_INSTR_META_CLASS(qsmm,move,0);

QSMM_REG_INSTR_CLASS_SET(qsmm,walker,0);

qsmm_engine_create(qsmm);

if (argc>1 && (seed=atoi(argv[1]))<0) {

qsmm_set_random(qsmm,1);

seed=-seed;

}

qsmm_rng_seed(qsmm_get_rng(qsmm),seed);

for (comm.visit=0; comm.visit<NVISIT; comm.visit++) {

if ((rc=pthread_create(&thread_maze,0,&maze_thread,&comm)))

ERREXIT("pthread_create() failed with error code %d",rc);

qsmm_node_call_default(qsmm,0,0);

pthread_join(thread_maze,0);

}

printf("\nn_gold_found=%d\npath_len=%d\nn_gold_found/path_len=%.8f\n",

n_gold_found, path_len, (double) n_gold_found/path_len);

exit_code=0;

Exit:

qsmm_destroy(qsmm);

qsmm_side_destroy(comm.side_walker);

qsmm_side_destroy(comm.side_maze);

return exit_code;

}

6.5 The Implementation of Functionality of STL map Template

The QSMM framework contains the implementation of functionality of STL map and multimap

templates. You can use the implementation in your C programs to create mapping objects wi-thout the need to rewrite the programs in C++, which may substantially increase their complexi-ty.

Chapter 6: Miscellaneous Topics 230

The behavior of the current implementation differs from the behavior of STL map andmultimap templates in the following.

• Function qsmm_map_erase, which corresponds to method erase of map and multimap

templates, may call a key comparison function for the key of a key-value pair being removedand that key must be a valid object. Therefore, when removing a key-value pair from amap or a multimap, the key of the pair must be uninitialized and/or destroyed after callingfunction qsmm_map_erase, not before.

• The implementation of functionality of the STL multimap template does not provide storingkey-value pairs with the same key in order, in which they were added to a multimap.

Datatypes and functions of the implementation are declared in header file ‘qsmm/map.h’,which is installed in a directory for C header files set by the ‘configure’ script.

6.5.1 Creating Maps and Iterators

A mapping object is referred to by a map handle.

[Data type]qsmm_map_tThis is a type for a map handle, which corresponds to a mapping object that implements thefunctionality of STL map or multimap template. It is a pointer, so variables of this type canhave zero value. A new map handle is allocated by functions qsmm_map_create, qsmm_map_create_sz, qsmm_map_multi_create, and qsmm_map_multi_create_sz. Function qsmm_

map_destroy frees an existing map handle. After allocating a map handle, it can be passedto API functions that take argument qsmm_map_t until the handle is freed.

There are the following ways of dealing with keys and values in key-value pairs of a mappingobject.

1. Keys and/or values stored in key-value pair objects are untyped pointers. In this case,the developer should code allocation and deallocation of memory blocks addressed by theuntyped pointers explicitly. However, when keys and/or values are integer numbers, theycan be converted to the standard intptr_t type and stored as pointers, which does notrequire manual memory allocation and deallocation.

2. Contents of keys and/or values are stored at the end of memory blocks of key-value pairobjects. The size of key-value pair object is extended by the size of key and/or value memoryblock. The size of each key and/or value memory block has to be specified when creatingthe mapping object. Thus, there is no need to perform manual allocation and deallocationof memory blocks for keys and/or values. At the same time, no additional memory blocksare allocated and deallocated by the mapping object itself—memory blocks of keys and/orvalues are simply parts of memory blocks of key-value pair objects. This method of dealingwith keys and/or values speeds up program operation and removes memory overhead causedby storing additional memory management structures.

To create and destroy a mapping object, the following functions can be used.

[Function]qsmm_map_t qsmm_map_create (qsmm compar func t key_compar_func,void *paramp )

[Function]qsmm_map_t qsmm_map_create_sz (int key_sz, int val_sz,qsmm compar func t key_compar_func, void *paramp )

[Function]qsmm_map_t qsmm_map_multi_create (qsmm compar func tkey_compar_func, void *paramp )

[Function]qsmm_map_t qsmm_map_multi_create_sz (int key_sz, int val_sz,qsmm compar func t key_compar_func, void *paramp )

These functions create a mapping object. Functions qsmm_map_create and qsmm_map_

create_sz create a mapping object that implements the functionality of the STL map

Chapter 6: Miscellaneous Topics 231

template, i.e. a mapping object that may not contain duplicate keys in key-value pai-rs. Functions qsmm_map_multi_create and qsmm_map_multi_create_sz create a mappi-ng object that implements the functionality of the STL multimap template, i.e. a mappingobject that may contain duplicate keys in key-value pairs. However, as distinct from theSTL multimap template, a mapping object created by function qsmm_map_multi_create orqsmm_map_multi_create_sz does not provide storing key-value pairs with the same key inorder, in which they were added to the mapping object.

Argument key compar func specifies a comparison function for keys of the mapping object.Argument paramp specifies a user parameter of that comparison function.

Functions qsmm_map_create and qsmm_map_multi_create create a mapping object, whichkeys and values are untyped pointers. Functions qsmm_map_create_sz and qsmm_map_multi_

create_sz create a mapping object, which keys have size specified by key sz, and whichvalues have size specified by val sz. When key sz is negative, the keys are untyped pointers.When key sz is positive, each key has size key sz bytes. The value of key sz equal to 0 isdisallowed. When val sz is negative, the values are untyped pointers. When val sz is positive,each value has size val sz bytes. When val sz is 0, the mapping object cannot store values,which correspond to keys, i.e. the mapping object is actually a set object, and set elementsare the keys of the mapping object.

Call qsmm_map_create(&compar,paramp) is equivalent to call qsmm_map_create_sz(-1,-1,&compar,paramp). Call qsmm_map_multi_create(&compar,paramp) is equivalent to callqsmm_map_multi_create_sz(-1,-1,&compar,paramp).

On success, the functions return a non-zero map handle. If there is not enough memory tocreate the mapping object, then the functions will return 0.

[Function]void qsmm_map_destroy (qsmm map t mm )This function destroys a mapping object specified by map handle mm. After mapping objectdestruction, the map handle must not be used. If mm is 0, then the function will do nothing.If keys and/or values in key-value pairs of the mapping object contain untyped pointers tomanually created objects, then those objects will not be automatically destroyed by thisfunction and must be destroyed manually before destroying the mapping object. If memoryblocks of key-value pairs of the mapping object contain memory blocks of keys and/or values,which require special uninitialization, then that uninitialization must be performed manuallybefore destroying the mapping object.

When creating a mapping object, the developer must provide a function for comparing keysof the mapping object and a user parameter of that function. All key-value pairs in a mappingobject are sorted is ascending order of keys. The type of a pointer to the comparison functionis described below.

[Data type]qsmm_compar_func_tThis is a type of a pointer to a key comparison function. To this type the following declarationcorresponds:

typedef int (*qsmm_compar_func_t)(

const void *o1p,

const void *o2p,

void *paramp);

A key comparison function should compare two keys pointed by arguments o1p and o2p andreturn a value greater than 0 if the first key is greater than the second key, a value less than0 if the first key is less than the second key, or 0 if the keys are equal. A user parameter ispassed via argument paramp.

A pointer to a key comparison function and a user parameter of that function specified whencreating a mapping object can be obtained using the following functions.

Chapter 6: Miscellaneous Topics 232

[Function]qsmm_compar_func_t qsmm_map_key_compar_func (qsmm map t mm )This function returns a pointer to a key comparison function specified when creating mappingobject mm.

[Function]void * qsmm_map_key_compar_param (qsmm map t mm )This function returns a user parameter of key comparison function specified when creatingmapping object mm.

The size of keys and values specified when creating a mapping object can be obtained usingthe following functions.

[Function]int qsmm_map_key_sz (qsmm map t mm )This function returns the size of a key in each key-value pair of mapping object mm. Apositive result indicates the size in bytes of the memory block of key in the memory block ofkey-value pair object. A negative result indicates that the keys are untyped pointers. Thefunction shall not return 0.

[Function]int qsmm_map_val_sz (qsmm map t mm )This function returns the size of a value in each key-value pair of mapping object mm. Apositive result indicates the size in bytes of the memory block of value in the memory blockof key-value pair object. A negative result indicates that the values are untyped pointers.Zero result means that the mapping object cannot store values, which correspond to keys,i.e. the mapping object is actually a set object, and set elements are the keys of the mappingobject.

To access key-value pairs of mapping objects, map iterators are used. A map iterator isreferred to by an iterator handle.

[Data type]qsmm_iter_tThis is a type for an iterator handle. It is a pointer, so variables of this type can have zerovalue.

A new iterator handle is allocated by functions qsmm_map_iter_create and qsmm_map_

multi_iter_create. An iterator handle allocated by function qsmm_map_iter_create

should be used with mapping objects, which handles were allocated by functions qsmm_

map_create and qsmm_map_create_sz. An iterator handle allocated by function qsmm_map_

multi_iter_create should be used with mapping objects, which handles were allocated byfunctions qsmm_map_multi_create and qsmm_map_multi_create_sz.

Function qsmm_map_iter_destroy frees an existing iterator handle. After allocating aniterator handle, it can be passed to API functions that take argument qsmm_iter_t untilthe handle is freed.

To create and destroy a map iterator, the following functions can be used.

[Function]qsmm_iter_t qsmm_map_iter_create ()This function creates an iterator to be used with mapping objects that implement the functi-onality of the STL map template. On success, the function returns a non-zero iterator handle.If there is not enough memory to create the iterator, then the function will return 0.

[Function]qsmm_iter_t qsmm_map_multi_iter_create ()This function creates an iterator to be used with mapping objects that implement the functi-onality of the STL multimap template. On success, the function returns a non-zero iteratorhandle. If there is not enough memory to create the iterator, then the function will return 0.

Chapter 6: Miscellaneous Topics 233

[Function]void qsmm_map_iter_destroy (qsmm iter t iter )This function destroys a map iterator specified by iterator handle iter. After map iteratordestruction, the iterator handle must not be used. If iter is 0, then the function will donothing.

6.5.2 Operations on Maps

In this section, basic operations on mapping objects are described. Every operation correspondsto a method of STL map and multimap templates.

[Function]size_t qsmm_map_size (qsmm map t mm )This function returns the number of key-value pairs contained in mapping object mm. Thefunction corresponds to method size of STL map and multimap templates.

[Function]int qsmm_map_is_empty (qsmm map t mm )This function returns a positive value if mapping object mm does not contain key-value pairs,or zero if it does. Negative values are never returned. The function corresponds to methodempty of STL map and multimap templates.

[Function]int qsmm_map_assign (qsmm map t dst, qsmm map t src )This function copies all key-value pairs of mapping object src to mapping object dst. Allkey-value pairs, which were in mapping object dst before the copying, are discarded. Mappi-ng objects src and dst must be both created using either functions qsmm_map_create andqsmm_map_create_sz or functions qsmm_map_multi_create and qsmm_map_multi_create_

sz, have the same pointer to the key comparison function and its user parameter.

If keys and/or values stored in key-value pair objects are untyped pointers, then only thosepointers will be copied or discarded, memory blocks the pointers may point to will not beaffected. If memory blocks of key-value pair objects contain memory blocks of keys and/orvalues, then the contents of those memory blocks will be copied or discarded.

Function qsmm_map_assign corresponds to operator= of STL map and multimap templates.The function returns a non-negative value on success or a negative value on out of memoryerror.

[Function]int qsmm_map_insert (qsmm map t mm, void *keyp, void *valp,qsmm iter t result_loc )

This function inserts a key-value pair in mapping object mm. Argument keyp specifies a keyof the pair. Argument valp specifies a value of the pair.

If keys and/or values stored in key-value pair objects are untyped pointers, then the functionwill insert untyped pointer keyp and/or valp in the mapping object. If memory blocks ofkey-value pair objects contain memory blocks of keys and/or values, then a memory blockpointed by keyp and/or valp will be copied to the key-value pair object being inserted. Ifmemory blocks of key-value pair objects contain memory blocks of values and valp is 0, thenthe memory block of value in the key-value pair object being inserted will be initialized withzero bytes.

If mapping object mm is created using function qsmm_map_create or qsmm_map_create_sz,then it cannot contain duplicate keys. Uniqueness of keys is determined using a comparisonfunction specified when creating the mapping object. When adding a new key-value pair witha key, which is already contained in the mapping object, the new key-value pair replaces an oldkey-value pair. Replacing the old pair may cause a memory leak if the pair contains pointersto manually allocated memory blocks. If mapping object mm is created using function qsmm_

map_multi_create or qsmm_map_multi_create_sz, then it can contain multiple key-valuepairs with the same key.

Chapter 6: Miscellaneous Topics 234

If result loc is not 0, then after successful function completion, iterator result loc will pointto a new key-value pair inserted in mapping object mm. The type of iterator result loc mustagree with the type of mapping object mm. Calling the function with non-zero result loc isuseful when memory blocks of key-value pair objects contain memory blocks of values andvalp is 0. In this case, a pointer to the memory block of value preinitialized with zero bytescan be obtained by call qsmm_map_iter_val(result_loc) for setting the value.

This function corresponds to method insert of STL map and multimap templates. Thefunction returns a non-negative value on success or a negative value on out of memory error.

[Function]void qsmm_map_clear (qsmm map t mm )This function removes all key-value pairs from mapping object mm. Memory blocks, pointersto which might be held in key-value pairs, are not affected. The function corresponds tomethod clear of STL map and multimap templates.

[Function]void qsmm_map_find (qsmm map t mm, const void *keyp, qsmm iter tresult )

This function finds in mapping object mm a key-value pair that has a key equal to keyp. Ifthe mapping object is created using function qsmm_map_multi_create or qsmm_map_multi_create_sz, then the function will find in the mapping object the first key-value pair that hasa key equal to keyp. Equality of keys is tested using a comparison function specified whencreating the mapping object. Function qsmm_map_find corresponds to method find of STLmap and multimap templates.

After function completion, iterator result refers to a key-value pair found. If a key-value pairnot found, then iterator result will refer to a place just after the last key-value pair in themapping object. The type of iterator result must agree with the type of mapping object mm.

[Function]void qsmm_map_lower_bound (qsmm map t mm, const void *keyp,qsmm iter t result )

This function finds in mapping object mm the first key-value pair that has a key greaterthan or equal to keyp. The function corresponds to method lower_bound of STL map andmultimap templates.

After function completion, iterator result refers to a key-value pair found. If a key-value pairnot found, then iterator result will refer to a place just after the last key-value pair in themapping object. The type of iterator result must agree with the type of mapping object mm.

[Function]void qsmm_map_upper_bound (qsmm map t mm, const void *keyp,qsmm iter t result )

This function finds in mapping object mm the first key-value pair that has a key greaterthan keyp. The function corresponds to method upper_bound of STL map and multimap

templates.

After function completion, iterator result refers to a key-value pair found. If a key-value pairnot found, then iterator result will refer to a place just after the last key-value pair in themapping object. The type of iterator result must agree with the type of mapping object mm.

[Function]void qsmm_map_erase (qsmm map t mm, qsmm iter t where )This function removes from mapping object mm a key-value pair addressed by iterator where.Memory blocks, pointers to which might be contained in the key-value pair, are not affected.The function corresponds to method erase of STL map and multimap templates.

Note: when removing a key-value pair from a mapping object, the key of the pairmust be uninitialized and/or destroyed after calling function qsmm_map_erase,not before. It is because in the current implementation function qsmm_map_erase

may call a key comparison function for the key of a key-value pair being removed,and that key must be a valid object.

Chapter 6: Miscellaneous Topics 235

6.5.3 Operations on Iterators

In this section operations on map iterators are described.

[Function]int qsmm_map_iter_is_end (qsmm map t mm, qsmm iter t iter )This function returns a positive value if iterator iter is a forward (normal) iterator that refersto a place just after the last key-value pair in mapping object mm or if iterator iter is areverse iterator that refers to a place just before the first key-value pair in mapping objectmm, or returns 0 otherwise. The function never returns negative values.

[Function]int qsmm_map_iter_are_equal (qsmm iter t iter1, qsmm iter t iter2 )This function returns a positive value if iterators iter1 and iter2 refer to the same locationin a mapping object, or returns 0 otherwise. The function never returns negative values.

[Function]void qsmm_map_iter_begin (qsmm map t mm, qsmm iter t result )This function retrieves a location of the first key-value pair in mapping object mm. Afterfunction completion, iterator result refers to that key-value pair. If the mapping object doesnot contain key-value pairs, then iterator result will refer to a place, commonly designatedas a place just after the last key-value pair in the mapping object. The type of iterator resultmust agree with the type of mapping object mm. The function corresponds to method begin

of STL map and multimap templates.

[Function]void qsmm_map_iter_end (qsmm map t mm, qsmm iter t result )This function makes iterator result to refer to a place just after the last key-value pair inmapping object mm. The type of iterator result must agree with the type of mapping objectmm. The function corresponds to method end of STL map and multimap templates.

[Function]void qsmm_map_iter_rbegin (qsmm map t mm, qsmm iter t result )This function makes iterator result to be a reverse iterator that refers to the last key-valuepair (in ascending order of keys) in mapping object mm. If the mapping object does notcontain key-value pairs, then iterator result will refer to a place, commonly designated as aplace just before the first key-value pair in the mapping object. The type of iterator resultmust agree with the type of mapping objectmm. The function corresponds to method rbegin

of STL map and multimap templates.

[Function]void qsmm_map_iter_rend (qsmm map t mm, qsmm iter t result )This function makes iterator result to be a reverse iterator that refers to a place just beforethe first key-value pair in mapping object mm. The type of iterator result must agree withthe type of mapping object mm. The function corresponds to method rend of STL map andmultimap templates.

[Function]void qsmm_map_iter_next (qsmm iter t iter )This function makes iterator iter to refer to the next key-value pair in a mapping object. Ifiterator iter is a forward (normal) iterator, then it will refer to the next key-value pair inascending order of keys. If iterator iter is a reverse iterator, then it will refer to the nextkey-value pair in descending order of keys (i.e. to the previous key-value pair in ascendingorder of keys).

[Function]void qsmm_map_iter_prev (qsmm iter t iter )This function makes iterator iter to refer to the previous key-value pair in a mapping object.If iterator iter is a forward (normal) iterator, then it will refer to the previous key-value pairin ascending order of keys (i.e. to the next key-value pair in descending order of keys). Ifiterator iter is a reverse iterator, then it will refer to the previous key-value pair in descendingorder of keys (i.e. to the next key-value pair in ascending order of keys).

Chapter 6: Miscellaneous Topics 236

[Function]void qsmm_map_iter_assign (qsmm iter t dst, qsmm iter t src )This function makes iterator dst to refer to the same place as iterator src. An indicationwhether an iterator is forward (normal) or reverse one is also copied from src to dst. Iteratorssrc and dst must be both created using either function qsmm_map_iter_create or functionqsmm_map_multi_iter_create.

[Function]void qsmm_map_iter_set_val (qsmm iter t iter, void *valp )This function sets to valp the value part of a key-value pair addressed by iterator iter. Anold value is discarded. If a value stored in the key-value pair object is an untyped pointer,then this function will set the value equal to valp. If the memory block of the key-value pairobject contains the memory block of value, then this function will replace the contents of thelatter memory block with the contents of a memory block pointed by valp.

[Function]void * qsmm_map_iter_key (qsmm iter t iter )This function returns the key component of a key-value pair addressed by iterator iter. Ifa key stored in the key-value pair object is an untyped pointer, then that pointer will bereturned. If the memory block of the key-value pair object contains the memory block of key,then a pointer to the latter memory block will be returned.

[Function]void * qsmm_map_iter_val (qsmm iter t iter )This function returns the value component of a key-value pair addressed by iterator iter. Ifa value stored in the key-value pair object is an untyped pointer, then that pointer will bereturned. If the memory block of the key-value pair object contains the memory block ofvalue, then a pointer to the latter memory block will be returned.

6.5.4 Example of Using a Mapping Object

In the example of using a mapping object, the program counts frequencies of words in a text andprints the table of word frequencies in descending order by frequency. Words, which frequenciesare counted by the program, are sequences of alphanumeric characters. All other characters areconsidered as word delimiters.

The program should be invoked with an argument that specifies the name of a file with aninput text. An optional second argument should be a positive integer number that specifies howmany most frequent words to print in the resulting frequency table.

The source code of the example is provided in file ‘samples/fqtab.c’ in the package distri-bution and is also given below.

#include <ctype.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <qsmm/map.h>

#define ERREXIT(fmt, ...) \

do { \

fprintf(stderr,(fmt), ## __VA_ARGS__); \

fprintf(stderr,"\n"); \

goto Exit; \

} \

while (0)

struct word_fq_s {

char *word;

int fq;

};

Chapter 6: Miscellaneous Topics 237

static qsmm_iter_t iter_word_to_fq=0;

static qsmm_map_t map_word_to_fq=0;

static int word_add(const char *word) {

qsmm_map_find(map_word_to_fq,word,iter_word_to_fq);

if (qsmm_map_iter_is_end(map_word_to_fq,iter_word_to_fq)) {

char *keyp=strdup(word);

if (!keyp) return -1;

if (qsmm_map_insert(map_word_to_fq,keyp,0,iter_word_to_fq)<0) {

free(keyp);

return -1;

}

}

(*((int *) qsmm_map_iter_val(iter_word_to_fq)))++;

return 0;

}

static int word_compar(const void *o1p, const void *o2p, void *dummyp) {

return strcmp(o1p,o2p);

}

static int word_fq_compar(const void *o1p, const void *o2p) {

int result;

const struct word_fq_s *word_fq_1p=o1p, *word_fq_2p=o2p;

if ((result=word_fq_2p->fq-word_fq_1p->fq)) return result;

return strcmp(word_fq_1p->word,word_fq_2p->word);

}

int main(int argc, char **argv) {

const char *fln_text;

char *word_p=0;

int ii, nword, word_sz=0, word_allo=2, n_word_top=0, exit_code=1;

FILE *file_text_p=0;

struct word_fq_s *word_fq_p=0;

if (argc<2) ERREXIT("input file not specified");

fln_text=argv[1];

if (!(file_text_p=fopen(fln_text,"r")))

ERREXIT("%s: failed to open the file",fln_text);

if (argc>2 && (n_word_top=atoi(argv[2]))<1)

ERREXIT("invalid number of the most frequent words");

if (!(word_p=calloc(word_allo,sizeof(*word_p))) ||

!(iter_word_to_fq=qsmm_map_iter_create()) ||

!(map_word_to_fq=

qsmm_map_create_sz(-1,sizeof(int),&word_compar,0)))

ERREXIT("out of memory");

while (1) {

int cc=fgetc(file_text_p);

if (cc==EOF) {

if (ferror(file_text_p))

ERREXIT("%s: failed to read the file",fln_text);

if (word_sz>0 && word_add(word_p)<0) ERREXIT("out of memory");

break;

}

if (isalnum(cc)) {

if (word_sz+2>word_allo) {

char *new_p;

int allo=word_allo*3/2;

if (!(new_p=realloc(word_p,allo)))

ERREXIT("out of memory");

Chapter 6: Miscellaneous Topics 238

word_p=new_p;

word_allo=allo;

}

word_p[word_sz++]=cc;

word_p[word_sz]=0;

}

else if (word_sz>0) {

if (word_add(word_p)<0) ERREXIT("out of memory");

*word_p=0;

word_sz=0;

}

}

nword=qsmm_map_size(map_word_to_fq);

if (!(word_fq_p=calloc(nword,sizeof(*word_fq_p))))

ERREXIT("out of memory");

for (ii=0, qsmm_map_iter_begin(map_word_to_fq,iter_word_to_fq);

!qsmm_map_iter_is_end(map_word_to_fq,iter_word_to_fq);

ii++, qsmm_map_iter_next(iter_word_to_fq)) {

word_fq_p[ii].word=qsmm_map_iter_key(iter_word_to_fq);

word_fq_p[ii].fq=*((int *) qsmm_map_iter_val(iter_word_to_fq));

}

qsort(word_fq_p,nword,sizeof(*word_fq_p),&word_fq_compar);

for (ii=0; ii<nword; ii++) {

printf("%d\t%s\n", word_fq_p[ii].fq, word_fq_p[ii].word);

if (n_word_top>0 && ii>=n_word_top) break;

}

exit_code=0;

Exit:

if (map_word_to_fq) {

if (iter_word_to_fq)

for (qsmm_map_iter_begin(map_word_to_fq,iter_word_to_fq);

!qsmm_map_iter_is_end(map_word_to_fq,iter_word_to_fq);

qsmm_map_iter_next(iter_word_to_fq))

free(qsmm_map_iter_key(iter_word_to_fq));

qsmm_map_destroy(map_word_to_fq);

}

if (iter_word_to_fq) qsmm_map_iter_destroy(iter_word_to_fq);

if (file_text_p) fclose(file_text_p);

if (word_fq_p) free(word_fq_p);

if (word_p) free(word_p);

return exit_code;

}

Below there is given sample program output. The program prints 10 most frequent wordscontained in its source text.

$ ./fqtab fqtab.c 10

86 word

52 fq

32 p

32 to

32 iter

32 map

23 0

23 if

21 qsmm

12 int

11 ii

Note that frequencies of words calculated for the text of the example program presented inthis subsection will differ from frequencies of words calculated for file ‘samples/fqtab.c’ in thepackage distribution because the file is prepended with a license block.

Chapter 7: Example Programs 239

7 Example Programs

In this chapter example programs are described, which demonstrate various aspects of packageuse and which source code is not included in this manual. Source code for these programs isavailable in directory ‘samples’ in the package distribution. The programs do not get installedby command make install.

7.1 optact

This program demonstrates a behavior of an actor when it emits more frequently output signalsimmediately followed by greater mean spur increments. However, the program does not reveal ageneric aspect of actor’s behavior when the frequency of emitting an output signal also dependson spur increments that were made at later time after emitting the output signal.

In the example program, the actor randomly receives one of signal vectors <3, 0, 4>, <1, 2,5>, <5, 3, 3>, <2, 4, 0>, and <4, 2, 1>, which represent action choice states shown in Figure 2.1(and one additional action choice state), and emits one of four output signals. The total numberof signal vectors received and output signals emitted is defined by macro NSTEP (that has value40000).

For each action choice state vector, fixed probabilities are assigned to four possible outputsignals. According to those probabilities, the actor receives spur increment 1 when it emitscorresponding output signals. The expected actor behavior is to emit more frequently outputsignals, to which greater probabilities correspond.

The researcher may want to change the problem statement and to make an actor emit outputsignals with frequencies proportional to the fixed probabilities. In this case, instead of makingspur increment 1 according to a fixed probability, spur increment equal to the logarithm ofthe fixed probability should be made. There are also other specifics that should be consideredwhen solving this another kind of problem. See a program described in Section 7.10 [optact-p],page 259, where the problem is solved. For example, run that program using command line

$ ./optact-p -i1 -a -n40000 --dump-prob=learnt 5 4

At the end of its run, the optact program prints a table with the numbers of output signalsemitted in each action choice state, i.e. with frequencies of those output signals. The frequenciesare printed near fixed probabilities of output signals specified in the program source text. Theprogram also dumps the contents of statistics storage of the actor.

A random seed can be specified by a program argument. If the random seed is non-negative,then the actor will operate normally. If the random seed is negative, then the actor will generateoutput signals completely randomly. You could compare the resulting frequencies of outputsignals for these two modes of program execution.

Below there is given sample program output for the completely random mode of operationof the program.

$ ./optact -1

< 3 0 4 > : 0.2/1975 0.4/2004 0.3/2010 0.1/1917

< 1 2 5 > : 0.4/2062 0.1/2071 0.3/1902 0.2/1966

< 5 3 3 > : 0.2/2010 0.2/2031 0.2/2026 0.4/2000

< 2 4 0 > : 0.1/1993 0.3/2000 0.5/2032 0.1/2017

< 4 2 1 > : 0.3/2052 0.3/1924 0.2/2000 0.2/2008

State < 1 2 5 >: sig_cycle_next=7, tmd0=159975, tmc0=119982, s0=10097

sig_next=6: fq=2062, pd_s=40584, pc_s=30438, sd_s=2903, ave=0.0953742

sig_next=7: fq=2070, pd_s=40996, pc_s=30747, sd_s=2283, ave=0.0742511

sig_next=8: fq=1902, pd_s=39252, pc_s=29439, sd_s=2646, ave=0.0898808

sig_next=9: fq=1966, pd_s=39132, pc_s=29349, sd_s=2264, ave=0.0771406

Chapter 7: Example Programs 240

State < 2 4 0 >: sig_cycle_next=7, tmd0=159967, tmc0=119976, s0=10097

sig_next=6: fq=1993, pd_s=40632, pc_s=30474, sd_s=2262, ave=0.0742272

sig_next=7: fq=1999, pd_s=39536, pc_s=29652, sd_s=2664, ave=0.0898422

sig_next=8: fq=2032, pd_s=39988, pc_s=29991, sd_s=2968, ave=0.098963

sig_next=9: fq=2017, pd_s=39788, pc_s=29841, sd_s=2199, ave=0.0736906

State < 3 0 4 >: sig_cycle_next=7, tmd0=159983, tmc0=119988, s0=10098

sig_next=6: fq=1975, pd_s=39632, pc_s=29724, sd_s=2374, ave=0.0798681

sig_next=7: fq=2003, pd_s=41184, pc_s=30888, sd_s=2894, ave=0.0936933

sig_next=8: fq=2010, pd_s=39808, pc_s=29856, sd_s=2638, ave=0.0883574

sig_next=9: fq=1917, pd_s=39340, pc_s=29505, sd_s=2189, ave=0.0741908

State < 4 2 1 >: sig_cycle_next=6, tmd0=159999, tmc0=120000, s0=10098

sig_next=6: fq=2051, pd_s=41372, pc_s=31029, sd_s=2719, ave=0.0876277

sig_next=7: fq=1924, pd_s=38692, pc_s=29019, sd_s=2526, ave=0.0870464

sig_next=8: fq=2000, pd_s=41208, pc_s=30906, sd_s=2460, ave=0.0795962

sig_next=9: fq=2008, pd_s=38720, pc_s=29040, sd_s=2393, ave=0.0824036

State < 5 3 3 >: sig_cycle_next=9, tmd0=159979, tmc0=119985, s0=10097

sig_next=6: fq=2010, pd_s=39676, pc_s=29757, sd_s=2380, ave=0.0799812

sig_next=7: fq=2031, pd_s=40344, pc_s=30258, sd_s=2421, ave=0.0800119

sig_next=8: fq=2026, pd_s=40760, pc_s=30570, sd_s=2477, ave=0.0810272

sig_next=9: fq=1999, pd_s=39196, pc_s=29397, sd_s=2819, ave=0.0958941

Below there is given sample program output for the normal mode of operation of the program.

$ ./optact 1

< 3 0 4 > : 0.2/1551 0.4/3253 0.3/2295 0.1/807

< 1 2 5 > : 0.4/3297 0.1/1333 0.3/2136 0.2/1235

< 5 3 3 > : 0.2/1797 0.2/1674 0.2/1321 0.4/3275

< 2 4 0 > : 0.1/1223 0.3/2031 0.5/3781 0.1/1007

< 4 2 1 > : 0.3/2506 0.3/2095 0.2/1624 0.2/1759

State < 1 2 5 >: sig_cycle_next=6, tmd0=159975, tmc0=119982, s0=11849

sig_next=6: fq=3296, pd_s=64696, pc_s=48522, sd_s=5176, ave=0.106673

sig_next=7: fq=1333, pd_s=26876, pc_s=20157, sd_s=1741, ave=0.086372

sig_next=8: fq=2136, pd_s=44124, pc_s=33093, sd_s=3327, ave=0.100535

sig_next=9: fq=1235, pd_s=24268, pc_s=18201, sd_s=1604, ave=0.088127

State < 2 4 0 >: sig_cycle_next=8, tmd0=159967, tmc0=119976, s0=11848

sig_next=6: fq=1223, pd_s=26192, pc_s=19644, sd_s=1641, ave=0.083537

sig_next=7: fq=2031, pd_s=39532, pc_s=29649, sd_s=2855, ave=0.0962933

sig_next=8: fq=3780, pd_s=74580, pc_s=55935, sd_s=6164, ave=0.110199

sig_next=9: fq=1007, pd_s=19640, pc_s=14730, sd_s=1185, ave=0.0804481

State < 3 0 4 >: sig_cycle_next=7, tmd0=159983, tmc0=119988, s0=11850

sig_next=6: fq=1551, pd_s=30904, pc_s=23178, sd_s=2102, ave=0.0906894

sig_next=7: fq=3252, pd_s=67292, pc_s=50469, sd_s=5375, ave=0.106501

sig_next=8: fq=2295, pd_s=46132, pc_s=34599, sd_s=3396, ave=0.0981531

sig_next=9: fq= 807, pd_s=15636, pc_s=11727, sd_s= 975, ave=0.0831415

State < 4 2 1 >: sig_cycle_next=6, tmd0=159999, tmc0=120000, s0=11850

sig_next=6: fq=2505, pd_s=50620, pc_s=37965, sd_s=3852, ave=0.101462

sig_next=7: fq=2095, pd_s=41828, pc_s=31371, sd_s=3172, ave=0.101112

sig_next=8: fq=1624, pd_s=33220, pc_s=24915, sd_s=2354, ave=0.0944812

sig_next=9: fq=1759, pd_s=34324, pc_s=25743, sd_s=2472, ave=0.0960261

State < 5 3 3 >: sig_cycle_next=9, tmd0=159979, tmc0=119985, s0=11849

sig_next=6: fq=1797, pd_s=34976, pc_s=26232, sd_s=2448, ave=0.0933211

sig_next=7: fq=1674, pd_s=34064, pc_s=25548, sd_s=2386, ave=0.0933928

sig_next=8: fq=1321, pd_s=25768, pc_s=19326, sd_s=1796, ave=0.0929318

sig_next=9: fq=3274, pd_s=65168, pc_s=48876, sd_s=5219, ave=0.10678

Chapter 7: Example Programs 241

7.2 apsamp

This program uses a pair of actors that investigates a state model represented in Figure 7.1.The first actor of the pair guesses current state of the state model. The second actor of the pairemits signals to the state model on the basis of current states guessed by the first actor.

The state model contains 10 states, shown in the figure by circles with state indices insidethem. The first actor of the pair works with two spur types, where spur type 0 corresponds tothe automatic spur, and spur type 1 corresponds to user spur. The second actor of the pairworks only with user spur. The goal of the operation of the pair of actors is to maximize thevelocity of increment of user spur.

Arrows represent allowed state transitions. The thick arrow indicates a transition, duringwhich the pair of actors receives user spur increment +1. A number before a slash shown nearevery arrow indicates a signal that can be emitted to the state model, and which makes themodel perform the state transition. A number after a slash shown near every arrow indicates asignal the state model emits to the pair of actors when performing the state transition. If thestate model receives from the pair of actors a signal, for which no state transition exists, thencurrent state of the model will be left unchanged, and signal 0 will be emitted to the pair ofactors.

As it could be seen from the figure, the optimal behavior of the pair of actors would becontinuous emitting sequence of output signals <7, 4, 6, 7>, which gives user spur increment +1.

Figure 7.1: sample state model investigated by the pair of actors

Unfortunately, the sample state model is too simple and permits guessing the optimalsequence of output signals to emit even without analyzing input signals received from the statemodel. However, you may experiment with other state models by modifying matrices trans_mat, emiss_mat, and spur_mat hard-coded in the program source text.

Macro NSTEP (that has value 40000) defines the number of steps of interaction of the pair ofactors with the state model equal to the number of signals emitted to the state model and to thenumber of signals received from the state model. At the end of its run, the example programprints the amount of user spur accumulated by the pair of actors.

A random seed can be specified by a program argument. If the random seed is non-negative,then the pair of actors will operate normally. If the random seed is negative, then the pair of

Chapter 7: Example Programs 242

actors will generate output signals completely randomly. You could compare the accumulatedvalues of user spur for these two modes of program execution.

The example program can be built for various schemes of using a pair of actors. To build theprogram for a selected scheme, delete executable and object files of the program if they exist,and run command

make name_of_executable_of_program_apsamp AP_MODE=name_of_scheme

in directory ‘samples’. The supported names of schemes are: ‘S1_S1’, ‘S1_S3’, ‘S1_L3’, ‘S3_S1’,‘S3_S3’, ‘S3_L3’, ‘L3_L3’. For example, the command might look like this: make apsamp AP_

MODE=L3_L3. If a scheme is not specified when building the program, then default scheme ‘S1_S1’will be used.

The schemes are encoded in the following way. The first letter and digit denote parametersof the first actor of the pair. The second letter and digit denote parameters of the second actorof the pair. Letter ‘S’ denotes a small actor, and letter ‘L’ denotes a large actor. Digit 1 denotesthe type of relative probability function similar to QSMM_RELPROB_BUILTIN1 used by an actor.Digit 3 denotes type of relative probability function QSMM_RELPROB_BUILTIN3 used by an actor.The name of the scheme also defines other parameters of the actors.

Here is given the output of the example program built for scheme ‘S1_S1’.

$ ./apsamp -1

spur = 373

$ ./apsamp 1

spur = 2236

Results of invocation of the example program in the normal mode of operation using each ofthe supported schemes and random seeds in the range 1 to 20, and in the completely randommode of operation using seeds in the range −20 to −1 are represented in the table below.Negative seeds for the completely random mode of operation are negated values of the ‘SEED’column. The ‘RAND’ column contains values of user spur accumulated in the completely randommode of operation.

SEED RAND S1_S1 S1_S3 S1_L3 S3_S1 S3_S3 S3_L3 L3_L3

------ ---- ----- ----- ----- ----- ----- ----- -----

1 373 2236 3854 4259 1022 824 1872 1735

2 380 823 900 1867 6 385 3254 5

3 397 1120 3 2473 46 1120 5452 2289

4 366 1071 638 3604 1130 713 3502 2266

5 411 1787 1451 3569 2253 3074 5210 1444

6 446 3493 3050 1758 5266 2224 5527 5487

7 430 1295 1940 1780 1882 1656 5169 311

8 387 3236 4513 1704 2532 4299 2320 3

9 351 4 2 3214 1501 4085 2071 1141

10 402 1262 3677 1 2181 3039 3 932

11 407 3547 1427 1264 1147 1665 2331 1742

12 428 2925 2650 1173 4013 3777 6665 1608

13 402 2710 2329 5059 304 3037 6356 15

14 384 3233 3575 3962 1010 1122 2309 1085

15 407 1962 1616 5921 3049 4168 3919 953

16 388 1082 2502 2786 5591 1453 719 270

17 378 2153 1937 1739 2040 2355 3714 2587

18 420 1294 1314 697 4813 5828 6463 1472

19 416 1 39 1454 2 1819 3358 738

20 392 4681 1633 8205 1691 4489 2666 2216

------ ---- ----- ----- ----- ----- ----- ----- -----

AVG 398 1996 1952 2824 2074 2557 3644 1415

STDDEV 23 1251 1321 1966 1707 1511 1919 1254

% EFR 100 502 490 710 521 642 916 356

The ‘AVG’ and ‘STDDEV’ rows contain arithmetic means and standard deviation of columnvalues located above. The ‘% EFR’ row contains values in the ‘AVG’ row multiplied by 100 and

Chapter 7: Example Programs 243

divided by the value of a cell at the intersection of the ‘AVG’ row and the ‘RAND’ column. As itcan be seen from the table, the average amount of user spur accumulated by the pair of actorsfor 20 invocations of the example program in the normal mode of operation is about 4–9 timesgreater than in the completely random mode of operation.

7.3 optpath

This program performs the search of a path in the state transition network represented inFigure 5.2. The final state of the path is 9. The example program tries to find a path thatsatisfies two optimization goals: the path should be short, and the path should have maximumgeometric mean probability of state transition. To find an optimal path, the example programtraverses the state transition network from the initial state to the final state a number of timesdefined by macro NVISIT (that has value 400).

The example program creates a single-node model that uses two spur types and has a restri-ction that the action emission matrix must define deterministic choice of an instruction classemitted in every node state. The restriction eliminates the need to specify stt instructions inan assembler program that represents the state transition network. To code the state transi-tion network in the assembler program, an approach is used analogous to one described inSection 5.14.6 [Specifying State Transition Networks], page 198.

The example program turns off the use of the automatic spur by the environment stateidentification engine. Instead of the automatic spur (of type 0), the environment state identifi-cation engine uses the spur equal to the sum of logarithms of probabilities of state transitionsperformed. Spur of type 1 countervails spur of type 0 and is incremented by 1 each time thefinal state is reached. Continuous time tracked by the model is incremented by 1 after everystate transition.

At the end of its run, the example program prints the sum of logarithms of probabilities ofstate transitions performed, the total number of state transitions performed, and the geometricmean probability of state transition. Arguments of incspr instructions in the assembler programspecify probabilities of state transitions less than 1. To register instruction classes ‘incsprprob ’, the memory representation of the assembler program is scanned, names and parametersof instructions are fetched by function qsmm_instr_str.

A random seed can be specified by a program argument. If the random seed is non-negative,then the program will operate normally. If the random seed is negative, then state transitionswill be selected completely randomly. You could compare the program output for these twomodes of program execution.

Here is given sample program output.

$ ./optpath -1

logprob = -1551.45

path_len = 2755

step_prob = 0.569417

$ ./optpath 1

logprob = -829.073

path_len = 1903

step_prob = 0.646834

Results of invocation of the example program in the normal mode of operation using randomseeds in the range 1 to 20, and in the completely random mode of operation using seeds in therange −20 to −1 are represented in the table below.

Chapter 7: Example Programs 244

SEED logprob path_len step_prob SEED logprob path_len step_prob

------ -------- -------- --------- ------ -------- -------- ---------

-1 -1551.45 2755 0.569417 1 -829.073 1903 0.646834

-2 -1580.21 2692 0.555991 2 -894.364 1867 0.619379

-3 -1590.75 2800 0.566587 3 -871.942 1861 0.625919

-4 -1628.23 2857 0.565577 4 -827.89 1876 0.643196

-5 -1661.79 2923 0.566361 5 -828.801 1882 0.64379

-6 -1582.71 2770 0.564748 6 -839.799 1873 0.638668

-7 -1552.68 2731 0.566352 7 -824.554 1855 0.641143

-8 -1619.09 2860 0.567726 8 -823.913 1867 0.643198

-9 -1606.98 2836 0.567431 9 -835.016 1885 0.642121

-10 -1540.68 2719 0.567431 10 -848.998 1888 0.637832

-11 -1605.54 2833 0.567379 11 -869.818 1873 0.628513

-12 -1596.22 2788 0.564095 12 -792.632 1912 0.660633

-13 -1524.97 2734 0.572479 13 -820.228 1852 0.642179

-14 -1577.36 2752 0.563737 14 -845.155 1858 0.634528

-15 -1623.44 2770 0.556506 15 -751.143 1831 0.663493

-16 -1579.98 2758 0.563904 16 -805.133 1819 0.642349

-17 -1570.52 2839 0.575109 17 -784.603 1873 0.657769

-18 -1577.83 2779 0.566789 18 -807.793 1822 0.641879

-19 -1555.77 2719 0.564291 19 -815.895 1870 0.646419

-20 -1497.82 2749 0.579922 20 -877.093 1918 0.632993

------ -------- -------- --------- ------ -------- -------- ---------

AVG -1581.2 2783.2 [0.566588] AVG -829.7 1869.3 [0.641554]

STDDEV 38.2 58.6 0.00534 STDDEV 33.7 26.3 0.010816

The intersections of the ‘AVG’ row and ‘logprob’ and ‘path_len’ columns contain arithmeticmeans of column values located above. The intersections of the ‘AVG’ row and ‘step_prob’columns contain geometric mean probabilities of state transitions for 20 invocations of theexample program. The ‘STDDEV’ row contains the standard deviation of column values locatedabove.

As it can be seen from the table above, the geometric mean probability of state transition for20 invocations of the example program for the normal mode of operation is by 0.074966 greaterthan that probability for the completely random mode of operation.

7.4 test

This program demonstrates basic features of algorithms used in the QSMM package and isimplicitly referred from paper “An Approach to Optimal Action Generation for a System thatInteracts with the Environment.” In QSMM version 1.16 that paper is removed from the packagedistribution, because despite being informative, the paper contains serious mistakes, which arenot fixed yet. In its current state, the paper can be accessed from the project home page (seeSection 1.6 [Obtaining QSMM], page 6, for the project home page URL).

The example program performs interaction between the system and an environmentrepresented by a deterministic finite automaton. The interaction can be performed in amode when the system is homogeneous and in a mode when the system is comprised of twosubsystems, the first of which identifies current environment states and the second generatesoptimal actions based on those states. An automaton that takes part in the interaction iseither read from a file specified by a program argument or generated randomly on the fly.

Format of Automaton File

A deterministic finite automaton that models the environment is described in a text file, anexample of which is shown below.

Non-empty line #1

Non-empty line #2

...

Non-empty line #n

Chapter 7: Example Programs 245

2 5 3 0

1 0 0 0 0

1/3 2/4

2/1 1/2

0/4 1/0

All lines before the first empty line are ignored. The first line after that empty line hasformat

number_of_input_signals number_of_output_signals number_of_states initial_state_index

Indices of signals and states start from 0.

The second line after the empty line contains floating-point numbers, which are the incrementsin system spur for all output signals. Those increments take place when corresponding outputsignals are emitted by the automaton.

Starting from the third line after the empty line, there go descriptions of transitions betweenstates upon receiving input signals. The third line corresponds to transitions from state 0, thefourth—from state 1, the fifth—from state 2, and so on. Each line contains number pairs thatcorrespond to input signals. The first pair corresponds to input signal 0, the second—to inputsignal 1, the third—to input signal 2, and so on. A pair has format

target_state/output_signal

and specifies a transition from a source state to a target state triggered by an input signal,during which an output signal is emitted.

Generating Random Automatons

To generate a random deterministic finite automaton, the following command can be used:

$ ./test -o out_file -i random_seed [ -C VAL ] num_in_sig num_out_sig num_states

The command creates file out file with a description of deterministic finite automatonproduced using seed random seed. The automaton has given numbers of input, output signals,and states. A random seed should always be specified; otherwise some standard fixed value willbe used. The first output signal will have spur increment 1 and all others 0.

If option ‘-C VAL ’ with non-zero VAL is specified, then the automaton will have its stategraph connected. If VAL is a number greater than 0, then the automaton will have not morethan that number of cycles in the graph, and the best cycle among them will be found. If thenumber is relatively small, then the automaton may not be generated at one push. When anattempt to generate the automaton fails, a warning message is printed, and the program makesanother attempt. If the number is relatively big, then an attempt to generate the automatonmay take a long time, so the impression can be that the program has hung.

In QSMM version 1.16, there are supported VAL=‘c’ and VAL=‘cs’. Value ‘c’ makes theprogram to provide state connectivity of the state graph and to find the best cycle in the graphusing an algorithm analogous to Viterbi one. Value ‘cs’ makes the program to provide the stateconnectivity, simplify the state graph, as it performed when VAL is a number greater than 0,and find the best cycle in the graph using an algorithm analogous to Viterbi one.

To comment lines before the first empty line in out file the value of random seed is written.If option ‘-C VAL ’ with non-zero VAL is specified, then to comment lines will also be writteninformation on the best cycle in the state graph:

– the length of the best cycle (a cycle, continuous repeating of which will give the maximumamount of spur to the system);

– the increment in spur the system will receive when the cycle is repeated;

– average spur increment per that cycle step;

Chapter 7: Example Programs 246

– the list of cycle steps; the description of each cycle step contains step index stp, automatonstate index stt, input signal inp received when the automaton was in that state, outputsignal out emitted, and spur increment spr that corresponds to the output signal.

Performing the Interaction

A test of algorithm efficiency that consists of num passes passes with a new random deterministicfinite automaton, which has defined numbers of input, output signals, and states, being chosenat each pass, is performed by command

$ ./test -t num_passes [ -C VAL ] [ additional options ] \

num_in_sig num_out_sig num_states

If option ‘-C VAL ’ with non-zero VAL is specified, then best cycles will be found in automatonstate graphs which will be provided to be connected ones. The command prints a test log, anexample of which is shown below.

$ ./test -t10 -Ccs 20 20 20

DFA inputs: 20

DFA outputs: 20

DFA states: 20

Input signals: dfa-state

Passes: 10

Steps per pass: 10000

Large: off

R. prob. type: 1

N-gram length: 1

Algorithms v.: 0

K*temp.: 1.000000000000000E+00

Max. cycles: -2

Random seed: 0

pass earned random maximal cl % efr % efa

---- ------------ ---------- ------------ -- -------- -------

1 5821.000 331.000 7500.000 4 1758.610 76.580

2 5826.000 441.000 10000.000 2 1321.088 56.334

3 5656.000 359.000 6666.667 3 1575.487 83.977

4 6443.000 414.000 10000.000 2 1556.280 62.894

5 7075.000 462.000 10000.000 2 1531.385 69.333

6 5949.000 329.000 7142.857 7 1808.207 82.479

7 4272.000 281.000 6666.667 3 1520.285 62.499

8 8781.000 411.000 10000.000 2 2136.496 87.288

9 8144.000 648.000 10000.000 2 1256.790 80.154

10 4671.000 270.000 6000.000 5 1730.000 76.806

TOTL 62638.000 3946.000 83976.190 3 1587.380 73.337

stddev efr: 253.554

stddev efa: 10.486

The log begins with a description of test modes used. Then there goes a table, where eachrow corresponds to a test pass, with a summary row. The columns of the table have the followingmeaning.

pass A test pass index. For the summary row ‘TOTL’ is printed here.

earned The amount of spur the system has received during interaction with the automatonaccording to the algorithm. In the summary row—the sum of values in the column.

random The amount of spur the system has received during random interaction with theautomaton when output signals are equiprobably chosen from the set of allowedsignals. In the summary row—the sum of values in the column.

maximal The amount of spur the system would receive during the most optimal interactionwith the automaton. Will be determined if option ‘-C VAL ’ with non-zero VAL is

Chapter 7: Example Programs 247

specified in the command line, otherwise will be equal to the number of steps at atest pass. In the summary row—the sum of values in the column.

cl The length of a cycle, continuous repeating of which would give the maximumamount of spur to the system. Will be determined if option ‘-C VAL ’ with non-zeroVAL is specified in the command line, otherwise will be equal to 0. In the summaryrow—the average length of cycles for all test passes.

% efr Relative efficiency equal to earnedrandom

· 100%. For the summary row is calculated usingcorresponding values in that row.

% efa Actual efficiency equal to earned−randommaximal−random · 100%. For the summary row is calculated

using corresponding values in that row.

A standard deviation of values in ‘% efr’ and ‘% efa’ columns is printed at the end of thelog.

Running Multiple Test Passes for a Single Automaton

To run certain number of test passes for an automaton specified in FILE, which has a formatdescribed in subsection [Format of Automaton File], page 244, the following command can beused:

$ ./test -t num_passes [ -C VAL ] [ additional options ] -f FILE

The automaton is checked for having its state graph connected. If VAL is a number greaterthan 0, then the automaton will also be checked for having the number of cycles in the graph lessthan or equal to VAL. If VAL is non-zero, then the test log will be prepended with informationon the best cycle in the automaton state graph as it described in subsection [Generating RandomAutomatons], page 245.

Options Common for Both System Types

Options of the program that can be used in both cases, when the system is homogeneous andwhen the system is comprised of two subsystems, the first of which is an environment stateidentification subsystem and the second of which is an optimal action generation subsystem, arelisted below.

-C, --ncycle-max=VAL

Parameters related to automaton state graphs: state connectivity, simplification,the maximum number of cycles, and finding the best cycle. In the description oftest modes is denoted by ‘Max. cycles’. Supported values are described below.

0 Do not provide the state connectivity, do not perform the simplification,do not restrict the maximum number of cycles in the graph, and do notfind the best cycle.

>0 Provide the state connectivity, perform the simplification, restrict themaximum number of cycles in the graph by VAL, and find the bestcycle.

“c” [New in QSMM 1.16] Provide the state connectivity and find the bestcycle by the algorithm analogous to Viterbi one. In the description oftest modes is denoted by value −1.

“cs” [New in QSMM 1.16] Provide the state connectivity, perform the simpli-fication, and find the best cycle by the algorithm analogous to Viterbione. In the description of test modes is denoted by value −2.

The simplification of an automaton state graph consists in replacing transitionsfrom (source) states to other states with transitions to the same (source) states on

Chapter 7: Example Programs 248

condition that resulting transitions do not yield positive spur increments, and theconnectivity of the state graph is preserved.

If search of the best cycle in the state graph is performed, then the maximumamount of spur the system would receive during the most optimal interaction withthe automaton will be calculated and printed in the ‘maximal’ column of test log.

-f FILE A file to read the automaton from. In the description of test modes is denoted by‘Automaton file’.

-i, --seed=INT

A seed to initialize the pseudorandom number generator. Default value is 0. In thedescription of test modes is denoted by ‘Random seed’.

--kt=FLOAT

The temperature (multiplied by some constant) of the homogeneous system or thetemperature of the environment state identification subsystem and the optimal acti-on generation subsystem in case when the system is comprised of two subsystems.Default value is 1. In the description of test modes is denoted by ‘K*temp.’.

-n, --nstep-pass=INT

The number of steps of interaction with a deterministic finite automaton at eachtest pass. At each step, the automaton receives an input signal and emits an outputsignal. Default value is 10000. In the description of test modes is denoted by ‘Stepsper pass’.

-o FILE A file to write program output to instead of stdout.

-S, --storage=flat|map

A statistics storage type for the system.

‘flat’ Use preallocated storage presumably of big size, but with quick accessto data elements. Is default mode when possible.

‘map’ Use dynamically allocated storage presumably of lesser size, but withslower access to data elements. The implementation of functionality ofthe STL map template is used for backing storage.

-t, --test=INT

Perform the test specified number of passes. This option should always be specifiedif testing has to be performed. If an automaton is specified via option ‘-f FILE ’,then it will be used at all test passes. Otherwise, at each test pass a differentrandom automaton will be generated having the numbers of input, output signals,and states equal to those specified by arguments at the end of command line. Inthe description of test modes is denoted by ‘Passes’.

Case of Homogeneous System

A system that interacts with an automaton will be homogeneous unless option ‘-s INT ’ isspecified. For this kind of system, the program supports the following special list of options.

-c, --compat=INT

The compatibility level of algorithms. Can be 0 or 1. Is assigned to field compat

of structure qsmm_actor_desc_s. In the description of test modes is denoted by‘Algorithms v.’.

-I, --input=dfa-state|dfa-out

The type of informational signals for the system.

‘dfa-state’Automaton states (default mode).

Chapter 7: Example Programs 249

‘dfa-out’ Automaton output signals.

In the description of test modes is denoted by ‘Input signals’.

-l, --ngram-length=INT

The length of system state n-gram. Default value is 1. If the type of informationalsignals for the system is ‘dfa-out’, then the best efficiency may be obtained whenn-gram length is equal to 2. In the description of test modes is denoted by ‘N-gramlength’.

-L, --large[=INT]

Use a large actor with specified tree arity. Default value is 2. In the description oftest modes is denoted by ‘Large’ and ‘Tree arity’.

-P, --relprob-type=0|1|2|3

The type of a function that returns a relative probability of output signal choice.

‘0’ QSMM_RELPROB_USER1 without a helper function provided.

‘1’ QSMM_RELPROB_BUILTIN1 (default mode).

‘2’ QSMM_RELPROB_BUILTIN2.

‘3’ QSMM_RELPROB_BUILTIN3.

In the description of test modes is denoted by ‘R. prob. type’.

Case of a System Comprised of Two Subsystems

If option ‘-s INT ’, which specifies the number of tracked environment states, is present inthe command line, then a system that interacts with an automaton will be comprised of twosubsystems, the first of which identifies current environment states and the second generatesoptimal actions based on those states. For the interaction with an automaton to be efficient,the number of interaction steps at each test pass should be much greater than in the case of ahomogeneous system. When the system is comprised of two subsystems, the program supportsthe following special list of options.

--kt-env=FLOAT

The temperature (multiplied by some constant) of the environment state identifi-cation subsystem. Default value is 1. In the description of test modes is denoted by‘K*temp. env.’.

--kt-opt=FLOAT

The temperature (multiplied by some constant) of the optimal action generationsubsystem. Default value is 1. In the description of test modes is denoted by‘K*temp. opt.’.

-s, --nstate=INT

The number of tracked environment states. The best efficiency may be obtainedwhen that number is twice or more times greater than the number of states in adeterministic finite automaton the system interacts with. In the description of testmodes is denoted by ‘Tracked states’.

How to Reproduce Plots Represented in the Paper

In subdirectory ‘scripts’ at the root of the package distribution there are located bash scriptsdescribed below. The scripts do not get installed by command make install.

‘qsmm-test-multi.sh’A script used to prepare plots of dependency of actual efficiency of interaction withdeterministic finite automatons on the number of steps at a test pass for a mode

Chapter 7: Example Programs 250

when the system is comprised of two subsystems. Such plots are included in paper“An Approach to Optimal Action Generation for a System that Interacts with theEnvironment” that can be accessed from the project home page. The script runsthe test program in a loop, producing a new file with test results and incrementingthe number of steps at a test pass for each subsequent iteration. Files with testresults populate a directory specified by a script argument, and the name of eachfile is the number of steps (at a test pass) used to create the file.

‘qsmm-mk-plot-dataset.sh’A script for generating a dataset to create a plot by program gnuplot. The scriptprocesses a directory with test result files generated by the ‘qsmm-test-multi.sh’script and prints to stdout a dataset that contains two columns: the number of stepsat a test pass and corresponding actual efficiency (in percents) of interaction withdeterministic finite automatons.

A way to reproduce the plots of dependency of actual efficiency of interaction with automatonson the number of steps at a test pass consists of the following stages.

1. Choose a new or an empty directory out dir to store files with test results for a selectedtest mode.

2. Run multiple tests in a selected mode using the ‘qsmm-test-multi.sh’ script to populateout dir with test result files. The name of each file in out dir is the number of steps (at atest pass) used to create the file. The script can be invoked using command line

$ ./qsmm-test-multi.sh -d out_dir [ -C VAL ] \

[ additional options ] num_in_sig num_out_sig num_states

For one-letter options, a whitespace after an option letter is obligatory. Options ‘-C VAL ’,‘-s num_model_states ’, and ‘-t num_passes ’ are passed to the test program as is. Caseof a system comprised of two subsystems is only supported, so if option ‘-s’ is not specified,then the number of automaton states multiplied by 2 will be used for num model states.Options that control the numbers of steps at test passes are listed below.

--ni=INT The initial number of steps at test passes. This is the name of the first filewritten to out dir. Default value is 100.

--nf=INT The final number of steps at test passes. This is the name of the last file thatwill be written to out dir. Default value is 100000.

--nd=INT The increment in the number of steps at test passes for each subsequent invocati-on of the test program when creating the next file in out dir. Can be negative,in which case the value of option ‘--ni’ should be greater than the value of opti-on ‘--nf’. Such negative value can be used for the second of two simultaneousruns of the script on a dual-core processor to reduce computing time twice.Default value is 100.

3. Extract a dataset for the gnuplot (or another) program from files in out dir. This canbe done using the ‘qsmm-mk-plot-dataset.sh’ script that prints coordinates of points forthe plot to stdout. The script supports options ‘--ni’, ‘--nf’, and ‘--nd’, using which itdetermines names of files to read from out dir. The script can be invoked using commandline

$ ./qsmm-mk-plot-dataset.sh [ options ] out_dir | tee data_set_file

4. Process the dataset by the gnuplot program to draw the plot with data points andthe regression line. Sample gnuplot script to perform this task is provided in file‘scripts/gnuplot.script’. You may also wish to draw the plot or to obtain a functi-on for the regression line by a program other than gnuplot.

Chapter 7: Example Programs 251

7.5 fw-simple

This program demonstrates basic features of the QSMM framework. The program performsinteraction of a trainer with a single-node model. The trainer is launched in a separate threadand communicates with the main thread using the Side API. Units of communication are signals.

The model is trained to emit output signal 2 after receiving input signal 0, to emit outputsignal 1 after receiving input signal 1, and to emit output signal 0 after receiving input signal 2.A training process performed by the trainer thread consists in sending random signal 0, 1, or 2to the model, receiving a response signal from the model, and making spur increment 1 if theresponse signal is correct.

The program registers instruction classes ‘sr 0’, ‘sr 1’, and ‘sr 2’ (‘sr’ is an abbreviationfor “send/receive”), using which the model emits output signal 0, 1, or 2 to the trainer threadand receives outcome 0, 1, or 2, which is an input signal from the trainer thread.

At the end of its run, the program prints the amount of spur accumulated by the model. Theprogram creates in the current directory file ‘prg’ with a disassembled program of the node, file‘mat_goto’ with a state transition matrix, and file ‘mat_action’ with an action emission matrix.

If options for tracing model execution are specified in the command line, then the programwill create trace log ‘trace’ in the current directory. If options for tracing data packets exchangeare specified in the command line, then the program will create trace log ‘trace_side’ in thecurrent directory. On first acquaintance with the package, those trace logs can be inspected tounderstand what kind of information goes there.

The program understands command-line options listed below. For definitions of referencedtrace flags of model execution, see Section 4.18 [Tracing Model Execution], page 129. Fordefinitions of referenced trace flags of data packets exchange, see Section 6.4.3 [Tracing Exchangeof Data Packets], page 223.

--deterministic

Generate the most probable deterministic program when disassembling the node.

-i, --seed=INT

A seed to initialize the pseudorandom number generator. A non-negative seed speci-fies normal behavior of the model. A negative seed specifies random behavior of themodel. Default value is 0.

-n, --nstep=INT

The number of modeling steps. At each step, an output signal is emitted, and aninput signal is received by the model. Default value is 5000.

-s, --nstate=INT

The number of tracked trainer states. Default value is 6.

--trace-api

Add constant QSMM_TRACE_API to trace flags of model execution.

--trace-ctrl

Add constant QSMM_TRACE_CTRL to trace flags of model execution.

--trace-evt

Add constant QSMM_TRACE_EVT to trace flags of model execution.

--trace-side-api

Add constant QSMM_SIDE_TRACE_API to trace flags of data packets exchange.

--trace-side-msg

Add constant QSMM_SIDE_TRACE_MSG to trace flags of data packets exchange andalso dump indices of modeling steps, values of spur at modeling steps, and spurincrements to the trace log.

Chapter 7: Example Programs 252

Command make builds the example program if the QSMM package is configured by the‘configure’ script to use the POSIX threads API. See file ‘INSTALL’ at the root of the packagedistribution, for information on the ‘configure’ script.

Below there are represented results of sample invocation of the program.

$ ./fw-simple -i1 --deterministic

spur = 2671

$ cat prg

jmp L2

; State 0 (activations = 933).

L1: sr 1 ; calls = 933

joe 0, L3 ; jumps = 91

joe 2, L4 ; jumps = 81

jmp L1 ; jumps = 127

; State 2 (activations = 724).

L2: sr 2 ; calls = 724

joe 1, L1 ; jumps = 80

joe 0, L3 ; jumps = 59

jmp L4 ; jumps = 121

; State 3 (activations = 957).

L3: sr 2 ; calls = 957

joe 0, L3 ; jumps = 112

joe 1, L1 ; jumps = 97

; State 5 (activations = 981).

L4: sr 0 ; calls = 981

joe 1, L1 ; jumps = 167

joe 0, L3 ; jumps = 156

jmp L4 ; jumps = 176

7.6 parse-asm

This program was used by the package developer to debug converting the text of an assemblerprogram to the memory representation of the assembler program and then converting therepresentation back to the assembler program text. The program can also be used to obtain aresult of preprocessing an assembler program text. This program does not perform convertingthe memory representation of an assembler program to the probability profile of a node.

The program supports a single optional argument that specifies the name of a file with anassembler program text. If the argument is not given, then the program will read an assemblerprogram text from stdin. After parsing an assembler program text, the parse-asm programprints the reinterpreted program text to stdout.

The program understands the following command-line options.

-E Perform preprocessing only and print the preprocessed text of an assembler program.

--no-preprocess

Do not preprocess an assembler program text before parsing it. This option isignored when option ‘-E’ is specified.

--no-space-after-comma

Do not print spaces after commas not within comments and string literals. Thisoption is ignored when option ‘-E’ is specified.

Chapter 7: Example Programs 253

--prob-prec=INT

The number of digits after the decimal point to print for probabilities. Anon-negative number specifies fixed-point notation. A negative number specifiesexponential notation, and its absolute value indicates the number of digits afterthe decimal point. Default value is 2. This option is ignored when option ‘-E’ isspecified.

-R, --margin-right=INT

A right margin column for comments. By default, no right margin is used. Thisoption is ignored when option ‘-E’ is specified.

--strip-comments

Do not print comments. This option is ignored when option ‘-E’ is specified.

7.7 asm-disasm

This program can be used to study or debug assembling a node, assigning values to controlledprobability variables of the node, and disassembling the node.

The program supports a single optional argument that specifies the name of a file withan assembler program text. If the argument is not given, then the program will read anassembler program text from stdin. After assembling the node and optional assigning values toits controlled probability variables, this program prints a disassembled program text to stdout.

To assemble a program, its instruction set must be previously defined. Specifying theinstruction class set has to be done using a number of options ‘-I STR[/INT]’, where eachoption defines an instruction, which is an element of the instruction set. Option argumentSTR specifies the name of instruction. The argument might contain whitespaces, in which caseit should be quoted. The argument might also contain characters ‘%’, which are interpretedas equivalents to whitespaces. Option argument INT specifies the number of outcomes of theinstruction. If the argument is not given, then default value 1 will be used for the number ofoutcomes.

For example, to define an instruction set that contains instructions ‘nop1’, ‘user 0’, and‘user 1’ with one outcome and instruction ‘test 3’ with three outcomes, the following list ofoptions ‘-I’ may be used:

-I nop1 -I "user 0" -I "user 1" -I "test 3/3"

If an assembler program contains definitions of probability variables, then assignments tothose variables can be made using a number of options ‘-P STR=FLOAT ’ where STR specifies thename of a controlled probability variable and FLOAT specifies the value of the variable. Forexample, to assign value 0.05 to variable var1 and value 0.15 to variable var2, the following listof options ‘-P’ may be used:

-P var1=0.05 -P var2=0.15

The list of command-line options understood by the asm-disasm program is given below.

-D, --determ-mat-action

Restrict the action emission matrix to defining only deterministic action choices.In this case, probabilities specified in the assembler program correspond only tothe state transition matrix, and there is no need to mark unnamed states of theassembler program by stt instructions.

--dont-reg-vars

Do not register controlled probability variables of the node.

--dump-action[=FILE]

Dump the action emission matrix to a file. If FILE not specified, then ‘mat_action’will be used for it. See Section 4.14 [Dumping an Action Emission Matrix], page 123,for an output format of the matrix.

Chapter 7: Example Programs 254

--dump-goto[=FILE]

Dump the state transition matrix to a file. If FILE not specified, then ‘mat_goto’will be used for it. See Section 4.13 [Dumping a State Transition Matrix], page 120,for an output format of the matrix.

--dump-var-choice

When option ‘--dump-var-out[=FILE]’ is specified, dump output probabilitiesarrays that correspond to choice instruction blocks.

--dump-var-out[=FILE]

Dump output probability variables and arrays of the node. There are dumpedoutput probabilities arrays that correspond to casels instructions. If option‘--dump-var-choice’ is specified, then there will also be dumped output probabi-lities arrays that correspond to choice instruction blocks. If FILE not specified,then ‘var_out’ will be used for it.

-I, --instruction=STR[/INT]

Add instruction class STR with INT outcomes to the instruction class set. Allcharacters ‘%’ in STR are converted to spaces. The default number of outcomes is1.

-L, --large=PE|,PO|PE,PO

Use a large actor for the environment state identification engine with size PE of thepool of probabilities lists in normal form and/or use a large actor for the instructionemitting engine with size PO of the pool of probabilities lists in normal form. Thesizes should be sufficient to support storing in the pools all those lists explicitlyand/or implicitly defined in the assembler program. The use of large actors is onlypermitted with map storage (see option ‘-S’).

--no-nop Do not define the nop instruction class.

--prob-action-min=FLOAT

When option ‘--template’ is provided, option ‘--prob-action-min=FLOAT ’ speci-fies the minimum probability of jprob and case instructions, which correspond tothe action emission matrix, to retain in the disassembled program. Instructionswith lesser probabilities will be removed from the disassembled program, althoughthey are present in the input assembler program. When option ‘--template’ isnot given, option ‘--prob-action-min=FLOAT ’ specifies the minimum probabilityof user or mixed type instruction invocation. Instructions with lesser invocationprobabilities will not be generated when disassembling the node.

--prob-goto-min=FLOAT

When option ‘--template’ is given, option ‘--prob-goto-min=FLOAT ’ specifies theminimum probability of jprob and case instructions, which correspond to the statetransition matrix, to retain in the disassembled program. Instructions with lesserprobabilities will be removed from the disassembled program, although they arepresent in the input assembler program. When option ‘--template’ is not gi-ven, option ‘--prob-goto-min=FLOAT ’ specifies the minimum probability of statetransition. State transitions with lesser probabilities will not be reflected in thedisassembled program.

--prob-prec-mat=INT

The number of digits after the decimal point to print for probabilities in the statetransition matrix and the action emission matrix. A positive number specifies fixed-point notation. A negative number specifies exponential notation, and its absolutevalue indicates the number of digits after the decimal point. Zero number is equi-valent to the default value −15.

Chapter 7: Example Programs 255

--prob-prec-var=INT

The number of digits after the decimal point to print for values of output probabilityvariables and elements of output probabilities arrays. A positive number specifiesfixed-point notation. A negative number specifies exponential notation, and itsabsolute value indicates the number of digits after the decimal point. Zero numberis equivalent to the default value −15.

-P, --variable=STR=FLOAT

Assign value FLOAT to controlled probability variable STR defined in the assemblerprogram.

-S, --storage=flat|map

A statistics storage type.

‘flat’ Use preallocated storage presumably of big size, but with quick accessto data elements.

‘map’ Use dynamically allocated storage presumably of lesser size, but withslower access to data elements. The implementation of functionality ofthe STL map template is used for backing storage. Is the default mode.

--template

Disassemble the node using an assembler program template which is the inputassembler program. As a side effect, all casels instructions encountered in theinput assembler program will be converted to choice instruction blocks (except forcasels instructions, which use probabilities lists that contain only one element;such instructions will be converted to jprob instructions).

--use-stt

Generate stt instructions when disassembling the node.

-W Show warnings that might have been generated while assembling the node.

7.8 asmat

This program performs the same function as the program represented in Section 7.2 [apsamp],page 241, but uses the Multinode Model API instead of direct creating a pair of actors to solvethe task. A workspace for the state transition matrix and the action emission matrix is definedusing an internally generated assembler program which is dumped to file ‘prg_src’ in the currentdirectory.

The asmat program prints the number of node states defined by the assembler program andprints the amount of spur accumulated during interaction of a single-node model with a determi-nistic environment defined by three matrices hard-coded in the program source text. Statetransition and action emission probabilities learned in the process of interaction are dumped tofile ‘var_out’ in the current directory.

A random seed can be specified by a program argument. If the random seed is non-negative,then the single-node model will operate normally. If the random seed is negative, then thesingle-node model will generate output signals completely randomly.

Like the apsamp program, the asmat program can be built for various schemes of using apair of actors upon which the multinode model is based. To build the program for a selectedscheme, delete executable and object files of the program if they exist, and run command

make name_of_executable_of_program_asmat AP_MODE=name_of_scheme

in directory ‘samples’. The supported names of schemes are: ‘S1_S1’, ‘S1_S3’, ‘S1_L3’, ‘S3_S1’,‘S3_S3’, ‘S3_L3’, ‘L3_L3’. If a scheme is not specified when building the program, then default

Chapter 7: Example Programs 256

scheme ‘S1_S1’ will be used. See Section 7.2 [apsamp], page 241, for a description of how todecode the names of schemes.

Here is given the output of the example program built for scheme ‘S1_S1’.

$ ./asmat -3

nstate = 30

spur = 399

$ ./asmat 3

nstate = 30

spur = 2108

7.9 tohuff-test

This program implements the basic functionality of large actor and can be used as a referenceprogram to experiment with that functionality or change it. The program creates a multinodemodel, in which every node holds a control transfer tree. Those trees might correspond todendrites of neurons. To every tree leaf an output signal of model node biuniquely corresponds.A tree provides fast selection of an output signal by a model node when the number of thosesignals is large.

At the beginning of its execution, the program assigns random probabilities to output signalsof all model nodes. During the execution of the model, its nodes are activated equiprobably.When a model node is activated, the root of the corresponding tree receives control, and thecontrol is transferred to one of leaves of the tree. When control reaches a leaf of the tree, anoutput signal is emitted, and increment of spur equal to the logarithm of a probability assignedto the output signal (at the beginning of program execution) is made. Each model node has tolearn the correlation between emitting its various output signals and overall change in the spuraccumulated by the multinode model and emit more frequently output signals to which greaterprobabilities correspond.

The program dynamically creates n-ary trees of arbitrary height specified by a programargument. This is done via generation of text of an assembler program, which contains macrodefinitions that correspond to tree tiers. The assembler program does not contain stt instructi-ons because the multinode model is created with a restriction that an action emission matrixof its every node must specify deterministic choice of actions for all node states. The assemblerprogram defines a sparse probability profile, which provides quick execution of the assemblerprogram when the tree is large.

For each model node, an n-ary tree of the same structure is used. The tree of model node0 is created by loading an assembler program into that model node. Trees of all other modelnodes are created by cloning a probability profile from model node 0 to them.

Every output signal of model node has a distinct address assigned to it. At every edge ofthe tree there is located an assembler instruction that appends a number to the address of anoutput signal. The number is in the range 0 to tree arity minus 1. Before transferring controlto the root of the tree, the sequence of numbers of the address is cleared. After transferringcontrol to a leaf of the tree, the sequence of numbers represents the address of an output signalthat should be emitted by the model node.

N-ary trees used by the example program have a regular structure. When output signalshave nonequal profile probabilities, to select those signals Huffman trees can be used instead.The use of Huffman trees provides that more probable output signals are chosen more quickly.Large actors, the basic functionality of which is implemented by this example program, supportbuilding Huffman trees for specific lists of profile probabilities.

The multinode model uses a relative probability function of type QSMM_RELPROB_BUILTIN2

and three spur types. Spur type 0 corresponds to the automatic spur of the environment

Chapter 7: Example Programs 257

state identification engine. Spur type 1 corresponds to the auxiliary automatic spur which isincremented at the time of emitting an output signal by the model node. The increment of spurof type 1 is equal to the logarithm of the ratio of the number of times the output signal wasemitted to the total number of activations of model nodes. Spur types 0 and 1 have weights 0.5,the normal way of perception, and countervail spur type 2, which has weight 1 and the inverseway of perception. The increment of spur of type 2 is performed at the time of emitting anoutput signal by the model node and is equal to the logarithm of a probability assigned to theoutput signal at the beginning of execution of the example program.

You should invoke the example program with two arguments. The first argument, a positiveinteger, specifies the number of model nodes, each corresponding to an n-ary tree. The secondargument, an integer greater than 2, specifies tree height. A root node is included in that height,so height 3 specifies a tree with a root node, an intermediate tier, and a tier with tree leaves.

The program understands the following command-line options.

-A, --tree-arity=INT

The arity of tree nodes. Default value is 2. In the description of test modes isdenoted by ‘Tree arity’.

-F, --sparse-fill=FLOAT

The maximum fill ratio for vectors that hold relative probabilities of output signalschoice, on the basis of which the environment state identification engine decideswhen to use sparse vectors instead of ordinary vectors. Must be a number in therange 0 to 1 (inclusive). Value 0 means that ordinary vectors must always be used.Value 1 means that sparse vectors must always be used. This option can be helpfulto compare the speed of program operation when sparse vectors are used and whenordinary vectors are used to receive evidence that for tall binary trees the programoperates many times faster when sparse vectors are used. Default value is 1.

-i, --seed=INT

A seed to initialize the pseudorandom number generator. Default value is 0. In thedescription of test modes is denoted by ‘Random seed’.

--kt-env=FLOAT

The temperature (multiplied by some constant) of the environment state identifi-cation engine. Default value is 1. In the description of test modes is denoted by‘K*temp. env.’.

-n, --nstep-pass=INT

The number of activations of model nodes during each test pass. After every acti-vation of a model node an output signal is emitted by the model node. Defaultvalue is 10000. In the description of test modes is denoted by ‘Steps per pass’.

-o FILE A file to write program output to instead of stdout.

-t, --test=INT

Perform the test specified number of passes. In the description of test modes isdenoted by ‘Passes’.

The program can be invoked in two modes. In the first mode, when option ‘-t INT’ is notgiven to the program, a single test pass is performed, probabilities of emitting output signalsand numbers, which indicate operating efficiency, are printed as a result of program invocation.In the second mode, when option ‘-t INT’ is given to the program, the specified number oftest passes is performed, and for each test pass numbers that indicate operating efficiency arecalculated. In both modes, the following numbers, which pertain to efficiency, are printed.

earned Is equal to the logarithm of the product of probabilities of output signals emitted.Each time an output signal is emitted the product of probabilities is multiplied by

Chapter 7: Example Programs 258

a corresponding output signal probability, which was randomly generated at thebeginning of program execution.

random Is the logarithm of the product of probabilities of output signals (see a descriptionof ‘earned’ number) calculated for the situation when all output signals of modelnode are emitted equal number of times.

maximal Is the logarithm of the product of probabilities of output signals (see a description of‘earned’ number) calculated for the situation when for every model node an outputsignal with maximum probability is always emitted.

distance The sum of Euclidean distances between pairs of vectors for all model nodes, wherethe first vector of pair is the vector of probabilities of output signals randomlygenerated at the beginning of program execution, and the second vector of pair isthe vector of probabilities of output signals calculated on the basis of actual numbersof times those signals were emitted by a model node during execution of the model.

ef1 Efficiency equal to earned−randommaximal−random · 100%.

ef2 Efficiency equal to(1− distance√

2·nsigIn

)· 100%, where nsigIn is the number of model

nodes.

To perform a single test pass, do not give option ‘-t INT’ to the program. In this case,the program output begins with a description of test modes used. After the description theregoes a table, where each row represents a model node and starts with its index followed bynumber pairs that correspond to output signals. The first element of a pair is an output signalprobability, which was randomly generated at the beginning of program execution and accordingto which a spur increment is made when the output signal is emitted. The second element of apair is a percentage of output signals, which were emitted during program execution. The sumof percentages in each row of the table is ≈ 100%. After the table there are printed numbersthat indicate operating efficiency.

To perform a test, which consists of test passes, give option ‘-t INT’ to the program andspecify the number of test passes as the option argument. Here is shown sample programoutput for this method of program invocation.

$ ./tohuff-test -i1 -t10 -n160000 5 11

Input signals: 5

Output signals: 1024

Tree arity: 2

Passes: 10

Steps per pass: 160000

K*temp. env.: 1.000000000000000E+00

Random seed: 1

pass earned random maximal distance % ef1 % ef2

---- -------- -------- -------- -------------- ------- -------

1 -1060590 -1158415 -999031 3.57817309E+00 61.4 49.4

2 -1076420 -1155144 -1000943 3.72134950E+00 51.1 47.4

3 -1076429 -1158869 -997977 4.38714574E+00 51.2 38.0

4 -1088714 -1157306 -998875 4.24814120E+00 43.3 39.9

5 -1046098 -1158339 -1000010 4.46812225E+00 70.9 36.8

6 -1053158 -1158577 -996437 4.27544598E+00 65.0 39.5

7 -1088164 -1158800 -998089 3.27629262E+00 44.0 53.7

8 -1068321 -1158087 -997921 4.29218964E+00 56.0 39.3

9 -1089652 -1157490 -998018 2.46268987E+00 42.5 65.2

10 -1068592 -1158506 -996874 4.08599981E+00 55.6 42.2

TOTL -10716138 -11579534 -9984177 3.87955497E+01 54.1 45.1

stddev ef1: 9.6

stddev ef2: 8.9

Chapter 7: Example Programs 259

The output begins with a description of test modes used. In the description of test modes,‘Input signals’ denotes the number of model nodes. After the description there goes a table,which contains numbers that indicate the efficiency of operation of the multinode model at everytest pass, with a summary row. Values ‘earned’, ‘random’, ‘maximal’, and ‘distance’ in thesummary row are equal to sums of those values in preceding rows of the table. Values ‘% ef1’and ‘% ef2’ in the summary row are calculated on the basis of other values in that row. At theend of the output the standard deviation of values ‘% ef1’ and ‘% ef2’ is printed.

Reference results of program invocation are represented below. Values of ‘% ef1’ and ‘% ef2’were taken from summary rows of test logs.

Options nSigOut % ef1 % ef2

====================== ======= ===== =====

-i1 -t100 -n10000 4 7 64 43.5 76.6

-i1 -t100 -n20000 4 7 64 52.2 69.9

---------------------- ------- ----- -----

-i1 -t100 -n10000 8 7 64 39.2 67.7

-i1 -t100 -n20000 8 7 64 47.3 59.3

-i1 -t100 -n40000 8 7 64 51.3 51.4

---------------------- ------- ----- -----

-i1 -t100 -n10000 4 8 128 39.4 75.6

-i1 -t100 -n20000 4 8 128 50.0 67.5

-i1 -t100 -n40000 4 8 128 58.4 58.5

---------------------- ------- ----- -----

-i1 -t100 -n10000 4 9 256 30.4 80.8

-i1 -t100 -n20000 4 9 256 42.6 70.7

-i1 -t100 -n40000 4 9 256 54.7 59.2

====================== ======= ===== =====

As it can be seen from the above results, for every pair, which consists of the number ofmodel nodes and tree height, there exists the number of activations of model nodes, which givesthe value of ‘% ef1’ greater than 50%.

7.10 optact-p

This program can be used to test operation of small and large actors in various modes. Here thegoal of the operation of an actor is the maximization of the product of probabilities of outputsignals emitted by the actor. Probabilities of output signals of the actor for its every inputsignal are randomly generated at the beginning of program execution. That is, the goal of theoperation of the actor is analogous to the goal of the operation of the tohuff-test program.

You should invoke the optact-p program with two arguments. The first argument specifiesthe number of input signals of the actor. The second argument specifies the number of outputsignals of the actor.

The program understands the following command-line options.

-a, --auto-spur

Use automatic spur. Its increment is performed every time the actor emits an outputsignal. In the description of test modes is denoted by ‘Automatic spur’.

--dump-prob=learnt|fq

Type of probabilities of output signals to dump.

‘learnt’ QSMM_PROB_LEARNT: learned probabilities.

‘fq’ QSMM_PROB_FQ: probabilities proportional to observed frequencies ofemitting output signals (default mode).

This option takes effect when option ‘-t’ is not specified.

-i, --seed=INT

A seed to initialize the pseudorandom number generator. Default value is 0. In thedescription of test modes is denoted by ‘Random seed’.

Chapter 7: Example Programs 260

--kt=FLOAT

The temperature (multiplied by some constant) of the actor. Default value is 1. Inthe description of test modes is denoted by ‘K*temp.’.

-L, --large[=INT]

Use a large actor with specified tree arity. Default value is 2. In the description oftest modes is denoted by ‘Large’ and ‘Tree arity’.

-n, --nstep-pass=INT

The number of input signals to receive and output signals to emit during each testpass. Default value is 10000. In the description of test modes is denoted by ‘Stepsper pass’.

-o FILE A file to write program output to instead of stdout.

-P, --relprob-type=0|1|2|3

The type of a function that returns a relative probability of output signal choice.

‘0’ QSMM_RELPROB_USER1 without a helper function provided.

‘1’ QSMM_RELPROB_BUILTIN1.

‘2’ QSMM_RELPROB_BUILTIN2 (default mode).

‘3’ QSMM_RELPROB_BUILTIN3.

In the description of test modes is denoted by ‘R. prob. type’.

-t, --test=INT

Perform the test specified number of passes. In the description of test modes isdenoted by ‘Passes’.

Like the tohuff-test program, the optact-p program can be invoked in two modes. In thefirst mode, when option ‘-t INT’ is not given to the program, a single test pass is performed,probabilities of emitting output signals and numbers, which indicate operating efficiency, areprinted as a result of program invocation. In the second mode, when option ‘-t INT’ is given tothe program, the specified number of test passes is performed, and for each test pass numbersthat indicate operating efficiency are calculated. In both modes, the following numbers, whichpertain to efficiency, are printed.

earned Is equal to the logarithm of the product of probabilities of output signals emitted.Each time an output signal is emitted the product of probabilities is multipliedby a corresponding output signal probability (for specific input signal), which wasrandomly generated at the beginning of program execution.

random Is the logarithm of the product of probabilities of output signals (see a descriptionof ‘earned’ number) calculated for the situation when for every input signal totalcounts of all output signals emitted are equal.

maximal Is the logarithm of the product of probabilities of output signals (see a description of‘earned’ number) calculated for the situation when for every input signal an outputsignal with the maximum probability is always emitted.

distance The sum of Euclidean distances between pairs of vectors for all input signals, wherethe first vector of pair is the vector of probabilities of output signals randomlygenerated at the beginning of program execution, and the second vector of pair isthe vector of probabilities of output signals calculated on the basis of actual numbersof times those signals were emitted for an input signal.

ef1 Efficiency equal to earned−randommaximal−random · 100%.

Chapter 7: Example Programs 261

ef2 Efficiency equal to(1− distance√

2·nsigIn

)· 100%, where nsigIn is the number of input

signals of the actor.

To perform a single test pass, do not give option ‘-t INT’ to the program. Sample programoutput for this method of program invocation is shown below.

$ ./optact-p -i1 -a -n40000 --dump-prob=learnt 5 8

Input signals: 5

Output signals: 8

Steps per pass: 40000

Large: off

R. prob. type: 2

Automatic spur: on

K*temp.: 1.000000000000000E+00

Random seed: 1

Type of probabilities (multiplied by 100) after slashes: QSMM_PROB_LEARNT

0: .09/010 .22/023 .16/015 .21/020 .00/000 .03/004 .07/007 .22/022

1: .06/007 .10/010 .04/004 .16/015 .08/007 .16/016 .14/012 .27/028

2: .09/009 .20/022 .12/011 .18/019 .09/008 .07/007 .15/014 .11/009

3: .05/006 .11/010 .23/024 .06/006 .01/002 .14/016 .17/014 .23/022

4: .11/010 .12/010 .14/015 .11/012 .04/005 .24/026 .05/006 .20/016

earned: -77632.7

random: -98287.4

maximal: -58330.1

distance: 2.95844925E-01

ef1: 51.7 %

ef2: 95.8 %

The program output begins with a description of test modes used, after which there goes atable, where each row represents an input signal and starts with its index followed by numberpairs that correspond to output signals. The first element of a pair is an output signal probability,which was randomly generated at the beginning of program execution and according to whicha spur increment is made when the output signal is emitted. The second element of a pair isan output signal probability (in percentage terms) of type QSMM_PROB_LEARNT or QSMM_PROB_FQ(see option ‘--dump-prob=learnt|fq’). The sum of percentages in each row of the table is≈ 100%. After the table there are printed numbers that indicate operating efficiency.

As it can be seen from the table above, in the selected mode of program invocation, learnedprobabilities of emitting output signals are approximately equal to probabilities of output signalsthat were randomly generated at the beginning of program execution.

To perform a test, which consists of test passes, give option ‘-t INT’ to the program andspecify the number of test passes as the option argument. Here is shown sample programoutput for this method of program invocation.

$ ./optact-p -i1 -t10 -a -n80000 4 64

Input signals: 4

Output signals: 64

Passes: 10

Steps per pass: 80000

Large: off

R. prob. type: 2

Automatic spur: on

K*temp.: 1.000000000000000E+00

Random seed: 1

pass earned random maximal distance % ef1 % ef2

---- -------- -------- -------- -------------- ------- -------

1 -318992 -360993 -277032 1.84619024E-01 50.0 96.7

Chapter 7: Example Programs 262

2 -318230 -358924 -279535 1.80716868E-01 51.3 96.8

3 -320984 -351922 -281495 1.83816822E-01 43.9 96.8

4 -319879 -355205 -277930 1.90002813E-01 45.7 96.6

5 -318188 -354105 -275123 1.96099943E-01 45.5 96.5

6 -317712 -357724 -273396 1.82284303E-01 47.4 96.8

7 -321754 -355919 -281390 1.78340284E-01 45.8 96.8

8 -321543 -353646 -282737 1.80150290E-01 45.3 96.8

9 -320502 -358849 -279461 1.64751281E-01 48.3 97.1

10 -319621 -356046 -279534 1.72587057E-01 47.6 96.9

TOTL -3197405 -3563333 -2787633 1.81336868E+00 47.2 96.8

stddev ef1: 2.3

stddev ef2: 0.2

The output begins with a description of test modes used. After the description there goesa table, which contains numbers that indicate the efficiency of operation of the actor at everytest pass, with a summary row. Values ‘earned’, ‘random’, ‘maximal’, and ‘distance’ in thesummary row are equal to sums of those values in preceding rows of the table. Values ‘% ef1’and ‘% ef2’ in the summary row are calculated on the basis of other values in that row. At theend of the output the standard deviation of values ‘% ef1’ and ‘% ef2’ is printed.

Reference results of program invocation are represented below. Values of ‘% ef1’ and ‘% ef2’were taken from summary rows of test logs.

Options % ef1 % ef2

=========================== ===== =====

-i1 -t100 -a -n10000 4 64 40.7 94.0

-i1 -t100 -a -n20000 4 64 44.4 95.0

--------------------------- ----- -----

-i1 -t100 -a -n10000 8 64 30.6 91.9

-i1 -t100 -a -n20000 8 64 35.2 93.4

-i1 -t100 -a -n40000 8 64 38.4 94.7

--------------------------- ----- -----

-i1 -t100 -a -n10000 4 128 37.1 94.4

-i1 -t100 -a -n20000 4 128 40.7 95.4

--------------------------- ----- -----

-i1 -t100 -a -n10000 4 256 31.4 95.2

-i1 -t100 -a -n20000 4 256 36.7 95.9

-i1 -t100 -a -n40000 4 256 40.7 96.6

=========================== ===== =====

In comparison with results represented in the table at the end of Section 7.9 [tohuff-test],page 256, in the table above the value of ‘% ef2’ increases as the number of steps at a test passincreases.

7.11 predict-test

This program learns a state model, which corresponds to a signal sequence specified by a probabi-listic finite automaton that has output signals, but does not have input ones. Learning efficiencyis tested by measuring the ability of the program to predict the next signal of the sequence. Anexample of a file with a description of probabilistic finite automaton is shown below.

Chapter 7: Example Programs 263

Non-empty line #1

Non-empty line #2

...

Non-empty line #n

3 4 0

0/0 1/1 0/0

2/1 0/0 0/1

0/1 3/1 0/0

0/0 0/0 0/1

All lines before the first empty line are ignored. The first line after that empty line hasformat

number_of_signals number_of_states initial_state_index

Indices of signals and states start from 0.

Starting from the second line after the empty line there go descriptions of transitions betweenstates during which signals are emitted. The second line corresponds to transitions from state0, the third—from state 1, the fourth—from state 2, and so on. Each line contains number pairsthat correspond to signals. The first pair corresponds to signal 0, the second—to signal 1, thethird—to signal 2, and so on. A pair has format

target_state/relative_probability

and specifies a transition from a source state to a target state with indicated relative probability,during which a signal is emitted.

Files, which contain example descriptions of probabilistic finite automatons, are located indirectory ‘samples/dist’ of the package source tree.

The program creates one or more single-node models which action emission matrices definedeterministic choice of actions for all node states. The environment state identification engineof every model uses a relative probability function of type QSMM_RELPROB_BUILTIN2 and twospur types with the normal way of spur perception. Spur of type 0 is the automatic spur. Spurof type 1 has weight 1 and is incremented by 1 when the model correctly predicts the nextsequence signal. When a large actor is used for the environment state identification engine, theweight of the automatic spur of a small actor associated with the large actor and the weight ofthe automatic spur of the large actor (of type 0) are set to 0.5 to countervail spur of type 1 ofthe large actor.

Every single-node model is executed in a separate thread that communicates with the mainprogram thread using the Side API. Units of communication are signals. At every step ofprocessing a signal sequence, the next predicted signal is received from each single-node modeland the actual next sequence signal is sent to those models.

An important improvement made in QSMM version 1.16 for the example program is a newmethod of how the overall result of next signal prediction is computed on the basis of the nextsignal predicted by each single-node model. There is used a vector of signal weights, which iszeroed every time before predicting the next sequence signal. A signal predicted by every single-node model causes the increment of a corresponding element of that vector. For the overallresult of next signal prediction there is taken index i of an element of the vector that givesmaximum value of weight[i]·tmd

fq[i]. Here weight[i] is the value of the element, tmd is the length of a

signal sequence processed by the example program so far, and fq[i] is the number of occurrencesof signal i in that signal sequence.

For every single-node model, the program uses one of four built-in probability profiles. Thoseprobability profiles are represented by internally generated assembler programs and specify possi-ble transitions between states depending on signals received in the states. To every state there

Chapter 7: Example Programs 264

corresponds a vector of frequencies of signals received in the state during model execution. Forthe next signal predicted in the state, a signal that has the maximum frequency is taken.

The basic probability profile, which has index 0, is a uniform profile with all states connected,where from every state there are transitions to all other states upon receiving every signal. Thestructure of such profile with four states is represented in Figure 7.2. Dots denote the states,and lines denote groups of state transitions. The number of state transitions represented byevery line in the figure is equal to the number of signals multiplied by two because in this profileevery transition can be made in two directions.

Figure 7.2: state transition profile 0 with 4 states

Probability profile 1 is suitable for learning sequences of signals, which consist of independentsegments of similar structure. The profile has a rectangular form with the initial state to theleft. Every state has a reset transition to the initial state. The structure of probability profile1 with the initial state, three rows, and five columns is represented in Figure 7.3. This exampleprofile supports learning sequences, which consist of independent segments of similar structurethat have length up to 6. Dots denote the states, and arrows denote groups of state transitions,where each state transition corresponds to a received signal.

Figure 7.3: state transition profile 1 with 3 rows and 5 columns

Probability profile 2 is completely deterministic one. Its states are n-grams. This profilecould be used to compare the efficiency of next signal prediction using stochastic algorithms andusing the classical n-gram approach. The structure of the profile for n-gram length 3 and twosignals is represented in Figure 7.4. Rectangles denote the states. The rectangle of the initialstate has label “Start” inside it. Rectangles of other states contain n-gram contents. Arrowsindicate state transitions and are labeled by indices of signals that trigger the transitions.

Probability profile 3 is based on probability profile 2, but has a number of states thatcorrespond to every n-gram. That number is fixed and along with n-gram length are theparameters for creating the profile. The representation of probability profile 3 would beanalogous to the representation of probability profile 2, but would contain several substatesin place of every state and would have every arrow splitted into multiple ones. Every pair of

Chapter 7: Example Programs 265

states of probability profile 2 with an arrow between them would be replaced with two groupsof substates, where each substate from the first group is connected with each substate from thesecond group by an arrow that has the same direction. Unfortunately, the example figure ofprobability profile 3 is not provided because of its substantial complexity.

Chapter 7: Example Programs 266

Figure 7.4: state transition profile 2 for n-gram length 3 and two signals

You should invoke the predict-test program with an argument, which specifies the nameof a file containing the description of a probabilistic finite automaton that defines the signalsequence. The program understands the following command-line options.

--dump-asm

Dump the source text of an assembler program that corresponds to the first modelstructure (probability profile) descriptor specified by option ‘-M’.

--dump-disasm[=PREFIX]

Dump the disassembled learned program of every model to a file named “PREFIX i,”where i is a model index. If PREFIX not specified, then ‘prg_disasm_’ will be usedfor it.

--dump-goto[=PREFIX]

Dump the state transition matrix of every model to a file named “PREFIX i,” wherei is a model index. If PREFIX not specified, then ‘mat_goto_’ will be used for it.

-i, --seed=INT

A seed to initialize pseudorandom number generators. Default value is 0. In thedescription of test modes is denoted by ‘Random seed’.

-L, --large

Use a large actor for the environment state identification engine of every model. Inthe description of test modes is denoted by ‘Large’.

-M, --model=STR

One or more model structure (probability profile) descriptors. If several descriptorsare given, then they must be delimited by ‘;’, and STR should be put in quotes.Every descriptor must be specified in one of the following formats.

Chapter 7: Example Programs 267

‘0,nstate ’State transition profile 0 with nstate states.

‘1,nrow,ncol ’State transition profile 1 with a rectangular state transition matrix thathas nrow rows and ncol columns.

‘2,ngram_sz ’Deterministic state transition profile 2 with n-grams of lengths up tongram sz.

‘3,ngram_sz,nstate_ngram ’State transition profile 3 with n-grams of lengths up to ngram sz andnstate ngram states per every n-gram.

In the description of test modes is denoted by ‘Models’ and ‘model[i]’, where i isa model index.

-n, --nstep-pass=INT

The number of sequence signals to generate using the probabilistic finite automaton(specified by a program argument) and predict at each test pass. Default value is10000. In the description of test modes is denoted by ‘Steps per pass’.

-o FILE A file to write program output to instead of stdout.

-t, --test=INT

Perform the test specified number of passes. In the description of test modes isdenoted by ‘Passes’.

--template

When option ‘--dump-disasm[=PREFIX]’ is specified, disassemble the learnedprogram of every model using an assembler program template. The assemblerprogram template corresponds to an assembler program that can be dumped withthe help of option ‘--dump-asm’.

When invoked with option ‘-t INT’, the program prints a test log, an example of which isshown below. The log begins with a description of test modes used that includes parameters ofstate transition profiles specified by option ‘-M STR ’. Then there goes a table, where each rowcorresponds to a test pass, with a summary row. Finally, there is printed the standard deviationof values in ‘% efr’ and ‘% efa’ columns of the table.

$ ./predict-test -i1 -t10 -M1,5,40 -n640000 dist/dist1

Dist. file: dist/dist1

Signals: 10

Dist. states: 18

Passes: 10

Steps per pass: 640000

Large: off

Random seed: 1

Models: 1

model[0]: type=1, nrow=5, ncol=40

pass earned random maximal % efr % efa

---- -------- ------ ------------ -------- -------

1 532581 63825 640000.000 834.439 81.357

2 602249 64123 640000.000 939.209 93.445

3 635244 63973 640000.000 992.988 99.174

4 567070 64337 640000.000 881.406 87.331

5 617353 64130 640000.000 962.659 96.067

6 591651 63792 640000.000 927.469 91.609

7 527643 64022 640000.000 824.159 80.493

Chapter 7: Example Programs 268

8 637622 63784 640000.000 999.658 99.587

9 602574 64029 640000.000 941.095 93.502

10 635594 64214 640000.000 989.806 99.235

TOTL 5949581 640229 6400000.000 929.290 92.180

stddev efr: 63.568

stddev efa: 7.068

Columns of the table have the following meaning.

pass A test pass index. For the summary row, ‘TOTL’ is printed here.

earned The number of correctly predicted sequence signals. In the summary row—the sumof values in the column.

random The number of coincidences of sequence signals with uniformly distributed randomsignals. In the summary row—the sum of values in the column.

maximal The number of sequence signals that will be correctly predicted if the program everytime predicts a signal, which has the maximum probability in a row of emissionmatrix of probabilistic finite automaton. The row corresponds to the current stateof the automaton. In the summary row—the sum of values in the column.

% efr Relative efficiency equal to earnedrandom

· 100%. For the summary row, is calculated usingcorresponding values in that row.

% efa Actual efficiency equal to earned−randommaximal−random ·100%. For the summary row, is calculated

using corresponding values in that row.

When invoked without option ‘-t INT ’, but with option ‘-M STR ’ specified, the programprints the stream of pairs of signal identifiers

actual_signal:predicted_signal

The number of pairs is equal to the number of steps at a test pass (see option ‘-n INT ’).

When invoked without options ‘-t INT ’ and ‘-M STR ’, the program prints a stream of signalidentifiers produced by the probabilistic finite automaton. The number of signal identifiers isequal to the number of steps at a test pass (see option ‘-n INT ’). An example of such programoutput is shown below.

$ ./predict-test -n100 dist/dist1

0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2

1 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3

2 1 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9

Reference results of program invocation are represented below. Values of ‘% efr’ and ‘% efa’were taken from summary rows of test logs.

Dist. file Opts. Prefix Model nStep % efr % efa nStep % efr % efa

========== ============ =============== ====== ===== ===== ======== ===== =====

dist/dist1 -i1 -t100 -L -M0,40 -n8000 616.0 57.5 -n640000 824.7 80.5

-M"0,40[x4]" -n8000 837.7 82.2

-i1 -t100 -M1,5,45 -n8000 638.8 60.0 -n640000 894.0 88.2

-M"1,5,45[x6]" -n8000 909.7 90.2

-M3,1,4 -n8000 861.4 84.8 -n640000 936.8 93.0

-M"3,1,4[x4]" -n8000 959.3 95.7

dist/dist2 -i1 -t100 -L -M0,40 -n8000 815.6 79.5 -n640000 868.9 85.5

-M"0,40[x16]" -n8000 868.4 85.3

dist/dist3 -i1 -t100 -L -M0,40 -n8000 741.6 71.2 -n640000 862.8 84.7

-M"0,40[x8]" -n8000 868.8 85.3

Chapter 7: Example Programs 269

-i1 -t100 -M1,5,45 -n8000 710.8 67.8 -n640000 831.7 81.3

-M"1,5,45[x4]" -n8000 854.5 83.7

dist/dist4 -i1 -t100 -M0,40 -n8000 303.3 50.6 -n640000 362.8 65.7

-M"0,40[x16]" -n8000 375.8 68.6

dist/dist5 -i1 -t100 -L -M3,1,8 -n8000 405.4 71.8 -n640000 448.5 81.8

dist/dist6 -i1 -t100 -M3,1,8 -n8000 304.7 51.2 -n640000 382.4 70.6

dist/dist7 -i1 -t100 -L -M1,5,45 -n8000 232.8 33.3 -n640000 272.9 43.2

dist/dist8 -i1 -t100 -M1,5,45 -n8000 268.1 25.9 -n640000 476.1 57.9

-M"1,5,45[x16]" -n8000 503.5 62.1

-M3,1,8 -n8000 454.3 54.5 -n640000 588.7 75.2

======================= =============== ====== ===== ===== ======== ===== =====

Note: in the ‘Model’ column, notation ‘-M"...[xn]"’ means repeating an expressi-on denoted by ellipses n times with inserting delimiter ‘;’ between copies ofthe expression. For example, notation ‘-M"3,1,4[x4]"’ is to be expanded to‘-M"3,1,4;3,1,4;3,1,4;3,1,4"’.

As it can be seen from the table above, in many cases, loss of efficiency of signal predictionfor a shorter length of a signal sequence can be compensated by using more models of the samestructure. However, for some probabilistic finite automatons, adding more models of the samestructure does not provide appreciable increase in the number of correctly predicted signals.

Command make builds the example program if the QSMM package is configured by the‘configure’ script to use the POSIX threads API. See file ‘INSTALL’ at the root of the packagedistribution, for information on the ‘configure’ script.

7.12 langlearn-test

This program performs function analogous to the predict-test example program, but learns asignal sequence specified by a probabilistic context-free grammar (PCFG), not by a probabilisticfinite automaton. Thus, the langlearn-test program can be considered as a more obviousexample of learning a language than the predict-test program where the language is definedin an indirect way. As distinct from the predict-test program, which can use several typesof probability profiles defined by internally generated assembler programs that are loaded intosingle-node models, the langlearn-test program uses plain actors instead of single-node modelsand the uniform probability profile. In the predict-test program that profile has index 0.

An example of a file with a description of probabilistic context-free grammar is shown below.

S: A S

;

A: "a" B "a" "a" C "a"

;

B: "b" [0.67]

| "b" B [0.33]

;

C: "c" [0.67]

| "c" C [0.33]

;

Files, which contain sample grammar descriptions, are located in directory ‘samples/gram’of the package source tree. The above example is contained in file ‘samples/gram/gram7’.

Chapter 7: Example Programs 270

Nonterminal symbols are sequences of alphanumeric characters and character ‘_’, which startwith a letter or ‘_’. Terminal symbols are quoted (with single or double quotes) sequences ofcharacters; escape character ‘\’ can be used to insert a quote or character ‘\’ in these sequences.Every production starts with a nonterminal symbol followed by character ‘:’ and ends withcharacter ‘;’. A nonterminal symbol at the left hand side of the first production in a grammarbecomes the start nonterminal symbol of the grammar. Right hand sides of productions withthe same nonterminal symbol at their left hand sides can be delimited by ‘|’. However, theycan also be specified as multiple productions that end with ‘;’. A positive probability or relati-ve probability of production can be specified in square brackets after the right hand side ofproduction before characters ‘|’ or ‘;’. By default, the relative probability equal to 1 is used.

When applying grammar productions, left recursion is suppressed. Therefore, it isrecommended not to use such recursion in input grammars, possibly replacing it with rightrecursion.

To evaluate the efficiency of learning a language, the number of correctly predicted terminalsymbols in the sequence is compared with a lower bound and an upper bound. The lower boundis equal to the number of symbols correctly predicted using the classical n-gram approach. Theupper bound is equal to the maximum possible number of symbols that can be predicted byany means. To calculate the upper bound, a set of stacks is kept, which contain information onnested productions that can be used to emit terminal symbols. One of those symbols becomesthe next terminal symbol of the sequence. With every stack a probability is associated, whichmakes possible calculating exact probabilities of next terminal symbols. After actual emittingthe next terminal symbol, only those stacks survive, which could emit that terminal symbol.The stacks survived then can be splitted into several next generation stacks that correspond topossible alternatives of selecting next grammar productions. Identical stacks are merged withsumming up probabilities associated with them. The upper bound on the number of terminalsymbols that can be correctly predicted as the next symbol of the sequence is taken equal to themaximum probability among exact probabilities of next terminal symbols. The upper boundon the number of terminal symbols that can be correctly predicted in a sequence is the sum ofupper bounds calculated for all symbols in the sequence.

The maximum allowed size of the set of stacks is specified by option ‘-C, --nstack-max=INT ’.When the actual size of the set exceeds the maximum allowed size, the program prints the numberof sequence symbols that were generated up to the moment and terminates with an error. Forsome grammars the stacks are spawned faster than killed, so the size of the set will not be limitedby a certain fixed number. In such cases, providing a large value for option ‘-C INT ’ sometimessolves the problem for specific sequence length. However, for some grammars the value of option‘-C INT ’ needs to be very large even for relatively short sequences, and an upper bound on thenumber of correctly predicted symbols will be impractical to calculate.

The length of every sequence of terminal symbols generated by the example program islimited by the value of option ‘-n, --nstep-pass=INT ’ (default value is 10000). The lengthwill be shorter if expanding a start nonterminal symbol finishes earlier. That is why manyof sample grammars included in the package distribution begin with a recursive production ofform ‘S: A S’, so the sequence of terminal symbols produced by the grammar never terminates.However, for big values of option ‘-n INT ’ this approach should be avoided, because it results inever increasing lengths of stacks used for calculating exact probabilities of next terminal symbols.Because long stacks require long memory blocks to hold them, splitting the stacks takes everincreasing time for block copying operations. To greatly limit the number of frames in the stackswhen generating a sequence of a certain length, the recursion can be replaced with a number ofnested productions as shown below.

S: A1 A1 A1 A1 A1 A1 A1 A1 A1 A1;

A1: A2 A2 A2 A2 A2 A2 A2 A2 A2 A2;

A2: A3 A3 A3 A3 A3 A3 A3 A3 A3 A3;

Chapter 7: Example Programs 271

A3: A A A A A A A A A A;

...

Such productions will generate sequence S that consists of 10000 copies of subsequence A.

In comparison with the predict-test program, the langlearn-test program has a fewsimplifications. The first one is that actors created by the langlearn-test program do not usepositive countervailing spur incremented every time a correct symbol is predicted. The secondsimplification is that when large actors are created, the use of the automatic spur by small actorsassociated with the large actors is turned off. The third simplification is that actors use a relativeprobability function of type QSMM_RELPROB_BUILTIN3. In other respects, the langlearn-test

program identifies current sequence states and makes the prediction of the next sequence signalin the same way as the predict-test program does when it uses a probability profile of type 0.

You should invoke the langlearn-test program with an argument, which specifies the nameof a file with a grammar description. The program understands the following command-lineoptions.

-C, --nstack-max=INT

The maximum allowed size of the set of stacks used to calculate exact probabilities ofnext terminal symbols. If is greater than 0, then the maximum exact probability ofthe next terminal symbol will be used as an upper bound on the number of terminalsymbols that can be correctly predicted as the next symbol of the sequence. If isequal to 0, then probability 1 will be used as the upper bound. Default value is 0.In the description of test modes is denoted by ‘Max. stacks’.

-i, --seed=INT

A seed to initialize pseudorandom number generators. Default value is 0. In thedescription of test modes is denoted by ‘Random seed’.

-l, --ngram-length=INT

The length of n-grams for predicting the next terminal symbol in the sequence usingthe classical n-gram approach. The number of symbols correctly predicted in sucha way is taken as a lower bound on the number of terminal symbols that can becorrectly predicted in the sequence. Value 0 means predicting a terminal symbolthat occurs most frequently in a sequence processed so far. Default value is 0. Inthe description of test modes is denoted by ‘N-gram length’.

-L, --large[=INT]

Use large actors with specified tree arity. Default value is 2. In the description oftest modes is denoted by ‘Large’ and ‘Tree arity’.

-M, --model=NACTOR,NSTATE

The number of actors and the number of sequence states tracked by every actor. Theactors operate concurrently in separate threads. In the description of test modesare denoted by ‘Actors’ and ‘States’.

-n, --nstep-pass=INT

The maximum length of every sequence of terminal symbols to generate accordi-ng to the input grammar. The actual length can be shorter if expanding a startnonterminal symbol finishes earlier. Default value is 10000. In the description oftest modes is denoted by ‘Max. length’.

-o FILE A file to write program output to instead of stdout.

-t, --test=INT

Perform the test specified number of passes. In the description of test modes isdenoted by ‘Passes’.

Chapter 7: Example Programs 272

When invoked with option ‘-t INT’, the program prints a test log, an example of which isshown below. The log begins with a description of test modes used. Then there goes a table,where each row corresponds to a test pass, with a summary row. Finally, there is printed thestandard deviation of values in the ‘% ef’ column of the table.

$ ./langlearn-test -i1 -t10 -C3 -L -M6,16 gram/gram7

Grammar file: gram/gram7

Terminals: 3

Passes: 10

Max. length: 10000

N-gram length: 0

Actors: 6

States: 16

Large: on

Tree arity: 2

Max. stacks: 3

Random seed: 1

pass length earned ngram exact % ef

---- -------- -------- -------- ------------ --------

1 10000 7676 5744 8595.850 67.745

2 10000 7019 5725 8589.250 45.178

3 10000 7738 5718 8587.600 70.393

4 10000 7590 5675 8573.080 66.078

5 10000 5765 5706 8583.310 2.051

6 10000 7549 5703 8581.990 64.120

7 10000 6733 5726 8590.240 35.158

8 10000 6868 5746 8596.840 39.357

9 10000 7253 5782 8608.060 52.051

10 10000 7646 5743 8595.520 66.713

TOTL 100000 71837 57268 85901.740 50.881

stddev ef: 21.397

Columns of the table have the following meaning.

pass A test pass index. For the summary row, ‘TOTL’ is printed here.

length The length of the generated sequence of terminal symbols. Is equal to the value ofoption ‘-n INT ’ or to a lesser value if expanding a start nonterminal symbol finishesearlier. In the summary row—the sum of values in the column.

earned The number of terminal symbols correctly predicted according to the algorithm. Inthe summary row—the sum of values in the column.

ngram The number of terminal symbols correctly predicted using the classical n-gramapproach with n-gram length equal to the value of option ‘-l INT ’. Is a lowerbound used when calculating values in the ‘% ef’ column. In the summary row—thesum of values in the column.

exact The number of terminal symbols that can be correctly predicted by any means. Isan upper bound used when calculating values in the ‘% ef’ column. In the summaryrow—the sum of values in the column.

% ef The efficiency of prediction of sequence symbols equal to earned−ngramexact−ngram · 100% if

earned ≥ ngram and exact > ngram, or to 0 otherwise. For the summary row, iscalculated using corresponding values in that row.

When invoked without option ‘-t INT ’, but with option ‘-M NACTOR,NSTATE ’ specified, theprogram prints the stream of pairs of terminal symbols

actual_symbol:predicted_symbol

Chapter 7: Example Programs 273

When invoked without options ‘-t INT ’ and ‘-M NACTOR,NSTATE ’, the program prints astream of terminal symbols produced by an input grammar. An example of such programoutput is shown below.

$ ./langlearn-test -n100 gram/gram7

a b a a c c a a b b a a c c c a a b a a c a a b a a c a a b a a c c a

a b a a c a a b a a c a a b a a c c a a b a a c a a b a a c a a b a a

c c a a b a a c c a a b a a c a a b b a a c a a b b b a a c

Reference results of program invocation are represented below. The ‘Lower’ columncorresponds to the ‘ngram’ column of test log, and the ‘Upper’ column corresponds to the ‘exact’column. Values in ‘Lower’, ‘Earned’, ‘Upper’, and ‘% ef’ columns were taken from summary rowsof test logs.

Gram. file Options nStep Model Lower Earned Upper % ef

========== ================ ======= ======= ====== ======= ======= ====

gram/gram1 -i1 -t100 -C2 -L -n10000 -M2,16 62497 553800 875000 60.5

-M4,16 615529 68.1

-M8,16 695858 78.0

gram/gram2 -i1 -t100 -C2 -L -n10000 -M3,16 31009 514649 937500 53.4

-M6,16 602224 63.0

-M12,16 704557 74.3

gram/gram3 -i1 -t100 -C2 -L -n10000 -M1,16 100184 456693 800015 50.9

-M2,16 591133 70.1

-M4,16 622143 74.6

gram/gram4 -i1 -t100 -C3 -L -n10000 -M2,32 492575 708138 916612 50.8

-M4,32 772630 66.0

-M8,32 815670 76.2

gram/gram5 -i1 -t100 -C5 -L -n10000 -M4,16 332270 631169 893936 53.2

-M8,16 713483 67.9

-M16,16 767706 77.5

gram/gram6 -i1 -t100 -C6 -L -n40000 -M14,16 998909 1905534 2777543 51.0

-M28,16 2031198 58.0

-M56,16 2145155 64.4

gram/gram7 -i1 -t100 -C3 -L -n10000 -M6,16 572876 723772 859081 52.7

-M12,16 768748 68.4

-M24,16 799322 79.1

gram/gram8 -i1 -t100 -C3 -L -n10000 -M1,16 400000 746964 933286 65.1

-M2,16 794785 74.0

-M4,16 826898 80.1

========== ================ ======= ======= ====== ======= ======= ====

As it can be seen from the table above, the correctness of the prediction of sequence symbolsis increased by using more actors that operate concurrently.

Command make builds the example program if the QSMM package is configured by the‘configure’ script to use the POSIX threads API. See file ‘INSTALL’ at the root of the packagedistribution, for information on the ‘configure’ script.

GNU General Public License 274

GNU General Public License

Version 3, 29 June 2007Copyright c© 2007 Free Software Foundation, Inc. http://fsf.org/

Everyone is permitted to copy and distribute verbatim copies of thislicense document, but changing it is not allowed.

PreambleThe GNU General Public License is a free, copyleft license for software and other kinds of works.

The licenses for most software and other practical works are designed to take away your freedom to share and changethe works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change allversions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use theGNU General Public License for most of our software; it applies also to any other work released this way by its authors.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 tomake sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receivesource 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 thatyou know you can do these things.

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights.Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities torespect the freedom of others.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipientsthe same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you mustshow them these terms so they know their rights.

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2)offer you this License giving you legal permission to copy, distribute and/or modify it.

For the developers’ and authors’ protection, the GPL clearly explains that there is no warranty for this free software.For both users’ and authors’ sake, the GPL requires that modified versions be marked as changed, so that their problemswill not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, althoughthe manufacturer can do so. This is fundamentally incompatible with the aim of protecting users’ freedom to change thesoftware. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely whereit is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products.If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in futureversions of the GPL, as needed to protect the freedom of users.

Finally, every program is threatened constantly by software patents. States should not allow patents to restrictdevelopment and use of software on general-purpose computers, but in those that do, we wish to avoid the special dangerthat patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patentscannot be used to render the program non-free.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS0. Definitions.

“This License” refers to version 3 of the GNU General Public License.

“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”.“Licensees” and “recipients” may be individuals or organizations.

To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission,other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or awork “based on” the earlier work.

A “covered work” means either the unmodified Program or a work based on the Program.

To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarilyliable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy.Propagation includes copying, distribution (with or without modification), making available to the public, and insome countries other activities as well.

To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mereinteraction with a user through a computer network, with no transfer of a copy, is not conveying.

An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient andprominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is nowarranty for the work (except to the extent that warranties are provided), that licensees may convey the work underthis License, and how to view a copy of this License. If the interface presents a list of user commands or options, suchas a menu, a prominent item in the list meets this criterion.

GNU General Public License 275

1. Source Code.

The “source code” for a work means the preferred form of the work for making modifications to it. “Object code”means any non-source form of a work.

A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body,or, in the case of interfaces specified for a particular programming language, one that is widely used among developersworking in that language.

The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is includedin the normal form of packaging a Major Component, but which is not part of that Major Component, and (b)serves only to enable use of the work with that Major Component, or to implement a Standard Interface for whichan implementation is available to the public in source code form. A “Major Component”, in this context, means amajor essential component (kernel, window system, and so on) of the specific operating system (if any) on which theexecutable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

The “Corresponding Source” for a work in object code form means all the source code needed to generate, install,and (for an executable work) run the object code and to modify the work, including scripts to control those activi-ties. However, it does not include the work’s System Libraries, or general-purpose tools or generally available freeprograms which are used unmodified in performing those activities but which are not part of the work. For example,Corresponding Source includes interface definition files associated with source files for the work, and the source codefor shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as byintimate data communication or control flow between those subprograms and other parts of the work.

The Corresponding Source need not include anything that users can regenerate automatically from other parts of theCorresponding Source.

The Corresponding Source for a work in source code form is that same work.

2. Basic Permissions.

All rights granted under this License are granted for the term of copyright on the Program, and are irrevocableprovided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodifiedProgram. The output from running a covered work is covered by this License only if the output, given its content,constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided bycopyright law.

You may make, run and propagate covered works that you do not convey, without conditions so long as your licenseotherwise remains in force. You may convey covered works to others for the sole purpose of having them makemodifications exclusively for you, or provide you with facilities for running those works, provided that you complywith the terms of this License in conveying all material for which you do not control copyright. Those thus making orrunning the covered works for you must do so exclusively on your behalf, under your direction and control, on termsthat prohibit them from making any copies of your copyrighted material outside their relationship with you.

Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is notallowed; section 10 makes it unnecessary.

3. Protecting Users’ Legal Rights From Anti-Circumvention Law.

No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obli-gations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting orrestricting circumvention of such measures.

When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to theextent such circumvention is effected by exercising rights under this License with respect to the covered work, andyou disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work’susers, your or third parties’ legal rights to forbid circumvention of technological measures.

4. Conveying Verbatim Copies.

You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that youconspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices statingthat this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact allnotices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

You may charge any price or no price for each copy that you convey, and you may offer support or warranty protectionfor a fee.

5. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form ofsource code under the terms of section 4, provided that you also meet all of these conditions:

a. The work must carry prominent notices stating that you modified it, and giving a relevant date.

b. The work must carry prominent notices stating that it is released under this License and any conditions addedunder section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.

c. You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy.This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work,and all its parts, regardless of how they are packaged. This License gives no permission to license the work inany other way, but it does not invalidate such permission if you have separately received it.

d. If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Programhas interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.

A compilation of a covered work with other separate and independent works, which are not by their nature extensionsof the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a

GNU General Public License 276

storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not usedto limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of acovered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

6. Conveying Non-Source Forms.

You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you alsoconvey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

a. Convey the object code in, or embodied in, a physical product (including a physical distribution medium),accompanied by the Corresponding Source fixed on a durable physical medium customarily used for softwareinterchange.

b. Convey the object code in, or embodied in, a physical product (including a physical distribution medium),accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts orcustomer support for that product model, to give anyone who possesses the object code either (1) a copy of theCorresponding Source for all the software in the product that is covered by this License, on a durable physicalmedium customarily used for software interchange, for a price no more than your reasonable cost of physicallyperforming this conveying of source, or (2) access to copy the Corresponding Source from a network server atno charge.

c. Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source.This alternative is allowed only occasionally and noncommercially, and only if you received the object code withsuch an offer, in accord with subsection 6b.

d. Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalentaccess to the Corresponding Source in the same way through the same place at no further charge. You need notrequire recipients to copy the Corresponding Source along with the object code. If the place to copy the objectcode is a network server, the Corresponding Source may be on a different server (operated by you or a thirdparty) that supports equivalent copying facilities, provided you maintain clear directions next to the object codesaying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, youremain obligated to ensure that it is available for as long as needed to satisfy these requirements.

e. Convey the object code using peer-to-peer transmission, provided you inform other peers where the object codeand Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.

A separable portion of the object code, whose source code is excluded from the Corresponding Source as a SystemLibrary, need not be included in conveying the object code work.

A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normallyused for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling.In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. Fora particular product received by a particular user, “normally used” refers to a typical or common use of that classof product, regardless of the status of the particular user or of the way in which the particular user actually uses, orexpects or is expected to use, the product. A product is a consumer product regardless of whether the product hassubstantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of useof the product.

“Installation Information” for a User Product means any methods, procedures, authorization keys, or other informati-on required to install and execute modified versions of a covered work in that User Product from a modified versionof its Corresponding Source. The information must suffice to ensure that the continued functioning of the modifiedobject code is in no case prevented or interfered with solely because modification has been made.

If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and theconveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred tothe recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the CorrespondingSource conveyed under this section must be accompanied by the Installation Information. But this requirement doesnot apply if neither you nor any third party retains the ability to install modified object code on the User Product(for example, the work has been installed in ROM).

The requirement to provide Installation Information does not include a requirement to continue to provide supportservice, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Productin which it has been modified or installed. Access to a network may be denied when the modification itself materiallyand adversely affects the operation of the network or violates the rules and protocols for communication across thenetwork.

Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in aformat that is publicly documented (and with an implementation available to the public in source code form), andmust require no special password or key for unpacking, reading or copying.

7. Additional Terms.

“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or moreof its conditions. Additional permissions that are applicable to the entire Program shall be treated as though theywere included in this License, to the extent that they are valid under applicable law. If additional permissions applyonly to part of the Program, that part may be used separately under those permissions, but the entire Programremains governed by this License without regard to the additional permissions.

When you convey a copy of a covered work, you may at your option remove any additional permissions from thatcopy, or from any part of it. (Additional permissions may be written to require their own removal in certain caseswhen you modify the work.) You may place additional permissions on material, added by you to a covered work, forwhich you have or can give appropriate copyright permission.

GNU General Public License 277

Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorizedby the copyright holders of that material) supplement the terms of this License with terms:

a. Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or

b. Requiring preservation of specified reasonable legal notices or author attributions in that material or in theAppropriate Legal Notices displayed by works containing it; or

c. Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such materialbe marked in reasonable ways as different from the original version; or

d. Limiting the use for publicity purposes of names of licensors or authors of the material; or

e. Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or

f. Requiring indemnification of licensors and authors of that material by anyone who conveys the material (ormodified versions of it) with contractual assumptions of liability to the recipient, for any liability that thesecontractual assumptions directly impose on those licensors and authors.

All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If theProgram as you received it, or any part of it, contains a notice stating that it is governed by this License along with aterm that is a further restriction, you may remove that term. If a license document contains a further restriction butpermits relicensing or conveying under this License, you may add to a covered work material governed by the termsof that license document, provided that the further restriction does not survive such relicensing or conveying.

If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statementof the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or statedas exceptions; the above requirements apply either way.

8. Termination.

You may not propagate or modify a covered work except as expressly provided under this License. Any attemptotherwise to propagate or modify it is void, and will automatically terminate your rights under this License (includingany patent licenses granted under the third paragraph of section 11).

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a)provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently,if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies youof the violation by some reasonable means, this is the first time you have received notice of violation of this License(for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

Termination of your rights under this section does not terminate the licenses of parties who have received copies orrights from you under this License. If your rights have been terminated and not permanently reinstated, you do notqualify to receive new licenses for the same material under section 10.

9. Acceptance Not Required for Having Copies.

You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagationof a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewisedoes not require acceptance. However, nothing other than this License grants you permission to propagate or modifyany covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying orpropagating a covered work, you indicate your acceptance of this License to do so.

10. Automatic Licensing of Downstream Recipients.

Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run,modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by thirdparties with this License.

An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one,or subdividing an organization, or merging organizations. If propagation of a covered work results from an entitytransaction, each party to that transaction who receives a copy of the work also receives whatever licenses to thework the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possessionof the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it withreasonable efforts.

You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. Forexample, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License,and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patentclaim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

11. Patents.

A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which theProgram is based. The work thus licensed is called the contributor’s “contributor version”.

A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether alreadyacquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using,or selling its contributor version, but do not include claims that would be infringed only as a consequence of furthermodification of the contributor version. For purposes of this definition, “control” includes the right to grant patentsublicenses in a manner consistent with the requirements of this License.

Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor’s essentialpatent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of itscontributor version.

GNU General Public License 278

In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated,not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infri-ngement). To “grant” such a patent license to a party means to make such an agreement or commitment not toenforce a patent against the party.

If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work isnot available for anyone to copy, free of charge and under the terms of this License, through a publicly availablenetwork server or other readily accessible means, then you must either (1) cause the Corresponding Source to be soavailable, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange,in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients.“Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the coveredwork in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiablepatents in that country that you have reason to believe are valid.

If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuringconveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizingthem to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant isautomatically extended to all recipients of the covered work and works based on it.

A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of,or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License.You may not convey a covered work if you are a party to an arrangement with a third party that is in the businessof distributing software, under which you make payment to the third party based on the extent of your activity ofconveying the work, and under which the third party grants, to any of the parties who would receive the coveredwork from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you(or copies made from those copies), or (b) primarily for and in connection with specific products or compilations thatcontain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28March 2007.

Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringementthat may otherwise be available to you under applicable patent law.

12. No Surrender of Others’ Freedom.

If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions ofthis License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as tosatisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequenceyou may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for furtherconveying from those to whom you convey the Program, the only way you could satisfy both those terms and thisLicense would be to refrain entirely from conveying the Program.

13. Use with the GNU Affero General Public License.

Notwithstanding any other provision of this License, you have permission to link or combine any covered work with awork licensed under version 3 of the GNU Affero General Public License into a single combined work, and to conveythe resulting work. The terms of this License will continue to apply to the part which is the covered work, but thespecial requirements of the GNU Affero General Public License, section 13, concerning interaction through a networkwill apply to the combination as such.

14. Revised Versions of this License.

The Free Software Foundation may publish revised and/or new versions of the GNU General Public License fromtime to time. Such new versions will be similar in spirit to the present version, but may differ in detail to addressnew problems or concerns.

Each version is given a distinguishing version number. If the Program specifies that a certain numbered version ofthe GNU General Public License “or any later version” applies to it, you have the option of following the terms andconditions either of that numbered version or of any later version published by the Free Software Foundation. If theProgram does not specify a version number of the GNU General Public License, you may choose any version everpublished by the Free Software Foundation.

If the Program specifies that a proxy can decide which future versions of the GNU General Public License can beused, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version forthe Program.

Later license versions may give you additional or different permissions. However, no additional obligations are imposedon any author or copyright holder as a result of your choosing to follow a later version.

15. Disclaimer of Warranty.

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 PARTI-ES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSEDOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABI-LITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY ANDPERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOUASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. Limitation of Liability.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANYCOPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAMAS 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

GNU General Public License 279

THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDEREDINACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAMTO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEENADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

17. Interpretation of Sections 15 and 16.

If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect accordingto their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civilliability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of theProgram in return for a fee.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New ProgramsIf you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve thisis 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 mosteffectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to wherethe full notice is found.

one line to give the program’s name and a brief idea of what it does.

Copyright (C) year name of author

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 3 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, see http://www.gnu.org/licenses/.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

program Copyright (C) year name of author

This program 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. Ofcourse, your program’s commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclai-mer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, seehttp://www.gnu.org/licenses/.

The GNU General Public License does not permit incorporating your program into proprietary programs. If yourprogram 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 Lesser General Public License instead of this License. But first, please readhttp://www.gnu.org/philosophy/why-not-lgpl.html.

GNU Free Documentation License 280

GNU Free Documentation License

Version 1.3, 3 November 2008Copyright c© 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.http://fsf.org/

Everyone is permitted to copy and distribute verbatim copiesof this license document, but changing it is not allowed.

0. PREAMBLE

The purpose of this License is to make a manual, textbook, or other functional and useful document free in the senseof freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, eithercommercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get creditfor their work, while not being considered responsible for modifications made by others.

This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in thesame sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs freedocumentation: a free program should come with manuals providing the same freedoms that the software does. Butthis License is not limited to software manuals; it can be used for any textual work, regardless of subject matteror whether it is published as a printed book. We recommend this License principally for works whose purpose isinstruction or reference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyrightholder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-freelicense, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers toany such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the licenseif you copy, modify or distribute the work in a way requiring permission under copyright law.

A “Modified Version” of the Document means any work containing the Document or a portion of it, either copiedverbatim, or with modifications and/or translated into another language.

A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with therelationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) andcontains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook ofmathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historicalconnection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political positionregarding them.

The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of InvariantSections, in the notice that says that the Document is released under this License. If a section does not fit the abovedefinition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero InvariantSections. If the Document does not identify any Invariant Sections then there are none.

The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, inthe notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words,and a Back-Cover Text may be at most 25 words.

A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specificationis available to the general public, that is suitable for revising the document straightforwardly with generic text editorsor (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor,and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for inputto text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, hasbeen arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format isnot Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format,LaTEX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, Post-Script or PDF designed for human modification. Examples of transparent image formats include PNG, XCF andJPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors,SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generatedHTML, PostScript or PDF produced by some word processors for output purposes only.

The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold,legibly, the material this License requires to appear in the title page. For works in formats which do not have anytitle page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding thebeginning of the body of the text.

The “publisher” means any person or entity that distributes copies of the Document to the public.

A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or containsXYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific sectionname mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preservethe Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” accordingto this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to theDocument. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards

GNU Free Documentation License 281

disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect onthe meaning of this License.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided thatthis License, the copyright notices, and the license notice saying this License applies to the Document are reproducedin all copies, and that you add no other conditions whatsoever to those of this License. You may not use technicalmeasures to obstruct or control the reading or further copying of the copies you make or distribute. However, youmay accept compensation in exchange for copies. If you distribute a large enough number of copies you must alsofollow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numberingmore than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers thatcarry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on theback cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front covermust present the full title with all words of the title equally prominent and visible. You may add other material onthe covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Documentand satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many asfit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include amachine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard networkprotocols a complete Transparent copy of the Document, free of added material. If you use the latter option, youmust take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that thisTransparent copy will remain thus accessible at the stated location until at least one year after the last time youdistribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any largenumber of copies, to give them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above,provided that you release the Modified Version under precisely this License, with the Modified Version filling the roleof the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy ofit. In addition, you must do these things in the Modified Version:

A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those ofprevious versions (which should, if there were any, be listed in the History section of the Document). You mayuse the same title as a previous version if the original publisher of that version gives permission.

B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modificationsin the Modified Version, together with at least five of the principal authors of the Document (all of its principalauthors, if it has fewer than five), unless they release you from this requirement.

C. State on the Title page the name of the publisher of the Modified Version, as the publisher.

D. Preserve all the copyright notices of the Document.

E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

F. Include, immediately after the copyright notices, a license notice giving the public permission to use the ModifiedVersion under the terms of this License, in the form shown in the Addendum below.

G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’slicense notice.

H. Include an unaltered copy of this License.

I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year,new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled“History” in the Document, create one stating the title, year, authors, and publisher of the Document as givenon its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of theDocument, and likewise the network locations given in the Document for previous versions it was based on.These may be placed in the “History” section. You may omit a network location for a work that was publishedat least four years before the Document itself, or if the original publisher of the version it refers to givespermission.

K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preservein the section all the substance and tone of each of the contributor acknowledgements and/or dedications giventherein.

L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbersor the equivalent are not considered part of the section titles.

M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.

N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any InvariantSection.

GNU Free Documentation License 282

O. Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections andcontain no material copied from the Document, you may at your option designate some or all of these sections asinvariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. Thesetitles must be distinct from any other section titles.

You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modifi-ed Version by various parties—for example, statements of peer review or that the text has been approved by anorganization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-CoverText, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and oneof Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document alreadyincludes a cover text for the same cover, previously added by you or by arrangement made by the same entity youare acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from theprevious publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicityfor or to assert or imply endorsement of any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of theoriginal documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice,and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may bereplaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, makethe title of each such section unique by adding at the end of it, in parentheses, the name of the original author orpublisher of that section if known, or else a unique number. Make the same adjustment to the section titles in thelist of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled “History” in the various original documents, forming onesection Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled“Dedications”. You must delete all sections Entitled “Endorsements.”

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replacethe individual copies of this License in the various documents with a single copy that is included in the collection,provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, providedyou insert a copy of this License into the extracted document, and follow this License in all other respects regardingverbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or ona volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilationis not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When theDocument is included in an aggregate, this License does not apply to the other works in the aggregate which are notthemselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is lessthan one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Documentwithin the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they mustappear on printed covers that bracket the whole aggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the termsof section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders,but you may include translations of some or all Invariant Sections in addition to the original versions of these InvariantSections. You may include a translation of this License, and all the license notices in the Document, and any WarrantyDisclaimers, provided that you also include the original English version of this License and the original versions ofthose notices and disclaimers. In case of a disagreement between the translation and the original version of thisLicense or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License.Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate yourrights under this License.

However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a)provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently,if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies youof the violation by some reasonable means, this is the first time you have received notice of violation of this License(for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

GNU Free Documentation License 283

Termination of your rights under this section does not terminate the licenses of parties who have received copies orrights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of acopy of some or all of the same material does not give you any rights to use it.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from timeto time. Such new versions will be similar in spirit to the present version, but may differ in detail to address newproblems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particularnumbered version of this License “or any later version” applies to it, you have the option of following the terms andconditions either of that specified version or of any later version that has been published (not as a draft) by theFree Software Foundation. If the Document does not specify a version number of this License, you may choose anyversion ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy candecide which future versions of this License can be used, that proxy’s public statement of acceptance of a versionpermanently authorizes you to choose that version for the Document.

11. RELICENSING

“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyri-ghtable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody canedit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site meansany set of copyrightable works thus published on the MMC site.

“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative CommonsCorporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well asfuture copyleft versions of that license published by that same organization.

“Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.

An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published underthis License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1)had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site atany time before August 1, 2009, provided the MMC is eligible for relicensing.

GNU Free Documentation License 284

ADDENDUM: How to use this License for your documentsTo use this License in a document you have written, include a copy of the License in the document and put the followingcopyright and license notices just after the title page:

Copyright (C) year your name.

Permission is granted to copy, distribute and/or modify this document

under the terms of the GNU Free Documentation License, Version 1.3

or any later version published by the Free Software Foundation;

with no Invariant Sections, no Front-Cover Texts, and no Back-Cover

Texts. A copy of the license is included in the section entitled ‘‘GNU

Free Documentation License’’.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with. . .Texts.” line with this:

with the Invariant Sections being list their titles, with

the Front-Cover Texts being list, and with the Back-Cover Texts

being list.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternativesto suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallelunder your choice of free software license, such as the GNU General Public License, to permit their use in free software.

Function and Macro Index 285

Function and Macro Index

qsmm_actor_calc_action_prob . . . . . . . . . . . . . . . . . . . 29qsmm_actor_choice_sig_prob_release . . . . . . . . . . 31qsmm_actor_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14qsmm_actor_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15qsmm_actor_enum_ngrams . . . . . . . . . . . . . . . . . . . . . . . . 27qsmm_actor_permut_add . . . . . . . . . . . . . . . . . . . . . . . . . 43qsmm_actor_profile_add . . . . . . . . . . . . . . . . . . . . . . . . 42qsmm_actor_reg_sig_action . . . . . . . . . . . . . . . . . . . . . 26qsmm_actor_reg_sig_in . . . . . . . . . . . . . . . . . . . . . . . . . 25qsmm_actor_remove_ngram . . . . . . . . . . . . . . . . . . . . . . . 28qsmm_actor_shl_sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24qsmm_actor_shr_sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26qsmm_actor_spur_delta . . . . . . . . . . . . . . . . . . . . . . . . . 23qsmm_actor_time_delta . . . . . . . . . . . . . . . . . . . . . . . . . 21QSMM_ASM_DETERM_OPT . . . . . . . . . . . . . . . . . . . . . . . . . . . 166QSMM_ASM_TEMPLATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167QSMM_ASM_VAR_AUX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167QSMM_ASM_VAR_OUT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167qsmm_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78qsmm_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79qsmm_engine_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105qsmm_engine_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . 106qsmm_enum_ent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128qsmm_enum_var_prob . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174qsmm_enum_var_prob_out . . . . . . . . . . . . . . . . . . . . . . . 180qsmm_err_str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10QSMM_EVT_ACTIVATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84QSMM_EVT_ENGINE_DONE . . . . . . . . . . . . . . . . . . . . . . . 84, 92QSMM_EVT_ENGINE_INIT . . . . . . . . . . . . . . . . . . . . . . . 84, 92QSMM_EVT_ENT_DONE . . . . . . . . . . . . . . . . . . . . . . . . . . 83, 92QSMM_EVT_ENT_INIT . . . . . . . . . . . . . . . . . . . . . . . . . . 83, 92QSMM_EVT_INSTR_CLASS_DONE . . . . . . . . . . . . . . . . . . . . . 84QSMM_EVT_INSTR_CLASS_INIT . . . . . . . . . . . . . . . . . . . . . 83QSMM_EVT_NODE_ENTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93QSMM_EVT_NODE_LEAVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93qsmm_except_dump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132qsmm_find_instr_class_in_set_f . . . . . . . . . . . . . . . 96qsmm_find_instr_class_in_set_fv . . . . . . . . . . . . . . 96qsmm_get_actor_auto_spur_type . . . . . . . . . . . . . . . . 46qsmm_get_actor_choice_sig_prob . . . . . . . . . . . . . . . 31qsmm_get_actor_choice_sig_prob_vec . . . . . . . . . . 32qsmm_get_actor_compat . . . . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_continuous_time . . . . . . . . . . . . . . . 21qsmm_get_actor_discrete_cycle_period_last . . 48qsmm_get_actor_discrete_cycle_period_mean . . 48qsmm_get_actor_discrete_time . . . . . . . . . . . . . . . . . 21qsmm_get_actor_ktemperature . . . . . . . . . . . . . . . . . . . 40qsmm_get_actor_large_model . . . . . . . . . . . . . . . . . . . . 21qsmm_get_actor_naction_per_evt . . . . . . . . . . . . . . . 46qsmm_get_actor_ngram_profile . . . . . . . . . . . . . . . . . 44qsmm_get_actor_ngram_sz . . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_nsig . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_nsig_ctrl . . . . . . . . . . . . . . . . . . . . . . 49qsmm_get_actor_nsig_out . . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_nspur . . . . . . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_prob_action . . . . . . . . . . . . . . . . . . . . 34qsmm_get_actor_profile_nsig_ctrl . . . . . . . . . . . . . 50qsmm_get_actor_profile_pool_sz . . . . . . . . . . . . . . . 20qsmm_get_actor_random . . . . . . . . . . . . . . . . . . . . . . . . . 47qsmm_get_actor_range_sig . . . . . . . . . . . . . . . . . . . . . . 20qsmm_get_actor_relprob_helper . . . . . . . . . . . . . . . . 37

qsmm_get_actor_relprob_type . . . . . . . . . . . . . . . . . . . 34qsmm_get_actor_rng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47qsmm_get_actor_sig_action . . . . . . . . . . . . . . . . . . . . . 32qsmm_get_actor_sig_ngram . . . . . . . . . . . . . . . . . . . . . . 27qsmm_get_actor_sig_weight . . . . . . . . . . . . . . . . . . . . . 41qsmm_get_actor_sparse_fill_max . . . . . . . . . . . . . . . 20qsmm_get_actor_spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23qsmm_get_actor_spur_perception . . . . . . . . . . . . . . . 38qsmm_get_actor_spur_time . . . . . . . . . . . . . . . . . . . . . . 22qsmm_get_actor_spur_weight . . . . . . . . . . . . . . . . . . . . 39qsmm_get_actor_storage . . . . . . . . . . . . . . . . . . . . . . . . 21qsmm_get_actpair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106qsmm_get_actpair_actor_env . . . . . . . . . . . . . . . . . . . 106qsmm_get_actpair_actor_opt . . . . . . . . . . . . . . . . . . . 106qsmm_get_continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111qsmm_get_default_dump_instr_desc . . . . . . . . . . . . 160qsmm_get_default_dump_prg_desc . . . . . . . . . . . . . . 164qsmm_get_determ_opt . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81qsmm_get_eh_instr_class_set_name . . . . . . . . . . . . . 85qsmm_get_eh_instr_param . . . . . . . . . . . . . . . . . . . . . . . 84qsmm_get_eh_instr_param_str . . . . . . . . . . . . . . . . . . . 88qsmm_get_eh_noutcome . . . . . . . . . . . . . . . . . . . . . . . . . . . 89qsmm_get_ent_type_by_name . . . . . . . . . . . . . . . . . . . . 129qsmm_get_err_handler . . . . . . . . . . . . . . . . . . . . . . . . . 130qsmm_get_instr_class_meta_name . . . . . . . . . . . . . . . 98qsmm_get_instr_class_name . . . . . . . . . . . . . . . . . . . . . 97qsmm_get_instr_class_noutcome . . . . . . . . . . . . . . . . 99qsmm_get_instr_class_param . . . . . . . . . . . . . . . . . . . . 99qsmm_get_instr_class_param_str . . . . . . . . . . . . . . . 98qsmm_get_instr_class_set_handler . . . . . . . . . . . . . 94qsmm_get_instr_class_set_sz . . . . . . . . . . . . . . . . . . . 96qsmm_get_instr_class_weight . . . . . . . . . . . . . . . . . 115qsmm_get_instr_class_weight_by_name_f . . . . . . 116qsmm_get_instr_label . . . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_instr_ls_name . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_instr_meta_class_handler . . . . . . . . . . . . 87qsmm_get_instr_nested . . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_instr_nlabel . . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_instr_nnested . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_instr_outcome . . . . . . . . . . . . . . . . . . . . . . . 112qsmm_get_instr_type . . . . . . . . . . . . . . . . . . . . . . . . . . . 159qsmm_get_la_sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114qsmm_get_msglist_sz . . . . . . . . . . . . . . . . . . . . . . . . . . . 221qsmm_get_ngram_env_la_sz . . . . . . . . . . . . . . . . . . . . . . 82qsmm_get_nnode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104qsmm_get_node_array_prob_cycle . . . . . . . . . . . . . . 187qsmm_get_node_array_prob_mat . . . . . . . . . . . . . . . . 185qsmm_get_node_array_prob_out . . . . . . . . . . . . . . . . 185qsmm_get_node_class_name . . . . . . . . . . . . . . . . . . . . . 103qsmm_get_node_fq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110qsmm_get_node_nstate . . . . . . . . . . . . . . . . . . . . . . . . . 104qsmm_get_node_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126qsmm_get_node_recurs . . . . . . . . . . . . . . . . . . . . . . . . . 110qsmm_get_node_state_by_name . . . . . . . . . . . . . . . . . 170qsmm_get_node_state_name . . . . . . . . . . . . . . . . . . . . . 171qsmm_get_node_var_prob . . . . . . . . . . . . . . . . . . . . . . . 174qsmm_get_node_var_prob_cycle . . . . . . . . . . . . . . . . 181qsmm_get_node_var_prob_mat . . . . . . . . . . . . . . . . . . . 178qsmm_get_node_var_prob_out . . . . . . . . . . . . . . . . . . . 180qsmm_get_nsig_ngram_env_la . . . . . . . . . . . . . . . . . . . . 82qsmm_get_nspur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Function and Macro Index 286

qsmm_get_nstate_max . . . . . . . . . . . . . . . . . . . . . . . . . . . 100qsmm_get_prg_instr . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158qsmm_get_prg_ls_nprob . . . . . . . . . . . . . . . . . . . . . . . . 160qsmm_get_prg_ninstr . . . . . . . . . . . . . . . . . . . . . . . . . . . 158qsmm_get_prg_nstate . . . . . . . . . . . . . . . . . . . . . . . . . . . 169qsmm_get_prg_nvar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172qsmm_get_prg_var_name . . . . . . . . . . . . . . . . . . . . . . . . 172qsmm_get_prob_action . . . . . . . . . . . . . . . . . . . . . . . . . 113qsmm_get_prob_goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113qsmm_get_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126qsmm_get_rng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125qsmm_get_rng_default . . . . . . . . . . . . . . . . . . . . . . . . . 214qsmm_get_side_err_handler . . . . . . . . . . . . . . . . . . . . 224qsmm_get_side_name . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222qsmm_get_side_trace_flags . . . . . . . . . . . . . . . . . . . . 223qsmm_get_side_trace_stream . . . . . . . . . . . . . . . . . . . 224qsmm_get_stack_frame . . . . . . . . . . . . . . . . . . . . . . . . . 120qsmm_get_stack_frame_sz . . . . . . . . . . . . . . . . . . . . . . 119qsmm_get_stack_instr_class . . . . . . . . . . . . . . . . . . . 118qsmm_get_stack_node . . . . . . . . . . . . . . . . . . . . . . . . . . . 118qsmm_get_stack_state . . . . . . . . . . . . . . . . . . . . . . . . . 118qsmm_get_stack_sz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117qsmm_get_stack_sz_max . . . . . . . . . . . . . . . . . . . . . . . . . 82qsmm_get_storage_cycle_next . . . . . . . . . . . . . . . . . . . 64qsmm_get_storage_cycle_next_redir . . . . . . . . . . . . 67qsmm_get_storage_cycle_stats . . . . . . . . . . . . . . . . . 61qsmm_get_storage_cycle_stats_redir . . . . . . . . . . 66qsmm_get_storage_msglist . . . . . . . . . . . . . . . . . . . . . . 68qsmm_get_storage_nspur . . . . . . . . . . . . . . . . . . . . . . . . 58qsmm_get_storage_state_stats . . . . . . . . . . . . . . . . . 60qsmm_get_storage_state_stats_redir . . . . . . . . . . 65qsmm_get_trace_flags . . . . . . . . . . . . . . . . . . . . . . . . . 129qsmm_get_trace_stream . . . . . . . . . . . . . . . . . . . . . . . . 129qsmm_get_use_instr_class_weights . . . . . . . . . . . . . 81qsmm_get_vec_elm_by_pos . . . . . . . . . . . . . . . . . . . . . . 217qsmm_get_vec_npos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217qsmm_get_vec_pos_by_idx . . . . . . . . . . . . . . . . . . . . . . 217QSMM_HAS_INSTR_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . 85QSMM_HEADERS_VERSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9QSMM_INSTR_CLASS_SET . . . . . . . . . . . . . . . . . . . . . . . . . . . 91QSMM_INSTR_META_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . 82qsmm_instr_str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160qsmm_map_assign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233qsmm_map_clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234qsmm_map_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230qsmm_map_create_sz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230qsmm_map_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231qsmm_map_erase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234qsmm_map_find . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234qsmm_map_insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233qsmm_map_is_empty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233qsmm_map_iter_are_equal . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_assign . . . . . . . . . . . . . . . . . . . . . . . . . 236qsmm_map_iter_begin . . . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_create . . . . . . . . . . . . . . . . . . . . . . . . . 232qsmm_map_iter_destroy . . . . . . . . . . . . . . . . . . . . . . . . 233qsmm_map_iter_end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_is_end . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236qsmm_map_iter_next . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_prev . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_rbegin . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_rend . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235qsmm_map_iter_set_val . . . . . . . . . . . . . . . . . . . . . . . . 236qsmm_map_iter_val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236

qsmm_map_key_compar_func . . . . . . . . . . . . . . . . . . . . . 232qsmm_map_key_compar_param . . . . . . . . . . . . . . . . . . . . 232qsmm_map_key_sz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232qsmm_map_lower_bound . . . . . . . . . . . . . . . . . . . . . . . . . 234qsmm_map_multi_create . . . . . . . . . . . . . . . . . . . . . . . . 230qsmm_map_multi_create_sz . . . . . . . . . . . . . . . . . . . . . 230qsmm_map_multi_iter_create . . . . . . . . . . . . . . . . . . . 232qsmm_map_size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233qsmm_map_upper_bound . . . . . . . . . . . . . . . . . . . . . . . . . 234qsmm_map_val_sz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232qsmm_mat_action_dump . . . . . . . . . . . . . . . . . . . . . . . . . 123qsmm_mat_goto_dump . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120qsmm_msg_create_f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219qsmm_msg_create_fv . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219qsmm_msg_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220qsmm_msglist_add_msg . . . . . . . . . . . . . . . . . . . . . . . . . 220qsmm_msglist_clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221qsmm_msglist_create . . . . . . . . . . . . . . . . . . . . . . . . . . . 218qsmm_msglist_destroy . . . . . . . . . . . . . . . . . . . . . . . . . 219qsmm_msglist_dump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221qsmm_msglist_extend . . . . . . . . . . . . . . . . . . . . . . . . . . . 220qsmm_node_asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167qsmm_node_call_default . . . . . . . . . . . . . . . . . . . . . . . 109QSMM_NODE_CLONE_STATE_NAMES . . . . . . . . . . . . . . . . . 190QSMM_NODE_CLONE_TEMPLATE . . . . . . . . . . . . . . . . . . . . . 190QSMM_NODE_CLONE_VARS . . . . . . . . . . . . . . . . . . . . . . . . . 190qsmm_node_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102QSMM_NODE_CREATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103qsmm_node_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103qsmm_node_disasm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153qsmm_node_profile_clone . . . . . . . . . . . . . . . . . . . . . . 189qsmm_node_reserve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104qsmm_node_unload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194qsmm_node_var_out_forget . . . . . . . . . . . . . . . . . . . . . 183qsmm_node_var_realize . . . . . . . . . . . . . . . . . . . . . . . . 175qsmm_parse_asm_source_buf . . . . . . . . . . . . . . . . . . . . 165qsmm_parse_asm_source_file . . . . . . . . . . . . . . . . . . . 166qsmm_parse_asm_source_stream . . . . . . . . . . . . . . . . 165qsmm_preprocess_asm_source_buf . . . . . . . . . . . . . . 200qsmm_preprocess_asm_source_file . . . . . . . . . . . . . 201qsmm_preprocess_asm_source_stream . . . . . . . . . . . 200qsmm_prg_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143qsmm_prg_dump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163qsmm_reg_instr_class . . . . . . . . . . . . . . . . . . . . . . . . . . . 95QSMM_REG_INSTR_CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . 95QSMM_REG_INSTR_CLASS_PARAM . . . . . . . . . . . . . . . . . . . . 96qsmm_reg_instr_class_set . . . . . . . . . . . . . . . . . . . . . . 94QSMM_REG_INSTR_CLASS_SET . . . . . . . . . . . . . . . . . . . . . . 93qsmm_reg_instr_meta_class . . . . . . . . . . . . . . . . . . . . . 86QSMM_REG_INSTR_META_CLASS . . . . . . . . . . . . . . . . . . . . . 86qsmm_reg_var_prob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173QSMM_REG_VAR_PROB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174qsmm_return_to_caller_node . . . . . . . . . . . . . . . . . . . 111QSMM_RNG_CMD_CREATE . . . . . . . . . . . . . . . . . . . . . . . . . . . 215QSMM_RNG_CMD_DESTROY . . . . . . . . . . . . . . . . . . . . . . . . . 215QSMM_RNG_CMD_GENERATE . . . . . . . . . . . . . . . . . . . . . . . . 215QSMM_RNG_CMD_SEED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215qsmm_rng_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212qsmm_rng_create_custom . . . . . . . . . . . . . . . . . . . . . . . 213qsmm_rng_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213qsmm_rng_seed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214qsmm_rng_uniform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213qsmm_rng_uniform_int . . . . . . . . . . . . . . . . . . . . . . . . . 213qsmm_rng_uniform_pos . . . . . . . . . . . . . . . . . . . . . . . . . 214qsmm_set_actor_auto_spur_type . . . . . . . . . . . . . . . . 46

Function and Macro Index 287

qsmm_set_actor_discrete_time . . . . . . . . . . . . . . . . . 22qsmm_set_actor_ktemperature . . . . . . . . . . . . . . . . . . . 40qsmm_set_actor_naction_per_evt . . . . . . . . . . . . . . . 46qsmm_set_actor_ngram_profile . . . . . . . . . . . . . . . . . 44qsmm_set_actor_nsig_ctrl . . . . . . . . . . . . . . . . . . . . . . 49qsmm_set_actor_random . . . . . . . . . . . . . . . . . . . . . . . . . 48qsmm_set_actor_relprob_helper . . . . . . . . . . . . . . . . 37qsmm_set_actor_relprob_type . . . . . . . . . . . . . . . . . . . 34qsmm_set_actor_sig_weight . . . . . . . . . . . . . . . . . . . . . 41qsmm_set_actor_spur_perception . . . . . . . . . . . . . . . 39qsmm_set_actor_spur_time . . . . . . . . . . . . . . . . . . . . . . 22qsmm_set_actor_spur_weight . . . . . . . . . . . . . . . . . . . . 39qsmm_set_continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111qsmm_set_eh_instr_param_str_f . . . . . . . . . . . . . . . . 87qsmm_set_eh_noutcome . . . . . . . . . . . . . . . . . . . . . . . . . . . 89qsmm_set_err_handler . . . . . . . . . . . . . . . . . . . . . . . . . 130qsmm_set_instr_class_weight . . . . . . . . . . . . . . . . . 115qsmm_set_instr_class_weight_by_name_f . . . . . . 116qsmm_set_instr_meta_class_weight . . . . . . . . . . . . 117qsmm_set_instr_outcome . . . . . . . . . . . . . . . . . . . . . . . 112qsmm_set_la_sig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114qsmm_set_msg_lineno . . . . . . . . . . . . . . . . . . . . . . . . . . . 220qsmm_set_node_nstate . . . . . . . . . . . . . . . . . . . . . . . . . 104qsmm_set_node_profile_source . . . . . . . . . . . . . . . . 193qsmm_set_node_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126qsmm_set_node_var_prob . . . . . . . . . . . . . . . . . . . . . . . 175qsmm_set_nstate_max . . . . . . . . . . . . . . . . . . . . . . . . . . . 100qsmm_set_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126qsmm_set_random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125qsmm_set_rng_default . . . . . . . . . . . . . . . . . . . . . . . . . 214qsmm_set_side_err_handler . . . . . . . . . . . . . . . . . . . . 225qsmm_set_side_trace_flags . . . . . . . . . . . . . . . . . . . . 224qsmm_set_side_trace_stream . . . . . . . . . . . . . . . . . . . 224qsmm_set_stack_frame_sz . . . . . . . . . . . . . . . . . . . . . . 119

qsmm_set_storage_cycle_next_redir . . . . . . . . . . . . 68qsmm_set_storage_cycle_stats . . . . . . . . . . . . . . . . . 61qsmm_set_storage_cycle_stats_redir . . . . . . . . . . 66qsmm_set_storage_state_stats . . . . . . . . . . . . . . . . . 60qsmm_set_storage_state_stats_redir . . . . . . . . . . 65qsmm_set_trace_flags . . . . . . . . . . . . . . . . . . . . . . . . . 129qsmm_set_trace_stream . . . . . . . . . . . . . . . . . . . . . . . . 129qsmm_side_create . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222qsmm_side_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222qsmm_side_err_str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224qsmm_side_recv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223QSMM_SIDE_RECV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223qsmm_side_send . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222QSMM_SIDE_SEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223QSMM_SIDE_TRACE_API . . . . . . . . . . . . . . . . . . . . . . . . . . . 223qsmm_side_trace_f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224qsmm_side_trace_fv . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224QSMM_SIDE_TRACE_MSG . . . . . . . . . . . . . . . . . . . . . . . . . . . 223QSMM_SIG_INVALID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14QSMM_SIG_MAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14qsmm_spur_delta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108qsmm_storage_enum_states . . . . . . . . . . . . . . . . . . . . . . 63qsmm_storage_remove_state . . . . . . . . . . . . . . . . . . . . . 62QSMM_TERMINATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111qsmm_time_delta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107QSMM_TRACE_API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129QSMM_TRACE_CTRL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129QSMM_TRACE_EVT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129qsmm_trace_f . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130qsmm_trace_fv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130qsmm_vec_clone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217qsmm_vec_destroy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218qsmm_version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Type Index 288

Type Index

qsmm_actor_desc_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15qsmm_actor_large_desc_s . . . . . . . . . . . . . . . . . . . . . . . 18qsmm_actor_sig_spec_e . . . . . . . . . . . . . . . . . . . . . . . . . 17qsmm_actor_sig_spec_in_out_s . . . . . . . . . . . . . . . . . 18qsmm_actor_sig_spec_mask_s . . . . . . . . . . . . . . . . . . . . 18qsmm_actor_sig_spec_u . . . . . . . . . . . . . . . . . . . . . . . . . 17qsmm_actor_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14qsmm_actpair_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106qsmm_compar_func_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231qsmm_cspur_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59qsmm_cycle_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59qsmm_desc_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79qsmm_disasm_desc_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154qsmm_dump_instr_desc_s . . . . . . . . . . . . . . . . . . . . . . . 160qsmm_dump_mat_action_desc_s . . . . . . . . . . . . . . . . . 123qsmm_dump_mat_goto_desc_s . . . . . . . . . . . . . . . . . . . . 121qsmm_dump_prg_desc_s . . . . . . . . . . . . . . . . . . . . . . . . . 164qsmm_ent_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127qsmm_ent_u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127qsmm_enum_ent_callback_func_t . . . . . . . . . . . . . . . 128qsmm_enum_ngrams_callback_func_t . . . . . . . . . . . . . 28qsmm_enum_states_callback_func_t . . . . . . . . . . . . . 63qsmm_err_handler_func_t . . . . . . . . . . . . . . . . . . . . . . 130qsmm_except_evthndlr_s . . . . . . . . . . . . . . . . . . . . . . . 133qsmm_except_exist_s . . . . . . . . . . . . . . . . . . . . . . . . . . . 133qsmm_except_nosamenc_s . . . . . . . . . . . . . . . . . . . . . . . 134qsmm_except_nostate_s . . . . . . . . . . . . . . . . . . . . . . . . 134qsmm_except_notfound_s . . . . . . . . . . . . . . . . . . . . . . . 133qsmm_except_outcome_s . . . . . . . . . . . . . . . . . . . . . . . . 133qsmm_except_profsrcp_s . . . . . . . . . . . . . . . . . . . . . . . 134qsmm_except_profsrcu_s . . . . . . . . . . . . . . . . . . . . . . . 134qsmm_except_psumgt1_s . . . . . . . . . . . . . . . . . . . . . . . . 135qsmm_except_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130qsmm_except_type_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

qsmm_except_u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131qsmm_get_cycle_next_func_t . . . . . . . . . . . . . . . . . . . . 67qsmm_get_cycle_stats_func_t . . . . . . . . . . . . . . . . . . . 66qsmm_get_state_stats_func_t . . . . . . . . . . . . . . . . . . . 65qsmm_instr_class_set_func_t . . . . . . . . . . . . . . . . . . . 91qsmm_instr_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158qsmm_instr_meta_class_func_t . . . . . . . . . . . . . . . . . 83qsmm_instr_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143qsmm_iter_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232qsmm_map_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230qsmm_mat_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177qsmm_msg_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219qsmm_msg_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219qsmm_msglist_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218qsmm_pair_sig_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18qsmm_prg_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143qsmm_prob_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30qsmm_proxy_func_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214qsmm_relprob_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35qsmm_relprob_user1_func_t . . . . . . . . . . . . . . . . . . . . . 36qsmm_relprob_user2_func_t . . . . . . . . . . . . . . . . . . . . . 36qsmm_rng_cmd_seed_in_s . . . . . . . . . . . . . . . . . . . . . . . 216qsmm_rng_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212qsmm_side_err_handler_func_t . . . . . . . . . . . . . . . . 225qsmm_side_except_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225qsmm_side_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222qsmm_sig_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14qsmm_spur_perception_e . . . . . . . . . . . . . . . . . . . . . . . . 38qsmm_sspur_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59qsmm_state_s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58qsmm_storage_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57qsmm_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78qsmm_time_e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22qsmm_vec_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

Concept Index 289

Concept Index

Aaction choice state . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11, 23action choice state, condition for . . . . . . . . . . . . . . . . . 58action emission matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 123actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4, 11actor handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14actor pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106actor pair handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106actor temperature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39actor, large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12actor, small . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12actual number of output signals . . . . . . . . . . . . . . . . . . 48array of probabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185assembler instruction . . . . . . . . . . . . . . . . . . . . . . . 143, 144assembler program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143assembler program section . . . . . . . . . . . . . . . . . . . . . . 144assembler program section, data . . . . . . . . . . . . 171, 183assembler program, parsing . . . . . . . . . . . . . . . . . . . . . 165assembler program, preprocessing . . . . . . . . . . . . . . . 195assembling a node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166automatic spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45auxiliary probability variable . . . . . . . . . . . . . . . . . . . . 183

Bbehavior mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47, 125binary instruction parameters . . . . . . . . . . . . . . . . . . . . 84built-in instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

Ccallback function, enumeration . . . . . . . . . . . 28, 63, 128calling a node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75, 109cloning a probability profile . . . . . . . . . . . . . . . . 189, 191complexity of choice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5condition for an action choice state . . . . . . . . . . . . . . . 58continuous time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21control, possessing by a node . . . . . . . . . . . . . . . . . . . . . 75control, returning from a node . . . . . . . . . . . . . . . . . . 111control, transferring to a node . . . . . . . . . . . . . . . 75, 109controlled probability variable . . . . . . . . . . . . . . . . . . . 172cycle period, discrete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35cycle type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38cycle type, statistics for . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Ddata section of assembler program . . . . . . . . . . 171, 183defining a probabilities list . . . . . . . . . . . . . . . . . . . . . . 183defining a probability variable . . . . . . . . . . . . . . . . . . . 171diassembling a node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153direction of signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16discrete cycle period . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35discrete time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Eentity identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127entity type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127enumeration callback function . . . . . . . . . . . . 28, 63, 128

environment state identification engine . . . . . . . . . . . 75error handler function . . . . . . . . . . . . . . . . . . . . . . 130, 224event handler, instruction class set . . . . . . . 91, 93, 101event handler, instruction meta-class . . . . . . 82, 86, 90event history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11event type, instruction class set . . . . . . . . . . . . . . . . . . . 92event type, instruction meta-class . . . . . . . . . . . . . . . . 83excitatory (positive) spur . . . . . . . . . . . . . . . . . . . . . . . . . 45execution of model . . . . . . . . . . . . . . . . . . . . . . . . . 105, 111execution of node . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75, 109

Fflat storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57function, enumeration callback . . . . . . . . . . . 28, 63, 128function, error handler . . . . . . . . . . . . . . . . . . . . . 130, 224function, event handler . . . . . . . . . . . . . . . . . . . . . . . 82, 91function, key comparison . . . . . . . . . . . . . . . . . . . . . . . . 231function, proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214function, storage redirection . . . . . . . . . . . . . . . . . . . . . . 64

Hhandle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9handle of actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14handle of actor pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106handle of instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143handle of iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232handle of map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230handle of message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219handle of message list . . . . . . . . . . . . . . . . . . . . . . . . . . . 218handle of model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78handle of program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143handle of random number generator . . . . . . . . . . . . . 212handle of side . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222handle of storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57handle of vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

Iincrementing spur . . . . . . . . . . . . . . . . . . . . . . . . . . . 23, 108incrementing time . . . . . . . . . . . . . . . . . . . . . . . . . . . 21, 107inhibitory (negative) spur . . . . . . . . . . . . . . . . . . . . . . . . 45instance of a model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143, 144instruction class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77instruction class set . . . . . . . . . . . . . . . . . . . . . . . 75, 78, 91instruction class weight . . . . . . . . . . . . . . . . . . . . . . . . . 114instruction emitting engine . . . . . . . . . . . . . . . . . . . . . . . 75instruction handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143instruction instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78instruction invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . 112instruction meta-class . . . . . . . . . . . . . . . . . . . . . . . . 77, 82instruction outcome . . . . . . . . . . . . . . . . . . . . . . 77, 89, 112instruction parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . 84instruction parameters, normalization . . . . . . . . . . . . 88instruction, built-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144instruction, mixed type . . . . . . . . . . . . . . . . . . . . . . . . . 144instruction, user . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 153intelligence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

Concept Index 290

internal state of an actor . . . . . . . . . . . . . . . . . . . . . . . . . 45iterator handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232

Kkey comparison function . . . . . . . . . . . . . . . . . . . . . . . . 231

Llarge actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12loading a probability profile into a node . . . . . . . . . 166look-ahead signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Mmap handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230map storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57mapping, probabilistic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4matrix, action emission . . . . . . . . . . . . . . . . . . . . . . . . . 123matrix, state transition . . . . . . . . . . . . . . . . . . . . . . . . . 120mean number of output signals . . . . . . . . . . . . . . . . . . . 49message handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219message list handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218mixed type instruction . . . . . . . . . . . . . . . . . . . . . . . . . . 144mode of behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47, 125model execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105, 111model handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78model instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105multinode model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

Nname of state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147, 170node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5, 75node class, instruction class set . . . . . . . . . . . . . . . 75, 91node execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75, 109node, assembling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166node, calling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75, 109node, creating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102node, destroying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103node, disassembling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153node, loading a probability profile into . . . . . . . . . . 166node, possessing control . . . . . . . . . . . . . . . . . . . . . . . . . . 75node, returning control from . . . . . . . . . . . . . . . . . . . . 111node, transferring control to . . . . . . . . . . . . . . . . . 75, 109node, unloading a probability profile from . . . . . . . 194normalization of instruction parameters . . . . . . . . . . 88normalization of probabilities list . . . . . . . . . . . . . . . . . 41number of output signals, actual . . . . . . . . . . . . . . . . . . 48number of output signals, mean . . . . . . . . . . . . . . . . . . 49

Ooptimal action generation engine . . . . . . . . . . . . . . . 4, 11outcome of instruction . . . . . . . . . . . . . . . . . . . 77, 89, 112output probabilities array . . . . . . . . . . . . . . . . . . . . . . . 185output probability variable . . . . . . . . . . . . . . . . . . . . . . 177output signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11output signals, permutation . . . . . . . . . . . . . . . . . . . . . . 41

Pparameters of instruction . . . . . . . . . . . . . . . . . . . . . . . . . 84parameters of instruction, normalization . . . . . . . . . . 88

parsing an assembler program . . . . . . . . . . . . . . . . . . . 165perception of spur, a way of . . . . . . . . . . . . . . . . . . . . . . 37permutation of output signals . . . . . . . . . . . . . . . . . . . . 41pool of permutations of output signals . . . . . . . . . . . . 42pool of probabilities lists in normal form . . . . . . . . . . 41possessing control by a node . . . . . . . . . . . . . . . . . . . . . . 75preprocessing an assembler program . . . . . . . . . . . . . 195probabilistic mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4probabilities array, output . . . . . . . . . . . . . . . . . . . . . . . 185probabilities list in an assembler program . . . . . . . . 183probabilities list, defining . . . . . . . . . . . . . . . . . . . . . . . 183probabilities list, normalization . . . . . . . . . . . . . . . . . . . 41probability profile, cloning . . . . . . . . . . . . . . . . . . 189, 191probability profile, loading into a node . . . . . . . . . . 166probability profile, preloaded . . . . . . . . . . . . . . . . . . . . . 40probability profile, unloading from a node . . . . . . . 194probability variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171probability variable, auxiliary . . . . . . . . . . . . . . . . . . . 183probability variable, controlled . . . . . . . . . . . . . . . . . . 172probability variable, defining . . . . . . . . . . . . . . . . . . . . 171probability variable, output . . . . . . . . . . . . . . . . . . . . . 177program handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143program, assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143proxy function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214pseudorandom number generator . . . . . . . . . . . . . . . . 212

Rrandom number generator . . . . . . . . . . . . . . . . . . . . . . . 212relative probability function . . . . . . . . . . . . . . . . . . . . . . 34returning control from a node . . . . . . . . . . . . . . . . . . . 111

Ssection of assembler program . . . . . . . . . . . . . . . . . . . . 144section of assembler program, data . . . . . . . . . 171, 183Side API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221side handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222signal direction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16signal weight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40signal, look-ahead . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113signal, output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11small actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3spur perception, a way of . . . . . . . . . . . . . . . . . . . . . . . . . 37spur scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11spur type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3spur weight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39spur, automatic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45spur, excitatory (positive) . . . . . . . . . . . . . . . . . . . . . . . . 45spur, incrementing . . . . . . . . . . . . . . . . . . . . . . . . . . 23, 108spur, inhibitory (negative) . . . . . . . . . . . . . . . . . . . . . . . . 45stack, system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117stack, user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4state model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2state name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147, 170state submodel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5state transition matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 120statistics for a cycle type . . . . . . . . . . . . . . . . . . . . . . . . . 59STL map template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229storage handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57storage of flat type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57storage of map type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Concept Index 291

storage redirection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57storage redirection function . . . . . . . . . . . . . . . . . . . . . . 64storage type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57system stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

Ttemperature of actor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39terminating model execution . . . . . . . . . . . . . . . . . . . . 111textual instruction parameters . . . . . . . . . . . . . . . . 84, 87time of continuous type . . . . . . . . . . . . . . . . . . . . . . . . . . 21time of discrete type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21time, incrementing . . . . . . . . . . . . . . . . . . . . . . . . . . 21, 107trace log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129, 223transferring control to a node . . . . . . . . . . . . . . . . 75, 109type of cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38type of entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127type of spur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3type of storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

type of time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Uunloading a probability profile from a node . . . . . . 194user instruction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144, 153user stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

Vvariable, probability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171vector handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

Wweight for spur type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39weight of instruction class . . . . . . . . . . . . . . . . . . . . . . . 114weight of signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40window associated with an actor . . . . . . . . . . . . . . . . . 23