SYNERGY

 

A visual, activation and propagation-based

multi-paradigm programming language based on

Executable Conceptual Graph

 

by

Adil KABBAJ

 

 

1. Introduction

2. A Brief History of SYNERGY

3. The Core of SYNERGY

    3.1. Primitive concept types and primitive relation types of Synergy

    3.2. Programming in SYNERGY

        3.2.1 Expression

        3.2.2 Sequence

        3.2.3 Parallelism

        3.2.4 Conditional Code

        3.2.5 Iteration

    3.3. Defined Concept Type

        3.3.1 Parameters and Arguments

        3.3.2 Operation vs Process

        3.3.3 Recursion

        3.3.4 Example of defined concept type

    3.4 Concept state and Concept life-cycle

    3.5 Propagation rules for Data/Control relations

    3.6 CG activation mechanism and the interpreter of SYNERGY

        3.6.1 Concept-life cycle: complement

        3.6.2 Parallelism and the Synergy interpreter

    3.7 Examples of CG activation

    3.8 Procedural vs Functional interpretation of Synergy relations

    3.9 Control of Forward/Backward propagation

    3.10 Examples (complement)

4. Checking Functional Dependency 

5. Call Java (Methods) from Synergy

5. Calling Synergy from Java (Code) 

6. Calling Synergy from other components of Amine  

7. Dynamic Programming in Synergy

8. Automatic composition of web services with Synergy (since Amine 9)

9. Synergy GUI

10. Synergy vs CharGer: A brief comparison

11. Interoperability between Synergy and CharGer

12. Implementation Issues

13. Limitations

14. References

 

Introduction

Synergy is a visual, activation and propagation-based multi-paradigm programming language based on executable Conceptual Graph (CG). Execution is based on a CG-activation mechanism for which concept lifecycle, relation propagation rules and designator instantiation operation constitute the key elements. Synergy has been designed and developed by Adil Kabbaj in his Ph.D. thesis (1992-1996).

We proposed CG activation-based mechanism as a computation model for executable conceptual graphs [7-10]. Activation-based computation is an approach used in visual programming, simulation and system analysis where graphs are used to describe and simulate sequential and/or parallel tasks of different kinds: functional, procedural, process, event-driven, logical and object oriented tasks. Activation-based interpretation of CG is based on concept lifecycle, relation propagation rules and referent/designator instantiation. A concept has a state (which replaces and extends the notion of control mark used by Sowa) and the concept lifecycle is defined on the possible states of a concept. Concept lifecycle is similar to process lifecycle (in process programming) and to active-object lifecycle (in concurrent object oriented programming), while relation propagation rules are similar to propagation or firing rules of procedural graphs, dataflow graphs and Petri Nets.

SYNERGY is a visual multi-paradigm programming language based on CG activation mechanism. It integrates functional, procedural, process, reactive, object-oriented and concurrent object-oriented paradigms. The integration of these paradigms is done using CG as the basis knowledge structure, without actors or other external notation. Previous versions of Synergy have been presented [6, 7]. The integration of Synergy in Amine required a re-engineering work and some changes and extensions to the language and to its interpreter. New features of Synergy include:

·        Long-term memory introduced in previous definitions of Synergy corresponds now to ontology that plays the role of a support to a Synergy “expression/request”,

·        Previous versions of Synergy did not have an interface with Java. The new version of Synergy includes such an interface; Java objects can be created and methods activated from Synergy. This is an important feature since user is not restricted to (re)write and to define anything in CGs. Also, primitive operations are no more restricted to a fixed set of operations.

·        The new version of Synergy has an access to the two first layers of Amine. Also, since all the components (Prolog+CG, Synergy, dynamic ontology formation process, etc.) are integrated in the same platform and share the same underlying implementation, it is now possible to develop applications that require all these components. We provide an example of this possibility in the next section.

·        The new version has an interface with Java: Java objects and methods can be created/used from Synergy programs.

·        Another new feature is the possibility to perform dynamic programming, i.e. dynamic formation-and-execution of the program. We focus on this feature in section dynamic_programming.

·        Other new features are introduced in this document.

 

A Brief History of SYNERGY

Conceptual Graph (CG) theory is proposed by Sowa [18, 19] as a graphic system of logic and as a CG Interchange Format (CGIF) [21]. In [19], Sowa notes that many popular diagrams (e.g., type hierarchies, dataflow diagrams, state-transition diagrams, Petri-Nets, etc.) can be mapped to CG and in [20] he proposes CG as a logical foundation for object-oriented systems. Thus, CG is presented by Sowa as a formalism for the representation of knowledge (both declarative and procedural) with a logical interpretation; execution should be done with proof techniques of logic using rules of inference. Other CG execution mechanisms have been proposed in literature [1, 3, 4, 7, 13, 14, 15, 16].

In [7, 8] we proposed CG activation-based mechanism as a computation model for executable conceptual graphs. Activation-based computation is an approach used in visual programming, simulation and system analysis where graphs are used to describe and simulate sequential and/or parallel tasks of different kinds: functional, procedural, process,  event-driven, logical and object oriented tasks [2, 11, 12, 17, 23, 24].

Activation-based interpretation of CG [7, 8] is based on concept lifecycle, relation propagation rules and referent/designator instantiation. A concept has a state (which replaces and extends the notion of control mark used by Sowa [18]) and the concept lifecycle is defined on the possible states of a concept. Concept lifecycle is similar to process lifecycle (in process programming) and to active-object lifecycle (in concurrent object oriented programming), while relation propagation rules are similar to propagation or firing rules of procedural graphs, dataflow graphs and Petri Nets [8]. Since 1995, we have designed and implemented a visual language, called SYNERGY that is based on such an activation mechanism. SYNERGY is a visual multi-paradigm programming language; it integrates functional, procedural, process, reactive, object-oriented and concurrent object-oriented paradigms. The integration is done using CG as the basis knowledge structure, without actors or other external notation.

SYNERGY is designed for visual programming, modeling and simulation. It can be used for different purposes and in many fields: programming languages, simulation, database, information systems, software engineering, knowledge acquisition, knowledge base systems, intelligent tutoring systems and multi-agent systems. SYNERGY has been used for the development of a concurrent-object oriented application (e.g., a visual agent-oriented modeling of the Intensive Care Unit) and in modeling some components of an intelligent tutoring system [9]. It has been used also for the specification of a multi-agent system [25]. A hybrid object-oriented use of Synergy is illustrated in [10].

First implementation of SYNERGY has been done in C++ by Adil Kabbaj with the collaboration of Khalid Rouane (1995-1996). A reformulation of Synergy interpreter in Java has been done by Adil in the period 1998-2000. However, for the integration of SYNERGY in Amine platform, the previous reformulation had to be debuged and adapted. This work has been done for the Core of Synergy, by Adil Kabbaj with the help of Said Ladib. Other aspects of Synergy are being considered by Adil and Said.

SYNERGY has been presented through five papers, submitted to previous ICCS conferences :

1.   Contexts, Canons and Coreferences as a basis for a multi-paradigm language : This paper shows how basic elements of CG theory, like CG structure, canon, context and coreference constitute the basis for the multi-paradigm language SYNERGY. For computational purpose, a) the definition of coreference is extended to include compound coreference, b) states and lifecycles are associated to concepts and c) a finite set of data and control relations (in, out, guard, next) are defined with propagation rules as their procedural semantic. Computation model of SYNERGY corresponds to a context activation mechanism which is based on concept lifecycle and relation propagation rules.

2.   Synergy : A Conceptual Graph Activation-Based Language: This paper presents the Core of Synergy: the CG structure (concept, relation, context, co-reference) and the activation mechanism used in Synergy as well as the concept type definition, the encapsulation mechanism and the knowledge base of Synergy. Examples are given to illustrate some aspects of the language.

3.   SYNERGY as a concurrent object oriented language: This paper presents the concurrent object oriented model embedded in SYNERGY and an application that illustrates this use of the language. Basic features of the SYNERGY concurrent object oriented model are: 1) an active object, with its message queue, its declarative part and its procedural part (script + body) is described as a labeled context, 2) both “coupled” communication mode (objects communicate directly with one another by sending/receiving messages) and “non-coupled” communication mode (objects share and communicate information via a common space) are provided, 3) objects types form a hierarchy used by inheritance mechanism and, 4) both inter- and intra-concurrency are provided; several objects can be active in parallel and several methods of an object can be executed in parallel. This paper shows also that the integration to SYNERGY of the concurrent object oriented model is based on the use of key elements as CG structure, contexts and coreferences.

4.   Synergy as an Hybrid Object-Oriented Conceptual Graph Language: This paper presents the use of Synergy as an Hybrid Object-Oriented Conceptual Graph Language (HOO-CGL). It describes the formulation in Synergy of basic concepts of the hybrid object-oriented paradigm: encapsulation, definition of a class with methods and daemons, method and daemon definitions, class hierarchy, instance and instantiation mechanism, inheritance (both property and method inheritance), method call, method execution and daemon invocation due to data access. An example is used to illustrate the presentation of such an Hybrid Object-Oriented Conceptual Graph Language.

5.   Development of Intelligent Systems with Amine: This paper presents an overview of Amine. A section of this paper introduces Dynamic Programming in Synergy. See Dynamic Programming for more detail.

Full integration of SYNERGY in Amine is being performed in five steps:

1.   Integration of the Core of SYNERGY,

2.   Integration of interface with Java and of Dynamic Programming in Synergy

3.   Extension of the Core with the treatment of compound coreferences,

4.   Integration of Object Oriented SYNERGY,

5.   integration of Concurrent Object Oriented SYNERGY.

Integration of the Core of SYNERGY to Amine is finished (but test and debug continue !). The current document introduces this work. It presents also the implementation of the second step: Integration of interface with Java and of Dynamic Programming in Synergy. Next versions of this document will report the progress concerning the implementation of the other steps, with examples and other details.

 

The Core of SYNERGY

A procedural knowledge (action, operation, function, expression, procedure, process, task, etc.) can be represented by CG. Execution/Interpretation of procedural knowledge corresponds to the execution/interpretation of CG. To enable this extension of CG, we have extended the standard interpretation/view of concepts and relations (of a CG): a concept can represent both a static and/or a dynamic (or active) entity. Thus, primitive operations like arithmetic, relational and logical operations can be represented as concepts. Also, a relation can be used to establish a static/descriptive structure and/or to establish a procedural/control structure.

 

Primitive concept types and primitive relation types of Synergy

The type of a concept can be a defined concept type or a primitive concept type (primitive data type like Int, Real, Number, Boolean, String, or a primitive operation type: Add, Sub, Mul, Div, Sqrt, Assign, Equal, Dif, NotEq, Inf, Sup, InfEq, SupEq, And, Or, Not, Read, Write, etc.). Like Prolog+CG, Synergy provides a very small set of primitives. This is not really a limitation because Synergy provides, via Calling Java objects/methods from Synergy, a means to use an infinity of operations/methods, including all methods offered by Amine platform.

Beside the primitive data and operation types, Synergy provides a set of procedural relations = {“in”, “out”, “grd”, “next”}. "in" and "out" are data relations (they relate income and outcome arguments to the operation) while "grd" and "next" are control relations ("grd" relates a condition to an operation and "next" imposes a sequential execution of two operations).

Note: in each of the following statements, C and C’ represent respectively the source and the target concepts of the relation in question.

C —in-> C’  : C is an income argument for C’.

C —out-> C’ : C has C’ as an outcome argument.

C —grd-> C’ : C is a precondition for the execution of C’.

C —next-> C’ : After the execution of C, execute C’.

 

Programming in SYNERGY

Like Lisp language, Synergy provides a set of primitives and also a possibility to define new types (that represent functions or procedures or processes). Also, like Lisp, Synergy is interactive: user formulates requests (represented by CG) and Synergy interpreter attempts to evaluate and get an answer to these requests.

Primitives concept types and primitives relation types constitute "Synergy Ontology". This ontology (of primitives) is automatically loaded by Synergy Interpreter. Defined concept types are defined in an ontology and of course such an ontology should be loaded to enable the edition and the execution of the request.

See examples below and See Synergy GUI for more detail.

 

Examples:

Note: Examples below are illustrated with "Amine proper LF/CGIF notation" adopted by versions of Amine previous to Amine 6. With Amine 6.0, these examples work also with Standard CGIF notation.

 

Expression

Figure 1 shows the graph/visual formulation of the following code (composed of two affectations):

     z = 4 * 7;
     r_result = x * y + z - 1;

Figure 1: Formulation of an expression (a request)

Figure 1 illustrates the fact that concepts represent (primitive) data types as well as (primitive) operations. Figure 1 illustrates a request that corresponds to an expression (represented as a CG). Synergy interpreter will execute the expression by CG activation. The detail of the execution/activation is presented below.

Note: Since Amine 6.0, once Synergy GUI is activated, Synergy ontology that contains primitive types is automatically loaded. So, if only primitive types are used in the program/request, then the user can edit/execute his program/request without any load of any ontology. However, if his program/request contains defined concepts, then he should load first the appropriate ontology where the types are defined.

 

Sequence

The sequence of operations execution is implicit, determined by dependency between operations, and explicit, determined by the use of "Next" relation. Examples in this document illustrate various forms of Sequence.

 

Parallelism

The default control structure in Synergy is (simulated) parallelism, not sequence. Depending on data/control dependency, concepts (that represent operations, functions, procedures, processes) can be executed/activated in parallel. Examples in this document illustrate this basic feature of Synergy. See Parallelism in Synergy for complement details.

 

Conditional Code

"Grd" (guard) relation is a primitive relation that can be used to express conditions on operations/functions/procedurses. Figure 2 shows the graph/visual reformulation of a conditional instruction (if-then-else) in terms of Grd relations:

 if (x < y)
    z = x + y
 else
    z = x - y.

Note: The result of a function can be assigned to an explicit outcome argument or to the function itself, as illustrated by Figure 2.b. The two formulations (in Figure 2.b) are equivalent.

                        

                                   (a)                                                                             (b)

Figure 2: Formulation of a conditional instruction

Iteration

Like conditional instruction, Iteration can be expressed using Synergy relation primitives (especially Grd and Next). As an example of iterative code, consider the iterative (non recursive) definition of the function factorial (it is provided in the ontology "samples/ontology/synergyOntology/ontology1.xml"). The detail of the definition as well as the detail of its execution/activation are considered in Execution/Activation of Iterative Code.

int IterativeFactorial(int i) { // for i > 0
    x := 1;
    y := 1;
    while (x < i) do {
        x := x + 1;
        y := x * y;
    }
    return y;
}

Figure 2Bis: Formulation of an iteration

 

Defined Concept Type

The type of a concept in a CG can be defined; defined by the user in an ontology.

Parameters and Arguments: If the concept type is defined and represents a treatment with arguments, then the corresponding parameters should be specified in the definition of the type. In Synergy, the designator of an income parameter should be prefixed by "inX" where X stands for an optional integer that specifies the range of the income parameter (an example of an income parameter: [Integer in3:y]; this concept represents the third income parameter in the definition of the concept type). The designator of an outcome parameter should be prefixed by "outX" (an example of an outcome parameter: [Integer out2:z]; this concept represents the second outcome parameter in the definition of the concept type).

In general and as discussed below, an activation of a concept with a defined type and a null descriptor will involve an instantiation of the type definition: a copy of the definition is created and assigned as a descriptor for the concept. Then, state of parameters in the definition are initialized to state "trigger" and parameters will refeer to their corresponding arguments (we adopt a transmission by address, between arguments and parameters).

 

Operation vs Process: If the defined type represents a treatment, then the user should specify the concept [Operation :super] or [Process :super] in its definition to indicate how the type should be interpreted: if the concept [Operation :super] is specified, then once the operation terminates its execution, its description is destroyed as the case for the “record activation” of a procedure in procedural programming. However, if the concept [Process :super] is specified, its description is not destroyed (after the end of its execution/interpretation). If no one of the two is specified, the treatment is interpreted as a process, by default.

 

Recursion: Recursive definition of a concept type

Synergy considers the case of concept type with recursive definition. The example of recursive definition of Factorial is described and discussed below (RecursiveFactorial).

 

Example of defined concept type

Figure 3 shows an example of a defined type; the definition of the function Average (Figure 3.a) and an example of a call to this function in an expression/request (Figure 3.b). To run this example, load first the following ontology: "aminePlatform/samples/ontology/synergyOntology/ontology1.xml". The expression/request that contains the call to Average is stored in the file "aminePlatform/samples/synergy/expleDefConcType.lnf". So you can open this file to edit and execute the expression/request.

The concept type Average has two income parameters and one outcome parameter. Since the concept [Operation:super] is specified in the definition of Average, then once the concept [Average] terminates its execution, its description is destroyed. A new activation of the concept [Average] will involve the creation of a new description (by definition instantiation). If [Process:super] was specified (instead of [Operation:super]), then upon the termination of the execution of the concept, its description will not be destroyed. A new activation of the concept will use the same description.

The detail of the activation/execution of this example is described and discussed below; in the next section.

(a)

(b) 

Figure 3: Definition of the concept type "Average" and a "call" to this concept type in an expression

 

Concept state and Concept life-cycle

Beside concept type, concept designator and concept descriptor, a concept (in SYNERGY) has a state. The state field of a concept is defined on the following set: {steady, trigger, check-preconditions, wait-preconditions, wait-value, in-activation, wait-affectation, wait-end-affectation}. This set enumerates the possible states of a concept. Each state of a concept has a visual representation. For instance, the rectangle (that encloses a concept) is green if the concept state is “trigger” and it is red if the state is “in_activation”. See Synergy GUI for the visual representation of the other states.

The dynamic of a concept is described according to the concept life-cycle (which is a transition network), defined on the possible states of a concept. Concept life-cycle is introduced below.

 

Concept life-cycle

Concept life-cycle is a state transition diagram (Figure 4) where states correspond to the possible states of a concept and transitions to the conditions/actions on the concept and on the data/control relations linked to the concept.

 

Figure 4: Concept’ life-cycle

A concept C in “trigger” state is asked "to determine its descriptor and attempt to activate/execute/interpret it". The concept C can have already a descriptor, or its type is a primitive operation type (with a built-in interpretation), or its type is defined and in this case the descriptor will be determined by definition instantiation (i.e. a copy of the definition body). If none of these possibilities hold, the interpreter will attempt to compute the descriptor by backward propagation (through the “out” relation) and the concept C becomes at state “wait-value” (wait for the creation/computation of its descriptor).

