For the final section of this tutorial, I am going to say a little more about functions.
An important thing about functions, that doesn’t really apply in the case of predicates, is that when you apply functions to arguments, they don’t give you something that is true or false like a sentence, they give you a term that denotes something. It would be useful to be able to say what kind of thing a given function returns when you apply it to appropriate arguments. We have ways of doing that in CycL.
#$MotherFn, that we’ve seen, always returns a female animal. So, if I apply the #$MotherFn function to any appropriate argument, the resulting NAT (non-atomic term) would denote somebody’s mother, some female animal. We can specify that to help define the meaning of that function.
#$TransportViaFn always returns some collection of transportation events, so we also want to have a way to be able to say that a certain function returns a collection of a certain type. So how do we do that in CycL?
There are two ways of doing that.
First is with a predicate called #$resultIsa. #$resultIsa is a predicate that relates a function to a type of thing that the result of a function must be an instance of (by “type of thing” we mean a collection of things).
Second is $#resultGenl. This relates a function to at type of thing (a collection, again) such that the result of the function must be a specialization of this collection. So this predicate will apply to functions that denote collections, because only collections are specializations of other collections.
Look at the first example. We see that the “result is a” for #$GovernmentFn is #$RegionalGovernment. That tells us that the #$GovernmentFn function always returns an instance of #$RegionalGovernment. So, if you look below, if you form a term by applying the #$GovernmentFn function to Sweden, we know that will return a regional government. In other words, that NAT denotes something that is an instance of #$RegionalGovernment.
Similarly, if I apply the #$GovernmentFn function to #$CityOfAustinTX, again, that is an instance of #$RegionalGovernment. It has to be, by the definition of #$GovernmentFn in terms of its #$resultIsa.
Let’s look at another example where #$resultIsa and #$resultGenl are both applied to #$TransportViaFn. We’re told that the function always returns an instance of #$Collection and we’re also told that it always returns a specialization of #$TransportationEvent. In other words, whenever you apply it to an appropriate argument, #$TransportViaFn gives you back some collection of transportation events.
So, if I apply #$TransportViaFn to #$Automobile, the result there is an instance of #$Collection, and is a specialization of #$TransportationEvent. As you can probably figure out by the names of the terms, the specific thing that this usage of the function would return is the collection of all transportation events in which an automobile is the transporter.
There are certain things that can be inferred from the #$resultGenl statement regarding particular functions. One type of inference which you can draw has to do with what we call the “transitivity of #$genls,” which you’ve probably already read about in previous lessons. Just to review, by saying that #$genls is transitive, all we mean is that, for example, if the collection #$Dog generalizes to the collection #$Mammal and the collection #$Mammal generalizes to the collection #$Animal, then we can infer that the collection #$Dog generalizes to the collection #$Animal.
That fact, the transitivity of genls, can be used in conjunction with, say, a #$resultGenl assertion, to infer something from the two given statements. So, for example, since I know that the #$TransportViaFn #$resultGenls to #$TransportationEvent, and I know that #$TransportationEvent, itself, genls to #$Event, I can conclude what’s stated there at the bottom of the slide: if you apply #$TransportViaFn to #$Automobile, then that result will generalize to #$Event.
There’s something called the “transfer of #$isa through #$genls.” Here’s an example. If I know that Lassie is a dog, and that #$Dog generalizes to #$Mammal, I can infer that Lassie is a mammal.
This kind of reasoning can be used in conjunction with #$resultIsa. For example, since I know that the result of #$GovernmentFn is always an instance of #$RegionalGovernment, and #$RegionalGovernment generalizes to #$Organization, I can infer that when you apply #$GovernmentFn to an argument, such as Sweden, that the result is an instance of #$Organization.
Let’s look at a few examples of the use of particular functions that you haven’t seen yet, and determine if the uses are well-formed or not. We have the definition of a function called #$BodyPartFn. Now let’s see what that means. We’re told that it is a binary function, that its first argument must be an #$Animal, that its second argument must an #$AnimalBodyPartType, and also the second argument must be a #$UniqueAnatomicalBodyPartType. Together, this tells us that the second argument must be a type of animal body part that is such that a given animal only has one such part. So “leg” would not meet both of those conditions because animals that have legs have more than one. “Tail” or “head” would work, because animals that have tails or head have only one, making them unique body part types.
We’re also told that #$BodyPartFn takes, as its second argument, something that generalizes to #$AnimalBodyPart. It should be obvious already that it would have to do that. Finally, we’re told that the result of #$BodyPartFn is always an instance of #$AnimalBodyPart.
So this function takes a unique animal body part type, in other words, a collection of animal body parts of a certain type, and it gives you back a specific animal body part. In particular, what gives you back is the specific animal body part of the animal in question that is serving as the first argument.
Let’s look at these examples and see how it all plays out. In the first example, in the lower part of the slide, #$BodyPartFn is applied to #$SubaruCar and #$Fender. Now, is that well-formed? Well, arity is okay, it’s a binary function that’s applied to two arguments. What about argument type? The first argument is supposed to be an animal and #$SubaruCar is not an animal (in fact, it’s a collection of cars), so that violates the argument type constraints and it’s not semantically well-formed. In other words, it doesn’t make sense to ask what that NAT denotes. Because it is not semantically well-formed, it doesn't have a well-defined meaning at all; it’s essentially meaningless and should not ever be used.
Look at the second example NAT. Arity, again, is fine. The first argument is #$GoldenRetriever. Let’s see. The first argument of #$BodyPartFn is supposed to be an instance of #$Animal. #$GoldenRetriever, as you could probably guess by the way Cyc constants are named, denotes a collection, not an individual. It’s not the name of some specific golden retriever, it denotes the collection of all golden retrievers. The collection of all golden retrievers is not an instance of #$Animal, so that violated the arg type constraint for the first argument place. So that’s not well-formed, either.
Now we go down to the third example NAT. Right away you can see that arity is violated because it only has one argument. So that’s not good, either.
Look at the last example. Now have something that meets all of the specifications. The function applies to two arguments, so arity is fine. Note that the first argument, #$Rover, as you can surmise from the name, #$Rover is the name of a particular dog (it’s not a collection), so #$Rover is an instance of #$Animal. So that meets the constraints on the type for the first argument. And #$Tail, as we’ve already seen, meets the argument constraints for the second argument. So that NAT is the only one of the four that is well-formed. That NAT, as a whole, denotes Rover’s tail.
Let’s take an example of a function that you haven’t seen yet. This is called #$InstructionsFn-Making. Now let’s study its definition. It’s a unary function. Its first argument is an existing object type. Its first argument generalizes to an artifact. So, together, those two two statements tell us that the first argument to a function should be a type of artifact, or a collection of artifacts. The result of the function is an #$ObjectType and the result generalizes to an #$Instructions, so that tells us that what it returns is a type of instruction, or a collection of instructions. To be a little more specific about it (more than what this tells you here), when you apply this function to a type of artifact, what it returns is the collection of instructions for making artifacts of that type. So, for example, if I applied the function to #$Cabinet (which is the collection of all cabinets) what it should return is the collection of all instructions for making cabinets.
With that in mind, look at the examples at the bottom of the slide.
In the first example NAT, you’ll see that the function is being applied to two arguments, but #$InstructionFn-Making is a unary function, so arity is violated. That is not syntactically well-formed, so we can reject that.
Look at the second NAT. Here the function is applied to one argument, so arity is obeyed. Now let’s see about the type of argument. Think of #$RadioReceiver as the collection of all radio receivers. That is a type of object, or an existing object type, so that’s fine. Now, does #$RadioReceiver generalize to #$Artifact? Yes, radios are artifacts -- they are artificial things, or man-made things. So, #$RadioReceiver is a specialization of #$Artifact-Generic, so that’s fine as well. It meets the argument type constraints as well,so that is semantically well-formed as well as being syntactically well-formed. So that is a legitimate NAT and the NAT as a whole would denote the collection of all instructions for making radio receivers.
Look at the third NAT now. The arity is okay. What about argument type? Is #$Mud an existing object type? I don’t think it is. And even more definitely, it’s certainly not a type of artifact because mud is not, essentially, a man-made thing. Of course, a person can take some dirt and water and mix them together and make mud, so you can create mud; but as a collection, as a whole, mud is not a type of artifact, because most mud occurs naturally. So that violates the argument type constraints, making it not semantically well-formed.
Finally, the last NAT there applies the function to #$SetOrCollection. Arity is okay. I’m not sure that #$SetOrCollection is an existing object type, but I am sure that #$SetOrCollection is not a spec, or a specialization of #$Artifact-Generic because sets or collections are abstract mathematical sorts of entities which are not man-made artifacts (like chairs or radio receivers). So that violates arg type constraints as well, making the last example not semantically well-formed either.
There is a key distinction among functions that we have already addressed indirectly, but let me point it out specifically now. Some functions always return individuals, as opposed to collections. Like the #$MotherFn function, you apply it to any argument and you get back somebody’s mother, which is an individual. The #$BorderBetweenFn function takes two geographical regions and, if they do border each other, it would give you back the border (the geographical line that separates them). Again, that’s an individual, not a collection.
On the other hand, there are some functions, including some that we’ve already seen, that always return collections, not individuals, like #$TransportViaFn. As we’ve seen, when you apply it to an appropriate argument, it always gives you back a collection of transportation events. The #$GroupFn (I think we’ve seen that as well), when you apply that to any appropriate argument, it gives you back, not a particular group, but the collection of all groups of a certain type. So, again, that always returns a collection.
Now, the names for these types of functions are, first of all, #$IndividualDenotingFunction. That is a sub-collection of #$FunctionDenotational, and it is, in particular, the collection of all functions that always return an individual for any appropriate argument. You can assert that fact in CycL with a #$resultIsa statement, where you relate it to #$individual.
When you define an individual-denoting function in the KB, you have to specify its #$resultIsa. That’s just a condition we insist upon so that there is a way to tell what kind of thing a function returns. But note that with an individual-denoting function, you must not have a #$resultGenl specification. Why is that? Well, if you think about it, #$resultGenl means that the result of the function is a specification of some collection. Now, you can only be a specialization of a collection if you are a collection. An individual-denoting function always returns an individual, and an individual is never a specialization of anything, so it wouldn’t make sense for an individual-denoting function to have a #$resultGenl specification.
Here are two more examples of individual-denoting functions that we’ve already come across: #$GovernmentFn (it takes a geographical entity like a city or country, and it gives you back the government of that city or country, and that’s an individual) and #$BirthFn. #$BirthFn is a new one to us, I think. If you apply the #$BirthFn function to any animal, you get back the event, the particular event, in which that animal was born. That event is an individual, not a collection, so, again, these are individual-denoting functions.
Now, the other sort are called collection-denoting functions. These are all functions such that the result is always a collection of things, not an individual.. Now, collection-denoting functions, like all functions, has to have a #$resultIsa specification.
And a collection-denoting function may also have a #$resultGenl specification. Because of the fact that it always returns a collection, it does make sense to have a #$resultGenl assertion about it. It’s not required. It’s okay to define a function and put it in the KB without specifying the #$resultGenl, but if you can give one, it’s better.
A couple more examples of #$CollectionDenotingFunction would be #$ResidentsFn and #$TeacherFn. #$ResidentsFn takes a geographical region and it gives you back the collection of all residents of that region. So that’s obviously a collection-denoting function.
#$TeacherFn takes an academic subject and it returns the collection of all teachers who teach that academic subject. So, again, that’s a collection-denoting function.
Sort of summing up what we’ve been talking about, as you can see, #$Function-Denotational is divided into individual-denoting functions and collection-denoting functions. Those are disjoint from each other because obviously nothing can be both. If you’re an individual-denoting function, you certainly can’t be a collection-denoting function, and vice-versa. Below those are just some of the examples we’ve just seen.
This concludes the lesson that explores more functions in CycL.