home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
languags
/
prolog
/
epro23.ark
/
PROVE.MAC
< prev
next >
Wrap
Text File
|
1986-11-02
|
10KB
|
620 lines
; ===========================================================
; PROVE.Z80
; prove routine for E-Prolog
; June 22, 1985
.Z80
FALSE EQU 0
TRUE EQU 1
EMPTY EQU -1
UNDEF EQU -2
FROZEN EQU -3
DEBUG EQU FALSE
HT EQU 9
LF EQU 10
CR EQU 13
CTLZ EQU 26
CPM EQU 0000H
BDOS EQU CPM+0005H
CDMA EQU CPM+0080H
TPA EQU CPM+0100H
;BETASTATE * prbase;
DSEG
PRBASE: DW 0
CSEG
;
;prove(glist)
;/* This routine is iterative rather than recursive
; in order to use as little heap space as possible. */
; PAIR glist; /* list of goals */ in HL
; {
; ALPHASTATE * ast; in IX
; static BETASTATE * bst; in IY
; static BETASTATE * bbot;
; static int x;
DSEG
BBOT: DW 0
CSEG
;
PROVE::
; bst = prbase = makebeta(empty,listone(glist));
;#define listone(x) makepair((x),empty)
LD DE,EMPTY
CALL MKPAIR##
LD IX,EMPTY
CALL MKBETA##
LD (PRBASE),IY
; freeze(bst);
CALL FREEZE##
; goto bstart;
JP BSTART
;
;/*==========*/
; astart: /* start an alpha state here */
;/*==========*/
ASTART:
;#ifdef DEBUG
IF DEBUG
; printf("\nALPHA %04x: ",ast);
LD HL,AS1MSG
CALL MSG##
DSEG
AS1MSG: DB CR,LF,'ALPHA ',0
CSEG
PUSH IX
POP HL
CALL PRHEX
LD A,' '
CALL CHROUT##
; eprint(ast->goal->left.list,ast->pred->subst);
CALL XPRED##
CALL @SUBST##
PUSH HL
CALL XGOAL##
CALL @LEFT##
POP DE
CALL EPRINT##
;#endif
ENDIF
;
;/*==========*/
; arpt: /* repeat this alpha state */
;/*==========*/
ARPT:
; if (numbp(ast->datb))
CALL XDATB##
CALL NUMBP##
JP Z,AR1
; {
; /* built-in command */
; bst = (BETASTATE *)empty;
LD IY,EMPTY
; if (x = (*((BOOLEAN (*)())(ast->datb)))
; (ast->goal->left.list->right.list,ast,
; ast->pred->subst,&bst))
CALL XPRED##
CALL @SUBST##
PUSH HL ; ast->pred->subst
CALL XGOAL##
POP DE
CALL V@LEFT
CALL V@RIGHT
PUSH HL ; ast->goal->left.list->right.list
PUSH DE
CALL XDATB## ; ast->datb
LD (ADDR+1),HL
POP DE
POP HL
ADDR: CALL 0 ; address filled in here
JR Z,AR2
; {
; if (x == EMPTY)
LD DE,EMPTY
CALL CPHL##
JR NZ,AR4
; {
; /* CUT */
; bst = ast->back;
CALL XBACK##
PUSH HL
POP IY
; release(ast);
PUSH IX
POP HL
CALL RLS##
; ast = (bbot = (ast->pred))->pred;
CALL XPRED##
LD (BBOT),HL
CALL @PRED##
PUSH HL
POP IX
; if (ast == (ALPHASTATE *)empty)
LD DE,EMPTY
CALL CPHL##
JR NZ,AR5X
; return FALSE;
RETF: XOR A
RET
; *** release from here (bst) back to there (bbot)
AR5X:
CALL BRLS##
LD HL,(BBOT)
PUSH IY
POP DE
CALL CPHL##
JR Z,AR5
CALL YPRED##
CALL RLS##
CALL @XBACK##
PUSH HL
POP IY
JR AR5X
;AR5: combined with the other case, below
;
AR4:
; /* A fake beta to hold temporary data for unifies */
; if (bst == (BETASTATE *)empty)
PUSH IY
POP HL
LD DE,EMPTY
CALL CPHL##
JR NZ,AR9
; bst = makebeta(ast,empty);
LD HL,EMPTY
CALL MKBETA##
AR9:
; freeze(bst);
CALL FREEZE##
; goto bstart;
JP BSTART
; }
AR2:
; if (bst != (BETASTATE *)empty)
PUSH IY
POP HL
LD DE,EMPTY
JR Z,AR6
; release(bst);
CALL BRLS## ; ? RLS ?
AR6:
; ast->datb = empty; /* failure */
LD HL,EMPTY
CALL XLDATB##
; }
AR1:
; if (ast->datb == (PAIR)empty)
CALL XDATB##
LD DE,EMPTY
CALL CPHL##
JR NZ,AR7
; {
AR5:
; /* no (more) facts in the database - FAIL*/
; /* roll back pointer in tree-predecessor */
; ast->pred->assertion.list = ast->goal;
CALL XGOAL##
PUSH HL
CALL XPRED##
PUSH HL
POP IY
POP HL
CALL YLASS##
; bst = ast->back;
CALL XBACK##
PUSH HL
POP IY
; release(ast);
PUSH IX
POP HL
CALL RLS##
; goto bafail;
JP BAFAIL
; }
AR7:
; bst = makebeta(ast,ast->datb->left.list);
CALL XDATB##
CALL @LEFT##
CALL MKBETA##
; ast->datb = ast->datb->right.list;
CALL XDATB##
CALL @RIGHT##
CALL XLDATB##
; if (unify(ast->goal->left.list,ast->pred->subst,
; bst->assertion.list->left.list,bst->subst))
CALL YSUBST##
PUSH HL
CALL YASS##
CALL @LEFT##
POP DE
EXX
CALL XPRED##
CALL @SUBST##
PUSH HL
CALL XGOAL##
CALL @LEFT
POP DE
CALL UNIFY##
JR Z,AR8
; {
; freeze(bst);
CALL FREEZE##
;#ifdef DEBUG
IF DEBUG
;msg(" *** unified");
LD HL,AR7MSG
CALL MSG##
DSEG
AR7MSG: DB ' *** unified',0
CSEG
;#endif
ENDIF
; bst->assertion.list = bst->assertion.list->right.list;
CALL YASS## ; *** how about variable here?
CALL @RIGHT##
CALL YLASS##
; goto bstart;
JP BSTART
; }
AR8:
;#ifdef DEBUG
IF DEBUG
;msg(" *** not unified");
LD HL,AR8MSG
CALL MSG##
DSEG
AR8MSG: DB ' *** not unified',0
CSEG
;#endif
ENDIF
; brelease(bst);
CALL BRLS##
; goto abfail;
JP ABFAIL
;
;/*==========*/
; absucc: /* return to alpha after success of beta */
;/*==========*/
; fatal("\r\nabsucc not written.");
;
;/*==========*/
; abfail: /* return to alpha after failure of beta */
;/*==========*/
ABFAIL EQU ARPT
; goto arpt;
;
;/*==========*/
; bstart: /* start beta state here */
;/*==========*/
BSTART:
;#ifdef DEBUG
IF DEBUG
; printf("\nBETA %04x: ",bst);
LD HL,BSMSG
CALL MSG##
DSEG
BSMSG: DB CR,LF,'BETA ',0
CSEG
PUSH IY
POP HL
CALL PRHEX
LD A,' '
CALL CHROUT##
; eprint(bst->assertion.list,bst->subst);
CALL YSUBST##
PUSH HL
CALL YASS##
POP DE
CALL EPRINT##
;#endif
ENDIF
;
;/*==========*/
; brpt: /* repeat beta state */
;/*==========*/
;BRPT:
; if (bst->assertion.list == (PAIR)empty)
CALL YASS
LD DE,EMPTY
CALL CPHL##
JR NZ,BR1
; {
; /* no (more) goals - Succeed */
; bbot = bst;
LD (BBOT),IY
; while (bst->assertion.list == (PAIR)empty)
BR3:
CALL YASS##
LD DE,EMPTY
CALL CPHL##
JR NZ,BR4
; {
; if (bst == prbase)
PUSH IY
POP HL
LD DE,(PRBASE)
CALL CPHL##
JR NZ,BR5
; {
; if (infile == stdin && outfile == stdout)
LD A,(INF##)
OR A
JR NZ,BR6
LD A,(OUTF##)
OR A
JR NZ,BR6
; msg("Yes.");
LD HL,BR6MSG
CALL MSG##
DSEG
BR6MSG: DB 'Yes.',0
CSEG
BR6:
; if (prvals())
CALL PRVALS
JR Z,BR7
; {
; bst = bbot;
LD IY,(BBOT)
; goto bafail;
JP BAFAIL
; }
BR7:
; else
; return;
RET
; }
BR5:
; bst = bst->pred->pred;
CALL YPRED##
CALL @PRED##
PUSH HL
POP IY
; }
JR BR3
BR4:
; ast = makealpha(bst,bst->assertion.list,bbot);
CALL YASS##
LD DE,(BBOT)
CALL MKALPHA##
; }
JR BR2
BR1:
; else
; /* both pointers are to bst */
; ast = makealpha(bst,bst->assertion.list,bst);
CALL YASS##
PUSH IY
POP DE
CALL MKALPHA##
BR2:
; bst->assertion.list = bst->assertion.list->right.list;
CALL YASS##
CALL @RIGHT##
CALL YLASS##
; goto astart;
JP ASTART
;
;/*==========*/
; basucc: /* return to beta after success of alpha */
;/*==========*/
;BASUCC EQU BRPT
; goto brpt;
;
;/*==========*/
; bafail: /* return to beta after failure of alpha */
;/*==========*/
BAFAIL:
; ast = bst->pred;
CALL YPRED##
PUSH HL
POP IX
; if (ast == (ALPHASTATE *)empty)
LD DE,EMPTY
CALL CPHL##
JR NZ,BA1
; return FALSE;
XOR A
RET
BA1:
; brelease(bst);
CALL BRLS##
; goto abfail;
JP ABFAIL
; }
;
;prvals()
; {
; SUBST * x;
; int cnt;
DSEG
X: DW 0
CNT: DB 0
CSEG
PRVALS:
;
; cnt = 0;
XOR A
LD (CNT),A
; for (x = prbase->subst ; substp(x) ; x++)
LD HL,(PRBASE)
CALL @SUBST##
LD (X),HL
PR2:
CALL SUBSTP##
JR Z,PR1
; {
; chrout('\t');
LD A,HT
CALL CHROUT##
; msg(x->vname->string);
CALL @VNAME##
CALL @STR##
CALL MSG##
; msg(" = ");
LD HL,PR1MSG
CALL MSG##
DSEG
PR1MSG: DB ' = ',0
CSEG
; prval(x);
LD HL,(X)
CALL PRVAL
; cnt = 1;
LD A,1
LD (CNT),A
; msg("\r\n");
CALL CRLF##
; }
LD HL,(X)
LD DE,6
ADD HL,DE
LD (X),HL
JR PR2
PR1:
; if (! cnt)
LD A,(CNT)
OR A
JR NZ,PR3
; {
; msg("\r\n");
CALL CRLF##
; return FALSE;
XOR A
RET
; }
PR3:
; msg("More?");
LD HL,PR3MSG
CALL MSG##
DSEG
PR3MSG: DB 'More?',0
CSEG
; while (separp(rdchar()))
; ;
PR4:
CALL RDCHAR##
CALL SEPARP##
JR NZ,PR4
; if (character == 'Y' || character == 'y')
; return TRUE;
; return FALSE;
LD A,(CHR##)
CP 'Y'
JR Z,RETT
CP 'y'
JR Z,RETT
XOR A
RET
RETT: LD A,1
OR A
RET
; }
;
;prval(sub)
; SUBST * sub;
; {
; static SUBVAL as;
DSEG
AS: DW 0
CSEG
PRVAL:
;
; as.val = value(sub);
CALL VALUE##
LD (AS),HL
; if (substp(as.val))
CALL SUBSTP##
JR Z,PR6
; msg(as.val->vname->string);
CALL @VNAME##
CALL @STR##
CALL MSG##
RET
PR6:
; else
; eprint(as.assgn->sexp.list,as.assgn->slist);
CALL @SLIST##
PUSH HL
LD HL,(AS)
CALL @EXPR##
POP DE
CALL EPRINT##
RET
; }
;
IF DEBUG
; display HL in hex
PRHEX: LD A,H
CALL HINYB
CALL LONYB
LD A,L
CALL HINYB
CALL LONYB
RET
HINYB: PUSH AF
AND 0F0H
RRCA
RRCA
RRCA
RRCA
CALL LONYBX
POP AF
RET
LONYB: AND 00FH
LONYBX: ADD A,90H
DAA
ADC A,40H
DAA
JP CHROUT##
ENDIF
; right (value if variable)
; expression in HL, substs in DE
V@RIGHT:
PUSH DE
PUSH HL
LD HL,@RIGHT##
LD (V@R+1),HL
V@9: POP HL
CALL VARP##
JR NZ,V@0
V@R: CALL 0 ; filled in
POP DE
RET
V@0: POP DE
CALL VF##
CALL VALUE##
PUSH HL
CALL SUBSTP##
JR Z,V@1
LD HL,V@ERR
JP ERROR##
DSEG
V@ERR: DB CR,LF,'Meta-variable remaining',0
CSEG
V@1: POP HL
PUSH HL
CALL @SLIST##
POP HL
PUSH DE
CALL @EXPR##
JR V@R
; left (value if variable)
; expression in HL, substs in DE
V@LEFT:
PUSH DE
PUSH HL
LD HL,@LEFT##
LD (V@R+1),HL
JR V@9
END