Once C has a descriptor or its type is a primitive operation type, its state changes from “trigger” to “check-preconditions”; the state where the concept C should check its preconditions (e.g., a concept C’ is a precondition for another concept C if C' is an income argument for C or it is a guard condition: C’ —in® C or     C’ —grd® C). The concept C’ that represents a precondition for the concept C can be triggered (by backward propagation through the “in” or “grd” relation) and C changes its state to “wait-preconditions”. Of course, a concept C can have no precondition.

If all the pre-conditions are satisfied, C changes its state from “check-preconditions” to the state “in-activation” and its description is activated/executed/interpreted: if the type of C is a primitive operation then the primitive is executed. If the description of C is a CG then the CG is executed (in parallel to other active CGs). If the description is a primitive data (like an integer or a string) then its execution is "null" (i.e. it takes no time and it has no effect).

If the activation of the description is terminated and the concept has no assignment post-conditions, then the concept C returns to the “steady” state. Assignment post-conditions will be considered later.

Concept life-cycle, as described above, constitutes the kernel of CG activation and Synergy Interpreter.

 

Propagation rules for Data/Control relations

Currently, relation propagation rules apply only to data and control relations as well as to co-reference link (viewed as a “virtual” data relation between a bound node C1 and its defining node C2: C1 –coref® C2. Co-reference link will be considered in next versions of this document). A data/control relation can propagate a concept state forward (from the source to the target concept of the relation) and/or backward (from the target to the source of the relation).

Forward propagation rule. If an active context contains a branch C1 –Rel® C2 where the state of C1 is “trigger” and Rel Î {"in", "out", "next", "coref"} then the relation Rel will propagate forward the state “trigger” to the concept C2. If Rel = “grd” then the propagation will be done only if the description of C1 is different from “false”.

Backward propagation rule. If an active context contains a branch C1 –Rel® C2 where the state of C2 is “trigger” and Rel Î {"in", "out", "grd", "coref"} then the relation Rel will propagate backward the state “trigger” to C1 if one of the following conditions is satisfied:

-    Rel = "in" and C1 is at state “steady” and it hasn’t a description.

-    Rel = "out" or "coref" and C2 hasn’t a description, its type isn’t a primitive operation and it isn’t defined (e.g., its description cannot be determined by instantiation).

-    Rel = "grd" and C1 is at state “steady” and it hasn’t a description.

 

Concept life-cycle with propagation rules for data and control relations, constitute the kernel of CG activation and Synergy interpreter.

 

CG activation mechanism and the interpreter of SYNERGY

SYNERGY interpreter is based on CG (or context) activation/execution. CG (context) activation begins with parallel interpretation of concepts of the CG, then data and control relations (if they are present) spread or propagate concept's parallel activation through the CG. Interpretation of a concept is done according to its life-cycle while the spreading activation is performed according to relation propagation rules.

SYNERGY interpreter starts with the interpretation of the working memory context; the first active context that contains the user requests (represented as CGs). An interpretation/activation of a concept with a primitive type involves the execution of the primitive. An interpretation/activation of a concept with a defined type will involve (in general) an instantiation of its definition and an interpretation/activation of this instantiation, producing a new active context, and so on. Hence, SYNERGY interpreter is concerned by a parallel interpretation of several active contexts and/or the execution of several primitive operations. The association of a state and a life-cycle to a concept enables the interpretation and management of such a parallelism. In effect, each concept is interpreted (e.g., evolves, changes) according to its state and to its life-cycle; the activation (or interpretation) of an active context is thus decentralized.

 

Concept-life cycle: complement

In our description of concept life-cycle, we specified that at the end of a concept activation, assignment post-conditions should be considered, without providing detail on these conditions. This section fills this gap. Three kinds of post-conditions are possible:

1.   Assignment of values computed by the concept C (if its description corresponds to the call of a primitive with outcome arguments). If C is related to one of its outcome argument C1 with a functional "out" relation (C –out,f-> C1) and C1 has already a description (a value), then C will change its state to "wait-for-affectation ; @aft"; waiting for C1 to become free (without descriptor).

2.   Even if all the values computed by C can be assigned to their corresponding outcome arguments, C can still wait due to a "conflict of affectations" that can occur when several concepts attempt, at the same time, to affect values to the same concept. In this case, C will change its state to "wait-for-end-of-affectation ; @nda".

3.   If the concept C has terminated its activation and has satisfied the above assignment post-conditions (if it has) and if it is related to a concept C1 (C –Rel-> C1) with Rel defined on {"in", "out", "grd", "next", "coref"} and without the cut_forward_propagation attribute ">|", then the forward propagation rule of Rel is applied.

Once all the post-conditions of the concept C are satisfied, the concept C returns to the “steady” state.

 

Parallelism and the Synergy interpreter

As noted in previous sections, Synergy interpreter should manage parallel activation of several contexts (CG) and/or the execution of several primitive operations. Each concept is interpreted (e.g., evolves, changes) according to its state and life-cycle, the activation (or interpretation) of a context is thus decentralized. As a parallel language, Synergy enables the user to write parallel programs, its interpreter is able to execute those programs and its graphical user interface (GUI) allows the user to see and debug the parallel activation of those programs. This “conceptual parallelism” is at the design/language level. It can be implemented on a parallel machine (e.g., “physical parallelism”) or it can be interpreted and simulated on a sequential machine. In our current implementation of Synergy, we have considered the second option. Some constraints have been assumed, especially for parallel execution of primitive operations. For instance, we assumed that during the execution of a primitive, no interaction could occur between the primitive and the other parts of the Synergy “program”.

 

Examples of CG activation

Note: Examples below are illustrated with "Amine proper LF/CGIF notation" adopted by versions of Amine previous to Amine6. With Amine 6.0, these examples work also with Standard CGIF notation.

 

Example #1: Expression execution/activation

Let us consider the activation of the expression formulated in Figure 1. State of the concept [Int=4] has been initialized to "trigger" (Figure 5). Consult Synergy GUI for the detail on the use of this GUI and how to create, open and use a Synergy application. The main frame of Synergy GUI is the working memory WM (working space) where requests are formulated. The CG file that contains the request is "samples/synergy/exple_expression.lnf" (there is also a CGIF version of this request).

Synergy interpreter attempts to interpret (to activate or execute) the content of the WM. In our case, the WM contains one request which corresponds to an expression. Note also that Synergy GUI provides facilities to execute the content of the WM at once or step-by-step (Figure 5). The latter enables the user to "see" and to follow the activation of CGs (that constitute the content of the WM).

Figure 5: Activation of the expression I

Concept [Int = 4] is a primitive data concept, so its activation is "null". However, forwad propagation of its state ("trigger") has been done to the concept [Mul] through relation "in1" (Figure 6.a). Concept [Mul] is a primitive operation, i.e. its activation involves the activation of the primitive. Note that the state of the concept [Mul] changed from "trigger" to "in-activation" (Figure 6.b) because all its preconditions are satisfied (in this case, its two income arguments have value). Execution of a primitive operation takes one Synergy cycle (i.e. one step). So in the next step, the primitive concept like [Mul] will terminate its execution/activation.

            

Figure 6: Activation of the expression II

After the termination of the activation of the concept [Mul], the result is assigned to the concept [Int:z] which becomes [Int :z = 28]. Due to the change in its descriptor, the state of the concept [Int :z = 28] changed to "trigger" (Figure 7.a). Its state is then propagated to the concept [Add] through the relation "in2" (Figure 7.b).

              

Figure 7: Activation of the expression III

Concept [Add] represents a primitive operation. Since its first income argument has not a value (Figure 7.b), its state changed from "trigger" to "wait-preconditions" (Figure 8.a). At the same time, the state of its first income argument (concept [Int]) changed to "trigger" (Figure 8.a). Since the concept [Int] represents a primitive data, it has not a value and it is an outcome argument of the concept [Mul], then its state ("trigger") is propagated to the concept [Mul] (Figure 8.b). The state of the concept [Int] changed from "trigger" to "wait-value" (Figure 8.b).

             

Figure 8: Activation of the expression IV

Concept [Mul] is ready for activation, since all its pre-conditions are satisfied (in this case, its two income arguments have value). The concept [Mul] changes its state to "in-activation" (Figure 9.a). Once its execution terminated (it takes one Synergy cycle), the returned value is assigned to the outcome argument [Int] which becomes [Int = 72]. Due to this assignation, the state of this concept changed from "wait-value" to "trigger" (Figure 9.b).

              

Figure 9: Activation of the expression V

Concept [Add], that was in state "wait-preconditions", changes its state to "in-activation" (Figure 10.a) since all its pre-conditions are (now) satisfied (in this case, its two income arguments have value). After the termination of its execution, the returned value is assigned to its outcome argument (Figure 10.b) which becomes at "trigger" state, with descriptor 100: [Int = 100].

                 

Figure 10: Activation of the expression VI

The state "trigger" of the concept [Int = 100] is propagated to the concept [Sub] (Figure 11.a) and since all its pre-conditions are satisfied, its state changes to "in-activation" (Figure 11.b) and the primitive operation is performed.

                             

Figure 11: Activation of the expression VII

The result of [Sub] is assigned to its outcome argument [Int :r_result] which becomes [Int :r_result = 99] with state "trigger". The concept [Int :r_result = 99] changes then its state to "steady" with no effect (since it is not related to other concepts and so, its state cannot be propagated to other concepts). Figure 12 shows the end of the execution: the content of the Working Memory is no more active.

      

Figure 12: Activation of the expression VII

Example #2: Let us consider now the activation of the conditional instruction formulated in Figure 2. This example illustrates the use of "grd" (guard) relation to express conditions on the activation of operations (i.e. primitive or defined treatment) and illustrates also backward propagation. Figure 13.a shows the CG that represents the conditional instruction: condition x < y is a guard for the operation x + y, i.e. this operation can be activated only if the condition (x < y) is satisfied. The operation x - y is conditioned by the negation of (x < y). Activation of this conditional instruction is initiated by putting the concept [Int: z] in state "trigger" (Figure 13.a). Then, by backward propagation, through "out" relations, operations [Sub] and [Add] are triggered, in parallel, and the concept [Int: z] changes its state to "wait-value" (Figure 13.b).

The CG file that contains the request is: "samples/synergy/exple_if.lnf" (there is also a CGIF version of this request).

          

Figure 13: Activation of a conditional instruction I

Both [Sub] and [Add] have a pre-condition: [Not] is the guard for [Sub] and [Inf] is the guard for [Add]. The two guard have not a value. Thus, the "trigger" state is propagated, backward, to [Not] and [Inf]. Then, concepts [Sub] and [Add] change their states to "wait-preconditions" (Figure 14.a). All the pre-conditions of the concept [Inf] are satisfied (i.e. its two income arguments have value), so its state changes from "trigger" to "in-activation" (Figure 14.b) and the primitive operation (<) is initiated. Its execution will take one Synergy cycle (one step). The operation [Not] cannot be activated immediatly however; it should wait for the value of its income argument.

          

Figure 14: Activation of a conditional instruction II

The execution of (6 < 4) returns false (Figure 15.a) which is assigned to the descriptor of the concept [Inf] (since its outcome argument is not specified; the operation will play the role of its outcome argument). Now, the operation [Not] can change its state from "wait-preconditions" to "in-activation" (Figure 15.b) since its income argument has now a value (it was the only pre-condition for [Not]). Note that the operation [Add] remains in state "wait-preconditions" since its precondition is not satisfied. In fact, [Add] will remain in the state "wait-preconditions" until the end of the execution.

         

Figure 15: Activation of a conditional instruction II

The execution of the operation [Not] returns true which is assigned to [Not] itself (Figure 16.a). The operation [Sub] is no more blocked; it will change its state from "wait-preconditions" to "in-activation" (Figure 16.b) since the condition, represented by the concept [Not], is satisfied.

     

Figure 16: Activation of a conditional instruction III

The execution of the operation [Sub] returns the value 2 which is assigned to the concept [Int:z] that becomes [Int :z = 2] with state "trigger" (Figure 17).

Figure 17: Activation of a conditional instruction IV

Concept [Int :z = 2] changes its state from "trigger" to "steady" without effect and the activation of the WM is finished (Figure 18).

Figure 18: Activation of a conditional instruction V

Example #3: Let us consider now the activation of an expression that contains a defined operation Figure 3. This example illustrates the activation of a concept with defined type. The activation of the content of the WM is initiated by setting the state of the concept [Int: _result] to "trigger" (Figure 19).

To run this example, load the ontology "samples/ontology/synergyOntology/ontology1.xml". Then open the CG file that contains the request ("samples/synergy/expleDefConcType.lnf").

 

Figure 19: Activation of an expression that contains a defined operation I

The state of the concept [Int: _result] is propagated backward to the concept [Add], through the relation "out", and the concept [Int: _result] changes its state to "wait-value" (Figure 20.a). The concept [Add] changes its state to "wait-preconditions" (Figure 20.b) since its first income argument has no value. The latter (the concept [Int]) changes its state to "trigger" (Figure 20.b). Next, the state of the concept [Int] is propagated backward to the concept [Average], through the relation "out", and the concept [Int] changes its state to "wait-value" (Figure 20.c).

                      

                         (a)                                                    (b)                                        (c)

Figure 20: Activation of an expression that contains a defined operation II

All the pre-conditions of the concept [Average] are satisfied and it has a defined type. Hence, definition instantiation operation is performed, which creates a copy of the definition and assigns it as a descriptor to the concept [Average]. Then reference transmission and state initialization are performed (by the instantiation operation) (Figure 21): the first income concept parameter [Int in1] in the descriptor of the concept [Average] (Figure 21) refers to the first income argument [Int = 14] in the WM, the second income concept parameter [Int in2] refers to the second income argument [Int = 8] and the outcome parameter [Int out] refers to the outcome argument [Int]. About state initialization: the state of income and outcome concept parameters are initialized to "trigger" (Figure 21). Once the instantiation operation performed, the state of the concept [Average = ...] changes to "in-activation" and the interpreter starts to interpret its description. Thus, the interpreter has now two active contexts (i.e. two active CGs); the WM context and the descriptor of the concept [Average = ...]  (Figure 21).

  

Figure 21: Activation of an expression that contains a defined operation III

Concept [Add], in the descriptor of [Average = ...], changes its state to "trigger", due to forward propagation. Also, concept [Div] changes its state to "trigger", due to backward propagation (Figure 22).

Figure 22: Activation of an expression that contains a defined operation IV

Since all the pre-conditions of the concept [Add] are satisfied, its state changes to "in-activation" (Figure 23).

Figure 23: Activation of an expression that contains a defined operation V

Concept [Add] terminates its execution and assigns the result to [Add] itself (Figure 24).

Figure 24: Activation of an expression that contains a defined operation VI

Now, concept [Div] can change its state to "in-activation" (Figure 25).

Figure 25: Activation of an expression that contains a defined operation VI

Once the concept [Div] terminates its execution, the result is assigned to the refered concept [Int] which becomes [Int = 11]. Also, the description of the concept [Average = ...] is no more active; its execution is finished and since it is defined as an operation, the description is destroyed and the concept is again without descriptor (Figure 26). Note also that the frame which displayed the description is now closed. We will focus now on the activation of the WM (the main active context) (Figure 26).

Figure 26: Activation of an expression that contains a defined operation VIII

After the activation of the concept [Add] (in the WM) and the execution of the associated primitive operation, the result is assigned to the concept [Int :_result].

Figure 27: Activation of an expression that contains a defined operation IX

Concept [Int :_result = 17] changes its state to "steady" and the activation of the WM is finished.

 

Procedural vs Functional interpretation of Synergy relations

Multiple-assignment and procedural interpretation of relations “in”, “out” and “grd” relations are considered by default in SYNERGY: for instance, with C1—in->C2 or C3—grd->C4, the concept C2 (or C4) will consult the description of C1 (or of C3 for C4) without consuming it. Also, with C5—out->C6, C5 can assign a new description (value) to C6 even if the latter has already a value. With a functional interpretation however, the concept C2 (or C4) will consult the description of C1 (or of C3 for C4) AND consume it. Also, C5 can assign a new description (value) to C6 ONLY IF it has not a value.

In Synergy, procedural interpretation of Synergy relations is adopted by default. If the user wants to adopt a functional interpretation for a relation R, he/she has to specify for R the optional attribute functional denoted by "f". For instance; with  C1—in,f->C2 or C3—grd,f->C4, the concept C2 (or C4) will consult the description of C1 (or of C3 for C4) and consume it. And with C5—out,f->C6, C5 can assign a new description to C6 only if C6 has not already a value, otherwise C5 will wait for the consumption of C6 description.

Example:

Figure 28.a shows a simple expression represented in CG. Procedural interpretation of Synergy relations (in this example: "In" and "Out") is adopted by default. We will follow the activation of this expression, according to the procedural interpreation and then we will change the expression to incorporate relations with functional attribute and we will its activation (to "see" the difference between the two interpretation).

Activation of the current CG starts with the concept [Int:r_result] that is in "trigger" state (Figure 28.a). Figure 28.b shows the state of the current CG after several backward propagations: primitive operation [Sub] has been triggered (to compute the value of the concept [Int:r_result]). Then, the concept [Int] (first argument of [Sub]) has been triggered (to get the value of the first argument of [Sub]). Then the primitive operation [Mul] has been triggered (to compute the value of [Int]). Then, the two concepts [Int] and [Int]  (the two arguments of [Mul]) have been triggered. Last, the two concepts [Read] and [Read] have been triggered (to produce value for the two concepts [Int] and [Int]), Figure 28.b. Note the use of the primitive operation "Read": it has no income argument and one outcome argument (the value provided by the user).

The CG file that contains the requestis "samples/synergy/exple_expr2.lnf" (there is also a CGIF version of this request).

                 

                    (a)                                                                            (b)

Figure 28: A simple expression with procedural interpretation of Synergy relations I

Execution of the primitive operation "Read" produces a "ReadFrame" (Figure 29.a) where the user enters its input. Then, he/she has to press button "Read" to close the frame. Figure 29.b shows the result of the execution of the two concepts [Read] (user enters 7) and [Read] (user enters 8).

            

                            (a)                                                                (b)

Figure 29: A simple expression with procedural interpretation of Synergy relations II

Then, after successive forward propagations, the concept [Int: r_result] will get a value: 55 (Figure 30.a). Note that intermediate values (like 7, 8 and 56) will remain (Figure 30.a). Note also that if the state of the concept [Int: r_result = 55] is set again to "trigger", then the activation of the CG will terminate immediatly at the next step since the concept will return to the state "steady" with no effect on the other parts of the CG. Why ? because the concept has already a value. Now, let us consider what will happen if we remove the value of the concept [Int: r_result = 55] and set its state to "trigger" (Figure 30.b).

             

Figure 30: A simple expression with procedural interpretation of Synergy relations III

As illustrated by Figure 31.a, the primitive operation [Sub] will be triggered and then activated (since its two income arguments have already a value). Its execution on the same input data will produce the same output: 55 (Figure 31.b). The reason behind this result is that intermediate results remain after the activation of the current CG (when we adopt procedural interpretation of Synergy relations).

              

Figure 31: A simple expression with procedural interpretation of Synergy relations IV

These intermediate results should not remain if we want a total reactivation of the current CG, with new input data and new intermediate results. In this case, the previous execution should leave no trace on the current CG. To do that, we should adopt functional interpretation of Synergy relations (not necessarly all the relations). Figure 32.a provides the functional reformulation of the above example: attribute "f" is added to the involved relations; "in" relations. Hence, to produce a result, each primitive operation will consume the values of its income arguments. Figure 32.b shows the state of the current CG after successive backward propagations, like in the previous example.

The CG file that contains the request is "samples/synergy/exple_expr2Func.lnf" (there is also a CGIF version of this request).

                 

Figure 32: A simple expression with function interpretation of Synergy relations V

Figure 33.a shows the state of the current CG after the activation of the two concepts [Read] and [Read]. Assume that the user provides again values 7 and 8. As illustrated by Figure 33.b, since income arguments of [Mul] are functional, its activation involves the consumption of their values (7 and 8).

               

Figure 33: A simple expression with function interpretation of Synergy relations VI

The result of the operation [Mul] is assigned to its outcome argument which becomes [Int = 56] (Figure 34.a). Again, since this concept is a functional income argument for the operation [Sub], its value will be consumed (Figure 34.b). Note however that the second argument of [Sub] is not functional. Thus, it will not be consumed by [Sub] (Figure 35).

              

Figure 34: A simple expression with function interpretation of Synergy relations VII

Figure 35 shows the state of the current CG after the end of its activation. Note the difference between this CG and the one described in Figure 30.a. Unlike the CG in Figure 30.b, if we remove the value 55 from the concept [Int :r_result = 55] and we set its state to "trigger", then the current CG is identical to the initial CG and its activation will be completly new (like the first one), with new input data and new intermediate results.

Figure 35: A simple expression with function interpretation of Synergy relations VIII

Functional interpretation is adopted by default in parallel functional programming (like Data Flow Graphs).

 

Control of Forward/Backward propagation

Forward and backward propagation through a relation Rel can be inhibited by the optional attribute “cut_forward_propagation: >|” (“Rel,>|”) or “cut_backward_ propagation: |<” (“Rel,|<”). For instance, if an active context contains C1 –in,>|® C2  and the concept C1 is at state “trigger” then the relation “in,>|” will not propagate the state “trigger” to the concept C2.

With the optional attributes “>|” and “|<”, the user can control the propagation of concepts activation in a CG. This is similar to the use of the “cut” to control backtracking in the PROLOG language.

 

Remark: More than one attribute can be associated to a Synergy relation. For instance, C —in,f,>|-> C’ means that C’ will consume the description of C, according to the semantic of the functional attribute, and that the computation of a new value for C will not trigger C’, due to the presence of the cut_forward_propagation “>|” attribute.

 

Examples (complement):

Example: Recursive definition of Factorial

To illustrate these attributes, Figure 36.a presents the recursive definition of the function factorial (called RecursiveFactorial). It has one income parameter (the concept [Int In]) and one outcome parameter (the concept [Int Out]). If the value of the income argument is equal to 1 then it assigns 1 (with the primitive operation Assign) to the outcome parameter. Otherwise, the result of RecursiveFactorial(in - 1) * in is assigned to the outcome paramter ("in" in the previous expression represents the income parameter). Note that the previous expression should be activated/evaluated only if the condition [Not] is true (i.e. in is not equal to 1). If attributes ">|" and "|<" are not used, the previous expression would be activated anyway (at least parts of it): being at trigger state, the input parameter [Int In] would trigger the operation [Sub], through the relation "In1" and trigger the operation [Mul] through a similar relation. After the termination of [Sub], this operation would trigger the call to factorial [RecursiveFactorial]. A similar activation would be done with the triggered outcome parameter: with backward propagation, through the relation "Out", the primitive operation [Mul] would be triggered. Then, its pre-conditions would be triggered too (the source of the guard relation would be triggered and also the two income arguments of the operation [Mul]). Then, the second income argument of the operation [Mul] would trigger the recursive call [RecursiveFactorial], etc.

So, to avoid this (unwanted) activation, we have to control the activation of the current CG; this is the role of the two attributes ">|" and "|<": adding the attribute "|<" to the relation "Out" (which links the operation [Mul] to the parameter [Int Out]) desables backward propagation through this relation (Figure 36.a). Also, adding the attribute ">|" to the relation "In1" that relates the parameter [Int In] and [Sub], and doing the same thing for the relation "In1" that relates the parameter [Int In] and [Mul], desable forward propagation through the two relations (Figure 36.a). Hence, the expression RecursiveFactorial(in - 1) * in will be activated only if the condition (in is not equal to 1) is true; the previous expression will be activated only by the satisfaction of the condition (in is not equal to 1). Let us follow now the activation of such a CG. Figure 36.b presents a simple expression that makes a call to the recursive definition of Factorial. The activation of this expression starts with the concept [Int] in state "trigger" (Figure 36.b). Then, backward propagation is performed, from the concept [Int] to the concept [RecursiveFactorial] (the reason is to compute a value for [Int]). Backward propagation continues: from the concept [RecursiveFactorial] to the concept [Int] (to compute the income argument for [RecursiveFactorial]) and then from [Int] to [Read] (to compute/determine the value of [Int]). The user is then asked to provide a value. Assume that he/she provides the value 3. This value is then assigned to the outcome argument of [Read]. Now, the concept [RecursiveFactorial] can be activated (Figure 37).

To run this example, load the ontology "samples/ontology/synergyOntology/ontology1.xml". Then open the CG file that contains the request ("samples/synergy/recFactorialTest.lnf") (there is also a CGIF version of this request).

                          

                                            (a)                                                                (b)

Figure 36: Recursive definition of Factorial I

Activation of the concept [RecursiveFactorial] involves its instantiation: copy of the definition of the type RecursiveFactorial followed by the initialization step (parameters should refer to their corresponding arguments and state of parameters are initialized to "trigger") (Figure 37).

Figure 37: Recursive definition of Factorial II

The primitive operation [Equal] is triggered, by forward propagation through "In" relation, and the operation [Assign] is triggered, by backward propagation through "Out" relation (Figure 38.a). Note that operations [Sub] and [Mul] are not triggered (due to the presence of ">|" and "|<"). Figure 38.b shows that [Equal] is in "in-activation" state while the operation "Assign" is in "wait preconditions" state.

           

Figure 38: Recursive definition of Factorial III

Execution of the primitive operation [Equal] returns false. Thus, the primitive operation [Assign] continues to "wait pre-conditions" and the primitive operation [Not] is triggered (Figure 39.a). Execution of [Not] returns true and so, the primitive operation [Mul] is triggered (Figure 39.b).

        

Figure 39: Recursive definition of Factorial IV

The primitive operation [Mul] becomes in state "wait pre-conditions" and its second income argument [Int] is triggered (Figure 40.a). Then, by backward propagation, concept [RecursiveFactorial] is triggered and then the primitive operation [Sub] (Figure 40.b).

            

Figure 40: Recursive definition of Factorial V

Execution of the operation [Sub] produces the result 2 (i.e. [Sub = 2]). Now that its income argument has a value, the concept [RecursiveFactorial] can be activated (Figure 41.a). The result of the execution of [RecursiveFactorial] is assigned to [Int] which becomes [Int = 2]. The primitive operation [Mul] can be then activated (Figure 41.b).

         

Figure 41: Recursive definition of Factorial VI

The result of the primitive operation [Mul] is assigned to the outcome parameter [Int Out] (in fact, it is assigned to the argument that is refered by the parameter). Activation of the concept [RecursiveFactorial] (Figure 37) is finished, so its description is destroyed and the initial simple expression (Figure 37) is now as described in Figure 42.

Figure 42: Recursive definition of Factorial VII

 

Example: Iterative definition of Factorial

The iterative definition of Factorial, presented in this section, is another illustration of the utility of functional interpretation of relations, and control of forward/backward propagation. We present first a sequential and textual definition of Factorial and then the visual/graphical definition using Synergy.

int IterativeFactorial(int i) { // for i > 0
    x := 1;
    y := 1;
    while (x < i) do {
        x := x + 1;
        y := x * y;
    }
    return y;
}

Reformulation in Synergy of this iterative definition of Factorial is described in the next figure. Activation of this definition starts with the activation of the concept [Inf] (triggered by forward propagation from the income parameter). Next, the addition concept [Add] is triggered (it is triggered by "Next" relation). This concept can be activated only if (x < i); the guard condition is satisfied. Next, the multiply conception [Mul] is triggered and activated (it is triggered by "Next" relation). Next, the concept [Inf] is triggered again, but this time by the "Next" relation. In this example, iteration is accomplished by this "Next" relation (which links [Mul] and [Inf]). Note also the use of "Next" to impose sequentiality.

Figure: Iterative definition of Factorial

This iterative definition of Factorial illustrates also the utility of functional interpretation of relation and of the control of forward/backward propagation:

·        "f" in "Grd,f" is used to impose that concept [Add] should wait until the concept [Inf] terminates its execution and produces the result.

·        ">|" is used to inhibite forward propagation. Indeed, if ">|" is not used, concepts [Add] and [Mul] would be triggered by forward propagation from [Int:x] and [Int:y] respectively.

Note also that the concept [Int :y 1] is not considered as the outcome parameter of the definition because paramater transmission in Synergy is by address; so any change of [Int Out :y 1] will be in fact a change in the argument, and this is not wanted in our example

To run this example, load the ontology "samples/ontology/synergyOntology/ontology1.xml". Then open the CG file that contains the request ("samples/synergy/iterativeFactorial.lnf") (there is also a CGIF version of this request).

 

Checking Functional Dependency

Amine 6.0 provides a procedure that checks functional dependency of a CG.

Checking functional dependency corresponds mainly to put in Trigger state any concept that is an income argument of other concepts ("actors"), and to put in Trigger state any concept that has a descriptor and is an outcome argument of other concepts ("actors"). The CG is then activated to check its functional dependency. See Synergy GUI for more detail on this new functionality.

Checking functional dependency constitutes the main activation mechanism (and mode) provided by CharGer.

 

Call Java (Methods) from Synergy

Like Prolog+CG, Synergy provides now the possibility to create and use Java (and Amine) objects and the possibility to call (Java) methods. Indeed, the definition of concept type has been extended to consider a Java message (ClassName.MethodName or identifier.MethodName or Variable.MethodName) as a new kind of concept type (Figure 28). Note that the complete Java class path should be specified as a String (i.e. "java.util.Stack" in Figure 28). Income/Outcome arguments of a method are specified as input concepts (with "in" relations) and output concepts (with out relations). Figure 28 provides an example: method New (which is a Synergy primitive that enables the creation of a new instance of the specified class) assigns the created object (a stack) to its output concept (i.e. [Object :_stack1]). Concept [_stack1.push] represents a Java message. To execute the message, Synergy determines first the reference of the variable "_stack1": to do that, Synergy locates the concept with the variable as its designator, then it considers the descriptor of the concept. As another example, let us consider the concept [Average.getDefinition]: "Average" is a type defined in the current ontology and "getDefinition" is a method of the class Type in Amine. The message "Average.getDefinition" will return the definition of the type "Average".

(a) Concept ["java.util.Stack".New] represents a message to create a Stack

(b) Other messages: [_stack1.push] and [_stack1.peek] and [Average.getDefinition]

(c) Message [Average.getDefinition] returns the definition of type Average

(d) The definition of Average is a CG

Figure 28: Java Invocation from Synergy

Calling Synergy from Java (code)

With Amine 6.0, it is possible to call Synergy interpreter from Java code. Here is the main steps (and Java code) to perform such a use:

1) set the static parameter "loadSynergyOntology" of Ontology to true

      Ontology.loadSynergyOntology = true;

