2015-10-18 2 views
1

Мне нужно реализовать программу Prolog, которая принимает список, такой как [[1, a], [2, b], [1, c]] и запрашивает ключ в петле. Если пользователь вводит 1 [a, c], должен быть напечатан, и пользователю следует попросить следующий ключ, пока пользователь не войдет в «выход».Пролог читает ключи и печатает значения, соответствующие клавише

Моя текущая программа:

%Input: AssocList and Key. 
%Output: FindList which contains all Values associated with the Key in AssocList. 
as_find(AssocList, Key, FindList) :- 
    as_find(AssocList, Key, Acc, FindList). 

as_find([], Key, Acc, Acc). 
as_find([], Key, Acc, FindList) :- as_find([], Key, Acc, Acc). 
as_find([[Key,D]|R], Key, Acc, FindList) :- my_append(D, Acc, NewFindList), as_find(R, Key, NewFindList, FindList). 
as_find([[H,D]|R], Key, List, FindList) :- as_find(R, Key, List, FindList). 

%Appends Elem to the given list and returns it in the other list. 
my_append(Elem,[],[Elem]). 
my_append(Elem,[H|R],[H|Z]) :- my_append(Elem,R,Z). 

%Asks for Keys and writes all Values associated with the keys. 
as_search(List) :- 
    repeat, 
    write('Key?'), 
    read(Key), 
    as_find(List, Key, FindList), 
    write(FindList), 
    Key == 'genug', 
    !. 

К сожалению Если я использую другой ключ, чем «сделано» программка завершится в бесконечном цикле. Не могли бы вы помочь?

С уважением, Гиперион

ответ

1

Эта программа использует отказ управляемый цикл, вы начинаете программу с целью. ?-start., вам будет предложено добавить список. Вы можете изменить это, если вы хотите, чтобы список был жестко закодирован в программу, а не как пользовательский ввод. Затем мы вводим цикл, мы даем термин, например, 1., тогда система будет печатать соответствующие значения из списка и цикла. Если вы введете stop., программа завершается.

start:- 
    format("Enter list:\n",[]), 
    read(List), 
    enter(List). 

enter(List):- 
    format("Enter key or stop:\n",[]), 
    read(X), 
    test(X,List). 

test(stop,_):-!. 
test(X,List):- 
    findall(Y,member([X,Y],List), Values), 
    format("~w\n",[Values]), 
    enter(List). 

Если вы введете ключ, которого нет в списке, пустой список распечатает и вернет вас, чтобы повторить попытку.

Пример запуска:

?- start. 
Enter list: 
|: [[1,a],[2,b],[1,c]]. 
Enter key or stop: 
|: 1. 
[a,c] 
Enter key or stop: 
|: 2. 
[b] 
Enter key or stop: 
|: stop. 

false. 

другую версию с помощью повторения:

start:- 
    format("Enter list:\n",[]), 
    read(List), 
    format("Enter key or stop:\n",[]), 
    repeat, 
    read(X), 
    ( X=stop->!; 
    ( findall(Y,member([X,Y],List), Values), 
      format("~w\n",[Values]), 
      format("Enter key or stop:\n",[])), 
      fail). 
+0

Есть ли какие-либо преимущества в использовании 'fail' в предложении органов' Тест/2'? – repeat

+0

Думаю, вам не понадобится вторая неудача. Первый сбой зависит от того, хотите ли вы, чтобы цель была успешной или сбой по умолчанию. Ill отредактируйте его, чтобы удалить их. – user27815

+0

Правильно! Не может быть лучшего способа. Но сохранение простых вещей является хорошим дефолтом, ИМО. – repeat