2012-01-09 3 views
0

Кто-нибудь знает, как я могу реализовать Я предикат, делая то, что делает этот, но без «findall»? Большое спасибо.Prolog - То же самое работает, но без findall

domains 
    oferta = rebaixat ; normal 
    element = string 
     list = element* 
database 
    producte (string, integer, oferta) 
predicates 
    nondeterm reduced2(list) 

clauses 

    producte("Enciam",2,rebaixat). 
    producte("Peix",5,normal). 
    producte("Llet",1,rebaixat). 
    producte("Formatge",5,normal). 

     reduced2(Vals):- 
      findall(Val, producte(Val,_,rebaixat),Vals). 
Goal 
    write("Amb findall"),nl, 
    reduced2(List). 
+0

Ваше требование кажется произвольным. Можете ли вы объяснить, почему «findall» отсутствует? –

+0

Честно говоря, это требования моей домашней работы. Но я здесь потерялся. – mkll

+0

ОК. Я добавил тэг 'homework' к вашему вопросу. –

ответ

0

Я мало знаю о Visual Prolog, но я постараюсь дать общий ответ. Это зависит от того, хотите ли вы найти замену findall/3 для конкретного случая или вообще.

В конкретном случае вы можете использовать аккумулятор. В вашем случае это будет список, в который значения добавляются по мере их нахождения. Что-то вроде:

acc(In, List) :- 
    ... % do something to generate possible next value 
    ... % test if value is already in list In 
    !, 
    Out = [Val|In], % adds to the head, but is faster than using append 
    acc(Out, List). 
acc(List, List). 

есть, когда вы не можете найти другое возможное значение, то возвращать список значений, которые вы нашли. Обратите внимание, что это может быть медленным, если вам нужно аккумулировать множество значений, а генерация следующего возможного значения выполняется с помощью обратного отслеживания. Кроме того, это не позволит вам создавать дубликаты, поэтому это не точная замена для findall/3.

Если вы хотите получить общую замену для findall/3, где вы можете указать цель и переменную или термин, который будет содержать экземпляр, который будет накапливаться, то вы не сможете использовать какую-то нелогичную глобальную переменную. После нахождения следующего значения вы добавляете его к тому, что хранилось в глобальной переменной, и вызывают обратное отслеживание. Если генерация следующего значения не выполняется, вы извлекаете содержимое глобальной переменной и возвращаете ее.

+0

Вы мастер ! Большое спасибо. – mkll

+0

Кстати, как бы вы контролировали, чтобы читать факты из «readterm» столько, сколько пожелал пользователь, пока он (пользователь) не решит нажать только «войти»? Огромное спасибо. Это касается другой проблемы, которую я испытываю. – mkll

+0

Мне не нравится отвечать на ответ, но я был бы удивлен, если это сработает. ИМХО, альтернативой findall должен быть цикл, управляемый сбоем, или цикл прямого чтения. – CapelliC

 Смежные вопросы

  • Нет связанных вопросов^_^