2) Load the ontology to work with and locate its main lexicon. For instance:

      String ontologyFilePath = ...;

      Ontology ontology = Ontology.loadOntologyFromXML(ontologyFilePath, CG.cgCSDescr);

      Lexicon lexicon = ontology.getMainLexicon();

3) Create a Synergy interpreter

    Interpreter interpreter = new Interpreter(lexicon);

4) Construct the CG that represents the query/request. For instance:

      CG.setFunctionalCG(false);

      CG request = CG.parseLF("[Int = 34]-in1->[Add]- \n" +

                                                "<-in2-[Int = 5],\n" +

                                                "-out->[Int $1]", lexicon);

5) If dynamic programming is allowed (i.e. dynamic join of situation is possible), set the parameter canJoinSituation to true. For instance:

      interpreter.setCanJoinSituation(true);

6) Initiate the execution of the request:

      interpreter.execute(request);

6) The result of the activation/execution will be in the request itself, since the request is transformed as the activation/execution proceed.

 

As a complete example, here is the code of a Java class that calls Synergy interpreter for the execution of a query/request:

import aminePlatform.engines.synergy.interpreter.*;

import aminePlatform.guis.util.*;

import aminePlatform.kernel.lexicons.*;

import aminePlatform.kernel.ontology.Ontology;

