Предыдущая страница [1] > 2 <

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

bokunopico

Members


Статус

54 сообщений

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

#4180   2011-04-13 03:49 GMT+3 часа(ов)      
> А написать конвертер все же стоит.
Я постараюсь, конечно, но думаю, что это слишком сложно для меня. А насчёт дизъюнкции, это "дурное свойство" можно преодолеть с помощью отсечения, но чтобы не изобретать деревянного велосипеда, можно воспользоваться (%if-then-else Gbool Gthen Gelse):
(define (плохой кто)
(%let (что)
(%and (любит кто что)
(%if-then-else (%member 'php что)
%true
(%member 'anime что)))))

Написал, и даже не за пару дней. Наверное, мой конвертер - образец того, как никогда не надо писать код.
 
(define (convert source-rel)
(do ([dest-rel %empty-rel]
[i (cdar (%which (who)
(%let (x)
(%set-of x
(source-rel x (_))
who))))
(cdr i)])
((null? i) dest-rel)
(let ([who (car i)]
[what (cdar (%which (what)
(%let (x)
(%bag-of x
(source-rel (car i) x)
what))))])
(%assert! dest-rel () [(who what)])
(printf "~a ~a~n" who what))))
 

Допустим, есть база фактов любит2, тогда используя уже готовые предикаты хороший и плохой, получим:
 
(define любит2
(%rel ()
[('Петя 'racket)]
[('Паша 'anime)]
[('Даша 'php)]
[('Паша 'php)]
[('Саша 'racket)]))
(define любит (convert любит2))
> (%find-all (кто) (плохой кто))
'(((кто . Паша)) ((кто . Даша)))
> (%find-all (кто) (хороший кто))
'(((кто . Петя)) ((кто . Саша)))
 

На первый взгляд, вроде работает, it's alive.

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

misha

Moderators


Статус

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

#4182   2011-04-13 20:36 GMT+3 часа(ов)      
> Написал, и даже не за пару дней. Наверное, мой конвертер - образец того, как никогда не надо писать код.
Хорошо что ты научился использовать имеющиеся у recklog-а предикаты.

#lang racket
 
(require racklog)
 
(define %любит
(%rel ()
[('Петя 'racket)]
[('Паша 'anime)]
[('Даша 'php)]
[('Паша 'php)]
[('Саша 'racket)]))
 
(define (converter %src)
(let ([all (%find-all (who what) (%src who what))]
[table (make-hash)]
[%dest %empty-rel])
(for-each (lambda(alist)
(let* ([who (cdr (assq 'who alist))]
[what (cdr (assq 'what alist))]
[table-val (hash-ref table who #f)])
(if table-val
(hash-set! table who
(if (list? what)
(append what table-val)
(cons what table-val)))
(hash-set! table who (list what)))))
all)
(hash-for-each table
(lambda(who what)
(%assert! %dest () [(who what)])))
%dest))
 
(set! %любит (converter %любит))
 
; Самый быстрый предикат
(define (%плохой1 кто)
(let ([test
(lambda(list)
(ormap (lambda(x)
(or (eq? x 'anime)
(eq? x 'php)))
list))])
(%let (увлечения)
(%and (%любит кто увлечения)
(%is #t (test увлечения))))))
 
(define-syntax (%!or stx)
(datum->syntax
stx
`(%cut-delimiter
(%or ,@(let next ([l (cdr (syntax->datum stx))])
(if (null? l)
l
(cons (if (null? (cdr l))
(car l)
`(%and ,(car l) !))
(next (cdr l)))))))))
 
(define (%дурные-увлечения? увлечения)
(%!or (%member 'anime увлечения)
(%member 'php увлечения)))
 
(define (%плохой2 кто)
(%let (увлечения)
(%and (%любит кто увлечения)
(%дурные-увлечения? увлечения))))
 
(define (%хороший кто)
(%let (увлечения)
(%and (%любит кто увлечения)
(%not (%дурные-увлечения? увлечения)))))

bokunopico

Members


Статус

54 сообщений

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

#4183   2011-04-13 21:12 GMT+3 часа(ов)      
> Хорошо что ты научился использовать имеющиеся у recklog-а предикаты.
Так это же путь наименьшего сопротивления. Не надо разбираться со словарём, код меньше получился, хотя вот функция конвертирования, предложенная тобой, выглядит более удобочитаемой и интуитивно понятней, за исключением непонятного мне assq. А так, очередное спасибо за интересный код. Надо будет %!or понять получше.

misha

Moderators


Статус

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

#4185   2011-04-13 23:20 GMT+3 часа(ов)      
> Так это же путь наименьшего сопротивления. Не надо разбираться со словарём, код меньше получился...
Может ты не в курсе, %bag-of использует полный проход по базе данных. На мой взгляд, N+1 проходов - непозволительная роскошь.

> Надо будет %!or понять получше.
%!or - типичный не гигиенический макрос.
(%!or A ... C) ==> (%cut-delimiter (%or (%and A !) ... C))

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


Онлайн :

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




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