Prolog 제어 구조

Prolog 제어 구조

GNU Prolog는 제어 구조에 대한 ISO 개념을 따르며, 미리 정의된 제어 구조들을 상세히 설명해요.

출처: GNU Prolog Manual - Prolog control constructs

본문

GNU Prolog는 제어 구조에 대한 ISO 개념을 따르며, 미리 정의된 제어 구조들을 상세히 설명해요.

true/0, fail/0, !/0

Templates

true
fail
!

Description

  • true - 항상 성공.
  • fail - 항상 실패(백트래킹 강제).
  • ! - 항상 성공하며, 부작용으로 그것을 활성화한 술어의 호출 이후 만들어진 모든 선택점을 제거.

Errors: 없음.

Portability: ISO 제어 구조.

(',')/2 - 연접, (;)/2 - 이접, (->)/2 - if-then, (*->)/2 - 소프트 컷(soft-cut)

Templates

','(+callable_term, +callable_term)
;(+callable_term, +callable_term)
->(+callable_term, +callable_term)
*->(+callable_term, +callable_term)

Description

  • Goal1, Goal2 - Goal1을 실행하고, 성공하면 Goal2를 실행.
  • Goal1 ; Goal2 - 먼저 선택점을 만들고 Goal1을 실행. 백트래킹 시 Goal2를 실행.
  • Goal1 -> Goal2 - 먼저 Goal1을 실행하고, 성공하면 Goal1이 만든 모든 선택점을 제거하고 Goal2를 실행. 이 제어 구조는 if-then처럼 동작해요(Goal1이 검사 부분, Goal2가 then 부분). Goal1이 실패하면 ->/2도 실패한다는 점을 주의하세요.
  • ->/2는 종종 ;/2와 결합되어 다음과 같이 if-then-else를 정의해요: Goal1 -> Goal2 ; Goal3. Goal1 -> Goal2(;)/2의 첫 번째 인자이고 Goal3(else 부분)이 두 번째 인자라는 점을 주의하세요. 이런 if-then-else 제어 구조는 먼저 else 부분에 대한 선택점(직관적으로 ;/2와 연관)을 만들고 Goal1을 실행해요. 성공하면 Goal1이 만든 모든 선택점과 else 부분에 대한 선택점이 제거되고 Goal2를 실행해요. Goal1이 실패하면 Goal3을 실행.
  • Goal1 *-> Goal2 ; Goal3 - 이른바 **소프트 컷(soft-cut)**을 구현. 위의 if-then-else처럼 동작하지만, Goal1이 성공하면 Goal3만 컷돼요(Goal1의 대안 해들은 보존되고 백트래킹으로 찾을 수 있음). Goal1 *-> Goal2 단독(즉 else 분기 Goal3 없이)은 (Goal1, Goal2)와 동일하다는 것을 주의하세요.

',', ;, ->, *->는 미리 정의된 중위 연산자예요(8.14.10절).

Errors

  • Goal1 또는 Goal2가 변수 - instantiation_error
  • Goal1이 변수도 callable 항도 아님 - type_error(callable, Goal1)
  • Goal2가 변수도 callable 항도 아님 - type_error(callable, Goal2)
  • Goal1 또는 Goal2의 술어 표시자 Pred가 기존 프로시저에 해당하지 않고 unknown Prolog 플래그의 값이 error임(8.22.1절) - existence_error(procedure, Pred)

Portability: (*->)/2가 GNU Prolog 고유인 것 외에는 ISO 제어 구조.

call/1

Templates

call(+callable_term)

Description call(Goal)Goal을 실행해요. Goal이 참인 목표를 나타내면 call/1은 성공해요. Goal이 하위 목표로 컷 기호 !(7.2.1절)를 포함하면 !의 효과는 Goal 밖으로 확장되지 않아요.

Errors

  • Goal이 변수 - instantiation_error
  • Goal이 변수도 callable 항도 아님 - type_error(callable, Goal)
  • Goal의 술어 표시자 Pred가 기존 프로시저에 해당하지 않고 unknown Prolog 플래그의 값이 error임(8.22.1절) - existence_error(procedure, Pred)

Portability: ISO 제어 구조.

catch/3, throw/1

Templates

catch(?callable_term, ?term, ?term)
throw(+nonvar)

Description catch(Goal, Catcher, Recovery)call(Goal)(7.2.3절)과 비슷해요. 이것이 성공하거나 실패하면 catch/3 호출도 그렇게 해요. 그러나 Goal 실행 중에 throw(Ball) 호출이 있으면 현재 제어 흐름이 중단되고, 제어는 실행 중인 catch/3 호출로 돌아가요. 이는 두 가지 방식 중 하나로 발생할 수 있어요:

  • 암시적으로, 내장 술어의 오류 조건이 충족될 때.
  • 명시적으로, 프로그램이 현재 처리를 포기하고 대신 대안적 조치를 취하기를 원할 때 throw/1 호출을 실행할 때.

throw(Ball)은 정상 제어 흐름이 기존의 catch/3 호출로 되돌아가게 해요. throw(Ball) 호출이 발생하면 Ball이 복사되고 스택이 catch/3 호출까지 풀리며, 그 시점에 Ball의 복사본이 Catcher와 통일돼요. 이 통일이 성공하면 catch/3call/1(7.2.3절)을 사용해 Recovery 목표를 실행해 catch/3의 성공 여부를 결정해요. 그렇지 않으면 통일이 실패할 경우 스택은 계속 풀리며 더 이른 catch/3의 호출을 찾아요.

Ball은 어떤 비변수 항이든 될 수 있어요.

Errors

  • Ball이 변수 - instantiation_error
  • Ball이 어떤 catch/3 호출의 Catcher 인자와도 통일되지 않으면 시스템 오류 메시지가 표시되고 throw/1은 실패.

catch/3Goal 또는 Recovery를 호출할 때 call/1(7.2.3절)을 사용하므로, Goal 또는 Recovery에 따라 instantiation_error, type_error, existence_error가 발생할 수 있어요.

Portability: ISO 제어 구조.

더 알아보기