import aminePlatform.util.*;

import aminePlatform.util.cg.*;

public class SynergyFromJava {

  public SynergyFromJava() {

  }

  public static void main(String[] args) {

    SynergyFromJava synergyFromJava = new SynergyFromJava();

    synergyFromJava.resolve();

  }

// We present here an example of a call of Prolog+CG from a Java class.

// The basic steps are illustrated.

  void resolve() {

    try {

      // The File Path of the Ontology to use in this example.

      String ontologyFilePath = AmineFrame.ontologyDirPath +

                                System.getProperty("file.separator") +

                                "synergyOntology" + System.getProperty("file.separator") +

                                "ontology1.xml";

      // load an ontology

      Ontology.loadSynergyOntology = true;

      Ontology ontology = Ontology.loadOntologyFromXML(ontologyFilePath, CG.cgCSDescr);

      Lexicon lexicon = ontology.getMainLexicon();

      // Create an instance of Synergy Interpreter

      Interpreter interpreter = new Interpreter(lexicon);

      // Construct the request

      CG.setFunctionalCG(false);

      CG request = CG.parseLF("[Int = 34]-in1->[Add]- \n" +

                                                "<-in2-[Int = 5],\n" +

                                                "-out->[Int $1]", lexicon);

      // Activate the interpreter: execute the request

      interpreter.setCanJoinSituation(true);

      interpreter.execute(request);

      // print the result of the execution

      System.out.println(AmineObjects.toString(request, lexicon));

    }

    catch (Exception ex) {

        System.out.println("Problem during the call of Synergy from Java : " + ex.getMessage());

    }

  }

}

