C++ Actions API
Note
This is correct for only versions of sc-machine that >= 0.10.0.
This API provides functionality to handle sc-actions.
Note
To include this API provide #include <sc-memory/sc_action.hpp>
in your hpp source.
What is action?
All actions are processes. Any process is performed by some subject. Each action can be defined as a process of solving some problem, i.e. as a process of achieving the given goal with the given conditions. Each action denotes some transformation carried out in the external environment or in the memory of some system.
Like an agent, an action has a specification. This specification includes: class, arguments, state, result. The specification of an action is called a problem.
ScAction
The sc-machine provides ScAction
class to handle actions in sc-memory. You can't use constructors of this class, because they are private. Use ScAgentContext
to generate action with provided class or use the existing one. All methods of this class work directly with the knowledge base, there is no local cache.
// Find action class and generate action.
...
ScAction action = context.GenerateAction(actionClassAddr);
...
Note
You should provide action class that is include to the one of types: receptor_action
, effector_action
, behavioral_action
or information_action
.
// Or find action and convert it to object of `ScAction` class.
...
ScAction action = context.ConvertToAction(actionAddr);
...
GetClass
To get class of action use this method.
GetArgument
Actions can have arguments. Action arguments are some objects using which this action should be performed. If action has arguments in knowledge base, then you will get them. There are a couple of getters for this.
...
// Provide relation here if your argument has specific role in action.
ScAddr const & argAddr = action.GetArgument(ScKeynodes::rrel_1);
// If there is no argument with such role, then `argAddr` will be empty.
...
...
// Or provide index of argument. 1 is equal to `ScKeynodes::rrel_1`,
// 2 is equal to `ScKeynodes::rrel_2` and etc.
ScAddr const & argAddr = action.GetArgument(1);
// If there is no argument with such role, then `argAddr` will be empty.
...
Note
There is a limit to the number of order role relations. You can get from rrel_1
up to and including rrel_20
.
Warning
This method will throw utils::ExceptionInvalidParams
if you provide invalid index for argument (for example, 0 or 21).
...
ScAddr const & argAddr = action.GetArgument(1, defaultArgumentAddr);
// If there is no argument with such role, then `argAddr` will equal
// to `defaultArgumentAddr`.
...
GetArguments
You can get all arguments using one getter.
...
// Here, 2 is number of arguments in specified action.
auto const & [argAddr1, argAddr2] = action.GetArguments<2>();
// If action doesn't have some argument, it will be empty.
...
...
// You can ignore some arguments.
auto const & [argAddr1, argAddr2, _] = action.GetArguments<3>();
...
SetArgument
You can set arguments for specified action.
...
// Provide relation here if your argument should have specific role in action.
action.SetArgument(ScKeynodes::rrel_1, argAddr);
...
...
// Or provide index of argument. 1 is equal to `ScKeynodes::rrel_1`,
// 2 is equal to `ScKeynodes::rrel_2`, etc.
action.SetArgument(1, argAddr);
...
Note
If action already has an argument with specified role, then connection between action and existing argument will be removed and connection between action and new argument will be generated.
SetArguments
Action result
All actions should have result (result situation). Result situation is structure that contains all sc-constructions that indicate result of performed (finished) action.
GetResult
You get can result of any action. Result may be empty.
...
// Use this method after some agent finishes
// performing action.
ScStructure const & actionResult = action.GetResult();
...
Warning
If you call this method for not finished action, then this method will throw utils::ExceptionInvalidState
. It prevents a situation where an agent that performs an action is still forming a result for that action, and you haven't waited for it and already want to get result for that action.
SetResult
...
// Use this method in agent performing action
// to set new result.
action.SetResult(resultStructure);
...
Note
If action has result, then existing result will be removed and the new one will be set.
Warning
If you call this method for not finished, but initiated action only, the this method will throw utils::ExceptionInvalidState
.
FormResult
You may not generate result structure. You can provide only elements of result for action.
...
// Use this method in agent performing action
// to form new result with provided sc-elements.
action.FormResult(elementAddr1, elementAddr2);
...
Note
If action has result, then existing result will be removed and the new one will be set.
UpdateResult
...
// Use this method in agent performing action
// for update existing result by new sc-elements.
action.UpdateResult(elementAddr1, elementAddr2);
...
Note
This method updates existing result for action.
Note
FormResult
and UpdateResult
don't append sc-element twice.
Note
If you don't form result then empty result for your action will be generated if you finish action.
Action states
All actions have state. There are three states of actions provided by this API:
- action isn't initiated;
- action is initiated, but isn't finished (that is, action is being performed);
- action is finished.
You can initiate, wait or finish actions.
IsInitiated
Use this method to check that specified action is initiated.
InitiateAndWait
You can initiate action and wait for it to finish. This method stores maximum customer waiting time of the action to finish in knowledge base.
...
// Provide maximum time of waiting while action will be finished.
action.InitiateAndWait(100); // milliseconds
// This argument has default value, that equals to 5000 milliseconds.
...
Warning
If you set maximum customer waiting time for an action that already has maximum customer waiting time, then this method will throw utils::ExceptionInvalidState
.
GetMaxCustomerWaitingTimeLink
You can get sc-link with time that customer will wait for action to finish. If action does not have waiting time then empty sc-address will be returned.
GetMaxCustomerWaitingTime
You can get time that customer will wait for action to finish. If action does not have waiting time then 0 will be returned.
Initiate
Or you can initiate and not wait for it to finish.
IsFinished
Use this method to check that specified action is finished.
All finished actions should be finished with one of the following statuses:
- finished successfully;
- finished unsuccessfully;
- finished with error.
IsFinishedSuccessfully
The set of actions finished successfully includes actions that have been successfully completed from the point of view of subject who performed them, i.e., the goal has been achieved, for example, the solution and result to a problem have been obtained, a construction has been successfully transformed, etc.
FinishSuccessfully
You can successfully finish action that does not have yet been finished.
...
ScResult const & result = action.FinishSuccessfully();
// Use result to return result from agent program.
...
Warning
If you finish action successfully that already has result, then this method will throw utils::ExceptionInvalidState
.
Warning
If you finish action successfully that is finished or not initiated, then this method will throw utils::ExceptionInvalidState
.
IsFinishedUnsuccessfully
The set of actions finished unsuccessfully includes actions that were not successfully finished from the point of view of subject who performed them for some reason. There are two main reasons why this situation may occur:
- corresponding problem is formulated incorrectly;
- formulation of corresponding problem is correct and understandable to the system, but solution of this problem at the current moment cannot be obtained in terms satisfactory from the point of view of executor.
FinishUnsuccessfully
You can finish unsuccessfully action that not finished yet.
...
ScResult const & result = action.FinishUnsuccessfully();
// Use result to return result from agent program.
...
Warning
If you finish action unsuccessfully that already has result, then this method will throw utils::ExceptionInvalidState
.
Warning
If you finish action unsuccessfully that is finished or not initiated, then this method will throw utils::ExceptionInvalidState
.
IsFinishedWithError
The set of actions finished with error includes actions whose execution was not successfully finished from the point of view of subject who executed them, because to some error, such as incorrect specification of this action or violation of sc-memory integrity by some subject.
FinishWithError
You can finish action with error that not finished yet.
...
ScResult const & result = action.FinishWithError();
// Use result to return result from agent program.
...
Warning
If you finish action with error that already has result, then this method will throw utils::ExceptionInvalidState
.
Warning
If you finish action with error that is finished or not initiated, then this method will throw utils::ExceptionInvalidState
.
All these methods return object of ScResult
. You should return it in agent program. You can't call constructor of ScResult
to generate new object.
Frequently Asked Questions
- What is difference between
ScAction
andScEvent
? - What if I want to set some edge as action result and not structure with this edge?
What is difference between ScAction
and ScEvent
?
ScAction
is a class that represents sc-action. A sc-action is a process performed by some entity to solve specified problem. ScEvent
represents a sc-event. A sc-event is a connection between process and its initial and result situation. Actions are generated after the occurrence of some sc-event and actions are performed by agents. Emergence of events in sc-memory leads to generation of new processes.
What if I want to set some edge as action result and not structure with this edge?
You're not allowed to do this. Action result should be a atomic formula (statement, situation or structure). Action result describes how action was performed. In the future, result can be non-atomic logical formula.