제스 (프로그래밍 언어)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

제스는 자바 기반의 전문가 시스템 및 규칙 엔진으로, CLIPS를 기반으로 개발되었다. 변수 바인딩, 함수 정의, 사실 집합 정의, 템플릿 정의, 새로운 사실 추가 등의 기능을 제공하며, 헌혈 가능 여부 판단과 같은 규칙을 정의하는 예시를 통해 사용법을 보여준다. 교육 및 정부 사용에는 프리웨어, 상업적 사용에는 라이선스가 필요한 독점 소프트웨어이며, CLIPS는 자유-오픈 소스 소프트웨어이다. 관련 시스템으로는 CLIPS, ILOG 규칙, JBoss Drools, Prolog, OpenL Tablets, DTRules 등이 있다.

제스 (프로그래밍 언어) - [IT 관련 정보]에 관한 문서
📚 더 읽어볼만한 페이지
  • 지식 표현 언어 - 설명 논리
    설명 논리(DL)는 지식 표현을 위한 형식 언어로, 개념, 역할, 개체 간의 관계를 정의하고 추론하며, TBox와 ABox로 구성된다.
  • 전문가 시스템 - 지식 베이스
    지식 베이스는 특정 주제 정보를 체계적으로 저장 및 관리하며 규칙 기반 추론으로 새로운 지식 도출에 활용되고, 웹 콘텐츠 관리 및 지식 관리 시스템으로 확장되어 온톨로지를 이용, 인공지능 기술과 결합하여 문제 해결책을 제시하고 경험을 통해 학습하는 시스템이다.
  • 전문가 시스템 - BRMS
    BRMS는 비즈니스 규칙을 소프트웨어 시스템에 적용하는 방식으로, 기업 의사 결정 관리의 중요한 부분이며 모델 중심 엔지니어링과 관련이 깊고, BMM, SBVR, PRR, DMN 등의 표준과 RuleML 같은 규칙 마크업 언어가 활용될 수 있다.
  • 자바 API - 자바 암호화 확장
  • 자바 API - 표준 위젯 툴킷
    표준 위젯 툴킷(SWT)은 자바 GUI 툴킷으로, 네이티브 룩앤필과 고성능을 위해 윈도 시스템의 그래픽 요소를 직접 사용하며, 이클립스 IDE의 기반 기술로 IBM에 의해 개발되었다.

2. 코드 예시

Jess리스프와 유사한 괄호 기반 문법을 사용하는 규칙 기반 시스템 개발 도구이다. 아래 하위 섹션에서는 Jess의 기본적인 문법 요소들과 이를 활용한 간단한 코드 예제를 살펴볼 수 있다. 예제에는 기본적인 문법 구조와 함께, 헌혈 가능 여부를 판단하는 규칙 시스템 구현 사례가 포함되어 있다.

2.1. 기본 문법 예제

Jess 프로그래밍 언어의 기본적인 문법 예시는 다음과 같다.

* 주석: 세미콜론(`;`)으로 시작하는 줄은 주석으로 처리된다.

; 이것은 주석입니다.


* 변수 바인딩: `bind` 함수를 사용하여 변수에 값을 할당한다. 변수 이름 앞에는 물음표(`?`)를 붙인다.

(bind ?x 100) ; 변수 ?x에 100을 할당한다. (다른 언어의 x = 100 과 유사)


* 함수 정의: `deffunction` 키워드를 사용하여 새로운 함수를 정의한다.

; 두 수 중 큰 값을 반환하는 max 함수 정의
(deffunction max (?a ?b)
(if (> ?a ?b) then ?a else ?b))


* 사실(Fact) 정의: `deffacts` 키워드를 사용하여 초기 사실들의 집합을 정의한다. 이는 프로그램 시작 시 작업 메모리에 로드된다.

; 'myroom'이라는 이름의 사실 집합 정의
(deffacts myroom
(furniture chair) ; 방 안에 의자가 있다는 사실
(furniture table) ; 방 안에 테이블이 있다는 사실
(furniture bed) ; 방 안에 침대가 있다는 사실
)


* 템플릿 정의: `deftemplate` 키워드를 사용하여 사실의 구조를 정의하는 템플릿을 만든다. 템플릿은 여러 개의 슬롯(slot)으로 구성될 수 있다.

; 'car'라는 이름의 템플릿 정의
(deftemplate car
(slot color) ; 색상 슬롯
(slot mileage) ; 주행 거리 슬롯
(slot value) ; 가격 슬롯
)


* 사실 생성: `assert` 함수를 사용하여 정의된 템플릿에 따라 새로운 사실을 작업 메모리에 추가한다.

; 'car' 템플릿을 사용하여 새로운 자동차 사실 생성
(assert (car (color red) (mileage 10000) (value 400)))


아래는 헌혈 가능 여부를 판단하는 규칙을 보여주는 Jess 샘플 코드이다.