The execution of this class produces the following result:

[Add #0] -

    -Out->[Int = 39],

    <-In2-[Int = 5],

    <-In1-[Int = 34]

 

Calling Synergy from other components of Amine

For an example of calling Synergy from other components of Amine, See DeductiveInference.

 

Dynamic Programming in Synergy

To illustrate what we mean by “dynamic programming”, let us start with the idea of database inference proposed by Sowa [18, p. 312] that combines the user’s query with background information about the database to compute the answer. Background information is represented as type definitions and schemata (represented as situations in Amine). Sowa stressed the need for an inference engine to determine what virtual relations to access. By joining schemata and doing type expansions, the inference engine expands the query graph to a working graph (WG) that incorporates additional background information. Actors bound to the schemata determine which database relations to access and which functions and procedures to execute. According to Sowa, his inference engine can support a dynamic way of deriving dataflow graphs [18, p. 312]. In other words, his inference engine can be considered as a basis for a dynamic programming approach (recall that dataflow graphs, Petri Nets, executable CG and other similar notations have been used to develop visual programming languages). Indeed, his inference engine is not restricted to database, it can be extended to other domains and be considered as an approach to dynamic programming.

Our task was to adapt, generalize and integrate the inference engine of Sowa to Synergy. The new version of Synergy includes the result of this integration. Figure 43 illustrates the implementation of Sowa’s example in Synergy. Background information (procedural knowledge in terms of strategies, methods, procedures, functions, tasks, etc.) is stored in ontology as situations associated to concept types (Figure 43.a). During the interpretation/execution of the working graph (WG) (Figure 43), if a concept needs a value that can not be computed from the actual content of the WG (Figure 43.b), then Synergy looks, in the ontology, for the best situation that can compute the value (i.e. the descriptor) of the concept. The situation is then joined to the WG (Figure 43.c) and Synergy resumes its execution. In this way, the program (i.e. the WG) is dynamically composed during its execution (Figure 43).

           

                                           (a) Snapshot of the ontology                                                (b) The request: initial state of the WG

       

                              (c) WG after first maximalJoin                        (d) WG after second maximalJoin and termination of execution

Figure 43: Example of Dynamic programming with Synergy (adapted from Sowa [18])

 

Remark: This simple example illustrates the advantage of Amine as an Integrated Development Environment (IDE); it illustrates how various components of Amine (ontology, CG operations, Prolog+CG, Synergy) can be easily used in one application: semantic analysis of the request can be done by a Prolog+CG program. The result (an executable CG), will be provided to Synergy which illustrates the visual execution of the “dynamic program”. After the termination of the execution, the final CG will be an input for a text generation program (that can be implemented in Prolog+CG) to provide a text that paraphrases the composed “program” responsible for the result.

 

Remarks on the implementation of the above example:

Figure 43 is based on an old implementation that makes use of a Java class "DB1.java" which simulates the access to a database. Also, DB1 Java class was placed at the same level as the directory of aminePlatform (that explains the direct call in Synergy program like "DB1.DtBirth" (Figure 43)). In the current version of Amine (version 4), we have created a directory "synargy_dynamic_programming" inside Amine Platform; in directory "applications" (i.e. aminePlatform/applications/synargy_dynamic_programming) that supports two implementations of the example:

·        an implementation that simulates the access to a database: this is supported by the Java class "DBMethods_Simulation.java".

·        an implementation that performs a real access to an Access database: this is supported by two Java classes:  "Connect2DB.java" and "DBMethods.java".

To run the first implementation (using Synergy GUI), user has to follow these steps: a) select/activate menuItem Ontology/Load First Synergy Ontology, b) select/activate menuItem Ontology/Load to load the ontology "ontologyDBSimulation.xml" located in directory "samples/ontology/synergyOntology/" (situations associated to Age and Hire in this ontology refeer to the Java class DBMethods_Simulation"), c) open Synergy file "sim_dynamicDB.lnf" located in directory "samples/synergy/", d) select/activate menuItem Parameters/canJoinSituation, e) initiate the execution/activation of the CG by a left click on button "initiate first step". Recall that once you load an ontology, you can display it by selection/activation of the menuItem (from the menu bar of Synergy GUI) Ontology/Run LexiconsOntology GUI.

To run the second implementation, user has to follow similar steps: a) select/activate menuItem Ontology/Load First Synergy Ontology, b) select/activate menuItem Ontology/Load to load the ontology "ontologyDB.xml" located in directory "samples/ontology/synergyOntology/" (situations associated to Age and Hire in this ontology refeer to the Java class DBMethods"), c) open Synergy file "dynamicDB.lnf" located in directory "samples/synergy/", d) select/activate menuItem Parameters/canJoinSituation, e) initiate the execution/activation of the CG by a left click on button "initiate first step". The Access database used in this example is "bd1" which is located in "aminePlatform/db_synergy/". Note that in this second implementation, the working graph contains not only the request but also a Java message to enable the connection to the DB "db1" (Figure 44.a). Of course, instead of using an Access database, user can use any other type of DB (like mySQL DB for instance). Some change to the Java class "Connect2DB.java" (located in aminePlatform/applications/synargy_dynamic_programming) may be required however.

Figure 44 shows some snapshots of the execution of this second implementation. Figure 44.a shows the need to call first the static method "connect2DB" of the class DBMethods in order to establish the connection with the DB "db1". The signature of connect2DB is:   void connect2D(String driver, String url, String login, String password).

(a) initial state of the working graph (wg) : wg corresponds to the request (and the call to the method connect2DB)

(b) wg after the first maximal join (join of a situation associated to Age)

(c) wg after the second maximal join (join of a situation associated to Hire)

(d) wg after the end of the execution/activation (the value of Age is computed)

Figure 44: Execution of the second implementation (effective access to a specific Database)

 

Synergy GUI

See Synergy GUI for a description of Synergy GUI.

 

Synergy vs CharGer: A brief comparison

CharGer is primarily a graphical CG editor. Related to Synergy, CharGer offers the following points (see the manual of CharGer for more detail):

·        Activation of some built-in actors, including several primitive ones for arithmetic and elementary operations, with an optional “animation” to show their operation.

·        Activation mechanism/mode in CharGer concerns checking functional dependency of the specified CG.

·        Database access through actors, although restricted to tab-separated text file “databases” at present.

·        User-written (in Java) actor plug-ins with a published plug-in interface.

Synergy offers basically the same built-in actors, also with an optional "animation" to show their operation. Checking functional dependency is a new procedure offered by Synergy (since Amine 6.0). Synergy offers Database access through the use of "calling of Java objects and methods from Synergy" and the use of JDBC. And again with the possibility to call/use/execute Java objects and methods from Synergy, Synergy provides a feature that is equivalent to "User-written actor plug-ins".

However and as this document illustrates, concerning "Executable CG"; Synergy provides much more constructs and features than CharGer (control built-in relations that enable the expression of sequence, condition and iteration, the use of defined types, recursion, dynamic programming, etc.).

In conclusion: as two CG tools for "executable CG", CharGer corresponds to a small subset of Synergy.

 

Interoperability between Synergy and CharGer

With the integration of standard CGIF notation in Amine, since Amine 6.0, it is now possible for Amine to read (to open) CGs that are created by CharGer. Moreover, most of them can be activated/executed by Synergy. This "semantic interoperability" is accomplished by two things:

·        A mapping between "CG with actors" (adopted by CharGer) and "Amine CG with activable concepts".

·        A mapping between CharGer actors identifiers and identifiers of Synergy primitive operations. In fact, CharGer actors identifiers are added in Amine as synonyms for identifiers of Synergy primitive operations. For instance "plus as synonym of Add", "minus as synonym of Sub", "multiply as synonym of Mul", etc. Also and in order to guaranty that CGs (that represent arithmetic expressions) created by Synergy can be opened and activated by CharGer, we made CharGer identifiers for arithmetic operations as the principal identifiers, i.e. concept/actor for addition will be expressed with [plus] instead of [Add].

However and since CharGer is equivalent to a subset of Synergy (concerning "Executable CG"), some CGs with Amine/Synergy features cannot be activated by CharGer (CGs that contains control relations, or that contains defined concept types, etc.).

Thus, interoperability between CharGer and Amine is accomplished through the adoption, by the two CG tools, of Standard CGIF notation. Note however that CharGer 3.6 is able to store a CG according to the CGIF notation but it is disable to read a CG written in Standard CGIF notation. See CG for some examples of interoperability between CharGer and Amine. Here is another example: Figure 45.a shows CharGer diagram notation of a CG with actors, and Figure 45.b shows Amine diagram notation of the same CG, produced by reading the Standard CGIF notation produced by CharGer, and then calling automatic drawing procedure and display functionalities to display the CG. Note the formulation in Amine/Synergy of actors in terms of concepts.

             

                                                                        (a) CharGer diagram CG notation      

                                            

(b) Amine diagram CG notation of the same CG

Figure 45: Mapping a CG from CharGer diagram formulation to Amine diagram formulation, through the use of Standard CGIF notation

 

Implementation Issues

Here is the packages and classes in Amine that concern SYNERGY and SYNERGY GUI. Like PROLOG+CG, SYNERGY is implemented as a package, called synergy with the full path aminePlatform.engines.synergy. It contains three sub-packages: bindingContext package that contains the class SynergyBindingContext which implements the binding context for SYNERGY, interpreter package that contains the class Interpreter which implements the interpreter of the language, and util package that contains two classes: ActivationRecord and AssignmentRecord, the two implement specific structures used by the interpreter. To each active context (CG), Synergy interpreter associates an ActivationRecord. This (composed) object contains an attribute, called binding, which stores the binding of each variable encountered in the active context. getValue() and setValue() methods, that are implemented by SynergyBindingContext make access to the attribute binding (which is a HashMap).

Please note that a new class (PrimitiveTypes) has been added to the package aminePlatform.kernel.ontology. PrimitiveTypes contains a HashMap that records primitive concept types (like Integer, Double, Boolean, String, Add, Div, Mul, etc.) and relation types (like in, out, grd and next). SYNERGY interpreter looks in this HashMap to check if the concept type or the relation type is a primitive.

SYNERGY GUI is implemented by the package synergyGUI with the full path aminePlatform.guis.synergyGUI.

"Synergy Ontology" is a "built-in ontology" that can be constructed if required by the user (by the activation of the menu action "Load First Synergy Ontology") and merged to any other ontology

Synergy Interpreter. The top level method of Synergy Interpreter, called activate(), corresponds basically to a loop (like any interpreter !) that is executed until there is no more activity in the Working Memory (or workSpace context) which is the first active context. The body of the main loop reflects the composition of the concept lifecycle (this is expected since the interpreter simulates a parallel interpretation of concepts lifecycle): the first part of the loop concerns the "left" part of the concept lifecycle and the second part of the loop concerns the "right" side of the concept lifecycle, the "in-activation" state represents the middle ! (Figure 4). We provide the code of the top level method of Synergy Interpreter:

public boolean activate(byte displayMode) {
  if (workSpace == null || workSpaceContent == null)
    return false;
  boolean doAStep = true;
  Concept concept;
  // if there is an active context that has still some concepts at state "Trigger" ,
  // "on_execution" or "check Preconditions", then loop again

  while ( redoLoop(workSpaceContent) && doAStep) {
    /************************ FIRST PART OF THE INTERPRETER *****************/
    // STEP 1.1 : for every active context, interpret every concept with state `trigger'
    // Step 1.1.1 : for every active context, locate every concept with state `trigger'
    // and put them in the list triggeredConcepts of the current active context

    ActivationRecord activRecord; // Recall: an activation record contains information
        // for the activation/interpretation of a context (= a concept with a CG as descriptor).
        // Often, we will use the expression "active context" to refer to the CG of the context
        // managed by the activation record.

    for (Iterator e = activationRecords.iterator(); e.hasNext(); ) {
        activRecord = (ActivationRecord) e.next();
        activRecord.triggeredConcepts.clear();
        for (Enumeration e1 = ((CG) activRecord.context.getDescriptor()).getConcepts();
                                                                        e1.hasMoreElements(); ) {
            concept = (Concept) e1.nextElement();
            if(concept.getState() == TRIGGER || isEffectiveStateTrigger(concept, activRecord))
                activRecord.triggeredConcepts.add(concept);
        }
    }

    // Step 1.1.2 : for every active context, for every concept in trigger state
    // (or in a state equivalent to trigger), interpret the concept according to its state

    for (Iterator e1 = activationRecords.iterator();e1.hasNext(); ) {
        activRecord = (ActivationRecord) e1.next();
        for (Iterator e2 = activRecord.triggeredConcepts.iterator();e2.hasNext(); ) {
            concept = (Concept) e2.next();
            interpretStateTrigger(concept, activRecord);
        }
    }
    // Step 1.2: for every active context, interpret all concepts in the active context
    // that are in state CHECK_PRECONDITIONS

    for (Iterator e2 = activationRecords.iterator(); e2.hasNext(); ) {
        activRecord = (ActivationRecord) e2.next();
        for (Enumeration e3 = ((CG) activRecord.context.getDescriptor()).getConcepts();
                                                                            e3.hasMoreElements(); ) {
            concept = (Concept) e3.nextElement();
            if (concept.getState() == CHECK_PRECONDITIONS)
                interpretStateCheckPreCd(concept, activRecord);
        }
    }

    // Due to the interpreation of the states TRIGGER and CHECK_PRECONDITIONS,
    // some concepts can start their activation and become in state IN_ACTIVATION.
    // Consult methods interpretStateTrigger() and interpretStateCheckPreCd()
    // for the detail of these steps.
    /************************ END FIRST PART OF THE INTERPRETER *************/

    /************************ SECOND PART OF THE INTERPRETER ****************/

    // Step 2.1: Check the end of activation of primitives concepts and
    // of active contexts

    terminationOfActivePrimitives();
    terminationOfActiveContexts();

    // Step 2.2: for every active context, interpret all concepts in the current
    // active context that are in the state WAIT_ASSIGNMENT.

    for (Iterator e3 = activationRecords.iterator(); e3.hasNext(); ) {
        activRecord = (ActivationRecord) e3.next();
        for (Enumeration e32 = ((CG) activRecord.context.getDescriptor()).getConcepts();
                                                                        e32.hasMoreElements(); ) {
            concept = (Concept) e32.nextElement();
            if (concept.getState() == WAIT_ASSIGNMENT)
                interpretStateWaitForAssignment(concept, activRecord);
        }
    }

    // Step 2.3: Manage the assignments that should be done in this cycle
    manageAssignments();
    // decremente the synergy time unit for all active primitives
    PrimitiveActivationRecord primActRecord ;
    for (Iterator e4 = activePrimitives.values().iterator();e4.hasNext(); ){
        primActRecord = (PrimitiveActivationRecord) e4.next();
        --(primActRecord.synergyTimeUnit);
    }

    // Step 2.4: Move all the new active contexts to the main active context list
    for (Iterator e5 = newActivationRecords.iterator(); e5.hasNext(); ) {
        ActivationRecord E1=(ActivationRecord) e5.next();
        activationRecords.add(E1);
    }
    newActivationRecords.clear();
    // Visual information
    if (displayMode == B_DSPLY_WT_DELAY) {
        updateConcDrawing(workSpace);
        try {
            Thread.sleep(1000);
        }
        catch (Exception ex){}
    }
    else if (displayMode == B_DSPLY_WTT_DELAY) {
        updateConcDrawing(workSpace);
        doAStep = (!step);

    }
  }
  if (redoLoop(workSpaceContent))
    return true;
  else return false;
}
 

For more detail, consult the source code of the class Interpreter.

 

Limitations

In this current implementation of the Core of Synergy, the set of primitive operations is small. Of course, it can be extended as desired and like Prolog+CG, this Core provides an easy interface with Java. Also, some semantic rules and constraints (that determine the interpreter of the language) may be modified. For instance, forward propagation through guard relation (grd) is currently performed when the condition (the source of the relation) is true. This means that activation and satisfaction of a condition can trigger operations that depend on this condition. If this possibility does not satisfy requirements of a specific domain, it can be removed. Another example: the instantiation of a type definition includes an initialization step where the state of parameters is initialized to "trigger". In previous implementations we adopted a more elaborate option: the state of parameters was initialized to the initial state of the corresponding arguments. With this option, it was possible to implement both strict and lazy evaluation strategies (currently, only strict evaluation is considered).

Next releases will provide the other aspects of Synergy: a) extension of the Core with the treatment of compound coreferences, b) integration of Object Oriented SYNERGY, and c) integration of Concurrent Object Oriented SYNERGY

 

