Manipulating Atoms in C++

From OpenCog
Jump to: navigation, search

Lesson: Manipulating Atoms in C++

Outline

We will use basic examples taken from here, but giving actual working code embodying these snippets

Then give an example of invoking the Pattern Matcher using C++


The link above provide detailed descriptions of all topics in this chapter.

This tutorial is a severely restricted selection from these pages. One should go back and explore those links to gain a deeper understanding of the topics introduced here.

In this lesson we will create some Atoms in Atomspace and execute the equivalent of cog-bind and cog-satisfying-set queries on the Atomspace using c++. c++ should not be used as the primary way to interact with Atomspace. These examples are given just to let a developer get started.

Making some Atoms(c++)

Choose a working directory of your choice and create a file createatoms.cc. We will use two functions atomspace::add_node and atomspace::add_link to add atoms in the atomspace. The contents of atomspace can be printed by passing it to the output stream.

 1 #include <iostream>
 2 
 3 #include <opencog/atomspace/AtomSpace.h>
 4 #include <opencog/truthvalue/AttentionValue.h>
 5 #include <opencog/truthvalue/SimpleTruthValue.h>
 6 #include <opencog/truthvalue/TruthValue.h>
 7 
 8 using namespace opencog;
 9 using namespace std;
10 
11 int main(int argc, char **argv){
12         //Instantiate the atomspace
13 	AtomSpace as;
14 
15 	//Create some atoms
16 	Handle h = as.add_node(CONCEPT_NODE, "Cat");
17 	Handle h1 = as.add_node(CONCEPT_NODE, "Human");
18 	Handle h2 = as.add_node(CONCEPT_NODE, "Animal");
19 
20 	//Create an InheritanceLink
21 	/*InheritanceLink
22 	      ConceptNode "Human"
23 	      ConceptNode "Animal"
24 	 */
25 	HandleSeq hseq = {h1, h2};
26 	Handle inheritancelink = as.add_link(INHERITANCE_LINK, hseq);
27 
28 	//Print out the contents of the atomspace
29 	cout << "Atomspace: " << endl << as << endl;

It is trivial to create more than one Atomspace instances. It is also possible to create nested Atomspaces as follows:

31 	//Create hierarchical atomspace
32 	//The child_as is more like a subclass in that it encompasses the
33 	//parent atomspace.
34 	AtomSpace child_as(&as);
35 	child_as.add_node(CONCEPT_NODE, "Puma");
36 
37 	cout << "Parent AtomSpace: " << endl << as
38 		 << "Child AtomSpace: " << endl << child_as;
39 
40 	return 0;
41 }

To compile and run this file issue the following command:

$ g++ createatoms.cc -std=c++11 -o createatoms -latomspace -latombase
$ ./createatoms

Note you may need to directly link to the path there the libraries (atomspace, atombase) exist by adding '-L/usr/local/lib/opencog'

$ g++ createatoms.cc -std=c++11 -o createatoms -L/usr/local/lib/opencog  -latomspace -latombase
$ ./createatoms

See the error handling section for more detail

Pattern Matcher

Make another file named patternmatcher.cc. In this example we will show how to perform the equivalent of cog-satisfying-set and cog-bind queries through c++.

First create some atoms: We add some color nodes to the atomspace just like we did in the scheme examples.

 1 #include <iostream>
 2 
 3 #include <opencog/atomspace/AtomSpace.h>
 4 #include <opencog/truthvalue/AttentionValue.h>
 5 #include <opencog/truthvalue/SimpleTruthValue.h>
 6 #include <opencog/truthvalue/TruthValue.h>
 7 #include <opencog/query/BindLinkAPI.h>
 8 
 9 using namespace opencog;
10 using namespace std;
11 
12 int main(int argc, char **argv){
13 	//Instantiate the atomspace
14 	AtomSpace as;
15 
16 	//Create some atoms
17 	Handle color = as.add_node(CONCEPT_NODE, "Color");
18 	Handle primarycolor = as.add_node(CONCEPT_NODE, "PrimaryColor");
19 	Handle c1 = as.add_node(CONCEPT_NODE, "100");
20 	Handle c2 = as.add_node(CONCEPT_NODE, "010");
21 	Handle c3 = as.add_node(CONCEPT_NODE, "001");
22 
23 	HandleSeq hseq = {c1, color};
24 	as.add_link(INHERITANCE_LINK, hseq);
25 
26 	hseq[0] = c2;
27 	as.add_link(INHERITANCE_LINK, hseq);
28 
29 	hseq[0] = c3;
30 	as.add_link(INHERITANCE_LINK, hseq);

Define pattern: Now we define the pattern to be grounded using a SatisfactionLink. The pattern written in a scheme-ish style is:

GetLink
 	TypedVariableLink 
 		VariableNode "$x"
 		TypeNode "ConceptNode
 	InheritanceLink
		VariableNode "$x"
		ConceptNode "Color"	

To define this pattern issue the following commands:

31 	Handle h1, h2;
32 	h1 = as.add_node(VARIABLE_NODE, "$x");
33 	h2 = as.add_node(TYPE_NODE, "ConceptNode");
34 	hseq[0] = h1;
35 	hseq[1] = h2;
36 	Handle TypedVariableLink = as.add_link(TYPED_VARIABLE_LINK, hseq);
37 	
38 	h2 = as.add_node(CONCEPT_NODE, "Color");
39 	hseq[1] = h2;
40 	Handle findpattern = as.add_link(INHERITANCE_LINK, hseq);
41 
42 	hseq[0] = TypedVariableLink;
43 	hseq[1] = findpattern;
44 	Handle SatisfactionLink = as.add_link(GET_LINK, hseq);

Ground the pattern: Now we ground the pattern using the satisfying_set function.

45 	//Run the PM to get the set of atoms that satisfy the pattern
46 	Handle colornodes = satisfying_set(&as, SatisfactionLink);
47 
48 	//Print out the query result
49 	cout << "Colors: " << endl << colornodes->toString() << endl;

Define pattern for rewrite query: Now we define a BindLink to perform a graph rewriting. The BindLink being defined is:

BindLink
 	TypedVariableLink 
 		VariableNode "$x"
 		TypeNode "ConceptNode"
 	InheritanceLink
		VariableNode "$x"
		ConceptNode "Color"
	InheritanceLink
		VariableNode "$x"
		ConceptNode "PrimaryColor"

This query will label all the colors in Atomspace as PrimaryColors. Define the BindLink as follows:

50 	h2 = as.add_node(CONCEPT_NODE, "PrimaryColor");
51 	hseq[0] = h1;
52 	hseq[1] = h2;
53 	Handle writepattern = as.add_link(INHERITANCE_LINK, hseq);
54 
55 	HandleSeq BLinkHseq = {TypedVariableLink, findpattern, writepattern};
56 	Handle BindLink = as.add_link(BIND_LINK, BLinkHseq);

Execute the rewrite query: The query defined through the BindLink can be executed using the bindlink function as follows:

57 	//Execute rewrite query
58 	colornodes = bindlink(&as, BindLink);
59 
60 	//Print the returned atoms
61 	cout << "PrimaryColors: " << endl << colornodes->toString() << endl;
62 	return 0;
63 }

The file can be compiled and run using the following commands:

$ g++ patternmatcher.cc -std=c++11 -o patternmatcher -latombase -latomspace -lquery -lexecution	
$ ./patternmatcher

Similarly to above, if it fails, then compile with a direct link to the libraries

g++ patternmatcher.cc -std=c++11 -o patternmatcher -L/usr/local/lib/opencog -latombase -latomspace -lquery -lexecution

Contact: (Misgana)

Notes

Error Handling

G++ Compile issues

Note if getting a problem compiling the code like so:

$ g++ createatoms.cc -std=c++11 -o createatoms -latomspace -latombase
/usr/bin/ld: cannot find -latomspace
/usr/bin/ld: cannot find -latombase
collect2: error: ld returned 1 exit status
  • Make sure you have installed atom space
  • Either :
  - make sure to add the library paths to gcc
  - link directly to the directory containing the libraries -L/usr/local/lib/opencog , making sure to do this before linking to the libraries like this:
$ g++ createatoms.cc -std=c++11 -o createatoms -L/usr/local/lib/opencog  -latomspace -latombase

(Thanks to Misgana)

More Path Issues

If the ./createatoms didn't work.. i.e. if it produces this error

 ./createatoms: error while loading shared libraries: libatomspace.so: cannot open shared object file: No such file or directory

Then try these commands:

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/opencog
$ sudo ldconfig

Note there is likely to be a better way to solve the path issues... will look into this later (Misgana, Adam)