Demo Prologue: Search for an apartment by catalog
In this demonstration, the apartment catalog, which shows the price, number of rooms and orientation, searches for the optimal object according to the specified criteria.
Show list of apartments
First, we put the catalog in memory and add a program that allows you to view the list of products contained in it.
app(appart1, sud, 3, 60).
app(appart2, nord, 5, 80).
app(appart3, sud, 4, 70).
app(appart4, sud, 6, 90).
app(appart5, sud, 4, 100).
app(appart6, ouest, 8, 50).
catalogue :-
write('Catalogue...\n'),
forall(app(X,O,T,P), format("Code ~a orientation ~a T~D prix ~D.000 ~n", [X, O, T, P])).
The forall prologue function is a union function. The first term is a condition, this condition collides with every "app" type predicate in memory. The second term is an action, it is performed for each instance that fills in the convention.
Since no predicate values are assigned, the condition is checked for all base predicates. If "south" were given as the second value, then the condition would be checked only for apartments with a "southern" orientation .
Therefore, to display a list of all apartments, regardless of their orientation, this condition is used without a predetermined value.
Select apartments by criteria
I would like to choose apartments with a certain orientation and the maximum set price .
If it was only about finding apartments with a certain orientation and price, it would be simple, we would use the previous catalog rule with two parameters:
catalogue(O,P) :-
write('Catalogue...\n'),
forall(app(X,O,T,P), format("Code ~a T~D ~n", [X, T])).
And a petition would be made, such as:
catalogue(sud, 70).
But we have to compare prices to the cap, and so the code will be a little more complicated.
The findall prolog function allows you to create a list of elements that meet the conditions.
findall(element, condition impliquant l'élément, liste)
The condition in our case is to have an orientation equal to the specified value O, and the price P is lower than this price PMax .
candidats(O, PMax) :-
findall(X, (app(X,O,_,P), P =< PMax), L),
write('\nCandidats au catalogue:\n'),
dispList(L).
We group in brackets app (X,O,_,P) and price comparison P = <PMax to form a condition into one parameter.
This code returns a list L of all X elements satisfying the condition. Let's see how to show this list.
Show list in Prolog
The form argument [A'B] stands for the first item in the list, followed by all other items. The rule with the L list in the parameter is called and the prologue splits this list into two parts .
It is convenient to list the contents of the list by recursion. Just replace the parameter [A'B] with B when the rule refers to itself.
dispList([A|B]) :-
(app(X,_,T,P), X = A),format('~w T~D ~D.000 euros ~n', [X, T, P]),
dispList(B).
The dispList rule recursively calls itself, each time replacing the list with a second part B that does not contain the first element. The first element A is considered in the rule.
Our rule combines element A with an application predicate, one of the values of which is this element A. The format function displays the values of the found predicate.
Find the largest apartment that meets the criteria
We are looking for apartment X with the number of rooms T. We want as many rooms as possible. Other conditions are added.
The unproven\+ operator returns true if its argument is unproven, and false if it is proven.
\+ (terme)
The point here is to get the unification of consecutive values by assigning a maximum value T.
Variables X and T are not assigned when the rule is called, unlike ORT and PMax. They are assigned each time a T2 value exceeds T in the application predicate and the other two criteria are met .
plusGrand(X, ORT, PMax) :-
app(X, _, T, _),
\+ (app(_, O, T2, P), (T2 > T, O = ORT, P =< PMax)).
The unproven formula looks for an app predicate or the O value is equal to the specified ORT value, the P value is less than or equal to the specified PMax value, and the T2 value is greater than the T value of the apartment already found.
As long as there is a T2 value above T, the formula is proven, a failure occurs, and the union continues in search of a solution.
As soon as T2 reaches the maximum value, a resolution is obtained, and you return to the call point of the rule with the assigned variables X and T. The apartment that meets the criteria has been found.
Apartment search, full demo
app(appart1, sud, 3, 60).
app(appart2, nord, 5, 80).
app(appart3, sud, 4, 70).
app(appart4, sud, 6, 90).
app(appart5, sud, 4, 100).
app(appart6, ouest, 8, 50).
catalogue :-
write('Catalogue...\n'),
forall(app(X,O,T,P), format("Code ~a orientation ~a T~D prix ~D.000 ~n", [X, O, T, P])).
dispList([]).
dispList([A|B]) :-
(app(X,_,T,P), X = A),format('~w T~D ~D.000 euros ~n', [X, T, P]),
dispList(B).
plusGrand(X, ORT, PMax) :-
app(X, _, T, _),
\+ (app(_, O, T2, P), (T2 > T, O = ORT, P =< PMax)).
meilleur(O,P) :-
plusGrand(X, O, P),
write('\nPlus grand: '),
write(X).
candidats(O, PMax) :-
findall(X, (app(X,O,_,P), P =< PMax), L),
write('\nCandidats au catalogue:\n'),
dispList(L).
recherche(O, P):-
meilleur(O, P);
write('Rien au catalogue.').
test1 :- candidats(sud, 80).
test2 :- recherche(sud, 80).
Pour utiliser ce programme, utilisez la commande consult de la console prolog. Puis tapez:
catalog.
test1.
test2.
Pour respectivement, afficher la liste de tous les appartements, la liste des appartements orientés sud et de prix inférieur à 80, enfin le plus grand parmi ceux qui respectent ces critères.
Vous pouvez aussi donner vos propres critères, comme dans cet exemple:
recherche(nord, 100).
Vous pouvez télécharger le code source.