2012-10-25 2 views
1

C#으로 작성된 학생 프로그램을 이해할 수있는 프롤로그 코드를 작성하려고했습니다. 이제 나는 학생 프로그램에서 'if'문을 인식하는 과정에 갇혀있다. 예 : 다음은 학생이 기대하는 코드입니다.Prolog에서 조건부 계획의 종류를 쓰는 방법은 무엇입니까?

int d = int.Parse(Console.ReadLine()); // value d is inputted by user 
int s = 0; 

if (d>0) 
    s = 2; 
else if (d==0) 
    s = 1; 
else 
    s = 0; 

나는 이것의 목표는 코드를 예상 정의 등 :

goal:- 
    hasVarName(Vid_s, s), 
    hasVarName(Vid_d, d), 
    hasVarValue(Vid_d, Vd), 
    ((not(gt(Vd,0)); hasVarValue(Vid_s, 2)),   %eq: [Vd>0] -> [val_s = 2] 
    ((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1)), %eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1] 
    ((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0).  %eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0] 

문제는 내가, 프롤로그 사실과 규칙 위의 수험 번호를 나타낼 수 목표에 대한 만족 것을 찾는 방법입니다 가능한 모든 조건.

나는 학생 코드의 첫 부분을 다음과 같은 사실이되도록 변경하려고했지만 실제로 프롤로그에서 사실/규칙으로 학생의 'if'진술문을 표현하는 방법을 알지 못했다. 바로, '경우'프롤로그로 변경?)

hasVarName(varID_d, d) 
hasVarValue(varID_d, val_d) %it is unknown, so I represent it as symbol 'val_d' 

hasVarName(varID_s, s) 
hasVarValue(varID_s, 0) 

그리고 또 하나, 내 목표에, 나는 내가 연산자보다 프롤로그 이상 사용할 수 없습니다 생각하지, 어느 쪽도 Vd> 0이나 원인이 Vd @> 0gt(Vd,0)으로 비교가있을 때 Vd의 값은 실제로 사용자가 입력 한 특정 값이지만 기호 값 (이 경우는 val_d)으로 표시됩니다.

참고 : 위의 목표를 사용하여 학생 코드가 다음 코드로 변경되면 정의 된 목표가 충족 될 것으로 생각됩니다.

int d = int.Parse(Console.ReadLine()); // value d is inputted by user 
int s = 0; 

if (d>0) 
    s = 2; 
else if (d==0) 
    s = 1; 

또는

int d = int.Parse(Console.ReadLine()); // value d is inputted by user 
int s = 10;   // any random initialization 

if (d>0) 
{ 
    int x = 2;  // unnecessary step, but still Ok. 
    s = x; 
} 
else if (d==0) 
    s = 1; 
else 
    s = 0; 

그러나 다시,이 코드는 목표를 달성하기 위해 액션/규칙/사실로 프롤로그에 표현 될 수있는 방법을 도움/아이디어가 필요합니다.

정말 도움이됩니다.

많은 감사

답변

0

나는 다음과 같은 부울 정체성 를 사용하여 암시를 통한 경우가-당시 다른 모델을 시도 같아요

A -> B == ~A v B. 

대신 의미의 접속사를 사용하여, 그것은에 을 쉽게 분기 사이에서 선택하기 위해 분리를 사용하고 제어 흐름에 따라 을 사용하십시오. 하지만 이전의 if-condition을 제외하려면 을 부정으로 처리해야합니다.

귀하의 예를 보자

if (d>0) 
    s = 2; 
else if (d==0) 
    s = 1; 
else 
    s = 0; 

