Как мне написать ‘findall’ в самом коде Prolog?

#prolog #prolog-findall

#пролог #prolog-findall

Вопрос:

Итак, я очень новичок в Prolog, и мне нужно написать короткий код о расписании. Как я могу добавить функцию findall в сам код?

 happening(monday,chemistry).
happening(monday,english).
happening(tuesday,chemistry).
happening(wednesday,maths).
happening(friday,chemistry).
happening(friday,maths).
  

И теперь я хочу написать команду, которая показывает, сколько раз у меня химия в неделю.

 find_lessons(X) :-
findall(X,happening(X,chemistry), Bag).
  

Ответ №1:

Я предполагаю, что вам нужен результат Bag , поэтому вы должны переписать find_lessons(X) в find_lessons(Bag) :

 find_lessons(Bag) :-
    findall(X, happening(X,chemistry), Bag).  

Затем будет выдан список дней, когда проводится урок химии, поэтому:

 ?- find_lessons(Bag).
Bag = [monday, tuesday, friday].
  

чтобы подсчитать количество уроков, вы можете использовать length/2 :

 ?- find_lessons(Bag), length(Bag, N).
Bag = [monday, tuesday, friday],
N = 3.
  

Но можно сделать это более эффективно. Прямо сейчас есть накладные расходы на построение списка и подсчет элементов. Мы можем использовать aggregate библиотеку [swi-doc] и использовать aggregate/3 предикат [swi-doc]:

 ?- aggregate(count, X^happening(X, chemistry), Total).
Total = 3.
  

таким образом, мы можем подсчитать количество уроков химии с:

 :- use_module(library(aggregate))

num_chem_lessons(N) :-
    aggregate(count, X^happening(X, chemistry), N).  

Комментарии:

1. Большое спасибо за быстрый и правильный ответ!!