References

1.        Bos C., B. Botella, and P. Vanheeghe, Modeling and Simulating Human Behaviors with Conceptual Graphs, in Proc. Of the Fifth International Conference on Conceptual Structures, ICCS’97, Springer (1997)

2.        Brauer W., W. Reisig and G. Rozenberg (eds.), Petri Nets: Applications and Relationships to Other Models of Concurrency, Springer-Verlag (1986)

3.        Cyre W. R., Executing Conceptual Graphs, in Proc. Of the 6th International Conference on Conceptual Structures, ICCS’98, Springer (1998)

4.        Ellis G., Object-Oriented Conceptual Graphs, in Proc. of the Third Intern. Conf. on Conceptual Structures, ICCS'95, Santa Cruz, CA, USA (1995)

5.        Esch J., Contexts, Canons and Coreferent Types, Proc. Second International Conference on Conceptual Structures, ICCS’94, College Park, Maryland (1994)

6.        Hee K. M., P. M. P. Rambags and P. A. C. Verkoulen, Specification and Simulation with ExSpect, in Lauer (Ed), Functional Programming, Concurrency, Simulation and Automated Reasoning, Springer-Verlag (1993)

7.        Kabbaj A. and C. Frasson, Dynamic CG: Toward a General Model of Computation, Proc. Third  International Conference on Conceptual Structures, ICCS’95, Santa Cruz, CA (1995)