(clear) ; 작업 메모리와 규칙을 초기화한다.

; 헌혈자 정보를 저장할 템플릿 정의 (이름, 혈액형)
(deftemplate blood-donor (slot name) (slot type))

; 초기 헌혈자 데이터 (사실) 정의
(deffacts blood-bank ; 이름과 혈액형을 작업 메모리에 추가한다.
(blood-donor (name "Alice")(type "A"))
(blood-donor (name "Agatha")(type "A"))
(blood-donor (name "Bob")(type "B"))
(blood-donor (name "Barbara")(type "B"))
(blood-donor (name "Jess")(type "AB"))
(blood-donor (name "Karen")(type "AB"))
(blood-donor (name "Onan")(type "O"))
(blood-donor (name "Osbert")(type "O"))
)

; 규칙 1: 같은 혈액형끼리 수혈 가능 (단, 자신에게 수혈 불가)
; A->A, B->B, O->O, AB->AB 처리
(defrule can-give-to-same-type-but-not-self
(blood-donor (name ?name)(type ?type))
(blood-donor (name ?name2)(type ?type2 &:(eq ?type ?type2) &: (neq ?name ?name2) )) ; 혈액형은 같고 이름은 다른 경우
=>
(printout t ?name " can give blood to " ?name2 crlf) ; 수혈 가능 메시지 출력
)

; 규칙 2: O형은 다른 모든 혈액형에게 수혈 가능 (단, 자신에게 수혈 불가)
; O->A, O->B, O->AB 처리 (O->O는 규칙 1에서 처리)
(defrule O-gives-to-others-but-not-itself
(blood-donor (name ?name)(type ?type &:(eq ?type "O"))) ; 헌혈자가 O형인 경우
(blood-donor (name ?name2)(type ?type2 &: (neq ?type ?type2) &: (neq ?name ?name2) )) ; 수혈자가 O형이 아니고, 다른 사람인 경우
=>
(printout t ?name " can give blood to " ?name2 crlf) ; 수혈 가능 메시지 출력
)

; 규칙 3: A형 또는 B형은 AB형에게 수혈 가능
; A->AB, B->AB 처리 (O->AB는 규칙 2에서, AB->AB는 규칙 1에서 처리)
(defrule A-or-B-gives-to-AB
(blood-donor (name ?name)(type ?type &:(or (eq ?type "A") (eq ?type "B" )))) ; 헌혈자가 A형 또는 B형인 경우
(blood-donor (name ?name2)(type ?type2 &: (eq ?type2 "AB") &: (neq ?name ?name2) )) ; 수혈자가 AB형이고, 다른 사람인 경우
=>
(printout t ?name " can give blood to " ?name2 crlf) ; 수혈 가능 메시지 출력
)

;(watch all) ; 모든 동작(사실 추가/제거, 규칙 활성화/실행 등)을 감시하려면 주석 해제
(reset) ; 작업 메모리를 deffacts에 정의된 초기 상태로 리셋
(run) ; 규칙 실행 시작

2.2. 헌혈 가능 여부 판단 규칙 예제

아래는 Jess를 사용하여 헌혈 가능 여부를 판단하는 간단한 규칙 기반 시스템 예제 코드이다. 이 코드는 Jess의 기본적인 기능인 템플릿 정의(`deftemplate`), 사실 정의(`deffacts`), 규칙 정의(`defrule`)를 보여준다.


(clear) ; 작업 메모리를 초기화한다.

; 헌혈자 정보를 저장하기 위한 템플릿 정의
(deftemplate blood-donor
(slot name) ; 이름 슬롯
(slot type) ; 혈액형 슬롯 (A, B, AB, O)
)

; 초기 헌혈자 데이터(사실)를 정의하여 작업 메모리에 추가
(deffacts blood-bank
(blood-donor (name "Alice")(type "A"))
(blood-donor (name "Agatha")(type "A"))
(blood-donor (name "Bob")(type "B"))
(blood-donor (name "Barbara")(type "B"))
(blood-donor (name "Jess")(type "AB"))
(blood-donor (name "Karen")(type "AB"))
(blood-donor (name "Onan")(type "O"))
(blood-donor (name "Osbert")(type "O"))
)

; 규칙 1: 같은 혈액형끼리 헌혈 가능 (단, 자기 자신에게는 불가)
; 예: A형 -> A형, B형 -> B형, O형 -> O형, AB형 -> AB형
(defrule can-give-to-same-type-but-not-self
(blood-donor (name ?name)(type ?type)) ; 첫 번째 헌혈자 (이름: ?name, 혈액형: ?type)
(blood-donor (name ?name2)(type ?type2 &:(eq ?type ?type2) &: (neq ?name ?name2))) ; 두 번째 헌혈자 (혈액형이 같고(?type == ?type2) 이름이 다른(?name != ?name2))
=> ; 조건 만족 시 실행될 액션
(printout t ?name " can give blood to " ?name2 crlf) ; 결과 출력: "?name 은(는) ?name2 에게 헌혈할 수 있습니다."
)

