Avatar
질문과 건의    daybreaker (daybreaker)

Written on 2009-02-23 04:56:29
Modified on 2009-02-23 13:25:22

어떻게 알고리즘을 개선해볼 수 있을까에 대한 아이디어를 찾아서 열심히 prolog로 구현해보고 있는데 언어가 워낙 패러다임이 다르다보니 어렵네요. ㅠㅠ

우선 질문 하나:

* File I/O Tutorial. Edinburgh-style IO와 ISO-style IO 방식이 있는데, 파일에서 공백 문자로 구분되는 단어를 읽어오려고 했더니 get_char predicate로 직접 구현하든지 아니면 prolog의 문법에 맞추어 string literal clause 형태로 적어서 그 단위로 읽어오는 방법(read predicate)밖에 없는 듯합니다. 좀더 편리(?)한 IO는 제공하지 않는 건가요?

* List를 다룰 때 [A|B]와 같은 표현을 많이 사용하는데 이것이 predicate 정의의 인자 목록에 있을 때와 대입문에 있을 때 등 여러 상황에 따라 조금씩 다른 의미를 가지는 것 같습니다. (어떤 땐 List에 추가하고 어떤 땐 잘라내고..?) 혹시 좀더 자세히 설명해주실 수 있을지요?;

* 수업시간에 잠깐 !에 대한 언급이 있었던 것 갈은데 실제적인 의미(기능)이 뭔지 궁금합니다. 찾아보니 backtracking을 막는(prune?) 용도로 쓴다는데
read_list([C | L]) :-
get0(C),
C =\= -1, % end of file
!,
read_list(L).
read_list([]).
이런 코드에서는 어떤 의미인가요?;; (end of file이라고 표시된 줄의 조건이 false이면 중단? 인 것 같은데 만약 그 사이에 뭔가 더 명령문을 집어넣는다거나 하면 어떻게 되는 건지, 혹은 제 해석이 맞는지 궁금)

* read_dictionary(WL). 이런 predicate를 만들어서 어쨌든 데이터를 읽어왔는데, 저 WL이란 변수를 다른 predicate에 넘겨서 뭔가 해보려고 하니 이상합니다.

?- read_dictionary(WL).
WL = [[a, b], [c, d], [e, f]].
?- .
|: lookup(Word, Meaning, Dictionary) :- member([Word, Meaning], Dictionary).
|:
% user://2 compiled 0.00 sec, 504 bytes
true.
?- lookup(a, Meaning_of_a, WL).
WL = [[a, Meaning_of_a]|_G486] ;
WL = [_G485, [a, Meaning_of_a]|_G489] ;
WL = [_G485, _G488, [a, Meaning_of_a]|_G492] ;
WL = [_G485, _G488, _G491, [a, Meaning_of_a]|_G495] ;
WL = [_G485, _G488, _G491, _G494, [a, Meaning_of_a]|_G498] ;
WL = [_G485, _G488, _G491, _G494, _G497, [a, Meaning_of_a]|_G501] .
?- lookup(a, Meaning_of_a, [[a, b], [c, d], [e, f]]).
Meaning_of_a = b ;
false.

직접 list를 써서 넘기면 원하는 대로 나오는데 제가 읽은 변수를 넘기면 이상한 결과가 나오는데 이것도 왜 이런 건지, 제가 쓴 변수를 참조시키려면 어떻게 해야 하는지 궁금합니다.


그리고...전반적으로 몇 가지 건의와 의견을 드려봅니다.

* 워낙에 패러다임이 다른 언어이다보니 실질적으로 자주 사용되는 구현 케이스에 대한 튜토리얼이 있었으면 좋겠습니다. 이 언어의 특징을 설명하는 튜토리어를은 많은데, C/Java/Python과 같은 비교적 imperative한 언어를 다루던 사람들이 궁금해할 만한 주제들(File IO, global variable, value assignment, list handling 등등)에 대해서는 어떻게 구현 가능하다든지, 이건 이렇게 패러다임이 다르니까 이런 식으로 바꿔서 생각해야 한다든지 하는 안내를 찾기 힘듭니다. 그나마 ML이나 Haskell을 조금이나마 접해봤으니 망정이지 안 그랬으면 정말 이해하기 힘들었을 것 같습니다.

* 그런 고로, 비록 숙제 듀는 얼마 안 남았지만(ㅠ_ㅠ) 이번 숙제 후에라도(?) 별도 연습시간을 잡아서라도 간단한 튜토리얼을 진행했으면 합니다. 원래 카이스트 수업에서 언어 자체를 가르치는 경우는 거의 없다지만 시스템 프로그래밍 수업에서 C Tutorial을 단 몇 시간이나마 진행하는 것처럼 Prolog도 그런 단초를 잡아줄 수 있는 시간이 있으면 좋겠습니다.