8.        Kabbaj A., Un système multi-paradigme pour la manipulation des connaissances utilisant la théorie des graphes conceptuels, Ph.D Thesis, DIRO, Université de Montréal, June (1996)

9.        Kabbaj A., Rouane K. and Frasson C., The use of a semantic network activation language in an ITS project, Third International Conference on Intelligent Tutoring Systems, ITS’96, Springer-Verlag (1996)

10.     Kabbaj A., Synergy as an Hybrid Object-Oriented Conceptual Graph Language, Seventh International Conference on Conceptual Structures, ICCS’99  this volume.

11.     Lakos C., From Coloured Petri Nets to Object Petri Nets, in Michelis G. and M. Diaz (Eds.), Application and Theory of Petri Nets, Springer  (1995)

12.     Liddle S. W., D. W. Embley and S. N. Woodfield, A Seamless Model for Object-Oriented System development, Bertino E. and S. Urban (Eds.), Object-Oriented Methodologies and Systems, Springer-Verlag (1994)

13.     Lukose D., Executable conceptual structures, Proc. First  International Conference on Conceptual Structures, ICCS’93, Quebec City, Canada  (1993)

14.     Lukose D., Complex Modelling Constructs in MODEL-ECS, in Proc. Of the Fifth International Conference on Conceptual Structures, ICCS’97, Springer (1997)

15.     Mineau G. W., From Actors to Processes : The Representation of Dynamic Knowledge Using Conceptual Graphs, in Proc. Of the 6th International Conference on Conceptual Structures, ICCS’98, Springer (1998)

16.     Raban and Delugach, Animating Conceptual Graphs, in Proc. Of the Fifth International Conference on Conceptual Structures, ICCS’97, Springer (1997)

17.     Shlaer S. and S. J. Mellor, Object Lifecycles - Modeling the World in States, Prentice-Hall (1992)

18.     Sowa J. F., Conceptual Structures : Information Processing in Mind and Machine, Addison-Wesley (1984)

19.     Sowa J. F., Relating Diagrams to Logic, Proc. First International Conference on Conceptual Structures, ICCS’93, Quebec City, Canada (1993a)

20.     Sowa J. F., Logical foundations for representing object-oriented systems, J. of Experimental and Theoretical AI, 5 (1993b)

21.     Sowa J. F., Conceptual Graph Standard and Extensions, in Proc. Of the 6th International Conference on Conceptual Structures, ICCS’98, Springer (1998)

22.     Spinner M. P., Improving Project Management Skills and Techniques, Prentice-Hall (1989)

23.     Thakkar S. S. (ed.), Selected Reprints on Dataflow and Reduction Architectures, IEEE Computer Society Press (1987)

24.     Törn A., Systems Modelling and Analysis Using Simulation Nets, in C. A. Kulikowski and al. (eds.), AI and ES Languages in Modelling and Simulation, North-Holland (1988)

25.     Zouaq A., Modélisation en Synergy d’un système multi-agents, Mémoire de fin d’étude, INSEA, Rabat, Morocco (1998)

 

Kabbaj A., Un système multi-paradigme pour la manipulation des connaissances utilisant la théorie des graphes conceptuels, Ph.D Thesis, DIRO, U. de Montréal, Juin, 1996.

A. Kabbaj, Contexts, Canons and Coreferences as a basis of a multi-paradigm language, submitted to the Fifth International Conference on Conceptual Structures (ICCS’97),

A. Kabbaj, SYNERGY as a concurrent object oriented language, submitted to the Fifth International Conference on Conceptual Structures (ICCS’97),

A. Kabbaj, Synergy : A Conceptual Graph Activation-Based Language, in the 7th International Conference on Conceptual Structures (ICCS’99), Springer-Verlag, 1999.

A. Kabbaj, Synergy as an Hybrid Object-Oriented Conceptual Graph Language, in the 7th International Conference on Conceptual Structures (ICCS’99), Springer-Verlag, 1999.

A. Kabbaj, Development of Intelligent Systems and Multi-Agents Systems with Amine Platform, in 15th Int. Conf. on Conceptual Structures, ICCS'2006, Springer-Verlag, 2006.