<< Tutorial 1 ^^Contents Tutorial 3 >> |
Yield Prolog Tutorial |
Python |
C# |
import sys |
using System; |
import sys |
using System; |
Check if it is square:But what happens if we call squaredRectangle first, before we bind Width?
10 by 10 rectangle is square.
Make it square:
A square of width 10 has height 10.
import sys |
using System; |
Make it square before we know the width:But how can this be? When we first call squaredRectangle, Width is still unbound, so how does it know to bind Height to 10? It doesn't. Instead, it binds Width to Height while Height is still an unbound variable, in a "variable chain". Next, how can Width.unify(10) bind Width to 10, because it is already bound to Height? Again, it doesn't. Width.unify follows the variable chain to find the unbound Height variable and binds that to 10. Finally, when we want the value from Width.getValue(), this follows the variable chain to find that Height is bound to 10 and returns that.
A square of width 10 has height 10.
import sys |
using System; |
Get one match:Often, you only want to know if one solution exists, so in Prolog you can "cut" [1] out of a loop like this, which is more efficient.
Hillary has a brother Tony.
Bill has a brother Roger.
import sys |
using System; |
Use cut for negation:In Tutorial 3, we work with lists.
Chelsea has no brother.
anyBrother(Person, Brother) :-You may remember that Variable needs to unbind the values before exiting the loop. So if we just break out of the loop, how does it do this? Inside the unify function, we use a try...finally block to unbind the variable:
brother(Person, Brother), !.
if not self._isBound: |
if (!_isBound) { |
noBrother(Person) :-There are other equivalent ways to write noBrother, such as:
brother(Person, _Brother), !, fail.
noBrother(_Person).
noBrother('Hillary'), write('Hillary has no brother.'), nl.
noBrother('Chelsea'), write('Chelsea has no brother.'), nl.
noBrother1(Person) :-but the -> operator translates into the pattern shown in noBrother which makes it clear how to do an "if...then...else". Of course, you can also write:
(brother(Person, _Brother) -> fail ; true).
noBrother2(Person) :-but you can think of the \+ operator as a simple "if...then...else" where "then" fails and "else" succeeds.
\+ brother(Person, _Brother).