GA - LISP-like-Language

1. LISP-like-Language(LlL)
실제로 리스프언어를 사용하여 진화알고리즘을 시험해 봤으면 좋겠습니다만... 약간의 문제가 있습니다.
진화알고리즘을 통해 만들어진 리스프 프로그램을 리스프 인터프리터와 연동시킬 수가 없다는 - 리스프 인터프리터까지 만들어야 한다는 - 문제죠(물론 그보다 더 큰 문제는 저 자신이 리스프언어를 잘 모른다는 점...).

그래서 여기서는 LlL이라는, 말 그대로 '리스프모양의 언어'를 만들어 사용하기로 했습니다.

2. LlL의 명령어
LlL에는 다음과 같은 19개의 명령어가 존재합니다.
2.1 (proc (ㄱ) (ㄴ) (ㄷ) ..... (ㅎ))
(ㄱ)부터 (ㅎ)까지 차례로 실행한 후 (ㅎ)의 리턴값을 리턴합니다. 만약 하위노드가 하나도 없다면 0을 리턴합니다.
2.2 (setv (ㄱ) (ㄴ) ....)
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ)번째 변수에 (ㄴ)의 리턴값을 넣습니다. 그리고 (ㄴ)의 리턴값을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.3 (getv (ㄱ) ... )
(ㄱ)를 실행한 후(만약 (ㄱ)가 없으면 0으로 간주) 해당되는 변수의 값을 리턴합니다. 두번째 이후의 식은 실행되지 않습니다.
2.4 (+ (ㄱ) (ㄴ) .... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) 두 값의 합을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.5 (- (ㄱ) (ㄴ) .... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) - (ㄴ)를 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.6 (* (ㄱ) (ㄴ) .... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) 두 값의 곱을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.7 (/ (ㄱ) (ㄴ) .... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) / (ㄴ)를 리턴합니다. 만약 (ㄴ)의 리턴값이 0이면 프로그램이 종료됩니다. 3번째 이후의 식은 실행되지 않습니다.
2.8 (if (ㄱ) (ㄴ) (ㄷ) ... )
(ㄱ)를 실행한 후 그 값이 0이 아니면 (ㄴ)를, 0이면 (ㄷ)를 실행후 그 값을 리턴시킵니다. (ㄴ)나 (ㄷ)가 없다면 0을 리턴시킵니다. 그 이외의 식은 실행되지 않습니다.
2.9 (while (ㄱ) (ㄴ) .... )
(ㄱ)를 검사하여 0이 아니면 (ㄴ)를 실행시킵니다. 이 과정을 (ㄱ)가 0이 될 때까지 반복합니다. (ㄱ)가 0이 되면 최후에 실행했을 때의 (ㄴ)값을 리턴합니다.
2.10 (> (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) > (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.11 (>= (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) >= (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.12 (== (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) == (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.13 (!= (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) != (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.14 (< (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) < (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.15 (<= (ㄱ) (ㄴ) ... ) (ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) <= (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.16 (& (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) & (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.17 (| (ㄱ) (ㄴ) ... )
(ㄱ)와 (ㄴ)를 차례로 실행한 후(만약 (ㄱ)나 (ㄴ)가 없다면 0으로 간주) (ㄱ) | (ㄴ)을 리턴합니다. 3번째 이후의 식은 실행되지 않습니다.
2.18 (exit (ㄱ) ... )
(ㄱ)식을 계산한 후 프로그램을 종료시키며 전체 값을 프로그램의 리턴값으로 합니다. 이후의 식은 실행되지 않습니다.
2.19 (숫자 (ㄱ) (ㄴ) .... )
하위 식들은 전혀 실행되지 않습니다. 그리고 숫자의 값이 리턴값이 됩니다. 숫자는 0 이상의 정수입니다.

3. 보기
이 LlL로 어떤 수 (0번째 변수에 입력된 수)가 소수인지 아닌지 확인하는 프로그램입니다.

(proc
.. (setv (1) (2)) // 1번변수(이후 [1]로 표시)에 2 입력
.................. // 이후 [1]을 계속 증가시켜가며 나누기할 예정
.. (while
..... (>
........ (*
(getv (1)) // [1]의 제곱이 [0]보다 커지면 더이상 계산 불필요
........... (getv (1)) // while문 탈출
........ )
........ (getv (0))
..... )
..... (proc
........ (setv (2)
.............. (/ (getv (0)) // 다음 단락까지 [0] / [1] * [1]을 계산
................. (getv (1))
.............. )
........ )
........ (setv (3)
.............. (* (getv (2)) // 계산결과를 [3]에 저장
................. (getv (1))
.............. )
........ )
........ (if (== (getv (3)) // [3]과 [0]이 같다는 것은 나머지가 0이라는 것
................ (getv (0))
............ )
............ (exit 0) // 소수가 아니므로 0을 리턴하고 프로그램 종료
........ }
........ (setv (1)
.............. (+ (getv (1)) // [1]값을 1 증가
................. (1)
.............. )
........ )
..... )
.. )
.. (1) // while문을 통과했다면 전체 proc함수가 1을 리턴하도록
}

댓글 없음:

댓글 쓰기