(This is an experimental repost – for testing purposes, using Scribefire. Original post is here).
The G.I.S. Prolog interpreter was originally based on the “PIE interpreter” (included as free source-code in Visual Prolog) but it ended up enhanced with many extra predicates, as well as an improved core-level inference mechanism.
A multitude of extra predicates, implemented in pure Assembly language, became available through G.I.S. Prolog for easy immediate experimentation: Coding in G.I.S. Prolog produced immediate results, without any need for (often tedious) EXE-file compilation. Code modifications could therefore be done very quickly and most mistakes were (semi-)automatically corrected by the interpreter’s own enhanced error-checking capabilities.
apply_func(PRED, [Arg,Arg2,…]) <=> PRED(Arg1,Arg2,…)
GLOBAL DOMAINS
dom_iii = determ INTEGER (INTEGER,INTEGER,INTEGER) -(i,i,i) language c % <– example domain
GLOBAL PREDICATES
apply_func(DWORD,ListDomain) -(i,i) language c % where arg-1 is a predicate-domain, such as “dom_iii”
PREDICATES
func2dword(dom_iii,DWORD) % converts a predicate to a doubleword memory-address
CLAUSES
func2dword(FUNC,DW):- DW = cast(dword,FUNC).
GOAL
func2dword(add3,DW),
Out = apply_func(DW,[10,20,30]),
write(“result = “,Out), nl, readchar(_).
OK, so here is the Assembly language code:
; ======================= _apply_func.asm ==========================
; Code for TASM 5 Assembler, command-line call for compilation:
; C:\TASM\BIN\TASM32.EXE /p /z /w2 /m2 /ml _apply_func.asm
IDEAL
P586
MODEL flat
CODESEG
ALIGN 4
public _apply_func ; (i,i)
PROC _apply_func near
ARG func:dword, list:dword
LOCAL fcnt:dword
ENTER 4,0
push esi ;
push edi ;
push ebx ;
mov ecx,[func] ; function………… ARG 1
mov esi,[list] ; list……………. ARG 2
xor ebx,ebx ; make EBX=0
mov [fcnt],ebx ; initialize local variable ‘fcnt’ to 0
lodsd ; load the first list-element’s “element-flag”
dec al ; decrement it, to check if it was equal to 1
jnz short @@x1 ; exit if not so (i.e. if it was the end of the list)
; ———————- else…
@@L1: ; loop to read the (Visual-Prolog-) argument-list
inc ebx ; increment ebx (counter for number_of_arguments)
lodsd ; load next list-element (argument of function)
push eax ; push it into the stack (for later function-call)
lodsd ; load the pointer to the next list-element in EAX
mov esi,eax ; now ESI = (pointer-to-) next list-element
lodsd ; load element-flag of next list-element
dec al ; decrement it, to check if it was a 1
jz short @@L1 ; if so, not yet the end of the list, so repeat!
; ====================== else…
@@x1:
call ecx ; call the (external) function (given in ARG-1)
mov ecx,[fcnt] ; get the function’s number of arguments from fcnt
@@L2:
jcxz @@x2 ; if the called function had NO arguments, exit
; ———————- else…
@@L3: ; loop to POP function-arguments, after the call
pop edx ; recover next argument from the stack
mov ecx,[fcnt] ; recover remaining arguments_counter
dec ecx ; decrement the remaining number_of_arguments
mov [fcnt],ecx ; store it again, in the local variable fcnt
jnz short @@L3 ; if not zeroed, continue popping arguments…
; ———————-
@@x2:
pop ebx ;
pop edi ;
pop esi ;
LEAVE
ENDP _apply_func
end
[…] Assembly Language for Visual Prolog Meta-programming […]
Pingback by Ultra-Fast Hybrid Genetic Algorithm in Assembly Language for the Travelling Salesman Problem (DLL for LPA Prolog) « A.I. programming in Prolog and Assembler — May 8, 2009 @ 4:51 pm