수업 시간에 교수님이 나름대로 introduction도 진행하시고 교과서의 appendix에도 꽤 상세하게 설명되어 있습니다만 오히려 아주 기초적인 부분들--예를 들어 다른 언어에서 자주 사용되는 while/for와 같은 반복문들은 어떻게 개념이 다르므로 어떻게 바꿔 생각 or 구현해야 하는지 등은 부족한 것 같습니다. (다행히 부분적으로 간단한 loop 구현은 appendix와 min_edit.pl에 있더군요.) 그냥 "이 정도는 당연히 알아서 알아내겠지" 하는 것들이 사실은 굉장한 암초가 되는 경우를 많이 봐와서...ㅠㅠ;;
지금은 어느 정도 감을 잡았지만 prolog console에서 입력하는 것과 prolog code file에서 입력하는 것과는 완전히 다르다는 것도 사실 따로 언급이 없어서 꽤나 헤맸습니다. (findol님 감사-_-) 이런 것도 딱 누가 정리해주면 좋았을 텐데 하는 생각이 드네요.

* 어쩌면 이런 색다른 패러다임의 프로그래밍 언어들이 그 우아하고 잘 추상화된 설계 철학에도 불구하고 사람들에게 '뭔가 어려운' 것으로 인식되는 이유가 이런 연결고리가 부족하기 때문이 아닐까 하는 개인적인 생각도 듭니다. 사람들이 해결하길 원하는 문제를 어떻게 해결할 수 있는지 바로 알 수 있는/접근할 수 있도록 초기진입장벽을 완화하는 방법은 없을지 궁금합니다.

사실 하스켈이나 ML도 그렇고 정말 밑바닥부터 쌓아올리되 그 간결한 추상화의 힘이 대단하다는 생각이 들곤 하는데 막상 실제로 써먹으려 하면 아주 간단한 것부터 어떻게 해야 될지 몰라서 버벅거리게 되고 이것이 이런 언어들을 멀리하게(?) 되는 요인 같습니다. 보통 이런 언어들을 주로 다루시는 분들은 '왜 다른 사람들은 이 아름다운 세계를 이해·활용하지 못하는 걸까?'라고 생각할 수도 있겠지만 그런 다른 사람 입장에서 보면 '아름다운 거 맞긴 한데 기초 표현부터 막히니 내 문제를 어떻게 해결해야 될지 모르겠어 orz 그냥 하던대로 할래'이 상태가 아닐까 싶어요. (단지 패러다임이 다르다는 것하고는 좀 다른 이야기입니다만 의도가 제대로 전달되었을지 모르겠네요) 물론 프로그래밍에 아무런 지식도 없는 사람이 처음부터 prolog를 배운다면 또 이야기가 좀 달라지겠습니다만...;;

뭔가 머릿속으로는 "아, 이런 알고리즘을 구현하면 되겠다"는 생각이 다 정리되었는데 prolog로 그걸 표현해내지 못하니 너무 답답하네요. OTL prolog라는 언어로 어디까지 표현이 가능하고, 내가 컴퓨터에게 시키고자 하는 일을 prolog의 형태로 표현하려면 어떻게 해야 하는지 모르니 부당한 설계를 했다가 갈아엎고...-_-;;
Avatar CT
ctinterim
(2 years, 11 months ago)
저도 비슷한 생각입니다. 기껏해서 괜찮은 알고리즘 생각해놨는데 정작 프롤로그로 짜려고 보니 기본적인 루프, Variable사용 같은 간단한 개념부터 막혀서 결국 처음 의도와는 완전히 어긋나는 방식으로 짜버렸죠; PROLOG가 뭔가 재미있는 언어인것 같기는 한데 실용적인 introduction이 부족하다고 생각합니다. 책의 introduction이 이론적인 설명은 충실하지만 실용성은 솔직히 떨어지는것 같아요 -_-;
Avatar daybreaker
(2 years, 11 months ago)
뭐랄까... 우리는 문제를 정의(?)만 하고 그 풀이는 prolog가 알아서 backtracking으로 풀어준다...는 컨셉 같기도 한데 문제는 우리가 생각한 그 알고리즘을 어떻게 prolog적으로 표현하는가겠죠.. 아흑...ㅠ_ㅠ
Avatar findol
(2 years, 11 months ago)
2. predicate를 정의할 때 잘라낼 지 추가할 지에 대해 정의하지는 않는 거 같아요. unification rule에 따르는 게 아닌가 싶어요.3. ! 가 없다면 가능한 모든 경우를 수행하기 때문에 문제가 되지 싶습니다.4. read_dctionary(WL), lookup(a, Meaning_of_a, WL) 하면 될 거 같아요
Avatar daybreaker
(2 years, 11 months ago)
@findol: 지금은 위에 올린 질문들의 답을 다 알게 되었습니다만 그래도 어떤 점에서 막히고 어려워했는지 알 수 있도록 남겨두려고(?) 합니다. ㅎㅎ
To post commment, please log in