The MRS represents variables in predicates using a several different types which really boil down to 3 (the others are generalizations of these three):
hvariables (handles): can hold “scope” or an entire branch of the predicate tree. I think of them like lambda variables in C++ or C#. They get terms in Prolog.
xvariables (instances): are just like normal First Order Logic variables. Think of them as containing a set of things in the world. Given the way Prolog executes, it is easier to think of them as a normal Prolog variable that iterates through the things in the set.
evariables (events): ahhh, events. Capturing this in a bullet is impossible.
I’m going to dedicate this whole section to event variables and events because they are rather unique.
Events in Linguistics and the ERG
I’ve written up some of the linguistics background I’ve needed to understand to build Perplexity, but I’m going to pull the part that describes “events” here and expand on it.
If you start looking at how verbs are represented in many (most?) descriptions of turning language into logic (including the ERG) you’ll run head-on into “(Neo)Davidsonian representations”. The “Davidsonian Semantics” were developed by Donald Davidson and articulated in his paper “The Logical Form of Action Sentences” (1967).
Before Davidson, you may have modelled “Brutus stabbed Caesar with a knife” as “stabbed(Brutus, Caesar)”. Seems logical (so to speak). The problem is how to deal with “brutally stabbed” or other words that are modifying the stabbing event? He proposed that verbs introduce an “event variable” that can be used and modified elsewhere like this “stabbed(e, Brutus, Caesar) & brutal(e)”. So far so good.
The “Neo” part comes from Terry Parsons’ “Events in the Semantics of English” by noticing that we have given a special place for Brutus and Caesar in this event by saying “stabbed(e, Brutus, Caesar)” why not make this more general? like this: “stabbed(e) & Agent(e, Brutus) & Target(e, Caesar) & brutal(e)”.
This type of representation solves a few problems. First, now we can ask things about e that were difficult (impossible?) to ask when it was a single predicate. “Who did it?” (Agent(e, X) -> X = Brutus) “Was it brutal?” (brutal(e) -> true), etc. Plus: we don’t have to figure out how many arguments to have in the predicate. We just keep adding predicates as long as we need to.
So, a linguistic “event” is just something that can collect information from one part of a phrase and pass it to another part of the phrase. Kind of like a generic “bag of stuff”. The ERG liberally uses events in predicates for this very reason, but instead of only adding them when they are used, they are added if they might be used. So a verb might have an event argument that used by an adverb somewhere else when there is an adverb, but the argument is still there (and ignored) if there is no adverb. This is just to keep things consistent.
Events in Prolog
I’ve represented events in Prolog simply as Prolog variables that start with
E. The values that get put in the variable are just simple Prolog atoms like
g0. New events get generated as needed with a monotonically increasing number. Think of it like a GUID.
Just like other atoms in the Perplexity ontology, event atoms can have relationships to other atoms, properties, etc. This is how any “quoted” values (described below) get stored in Perplexity: by creating an event id and setting up relationships to it.
The relationships that get set up for an event id are properties that indicate, for example, “who is doing what to whom” for an event representing a verb. An event for a verb might get built up by different predicates over the course of executing the entire Prolog expression. A preposition might build up an event that describes the “to whom” part, the verb may add the “who is doing what” part. By the time the verb’s query or task predicate gets run, all the information needs to be there.
Let’s do an example of what the event looks like for the verb “put” in the phrase “put the book on the table”. We’ll describe it using the triple format described in the Perplexity ontology). After the Prolog has finished processing the event looks like this:
"put the book on the table": Logic: pronoun_q__xhh( x3, pron__x(x3), _the_q__xhh( x17, _table_n_1__x(x17), _the_q__xhh( x8, _book_n_of__xi(x8, i14), _put_v_1__exxh( e2, x3, x8, _on_p_loc__exx(e16, x8, x17))))) % The event stored in e2 for _put_v_1__exxh: g99 instanceOf idEvent % d_put_v_1__exxh adds a property that represents the "action" that the event is doing (i.e. the verb) actionProperty propertyOf g99 actionProperty instanceOf idAction actionProperty hasValue task_put_v_1__exxh % d_put_v_1__exxh adds a property that represents the "actor" doing the event actorProperty propertyOf g99 actorProperty instanceOf idActor actorProperty hasValue idLexi % d_put_v_1__exxh adds a property that represents the "target" of the event targetProperty propertyOf g99 targetProperty instanceOf idTarget targetProperty hasValue idBook1 % d_put_v_1__exxh assumes that its scopal argument is a preposition and % add a preposition property to hold the event that % the preposition will add its data to (which is g100, defined below) prepositionProperty propertyOf g99 prepositionProperty instanceOf idLocativePrepositionEvent prepositionProperty hasValue g100 % The event stored in e16 for the _on_p_loc__exx ("on the table") g100 instanceOf idEvent % d_on_p_loc__exx adds a property to the event that represents % the "action" of the preposition (i.e. which preposition) actionProperty propertyOf g100 actionProperty instanceOf idLocativePreposition actionProperty hasValue task_on_p_loc__exx % d_on_p_loc__exx adds a property to the event that represents the left side of the preposition actionProperty propertyOf g100 actionProperty instanceOf idLocativePrepositionLeft actionProperty hasValue idBook1 % d_on_p_loc__exx adds a property to the event that represents the right side of the preposition actionProperty propertyOf g100 actionProperty instanceOf idLocativePrepositionRight actionProperty hasValue idTable1
So you can see in that example how the event that the verb uses (
g99) gets data built up from both the preposition and the verb.
Sometimes predicates need to use the information on the event to actually do something which I call “eval” or “evaluating”. Sometimes they are asked just to fill the data they describe into the event so that another predicate can do something, which I call “quote” (in the LISP sense). Why this happens is complicated and has its own section. When it does happen, the mechanism used to “quote”, or store all its data in the event, is the mechanism described above: it creates an EventID and adds a bunch of relationships that represent its information.
Storing Events in “Event Space”
One final note that is more housekeeping than anything. When a Prolog query is run, sometime it can create many millions of events like the one described above. That’s a lot of data for just one phrase. The event data isn’t used afterwards for anything at the moment, so it would just hang around and fill up memory. To solve this, data put into events is stored in its own “event space”, which is just an ID that stores triples as described in the ontology section. Then, after the phrase is done executing, the engine deletes all triples that weren’t create in the “default” (or real world) event space.
Note that I’ve had a notion to keep around the events that actually were used so that, later, if the user says “did you X?” that information could be queried to describe actions that had been taken. That isn’t part of the current prototype, however.