; 규칙 2: O형은 다른 모든 혈액형에게 헌혈 가능 (단, 자기 자신에게는 불가)
; O형 -> O형 경우는 규칙 1에서 처리됨
(defrule O-gives-to-others-but-not-itself
(blood-donor (name ?name)(type ?type &:(eq ?type "O"))) ; 첫 번째 헌혈자 (혈액형이 O형)
(blood-donor (name ?name2)(type ?type2 &: (neq ?type ?type2) &: (neq ?name ?name2))) ; 두 번째 헌혈자 (혈액형이 다르고 이름도 다른)
=>
(printout t ?name " can give blood to " ?name2 crlf) ; 결과 출력
)

; 규칙 3: A형 또는 B형은 AB형에게 헌혈 가능
; O형 -> AB형, AB형 -> AB형 경우는 다른 규칙에서 처리됨
(defrule A-or-B-gives-to-AB
(blood-donor (name ?name)(type ?type &:(or (eq ?type "A") (eq ?type "B" )))) ; 첫 번째 헌혈자 (혈액형이 A형 또는 B형)
(blood-donor (name ?name2)(type ?type2 &: (eq ?type2 "AB") &: (neq ?name ?name2))) ; 두 번째 헌혈자 (혈액형이 AB형이고 이름이 다른)
=>
(printout t ?name " can give blood to " ?name2 crlf) ; 결과 출력
)

;(watch all) ; 모든 동작(사실 추가/제거, 규칙 활성화/실행 등)을 감시하려면 주석 해제

(reset) ; 작업 메모리를 deffacts에 정의된 초기 상태로 리셋
(run) ; 규칙 엔진 실행 및 결과 출력


위 코드는 다음과 같이 동작한다.
* `deftemplate`로 `blood-donor`라는 데이터 구조(템플릿)를 정의한다. 이 구조는 `name`(이름)과 `type`(혈액형) 정보를 가진다.
* `deffacts`를 사용해 여러 `blood-donor` 사실(Alice는 A형, Bob은 B형 등)을 작업 메모리에 미리 넣어둔다.
* `defrule`로 세 가지 헌혈 규칙을 정의한다.
첫 번째 규칙은 같은 혈액형끼리의 헌혈 가능성을 검사한다 (단, 동일 인물 제외).
두 번째 규칙은 O형이 다른 혈액형(A, B, AB)에게 헌혈할 수 있는지 검사한다 (동일 인물 제외).
** 세 번째 규칙은 A형 또는 B형이 AB형에게 헌혈할 수 있는지 검사한다 (동일 인물 제외).
* `reset` 명령어로 작업 메모리를 초기 사실 상태로 되돌린다.
* `run` 명령어로 규칙 엔진을 실행한다. 엔진은 작업 메모리의 사실들과 정의된 규칙들을 비교하여 조건에 맞는 규칙들을 실행하고, `printout` 함수를 통해 가능한 헌혈 관계를 출력한다.

3. 라이선스

(내용 없음)

3.1. 라이선스 종류

Jess의 소프트웨어 라이선스는 교육 및 정부 사용에 대해서는 프리웨어로 제공된다. 그러나 상업적인 목적으로 사용할 경우에는 라이선스를 구매해야 하는 독점 소프트웨어이다. 한편, Jess의 기반이 된 CLIPS는 자유-오픈 소스 소프트웨어이다.

3.2. CLIPS와의 관계

Jess의 소프트웨어 라이선스는 교육 및 정부 사용에 대해서는 프리웨어이며, 상업적 사용의 경우에는 라이선스가 필요한 독점 소프트웨어이다. 반면, Jess의 기반이자 시작 코드인 CLIPS는 자유-오픈 소스 소프트웨어이다.

4. 관련 시스템

Jess와 유사한 규칙 기반 시스템 및 프로그래밍 언어는 다음과 같다.

* CLIPS
* ILOG 규칙
* JBoss Drools
* Prolog
* OpenL Tablets
* DTRules

4.1. CLIPS

CLIPS는 전문가 시스템을 구축하기 위한 공개 도메인 소프트웨어 도구이다.

4.2. ILOG 규칙

ILOG 규칙은 비즈니스 규칙 관리 시스템(BRMS)이다.

4.3. JBoss Drools

Drools는 비즈니스 규칙 관리 시스템(BRMS)이다.

4.4. Prolog

Prolog는 범용 논리 프로그래밍 언어이다.

4.5. OpenL Tablets

OpenL Tablets는 비즈니스 중심 규칙 및 BRMS이다.

4.6. DTRules

DTRules는 의사 결정표를 기반으로 하는 자바오픈 소스 규칙 엔진이다.