Найти все в прологе

У меня есть сотрудники:

employee(2,2,'George','Johnson','12/16/1987').
employee(4,3,'Noah','Jones','6/9/1984').
employee(5,4,'Jack','Brown','2/16/1992').
employee(6,6,'Charlie','Davis','3/28/1997').
employee(7,1,'Leo','Miller','6/6/1997').
employee(8,6,'Jacob','Wilson','2/16/1997').

Я хочу распечатать их все. Я сейчас делаю так:

run :- findall(Id, employee(Id, _, _, _, _), L), writeEmployees(L).

writeEmployees([]) :- !.
writeEmployees([Id|T]) :- employee(Id, PosId, FN, LN, Birth), 
   writeq(employee(Id, PosId, FN, LN, Birth)), nl, writeEmployees(T).

И это работает, но это не выглядит нормально, я имею в виду, что слишком много «_», и мне нужно написать строку «Id, PosId, FN, LN, Birth». Как найти сотрудника непосредственно в findall()?


person Dmitry Gashko    schedule 07.12.2019    source источник


Ответы (1)


Ничего страшного в том, что у вас есть. Да, у вас есть четыре _, но это нормально, если вас не волнует ни один из этих 4 аргументов.

Однако вы пропускаете эти аргументы, а затем просто извлекаете их позже. Если вы хотите избежать этого, вы можете написать свой findall, чтобы захватить все, что вы хотите, а затем написать этот список с помощью maplist.

run :-
    findall(employee(Id, PosId, FN, LN, Birth),
            employee(Id, PosId, FN, LN, Birth), Employees),
    writeEmployees(Employees).

writeEmployee(E) :- writeq(E), nl.
writeEmployees(Es) :- maplist(writeEmployee, Es).

В конечном счете, однако, это зависит от более широкого применения, в которое это может вписаться. Если вы управляете сотрудниками в более широком смысле, действительно эффективнее управлять ими с помощью Id, а затем получать данные только тогда, когда они вам нужны, как в настоящее время. Однако вы можете переписать текущий writeEmployees на maplist:

writeEmployee(Id) :-
    employee(Id, PosId, FN, LN, Birth), 
    writeq(employee(Id, PosId, FN, LN, Birth)), nl.

writeEmployees(EmployeeIds) :-
    maplist(writeEmployee, EmployeeIds).
person lurker    schedule 07.12.2019