Следующая страница > 1 < [2]

Автор Сообщение

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4082   2011-03-27 20:11 GMT+3 часа(ов)      
Подскажите, пожалуйста, как будет выглядеть следующая конструкция на Racket с использованием racklog:
любит(саша, аниме).
любит(саша, racket).
любит(маша, X) :- любит(саша, X).

С предикатами я вроде разобрался, получилось:
 
(require racklog)
(define likes
(%rel ()
[('sasha 'anime)]
[('sasha 'racket)]))
 

А вот правило никак не получается оформить в коде, поэтому просьба помочь. Заранее спасибо за помощь.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4087   2011-03-27 23:39 GMT+3 часа(ов)      
#lang datalog
 
любит(саша, аниме).
любит(саша, racket).
любит(маша, X) :- любит(саша, X).
 
> любит(маша, X)?
любит(маша, аниме).
любит(маша, racket).


#lang racket
 
(require racklog)
 
(define любит
(%rel (x)
[('саша 'аниме)]
[('саша 'racket)]
[('маша x) (любит 'саша x)]))
 
> (%find-all (x) (любит 'маша x))
'(((x . аниме)) ((x . racket)))

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4089   2011-03-28 00:34 GMT+3 часа(ов)      
misha, огромное Вам спасибо. Я смотрел описание модуля по первым главам, оказалось, что надо было заглянуть и в "Glossary of Racklog Primitives". Наверное, без Вашей помощи так бы и не догадался.
А можно ещё задать Вам пару вопросов:
 
(define (find name)
(%find-all (what)
(likes name what)))
 
(define (fun arg)
(if (null? arg)
'()
(if (not (car arg))
'()
(cons (cdaar arg) (fun (cdr arg))))))
 

В результате:
 
> (find 'masha)
'(((what . anime)) ((what . racket)))
> (fun (find 'masha))
'(anime racket)
> (find 'pasha)
'(#f)
> (fun (find 'pasha))
'()
 

Собственно вопрос: достаточно ли "грамотно" написана функция fun, преобразующая полученную конструкцию в "обыкновенный" список?
И совсем глупый вопрос: как Вы меняете раскладку в Racket 5.1? Потому что, перейдя с версии 5.0.3, я обнаружил, что такая возможность куда-то улетучилась. :-(

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4093   2011-03-28 02:22 GMT+3 часа(ов)      
> достаточно ли "грамотно" написана функция fun, преобразующая полученную конструкцию в "обыкновенный" список?
Две ветки if нужно сократить в одну:
(if (or (null? arg) (not (car arg))) ...)
Еще необходимо учитывать структуру списка возвращаемого %find-all. Как Вы думаете зачем дополнительные скобки '((what . anime))?

> И совсем глупый вопрос: как Вы меняете раскладку в Racket 5.1? Потому что, перейдя с версии 5.0.3, я обнаружил, что такая возможность куда-то улетучилась. :-(
Попробуйте изменить шрифт в настройках пользователя. Возможно, установленный по умолчанию, либо выбранный Вами ранее шрифт не поддерживает кириллицу.

Я бы Ваш код переписал так:
#lang racket
 
(require racklog)
 
(define любит
(%rel (x)
[('саша 'аниме)]
[('саша 'racket)]
[('маша x) (любит 'саша x)]))
 
(define-syntax-rule (find name)
(%find-all (what) (любит 'name what)))
 
(define (fun arg)
(with-handlers ([void (lambda(e)
(raise (exn:fail:user
(format "Bad argument: ~a" arg)
(exn-continuation-marks e))))])
(if (not (car arg))
null
(append* (map (lambda(list)
(map cdr list))
arg)))))
 
> (find маша)
'(((what . аниме)) ((what . racket)))
> (fun (find маша))
'(аниме racket)
Зачем создаю собственное исключение, надеюсь, Вам понятно? Обратите внимание, я использую (exn-continuation-marks e) вместо (current-continuation-marks)! Это необходимо для того, чтобы выявить источник возникновения перехваченного исключения.

отредактировал(а) misha: 2011-03-28 02:35 GMT+3 часа(ов)

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4094   2011-03-28 02:59 GMT+3 часа(ов)      
Ещё раз спасибо за ответ и потраченное на меня время. Как Вы элегантно включили в такой маленький код столько новых и интересных особенностей (или возможностей, не знаю, как лучше выразиться) - не передать словами! Может, для Вас всё элементарно, но у меня появился повод в них разобраться. :-)
> Еще необходимо учитывать структуру списка возвращаемого %find-all. Как Вы думаете зачем дополнительные скобки '((what . anime))?
В приципе, догадываюсь. Могут быть дополнительные пары "переменная-значение", если моя терминология уместна. Например:
 
> (%find-all (who what)
(любит who what))
'(((who . саша) (what . аниме)) ((who . саша) (what . racket)) ((who . маша) (what . аниме)) ((who . маша) (what . racket)))
 

Но я не планирую учитывать такие сложности в текущий момент.
> Зачем создаю собственное исключение, надеюсь, Вам понятно?
Честно говоря, нет, даже сама природа исключений мне не ясна. Но это уже мои проблемы и думаю, что если внимательно(!) прочитаю соответствующий раздел в документации, то разберусь с данным вопросом.
Ещё раз хочу поблагодарить за оказанную помощь.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4113   2011-04-01 20:06 GMT+3 часа(ов)      
Здравствуйте. Опять я со своими проблемами по тому же самому модулю. Подскажите, пожалуйста, как будет выглядеть отрицание правила в Racklog?
 
#lang racket
(require racklog)
(define likes
(%rel ()
[('pasha 'anime)]
[('dasha 'php)]
[('pasha 'php)]
[('sasha 'racket)]))
 
(define bad
(%rel (who)
[(who) (%or (likes who 'anime) (likes who 'php))]))
 
(define good
(%rel (who)
[(who) (%not (bad who))]))
 
> (%which () (good 'sasha))
'()
> (%find-all (who) (good who))
'(#f)
 

Я глупо понадеялся, что %not является особой формой, как %and и %or. Оказалось, что он содержит в своём определении cut (!), который не получается перехитрить. В моём примере, наверное, (%repeat) надо использовать, чтобы добиться нужного результата? В общем, просьба помочь.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4114   2011-04-01 21:41 GMT+3 часа(ов)      
%not возвращает либо %true, либо %false. Поэтому простейший выход без перебора всех фактов:
(define (good who)
(likes who 'racket))

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4115   2011-04-01 22:23 GMT+3 часа(ов)      
Спасибо, как я понял, ни %and, ни %or не вычисляются и вообще не возвращают ничего, а как-то хитро обрабатываются, поэтому и удаётся вытащить значение переменной в результирующий список. А %not вычисляется, но при этом теряет значение who. Сделал, как Вы предложили, хоть и жаль, что если фактов много, то придётся очень многие из них таким образом перечислять. Ну, раз нет лёгкого способа, то и не надо, все равно не пойму. Спасибо за помощь.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4135   2011-04-07 00:51 GMT+3 часа(ов)      
> ни %and, ни %or не вычисляются и вообще не возвращают ничего, а как-то хитро обрабатываются, поэтому и удаётся вытащить значение переменной в результирующий список.
Ну, так это же макросы

> Сделал, как Вы предложили, хоть и жаль, что если фактов много, то придётся очень многие из них таким образом перечислять.
Извиняюсь за тупость На самом деле все очень просто
#lang racket
 
(require racklog)
 
(define любит
(%rel ()
[('Петя 'racket)]
[('Паша 'anime)]
[('Даша 'php)]
[('Паша 'php)]
[('Саша 'racket)]))
 
(define (плохой кто)
(%or (любит кто 'anime) (любит кто 'php)))
 
(define (хороший кто)
(%and (любит кто (_))
(%not (плохой кто))))
 
> (%find-all (кто) (хороший кто))
'(((кто . Петя)) ((кто . Саша)))

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4136   2011-04-07 01:20 GMT+3 часа(ов)      
> Ну, так это же макросы
Я недавно начал изучать Scheme/Racket, так что многие элементарные вещи для меня становятся настоящим открытием. Не стоит удивляться этому факту.
> На самом деле все очень просто
Большое спасибо. Даже стыдно, что я могу лишь такими заурядными словами выразить благодарность за чуть ли не за меня разобранный Racklog.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4142   2011-04-08 22:30 GMT+3 часа(ов)      
> Даже стыдно, что я могу лишь такими заурядными словами выразить благодарность за чуть ли не за меня разобранный Racklog.
А Вы можете расписать по шагам как обрабатывается конъюнкция в предикате "хороший"?

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4143   2011-04-08 23:58 GMT+3 часа(ов)      
А Вы можете расписать по шагам как обрабатывается конъюнкция в предикате "хороший"?
Наверное, сперва проверяется истинность предположения (goal) (любит кто (_)). Из него нам важно вытащить имя человека, а уж его конкретные предпочтения не особо важны, поэтому можно обойтись _. Потом проверяется второе предположение (%not (плохой кто)). Поскольку %not отличается от макроса %and по своей природе, поэтому приходится хитрить с дополнительным предположением, чтобы запомнить имя. Верно?
К сожалению, такую конструкцию:
 
(define-syntax %and
(syntax-rules ()
((%and g ...)
(lambda (__fk)
(let* ((__fk ((logic-var-val* g) __fk))
...)
__fk)))))
 

я пока довольно плохо понимаю, если вопрос как-то касался её.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4144   2011-04-09 02:06 GMT+3 часа(ов)      
> Поскольку %not отличается от макроса %and по своей природе, поэтому приходится хитрить с дополнительным предположением, чтобы запомнить имя.
Смотрите, вот эквивалентный код на Прологе:
любит(петя, racket).
любит(паша, anime).
любит(даша, php).
любит(паша, php).
любит(саша, racket).
 
плохой(Кто) :-
любит(Кто, anime);
любит(Кто, php).
 
хороший1(Кто) :-
not(плохой(Кто)).
 
хороший2(Кто) :-
not(плохой(Кто)),
любит(Кто, _).
 
хороший3(Кто) :-
любит(Кто, _),
not(плохой(Кто)).
 
Найдите ошибочные предикаты и объясните в чем ошибка. Но перед этим разберитесь с бэктрекингом.
Справка: "," эквивалентна %and, а ";" - %or.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4150   2011-04-09 22:51 GMT+3 часа(ов)      
На мой взгляд, ошибочными будут вторая и третья версии предиката "хороший". И ошибка будет в лишних проверках истинности второго subgoal.
Например, для второго предиката "хороший", после того как выполнится первый subgoal, начнётся поиск подходящего второго subgoal, что в принципе ненужно, так как он точно "входит в состав" первого. Кроме того, если мы уже работаем в конце базы фактов и она достаточно объёмна, то разрешение второго subgoal может отнять некоторое время.
Аналогичная ситуация и с третьей версией предиката. Например, можно зафиксировать решение первого subgoal, и если второй вернёт ложь, то это значит, что человек из базы является "плохим" (not истина == ложь), т.е. можно останавливаться. Но будет сделан возврат, или backtracking, а поиск продолжится с проверки факта, следующего за сохраненением первого subgoal.
Надеюсь, что я всё же не сильно ошибаюсь.
misha, если Вы не против, то можно и на ты.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4151   2011-04-10 00:50 GMT+3 часа(ов)      
> misha, если Вы не против, то можно и на ты.
Ok

> Надеюсь, что я всё же не сильно ошибаюсь.
Трейсинг предикатов:
[debug] 16 ?- хороший1(Кто).
T Call: (6) хороший1(_G496)
T Fail: (6) хороший1(_G496)
false.
 
[debug] 18 ?- хороший2(Кто).
T Call: (6) хороший2(_G496)
T Fail: (6) хороший2(_G496)
false.
 
[debug] 19 ?- хороший3(Кто).
T Call: (6) хороший3(_G496)
T Exit: (6) хороший3(петя)
Кто = петя ;
T Exit: (6) хороший3(саша)
Кто = саша.
Racklog создан на основе Пролога, так что не стоит удивляться таким результатам

P.S. Тогда я хотел сократить рассуждения, а в итоге белиберда получилась
хороший1(Кто) :-
not(плохой(Кто)).

Ищем "плохиша" и если он найден, тогда предикат not возвращает fail.
хороший2(Кто) :-
not(плохой(Кто)),
любит(Кто, _).

По аналогии с первым.

Как ты уже знаешь, предикат может состоять из нескольких правил, выполняющихся по очереди. Кстати, %or - это всего лишь удобная форма записи составного предиката. Если одно из тел предиката вернет fail(неудачу), то в дело вступает следующее тело составного предиката. Отсечение используется чтобы ограничить поиск текущим телом.
Например,
 
not(X) :-
X, !, fail;
true.
Если бы мы не использовали отсечение предикат возвращал бы всегда true.

отредактировал(а) misha: 2011-04-10 04:28 GMT+3 часа(ов)

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4152   2011-04-10 01:27 GMT+3 часа(ов)      
Очень интересный пример, спасибо большое.
> Racklog создан на основе Пролога, так что не стоит удивляться таким результатам
Не знаю, как тут можно не удивляться! Вроде бы всё так понятно и легко с %and и %or (ну, и эквивалентами из Пролога), что и от %not ожидаешь "естественного" поведения. А когда первый предикат, не вызывающий подозрений, оказывается ошибочным...
P.S.
> Тогда я хотел сократить рассуждения, а в итоге белиберда получилась
На мой взгляд, сброс переменных и пустой стек из первоначального варианта сообщения лучше объясняли ошибку первых двух предикатов. Наверное, я не совсем внятно выразил своё удивление.

отредактировал(а) bokunopico: 2011-04-10 04:24 GMT+3 часа(ов)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4153   2011-04-10 04:32 GMT+3 часа(ов)      
> На мой взгляд, сброс переменных и пустой стек из первоначального варианта сообщения лучше объясняли ошибку первых двух предикатов.
Тогда я слил все в одну кучу Просто в случае неудачи происходит сброс переменных, а про стек и бэктрекинг я отпишусь чуть позже.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4154   2011-04-10 04:46 GMT+3 часа(ов)      
Я из Пролога знаю лишь название и пару базовых аспектов, поэтому очень удивился, узнав, что и он использует отсечение в отрицании. То есть такая конструкция в Racklog не из головы придумана:
 
(define %not
(%rel ()
[(g) g ! %fail]
[(g) %true]))
 

А на самом деле естественно позаимствована (после правки сообщения догадался) и "повторяет" пример выше. Вот и весь смысл моего предыдущего поста.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4155   2011-04-10 22:15 GMT+3 часа(ов)      
Рассмотрим трэйсинг предиката хороший2, задав системе вопрос
?- хороший2(X).

[trace] 10 ?- хороший2(X).
Call: (6) хороший2(_G464) ? creep
^ Call: (7) not(плохой(_G464)) ? creep
Call: (8) плохой(_G464) ? creep
Call: (9) любит(_G464, anime) ? creep
Exit: (9) любит(паша, anime) ? creep
Exit: (8) плохой(паша) ? creep
^ Fail: (7) not(user:плохой(_G464)) ? creep
Fail: (6) хороший2(_G464) ? creep
false.
Число в круглых скобках означает глубину абстрактного системного стека возвратов. Обозначим его R, а специальный (используемый в поиске) стек возвратов S.
   Call: (6) хороший2(_G464)

Вызов функции(предиката) с неконкретизированной переменной _G464.
^  Call: (7) not(плохой(_G464))
Call: (8) плохой(_G464)
Call: (9) любит(_G464, anime)

Последовательно задаем вопросы.
   Exit: (9) любит(паша, anime)
Exit: (8) плохой(паша)

Система возвращает первый найденный факт удовлетворяющий условию любит(_G464, anime), поэтому _G464 конкретизирована (_G464 = паша).
^  Fail: (7) not(user:плохой(_G464))

Т.к. предыдущий результат true, поэтому not возвращает fail. Следовательно, система считает, что "паша" ей не подходит, потому значение _G464 сбрасывается, точнее _G464 расконкретизируется.
   Fail: (6) хороший2(_G464)

Т.к. предыдущий результат fail и стек S пуст, и следующее правило отсутствует(предикат хороший2 не является составным), поэтому система считает, что поиск завершен неудачно.

Как будет себя "вести" предикат хороший2, если в базе отсутствуют "плохиши"?

отредактировал(а) misha: 2011-04-10 23:12 GMT+3 часа(ов)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4156   2011-04-10 22:43 GMT+3 часа(ов)      
Рассмотрим трэйсинг предиката хороший3
[trace] 11 ?- хороший3(X).
Call: (6) хороший3(_G464) ? creep
Call: (7) любит(_G464, _G533) ? creep
Exit: (7) любит(петя, racket) ? creep
^ Call: (7) not(плохой(петя)) ? creep
Call: (8) плохой(петя) ? creep
Call: (9) любит(петя, anime) ? creep
Fail: (9) любит(петя, anime) ? creep
Call: (9) любит(петя, php) ? creep
Fail: (9) любит(петя, php) ? creep
Fail: (8) плохой(петя) ? creep
^ Exit: (7) not(user:плохой(петя)) ? creep
Exit: (6) хороший3(петя) ? creep
X = петя ;
Redo: (7) любит(_G464, _G533) ? creep
Exit: (7) любит(паша, anime) ? creep
...
 

Приступим
   Call: (6) хороший3(_G464)
Call: (7) любит(_G464, _G533)
Exit: (7) любит(петя, racket)

Система сразу находит факт удовлетворяющий условию любит(_G464, _G533)
_G464 = петя;
система кладет в стек S указатель на найденный в базе данных факт любит(петя, racket).
^  Call: (7) not(плохой(петя))

Не удивляйся, ведь теперь _G464 конкретизирована
   Call: (8) плохой(петя)
Call: (9) любит(петя, anime)
Fail: (9) любит(петя, anime)
Call: (9) любит(петя, php)
Fail: (9) любит(петя, php)
Fail: (8) плохой(петя)
^ Exit: (7) not(user:плохой(петя))
Exit: (6) хороший3(петя)
X = петя

Система установила, что "петя" удовлетворяет всем условиям поиска.

В данном случае ";" означает продолжение поиска.
   Redo: (7) любит(_G464, _G533)

Система возобновляет поиск беря со стека S указатель (конечно, указатель необходимо инкрементировать)
   Exit: (7) любит(паша, anime)
...

Система находит факт удовлетворяющий условию любит(_G464, _G533) и т.д.

отредактировал(а) misha: 2011-04-10 23:04 GMT+3 часа(ов)

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4157   2011-04-11 02:11 GMT+3 часа(ов)      
misha, ты просто КОЛОССАЛЬНУЮ работу проделал, таким образом проиллюстрировав внутренние механизмы Пролога! И чтобы не повторяться, скажу: ОНТОНИ АРИГАТО.
> Как будет себя "вести" предикат хороший2, если в базе отсутствуют "плохиши"?
Я думаю, он выдаст список из всех имеющихся в базе фактов людей. Наверное, это единственный случай, когда он вернёт то, что от него ожидают.
Чтобы не быть голосословным, попытаюсь показать, как я себе представляю его "поведение" (благо имеются примеры, на которые можно ориентироваться):
 
[trace] 10 ?- хороший2(X).
Call: (6) хороший2(_G464) ? creep
^ Call: (7) not(плохой(_G464)) ? creep
Call: (8) плохой(_G464) ? creep
Call: (9) любит(_G464, anime) ? creep
Fail: (9) любит(_G464, anime) ? creep
Call: (9) любит(_G464, php) ? creep
Fail: (9) любит(_G464, php) ? creep
Fail: (8) плохой(_G464) ? creep
^ Exit: (7) not(user:плохой(_G464)) ? creep
Call: (7) любит(_G464, _G533) ? creep
Exit: (7) любит(петя, racket) ? creep
Exit: (6) хороший2(петя) ? creep
X = петя ;
Redo: (7) любит(_G464, _G533) ? creep
Exit: (7) любит(паша, neanime) ? creep
Exit: (6) хороший2(паша) ? creep
X = паша ;
...
 

Поиск возобновляется с вычисления subgoal любит(Кто, _), поскольку из стека достаётся соответствующий указатель. В случае с предикатом хороший3 поиск повторялся с самого начала составного предиката, т.е. с разрешения любит(Кто, _), так как (not ...) ничего со стеком не сделал.
Я всё к тому, что кажется, благодаря вышеизложенным комментариям трейсинга, мне стала ясна суть backtracking'а.

Например, есть предикат (%and g1 g2). Первый subgoal разрешился - в стек помещается указатель, переходим ко второму. Он тоже разрешается - в стек опять помещается указатель. Сперва работаем с указателем для второго subgoal, поскольку ничего другого из стека взять нельзя, а уже когда до конца прошлись по базе фактов с его помощью, только тогда достаём и инкрементируем то, что было помещено раньше.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4161   2011-04-11 15:56 GMT+3 часа(ов)      
> В случае с предикатом хороший3 поиск повторялся с самого начала составного предиката, т.е. с разрешения любит(Кто, _), так как (not ...) ничего со стеком не сделал.
Составным я называю предикат в котором используется дизъюнкция целей, т.е. его можно составить из нескольких предложений. Поэтому "хороший3" не является составным, а вот "плохой" и "not" являются составными.
(%and g1 g2 ...) - конъюнкция, а (%or g1 g2 ...) - дизъюнкция.

Как можно сделать поиск более эффективным? Твои предложения.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4168   2011-04-11 22:48 GMT+3 часа(ов)      
> Как можно сделать поиск более эффективным?
Используя только уже разобранные примитивы? Не используя всякие %set-of и не создавая новых предикатов, например, любим(язык, кем)?

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4169   2011-04-12 00:15 GMT+3 часа(ов)      
Реализация эффективного поиска процесс творческий. У нас простая база, поэтому мы можем лишь объединить факты относящиеся к Паше.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4170   2011-04-12 02:09 GMT+3 часа(ов)      
То есть сделать что-то по аналогии с GROUP BY, а потом использовать предикат хороший3? Так ведь получится, что предикат будет применяться к совершенно другой структуре, нежели та, на которую он был рассчитан, значит, надо воспользоваться новым. Кажется, я излагаю такие же рассуждения, как и в ответе на вопрос, какой предикат ошибочен.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4173   2011-04-12 23:45 GMT+3 часа(ов)      
> То есть сделать что-то по аналогии с GROUP BY, а потом использовать предикат хороший3?
(define любит
(%rel ()
[('Петя '(racket))]
[('Паша '(anime php))]
[('Даша '(php))]
[('Саша '(racket))]))

> Так ведь получится, что предикат будет применяться к совершенно другой структуре, нежели та, на которую он был рассчитан, значит, надо воспользоваться новым.
Так в чем проблема? Создайте новый.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4175   2011-04-13 01:09 GMT+3 часа(ов)      
Я ожидал, что будет какой-нибудь фокус с преобразованием базы фактов, так сказать, "на лету", а тут даже задача упростилась.
Вот что придумал в итоге:
 
(define (плохой кто)
(%let (что)
(%and (любит кто что)
(%or (%member 'php что) (%member 'anime что)))))
(define (хороший кто)
(%and (любит кто (_)) (%not (плохой кто))))
 

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

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4176   2011-04-13 02:34 GMT+3 часа(ов)      
> Я ожидал, что будет какой-нибудь фокус с преобразованием базы фактов, так сказать, "на лету", а тут даже задача упростилась.
Этот подход предполагает хотя бы один проход по всей базе вне зависимости того требуется ли нам найти первый подходящий факт, или же найти их все.
> (%or (%member 'php что) (%member 'anime что))
Ты уже должен был заметить, что дизъюнкция имеет дурное свойство: при возобновлении поиска начинать со следующего предложения. Короче, если (%member 'php что) = %true, то поиск возобновится с (%member 'anime что), а не сначала. Тебе необходимо исправить этот недостаток.

> Единственное - смущает повторение предиката любит, только никаких идей нет, как избежать этого.
Можешь написать функцию конвертирующую старую базу данных в новую.

bokunopico

Members


Статус

54 сообщений

Где: Russia Нижний Новгород
Род занятий:
Возраст:

#4178   2011-04-13 03:02 GMT+3 часа(ов)      
> Единственное - смущает повторение предиката любит, только никаких идей нет, как избежать этого.
> Можешь написать функцию конвертирующую старую базу данных в новую.
Я имел в виду, что в предикате хороший сперва вычисляется (любит кто (_)), а потом (любит кто что) уже в составе предиката %not.

> Короче, если (%member 'php что) = %true, то поиск возобновится с (%member 'anime что), а не сначала.
Именно поэтому и дублируется Паша.

отредактировал(а) bokunopico: 2011-04-13 03:18 GMT+3 часа(ов)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#4179   2011-04-13 03:24 GMT+3 часа(ов)      
> Я имел в виду, что в предикате хороший сперва вычисляется (любит кто (_)), а потом (любит кто что) уже в составе предиката %not.
Ты всегда можешь создать более эффективный предикат. А написать конвертер все же стоит.


Онлайн :

0 пользователь(ей), 36 гость(ей) :




Реклама на сайте: