2013-06-10 5 views
3

여기에는 한계가 있다는 것을 알고 있지만 Prolog 코드에 조건부 지시문을 넣어 합리적으로 GNU 또는 SWI에서 작동하도록 합법적 인 방법이 있습니까? 적어도 가장 단순한 경우를 생각하고 있는데, SWI의 sumlist과 GNU의 sum_list과 같은 내장 된 술어는 서로 맞춤법이 맞지 않습니다. 또는 SWI는 assert이지만 GNU는 그렇지 않습니다. 단순히GNU 및 SWI에서 작동하는 Prolog 코드 만들기

:- if($SWI). 
SWI version of stuff 
:- else. 
GNU version of stuff 
:- endif. 

또는 :

:- if(not_a_builtin(sumlist)) 
sumlist(L, S) :- sum_list(L, S). 
:- endif. 

또는 무엇을하지 그래서 뭔가를 가지고 좋은 것입니다. 조건부 지시어는 두 언어 모두에 있지만, 이런 종류의 일을 수행하는 데 필요한 조건을 제공하는 것만으로는 부족합니다. 아마 수동 검색이 나를 위해 나타나지 않은 것을 놓친 것 같습니다.

답변

3

GNU 프롤로그 및 SWI - 프롤로그 모두 최신 버전이 구현됩니다으로, BTW, 드 사실 표준입니다 dialect라는 플래그 (정의 당신이 조건부 컴파일 지시문에서 사용할 수있는 대부분의 프롤로그 시스템) :

$ gprolog 
GNU Prolog 1.4.4 (64 bits) 
Compiled Apr 23 2013, 17:24:33 with /opt/local/bin/gcc-apple-4.2 
By Daniel Diaz 
Copyright (C) 1999-2013 Daniel Diaz 
| ?- current_prolog_flag(dialect, Dialect). 

Dialect = gprolog 

yes 

$ swipl 
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.3.16-6-g9c0199c-DIRTY) 
Copyright (c) 1990-2013 University of Amsterdam, VU Amsterdam 
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, 
and you are welcome to redistribute it under certain conditions. 
Please visit http://www.swi-prolog.org for details. 

For help, use ?- help(Topic). or ?- apropos(Word). 

?- current_prolog_flag(dialect, Dialect). 
Dialect = swi. 

을 따라서, 같은 간단한 쓰기 무언가 :

:- if(current_prolog_flag(dialect, swi)). 

    % SWI-Prolog specific code 

:- elif(current_prolog_flag(dialect, gprolog)). 

    % GNU Prolog specific code 

:- else. 

    % catchall code 

:- endif. 
+0

정확히 내가 무엇을 찾고 있었습니까. 감사. – lurker

+0

나는 똑같은 대답을하고 나서 테스트를하기로 결심했고 나의 gprolog (소스에 의해 설치되지 않은)가 예외를 발생시켰다. '방언'은 갈 길입니다. – CapelliC

+0

이 경우에도 제한 사항이 있습니다. 나에게 조금 미치게하는 Prolog 버전의 차이점은'format' 술어 또는 일반적으로 출력 형식을 지정하는 것입니다. ISO 프롤로그 출력 기능은 매우 불편하며 Prolog의 각 버전은 SWI와 GNU 사이에서 본 것과 같은 방향으로 분기되어있는 것처럼 보입니다. – lurker

1

이식성은 Prolog의 가장 약점 중 하나입니다. ISO 표준은 current_prolog_flag/2를 정의하지만 은 아니며은 구현의 '이름'플래그를 나열합니다.

나는 SWI와 YAP

swi :- prolog_impl(swi). 
yap :- prolog_impl(yap). 

prolog_impl(K) :- 
    F =.. [K,_,_,_,_], 
    current_prolog_flag(version_data, F). 

사이를 전환하려면 다음 코드를 사용하고

:- if(swi). 

gen_hash_lin_probe(Key, HashTable, Value) :- 
    arg(_, HashTable, E), 
    nonvar(E), 
    E = Key-Value. 

:- elif(yap). 

gen_hash_lin_probe(Key, HashTable, Value) :- 
    HashTable =.. [htlp|Args], 
    nth1(_, Args, E), 
    nonvar(E), 
    E = Key-Value. 

:- endif. 

처럼 사용하지만 GNU는 version_data를 정의하지 않습니다.

는 predicate_property이있는 내장의 존재를 테스트하려면/2 (AFAIK하지 ISO) 및 실험을해야합니다 - : (테스트하지 않았 음) 그런 다음 코드는

... 
    catch(current_prolog_flag(version_data,F),_,K = gnu). 

처럼 더 많거나 적은 연장해야 평소처럼 - 실제 행동을 결정합니다.

OT : sumlist/2가되지 않습니다,이 sum_list/2

+0

'sum_list이/2' SWI - 프롤로그 6.0.2에서 나를 위해 작동하지 않습니다. 나는'오류 : 최상위 : 정의되지 않은 프로 시저 : sum_list/2 (DWIM이 목표를 수정할 수 없음)'를 얻습니다. 'sumlist/2'가 작동합니다. – lurker

+0

리눅스를 우선적으로 사용하고 있으므로 SWI-Prolog는 소스에서 업데이트 된 건물을 유지합니다. 아마도 최근에 백 컴프립 라이브러리에서 sumlist/2가 사라 졌을 것입니다. 방금 doc 페이지에서 언급 된 것을보고했습니다. 죄송합니다. – CapelliC

+0

CapelliC, 항상 귀하의 답변에 감사드립니다. 'sumlist'에 대한 헤드 업에 감사드립니다. 사과 할 필요가 없다. 나는 리눅스도 사용하고 있지만 최신 yum 설치 만 사용하고있다. – lurker

0

dialect 플래그는 기본 시스템을 테스트하는 데 가장 적합합니다. 그러나 GNU Prolog는 version_data도 제공합니다. BTW : version_data를 사용 prolog_impl을위한 더 나은 정의는 다음과 같습니다

prolog_impl(K) :- 
    current_prolog_flag(version_data, F), 
    functor(F, K, _).