:-
-- directional implication. E.g., head :- body . means: if body holds then conclude head .,
(comma) or \and
(for those who don't mind typing extra) -- conjunction.;
(semi-colon) or \or
-- disjunction.'a string with $#@^% in it'
"12345"^^xsd:integer
(same as 12345), "2015-10-13"^^\date
(a date constant, same as \d"2015-10-13"
), and more -- see Data Types in Ergo)?x, ?Var1, ?ABC, ?_ABC
(if a variable starts with an "_", it is called a silent variable), ?, ?_
(the last two are called anonymous variables, as they don't have names).f(1,a,?Var)
, ?p(b(?x),?q(c,d))
-- HiLog terms; [a,b,c]
, [1,2,3|[4,5]]
, [3,?X,?Y|?Z]
-- list terms. \naf
-- negation-as-failure, a.k.a. default negation; \neg
-- explicit negation. See More Advanced Features.=
-- unifies, :=: -- logically equal; :=
-- operator used in user-defined functions; \is -- arithmetic and string expression evaluator. Most of these features are illustrated in Section More Advanced Features, but see ErgoAI Reasoner User's Manual for more details.->
or \hasvalue; =>
or \hastype
; : or \isa
-- class membership; ::
or \sub
-- subclass-of. These constructors are used in the frame syntax of Ergo, which is described later in this section and in User-defined Types and Default Values in the Frame Syntax. //
-- comments out the rest of this one line; /*… */ -- multi-line comment. min, max, count, sum, avg
. See More Advanced Features.setof , bagof
. These operators are related to aggregation and are defined in ErgoAI Reasoner User's Manual.forall, exists
(or exist
or each
or all
). See the section Quantifiers and Omniform Rules (this is a fairly advanced feature).~~>, ==>, <~~, <==, <~~>, <==>
. See the section Quantifiers and Omniform Rules.@
(used for meta-info annotation, modules) , ’
(single quote, used to enclose non-alphanumeric symbols), #, \
(backslash - used for special operators).A complete grammar is defined in the ErgoAI Reasoner User's Manual. This manual is searchable and well-indexed, so finding specific features should be easy.
The following discussion makes use of the ergo files, socrates.ergo and socrates_frames.ergo. Please download the files and load the first into ErgoAI so you can follow along.
Users can teach Ergo basic facts or provide data for the reasoning engine to work on.
Here is an example of encoding a fact in the socrates.ergo example:
Ergo facts are also called literals and have the form: predicate(arguments) or \neg predicate(arguments), where arguments is a tuple of (zero or more) arguments separated by commas. Literals can also use the frame notation described later.
Here is a rule encoded from an English sentence in the socrates.ergo example:
?X, ?name, ?person, ?_437, ?avgAge, ?patient_1
?_
or ?
is an anonymous variable, a unique variable name is created for each occurrence of such a variable anywhere. ?_Alphanumeric
is a Silent variable because it starts with an underscore. Such variables have many purposes:Queries in Ergo use the same syntax as the bodies of the rules. That is, any rule body can be used as a query. Queries can be asked either interactively or they can be embedded inside Ergo knowledge bases. In the latter case, the embedded queries will be asked automatically after the corresponding knowledge base is loaded or added.
Interactive queries
A query can be asked interactively on the command line (in a terminal window or in the Ergo Listener), or it can be asked using the Query Panel, which is accessible via the Tools menu in the listener. In addition, the ErgoAI Studio Editor allows users to pose queries by selecting text and then choosing an appropriate item from the contextual menu opened via a right click. The images below use the Query Panel method.
For example, suppose we wish to query to find out whether Socrates is mortal.
Is Socrates mortal?
We could use the fact-form literal itself as a query if we put it in the query window or in the input area of the Studio Listener:
mortal(Socrates).
With the result:
Yes.
We could also be more indirect, and instead query to find out more generally who is mortal. To do so, we can use the rule head as a query (be sure to add a period):
mortal(?X).
The result shows all instances that satisfy the rule and bind to the variable ?X:
Try adding a few more facts to socrates.ergo about mortals and reloading it to see the query in action. For example, add:
mortal(Fred).
mortal(Linda).
mortal(turtle).
Then you will see more answers to the query mortal(?X
).
Another query: man(?X).
-- who is a man?
Try formulating and running a query in Ergo for each of the following English sentences (answers at the bottom of the page):
Non-interactive (embedded) Queries
Non-interactive queries are embedded directly into files and are asked when the file is first loaded or added. These queries are not asked again if the file is re-loaded/re-added unless the file was changed since the last load/add; it if was changed, it will be re-compiled (as well as re-loaded/re-added) which triggers re-execution of the query. An example of this use of queries is shown in the file socrates_with_embedded_queries.ergo. This is a little knowledge base, similar to socrates.ergo, but we added some information about a woman Safo and included two embedded queries:
?- writeln('Query 1:')@\io, mortal(?X), age(?X,?A), ?A < 56.
?- writeln('Query 2:')@\io, man(?X), age(?X,?A), ?A < 56.
Note the symbol ?- that indicates that we are dealing with embedded queries. If one loads this file (e.g., using [socrates_with_embedded_queries].) then the following will be output to the terminal window:
Query 1:
?X = Plato
?A = 27
?X = Safo
?A = 55
?X = Xenophon
?A = 27
3 solution(s) in 0.0010 seconds
Yes
Query 2:
?X = Plato
?A = 27
?X = Xenophon
?A = 27
2 solution(s) in 0.0000 seconds
Yes
Times (in seconds): elapsed = 1.0940; pure CPU = 1.0440
Yes
Besides embedded queries there also are latent queries, which are distinguished with the symbol !- instead of ?-. A latent query is similar to embedded queries in that it appears inside a file and is never asked interactively. However, latent queries are not run automatically when their containing files are loaded or added. Instead, they are run at later times by the user via the special command query{...},
which itself can be asked interactively or embedded in a file. More information on that appears in the ErgoAI Reasoner User's Manual., section "Latent Queries."
Now open and load the socrates_frames.ergo example.
There is a special syntax for expressing several values for the same property. The second, shorter variants (in blue) expand into the longer variants (in black).
If desired, we can write a frame containing several properties of the same subject:
Structures can be nested:
We can also make statements asserting what class, or kind of thing, an object is:
We can also express subclass relationships between classes:
We can also write rules in the frame syntax, including using class and subclass. Here we show two ways to represent the same English sentence in Ergo. The second variant (in blue) both of the predicate and the frame syntax uses the {...,...} construct, which expands into the first construct in each case.
Example queries and expected answers for the socrates_frames.ergo example are shown below:
name
, phoneNum
, and children
are the attributes.Additional features of the frame syntax (user-defined types and default values) are covered in Section User-Defined Types and Default Values.
In addition to regular variables as described above, Ergo supports typed variables. Typed variables can be bound to classes, which will restrict the variables so that they will be unifiable only with members of the specified classes.
For example:
To better understand the difference between the typed variables and the regular ones, consider the following set of facts:
p(John), p(Bob), p(Tom).
p(2), p(3).
John:student, Tom:student.
Then the query p(?X). will return five answers: ?X = John, ?X = Bob, ?X = Tom, ?X = 2, and ?X = 3. In contrast, the query p(?X^^student). will return only the first and the third (John and Tom). Why? Because Bob, 2, and 3 are not students. Similarly, the query p(?X^^\integer). will return only ?X = 2, and ?X = 3 (because integers are automatically made to be members of the type \integer -- see the tutorial page Data Types in Ergo).
For information on how to specify the types of the properties and methods in a class, including Inheritable Types, see the tutorial page, Types and Defaults in the Frame Syntax.
age(?person, ?age).
home(father(father(Socrates)),?home).