당신은 그것을 모델 CLP (*)를 사용할 수 있습니다. 변수가 재정의되지 않도록 추가 변수를 추가하십시오. 그러나 위의 작은 스 니펫 에서는 문제가되지 않습니다. CLP (*)에서 위의 조각은 내가 편의상 CLP (FD)를 사용하고,됩니다 :

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.3.0) 
Copyright (c) 1990-2012 University of Amsterdam, VU Amsterdam 
?- use_module(library(clpfd)). 
?- [user]. 
that_if(D, S) :- 
    (D #> 0, S #= 2; 
    D #=< 0, D #= 0, S #= 1; 
    D #=< 0, D #\= 0, S #= 0) 
^D 
당신 임의로 인스턴스화 할 수 괜찮은 CLP (*) 시스템에서

또는 구속의 D 또는 S를 쿼리에서.우리는 (FD) CLP 이미 예를 들면 얻을 :

/* What conditions give result S #= 1 ? */ 
?- S #= 1, that_if(D, S). 
S = 1, 
D = 0 . 

/* What results give condition D #= 1 */ 
?- D #= 1, that_if(D, S). 
D = 1, 
S = 2 ; 
false. 

/* What conditions give a result S #=< 1 */ 
?- S #=< 1, that_if(D, S). 
S = 1, 
D = 0 ; 
S = 0, 
D in inf.. -1. 

/* What results give a condition D #>= 0 */ 
?- D #>= 0, that_if(D, S). 
S = 2, 
D in 1..sup ; 
D = 0, 
S = 1 ; 
false. 

안녕

+0

CLP 재미있다. 그러나 나는 초심자가 ** 정말로 ** 그것을 이해할 수있는 힘든 시간을 가질 수 있다고 생각한다. – CapelliC

+0

내 의견이 아닙니다 : Budi Hartanto가 초보자인지 또는 CLP (*)가 특히 어려운 통계 데이터를 가지고 있는지 여부도 알지 못합니다. CLP (*)는 더 선언적이어야하므로 더 간단해야합니다. –

+0

일부 CLP가없는 경우 (*)별로 확인할 수 없습니다. int d = int.Parse (Console.ReadLine()); 데이터는 임의적 일 수 있으며, 표준 Prolog 철저한 검색은 실제로 쿼리에 응답하지 않습니다. CLP (*)와 같이 더 상징적 인 것이 필요합니다. –

0

보통 언어 구현은 우리가 허용하는 구조를 구현하는 의미 작업을 지정하는 것이 편리 추상 구문 트리를 필요로 표하다.

구문 트리 작성 단계를 건너 뛰고 (손으로?) 프로그램의 중간 수준을 나타냅니다.

중간 수준 표현을 고수하면 if(Condition, Then, Else)과 같은 재귀 용어 (사실상 추상 트리)를 사용할 수 있습니다. 여기서 각 var는 구문 트리입니다.

그렇지 않으면 실용적인 표현 (일반적으로 명령형 언어에 적용)은 실행 블록을 설명하기 위해 기본 블록 (점프없는 명령 시퀀스)의 개념과 레이블을 사용합니다.

결과는 그래프이며 프로그램의 동작은 해당 표현의 '토폴로지'에 의해 결정됩니다. 내가 제대로 샘플 프로그램을 설명하기 위해 어떤 관심을 지불하지 않았다

goal:- 
    hasVarName(Vid_s, s), 
    hasVarName(Vid_d, d), 
    hasVarValue(Vid_d, Vd), 

    %eq: [Vd>0] -> [val_s = 2] 
    ((not(gt(Vd,0)); hasVarValue(Vid_s, 2), goto(label(0))), 

    %eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1] 
    ((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1), goto(label(0))), 

    %eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0] 
    ((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0)), % the goto is useless here... 

    label(0), 
    ..... 

참고, 그냥

편집 내가 생각 ... 이러한 가능성을 보여주기 위해 점프를 배치 일반 문제가 수 튜링 머신의 경우 halting problem과 동일합니다. 한편으로는 루프가없는 특별한 경우에는 AST에서 추상 해석을 사용하여 문제를 공격합니다. 나는. 재미있는 것을 계산하는 인터프리터.

가능한 경우 대상 프로그램의 일반성에 따라 다릅니다. 각 조건 점에 관련된 각 변수에 대해 정수 도메인을 파티션 할 수 있어야합니다. 상황이 급속하게 복잡해진다.

특히 IF의 다음 조건에서 도메인을 분할하려고 시도한다. 이러한 접근법을 사용하여 Prolog IF 테스트를 실행하여 값을 전파합니다. 하지만 내가 말했듯이, 정말 쉽지는 않다 ...

+0

안녕하세요. Chac, 제안 된 솔루션에 감사드립니다. 좀 더 당신의 제안을 설명 할 수 있습니까? 귀하의 정보를 원하시면, 제가 한 모든 것입니다 : 나는 학생 C# 프로그램을 읽는 C# 프로그램을 가지고 있습니다. 내 C# 프로그램에서 나는 학생 코드의 AST를 가지고있다. 이 AST에서 프롤로그가 학생의 과제에 대해 설정 한 목표가 충족되었는지 여부를 결정할 수 있도록 프롤로그 절을 만듭니다. 따라서 C# 프로그램에서 AST를 사용할 준비가되었지만 프롤로그에 내 목표에 연결하는 방법을 알 수는 없습니다. 아니면 내 목표를 정의하는 방식이 올바르지 않습니까? 감사 –