/*Let's look at some operators! *An operator in Prolog is just a fancy way to define an *alternate usage of a functor (predicate name). */ %First off, we know we'll need some facts to test on: person(you). person(me). person(own_wilson). %yes, this was funny by Earl standards. %Next, let's say our current goal is to redefine the 'not' (\+) behaviour. %Basically, it'll be the exact same, but less polite. psyche(Term):- \+Term. %Try it out! %Confirm that psyche(person(someoneelse)) succeeds, while %psyche(person(you)) fails. %You can even use things like, psyche((person(me),person(frankie))). /*But, hold on a second here... *Obviously, the reason we chose 'psyche' was because it's "funny" *to be able to say, "you're totally a person... psyche!" *So, it needs to come after, but we're using it before. That's no fun! *... wait a minute... operators! */ %We can define an operator with 'op'. All 'op' does is explicitly define %alternate phrasings of specific functors, and how to resolve precedence. %Note that, when providing operators in a source file, you need to precede %with ':- '. Just think of it as being like a compiler directive. %Let's try a *bad* one first: nooot(X):- \+X. :- op(100,xf,nooot). %Notice that the 'xf' means it's a postfix expression. %That is, it expects "(goal) nooot". %Also note that, when using it, you wouldn't say "(goal), not". No comma! %So, why is it 'bad'? %First off, go try it out. Confirm that: % person(us) nooot. %actually works. You'll see that it does. %For that matter: % (person(me),person(you),person(halibut)) nooot. %also works just fine. %So then, why is it bad? %Consider we were using the original negation. What would you expect from: % \+ \+ person(me). %You'd expect it to work, right? Now try: % person(me) nooot nooot. %Doesn't work, does it? That's because it got confused over the order of %precedence. Or, more specifically, you told it that that phrasing wasn't %legal in terms of precedences. %So, what do we do? Change the priority? Obviously that won't work, %because 'nooot' will still have the same priority as 'nooot'. %Instead, we need to tell it that we're fine with chaining together with %other operators of the same precedence: :- op(100, yf, psyche). %Note that we said 'yf', instead of 'xf'. So, it's still postfix, but now %it says that: % person(me) psyche psyche. %is just fine. /*Just ignore this part. *I was playing with something. */ no(X):- write('no'),\+X,write('on'). psy(X):- write('psy'),\+X,write('ysp'). :- op(100,xf,no). :- op(100,yf,psy).