2016-10-21 5 views
2

특히 다음 유형의 문제를 해결하기위한 최선의 방법을 결정하려고합니다.논리적 프로그래밍에서 반복적 인 업데이트를 어떻게 처리해야합니까?

예를 들어 Mitchell 's Machine Learning의 find-s 알고리즘이 4 가지 학습 예제에 적용 되었기 때문에 관심이 있습니다.

기본 아이디어는 각 학습 예제 x와 가설 h에 대해 h를 결정합니다.보다 일반적인 것으로 x를 통합 했습니까? 훈련 세트의 각 x에 대해 h를 h '로 매핑해야합니다. 내가 겪고있는 문제는 논리적 인 프로그래밍 언어에서 이것을 가장 잘 접근하는 방법이다. 나는 계획에 포함 된 대략 프롤로그 인 minikanren을 사용하고 있습니다.

각 h '를 계산 한 후 설정해야합니다! 그것을 글로벌 변수 h로 변환 한 다음 다음 예제 x로 진행합니다. 아래 코드는 프로그램의 주요 부분입니다.

(define h '(0 0 0 0 0 0)) 

(define seto 
    (lambda (x) 
    (project (x) 
      (lambda (s) (set! h x) (succeed s))))) 

(run* (q) 
    (fresh (x h0 h1) 
      (trainingo x) 
      (== h h0) 
      (find-so h0 x h1) 
      (seto h1) 
      (== h1 q))) 

H 글로벌 변수, 세토 찾기-S 알고리즘 (찾을 이렇게)를 사용하고 X H0 훈련 예에서 다음 계산 가설 H1과 시간을 변이합니다.

어설 ('가설'(H)) 각 훈련 예를 들어, X 후에 해당 프롤로그는 (내가 생각하는) 것에서

후퇴 ('가설'(H))합니다 (이전 덮어 쓰기) 및 호출 모든 교육 사례가 적용된 후.

다시 한번이 문제를 해결하기위한 가장 좋은 방법은 부작용을 통한 것인가하는 것입니다.

편집 : 나는 그의 comment과 함께 @mat 응답을 허용했습니다. 요약하면 필자는 훈련 예제를 목록으로 취급하고 빈 목록에 도달 할 때까지 해당 목록에 대한 순방향 재귀를 사용해야했습니다. 내가 꼼짝 못하게되고 있었다면, 훈련 예제를 역 추적의 일부로 갖는 것과 함께 다음 가설을 찾기 위해 목록에 넣는 대신 빈 때까지 반복 할 수있었습니다.

+0

당신은 정확하게 당신이 부작용을 통해이 작업을 수행 할 수 이유를 설명 할 필요가있다. @mat의 대답은 왜 이런 부작용이 없어야 하는지를 설명합니다. –

+0

그런데 효율성 측면에서 부작용을 사용하는 Prolog 라이브러리 코드에서 예제를 찾을 수 있습니다. [SWI-Prolog의 라이브러리에있는이 코드 (aggregate)] (http://eu.swi-prolog.org/pldoc/doc_for?object=aggregate_all/3)를 참조하십시오. 어쨌든, 당신은'nb_ *'패밀리의 술어를 사용하게 될 것입니다. 여기서 "nb"는 "되돌릴 수없는"것을 의미합니다. –

+0

나는 이것을 다음과 같은 @mat 응답의 주석으로 언급했다 : "... 문제는 다음 가설을 얻은 후 다음 훈련 예로 되돌아가는 것입니다. 나는 다음 가설을 놓쳤습니다. 나는 원하지 않습니다. 가능한 경우이를 해결하기 위해 부작용을 사용하십시오. " –

답변

3

을 추천합니다. : assertz/0retract/1으로 글로벌 업데이트를 시뮬레이트합니다. 글로벌 상태를 사용하여 에서 당신을 방지

  • 분리에 및 테스트 술어 를 사용 : 당신이이   방식으로 할 경우

    그러나,  이
    을 단점 주요있다.
  • 파괴적인 업데이트를 사용하면 방향의 조건부 을 사용할 수 없습니다.
  • 전역 상태의 미묘한 및 암시 적 종속성으로 인해 조건 자의 변경이 매우 많이 발생합니다. 오류  이 발생하기 쉬운.

이러한 상태 변화를 시뮬레이션하기위한 선언 솔루션은   상태 사이 관계의 관점에서 생각하는 것입니다.당신이 다음 가설 H1을 계산하는 H0를 사용하는 경우 예를 들어

, 당신은 H0 및   H1, 그리고 아마도 더 매개 변수 사이의 관계로 이것을 표현할 수 있습니다. 이러한 조건이 모든 방향으로 및 — 이상적으로 — 실행을 읽을 수

  • hypothesis_next(H0, H1)
  • algorithm_hypothesis_next(A, H0, H1)
  • parameters_hypothesis_next(Ps, H0, H1)

참고 : 같은 조건에 대해 생각 ! 합계

는 전체 용액은 경우   가설시퀀스로 모델링된다 :

H0 및 우측으로 향하는 화살표; H1 & rightarrow; H2; & hellip; & rightarrow; H

더 많은 정보와 포인터를 들어, 밀접하게 관련 질문을 참조하십시오

How to avoid using assert and retractall in Prolog to implement global (or state) variables

+0

감사합니다! 그러나 나는 다음 가설을 얻은 다음에 ** 다음 훈련 예로 되돌아가 ** 나는 다음 가설을 잃어 버렸다. 가능하면이 문제를 해결하기 위해 부작용을 사용하고 싶지 않습니다. –

+1

이것에 대한 해결책은 ** forward recursion **에 의한 역 추적을 대체하는 것입니다. 가설'H0'을 다듬을 훈련 예'Es'가 있다고 가정 해보십시오. 'examples_h0_h ([], H, H) .'와 같은 술어로 설명 할 수있다. (예 : 예제가 없다면 마지막 가설은 초기 가정과 동일하다)'examples_h0_h ([E | Es ], H0, H) : hypothesis_next (E, H0, H1), examples_h0_h (Es, H1, H).이 패턴은 Prolog에서 자주 발생하기 때문에,'foldl (hypothesis_next, Es, H0, H)'에 대한'foldl/4'라는 메타 술어가있다. – mat