OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / examples / atomspace / querylink.scm

136 lines · scm ref:
;
; querylink.scm - querying and graph re-writing example.
;
; A common task in knowledge representation systems is searching and
; querying for data, and then re-shaping the query results into a new
; form. In Atomese, querying and graph-rewriting is done with the
; QueryLink atom. The QueryLink uses "pattern matching" to find subgraphs
; in the AtomSpace that match the query, and then creates a new graph
; with those results in them.
;
; Because QueryLink performs graph re-writing, it resembles logical
; implication `P->Q`, that is an if-then statement, `IF P THEN Q`.
; However, since it can match a pattern, it is more like an
; implication with a variable in it, so: `P(x)->Q(x)`.  Since it
; searches all of the AtomSpace, it is effectively adding a "for all x"
; to the implication, so that it states `ForAll x, P(x)->Q(x)` (with
; "x" being a bound variable).  In this way, the QueryLink can represent
; a very basic form of implication or logical inference.
;
; Although QueryLink resembles implication, it is intended for query,
; not reasoning. If pure logical inference, without the query is needed,
; then RuleLink is better suited for that task. This is a practical
; recommendtation: the QueryLink performs some heavyweight and expensive
; pattern compilation, and caches the results. This makes QueryLink
; initialization fat and slow, which is OK because it pays for itself
; during the query. But if the query is never done, then QueryLik is
; merely fat and slow. Use RuleLink is you need inference without the
; query.
;
; Unlike most query languages (SQL, etc.) Atomese queries are stored
; in the AtomSpace itself, as graphs. Thus QueryLink is just another
; link type. It is stored in the AtomSpace, along with everything else.
;
; This example places some typical "semantic triple" natural-language
; style data in the AtomSpace, and then defines a query, build from
; QueryLink, to perform some "basic inference" on that data.
;
; The example data says that one can "make pottery" and that things
; are "made from clay". The resulting inference is that "pottery is
; made from clay":
;
; (UnisetValue
;     (Edge (Predicate "make_from")
;         (ListLink (Concept "pottery") (Concept "clay"))))
;
; The UnisetValue wraps the collection of results; there is only one
; result, in this case.


(use-modules (opencog))

; Place some data in the AtomSpace to work with. Its some very basic
; natural-language dependency grammar parse data.
;
; A dependency "_obj(make, pottery)" from a dependency parse of the
; sentence "Susan makes pottery": so that "make" is the verb (a
; transitive verb), and "pottery" is the object of that verb.
;
(Edge
	(Predicate "_obj")
	(ListLink
		(Concept "make")
		(Concept "pottery")))

; A prepositional dependency "from(make, clay)".  Here "from" is the
; preposition, one of a closed set of possible prepositions, stating
; that this can be made from clay. This might occur in the parse of
; "George makes sculptures from clay".
;
(Edge
	(Predicate "from")
	(ListLink
		(Concept "make")
		(Concept "clay")))

; Create a "semantic triple" by combining a verb, an object and a
; preposition. This searches the AtomSpace for a verb-object pair,
; and a verb-preposition pair, and if it finds them, creates a triple.
;
; This encodes the re-write rule:
;    IF
;         _obj(verb, thing) AND from(verb, substance)
;    THEN
;         make_from(thing, substance)
;
(define make-semantic-triple
	(QueryLink
		(VariableList   ; Variable declaration (optional)
			(Variable "$var0")
			(Variable "$var1")
			(Variable "$verb")
		)

		; The premise of the implication is wrapped by an AndLink.
		; This means that each of the clauses must be satisfied in
		; the AtomSpace. In SQL terms, this is an "inner join".
		(AndLink
			; Look for _obj($verb, $var0)
			(Edge
				(Predicate "_obj")
				(ListLink
					(Variable "$verb") ; This will match: (Concept "make")
					(Variable "$var0") ; This will match: (Concept "pottery")
				)
			)
			; Look for from($verb, $var1)
			(Edge
				(Predicate "from")
				(ListLink
					(Variable "$verb") ; This will match: (Concept "make")
					(Variable "$var1") ; This will match: (Concept "clay")
				)
			)
		)
		; Combine the two above into one.
		(Edge
			(PredicateNode "make_from")
			(ListLink
				(VariableNode "$var0")
				(VariableNode "$var1")
			)
		)
	)
)

; Run the pattern matcher. This matches both required clauses,
; and creates a set of all matching results.
(cog-execute! make-semantic-triple)

; The following should have been printed:
;
; (UnisetValue
;     (Edge (Predicate "make_from")
;         (ListLink (Concept "pottery") (Concept "clay"))))
;