/************************************************************************ * * * The SB-Prolog System * * Copyright SUNY at Stony Brook, 1986 * * * ************************************************************************/ /*----------------------------------------------------------------- SB-Prolog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the SB-Prolog General Public License for full details. Everyone is granted permission to copy, modify and redistribute SB-Prolog, but only under the conditions described in the SB-Prolog General Public License. A copy of this license is supposed to have been given to you along with SB-Prolog so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. ------------------------------------------------------------------ */ /* This file contains Prolog predicates that compiles a clause into a buffer. It treats all rules as though they had a single literal on the right-hand-side. Thus it compiles a clause with more than one literal on the right-hand-side as a call to the predicate ,/2 */ $dbcmpl_export([$db_cmpl/5,$db_cmpl/6,$db_putbuffop/4,$db_putbuffbyte/4, $db_putbuffnum/4]). /* $dbcmpl_use($buff, [$alloc_perm/2,$alloc_heap/2,$trimbuff/3,$buff_code/4,$symtype/2, $substring/6,$subnumber/6,$subdelim/6,$conlength/2, $pred_undefined/1, $hashval/3]). $dbcmpl_use($bmeta,[$atom/1,$atomic/1,$integer/1,$number/1,$structure/1, $functor0/2,$bldstr/3,$arg/3,$arity/2,$real/1,$floor/2]). $db_use($bio,[$writename/1,$writeqname/1,$put/1,$nl/0,$tab/1, $tell/1,$tell/2,$telling/1,$told/0,$get/1,$get0/1,$see/1,$seeing/1, $seen/0]). */ $db_putbuffop(Opn,Buff,Li,Lo) :- $buff_code(Buff,Li,3 /*pb*/ ,Opn), Lo is Li+1. $db_putbuffope(Opn,Buff,Li,Lo) :- $buff_code(Buff,Li,3 /*pb*/ ,Opn), Li1 is Li+1, $buff_code(Buff,Li1,3 /*pb*/ ,0), Lo is Li1+1. $db_putbuffbyte(Num,Buff,Li,Lo) :- $buff_code(Buff,Li,3 /*pb*/ ,Num), Lo is Li+1. $db_putbuffnum(Num,Buff,Li,Lo) :- $buff_code(Buff,Li,2 /*pn*/ ,Num), Lo is Li+4. $db_putbuffloat(Num,Buff,Li,Lo) :- $buff_code(Buff,Li,27 /*pf*/ ,Num), Lo is Li+4. $db_putbuffptr(Num,Buff,Li,Lo) :- $buff_code(Buff,Li,1 /*pppsc*/ ,Num), Lo is Li+4. $db_putbuffpsc(Num,Buff,Li,Lo) :- $buff_code(Buff,Li,0 /*ppsc*/ ,Num), Lo is Li+4. /* $db_cmpl(Clause,Clref,Index,Where,Supbuff): where Clause is a fact or rule. Clref is a variable through which is returned the Clref, and Index is the argument to index on (0 if none). Where is 0 if the buffer is to be allocated from the permanent area, and 2 if from a superbuff, which is in Supbuff. */ $db_cmpl(Clause,Buff,Index,Where,Supbuff) :- $db_cmpl(Clause,Buff,Index,Where,Supbuff,1). $db_cmpl(Clause,Buff,Index,Where,Supbuff,Flatten) :- $alloc_buff(5000,Buff,Where,Supbuff,_), /* must return Buff */ ((Clause=(_:-_) -> Clause=(Head:-Body); Clause=Head, Body=true), $arity(Head,Arity), Tempreg is Arity+1, $buff_code(Buff,0,14 /*ptv*/ ,Buff), /*set back pointer*/ $db_gentop(Head,Arity,1,Tempreg,Freereg,Buff,10,Lhd,uniq), (Flatten =:= 1 -> ($db_flatten(Body,FBody,[],Unifs), $db_flcode(Unifs,Freereg,R0,Buff,Lhd,Lm0,uniq) ) ; (Body = FBody, R0 = Freereg, Lm0 = Lhd) ), $arity(FBody,Barity), $db_genbod(FBody,Barity,1,[],Mvl,R0,Maxreg,Buff,Lm0,Lm1,uniq), (Index > 0 -> $db_putbuffchain(Buff, Lm1, Length); Length = Lm1), (Length > 5000,!,$db_mfail('Asserted clause too long ',Length); Length =< 5000, (Maxreg > 255,!, $db_mfail('Assert: too many registers required ',Maxreg); Maxreg =< 255, $trimbuff(Length,Buff,Where,Supbuff),fail ) ) ; true ). $db_mfail(Msg,Val) :- $telling(F),$tell(user), $writename(Msg),$writename(Val),$nl, $tell(F),fail. $db_putbuffchain(Buff, Lin, Lout) :- /* put code at the end for chaining clauses in the same bucket */ $db_putbuffop(249 /* noop */, Buff, Lin, L1), $db_putbuffbyte(2, Buff, L1, L2), $db_putbuffnum(0, Buff, L2, L3), $db_putbuffope(240 /* jump */, Buff, L3, L4), $buff_code(Buff, 10, 4, EPADDR), /* get start address of the code*/ $db_putbuffnum(EPADDR, Buff, L4, Lout). $db_gentop(Fact,Arity,Argno,Ri,Ro,Buff,Li,Lo,U) :- Argno > Arity, Ri = Ro, Li=Lo ; Argno =< Arity, $arg(Argno,Fact,T), $db_gentopinst(T,Argno,Ri,Rm,Buff,Li,Lm,U), Argno1 is Argno + 1, $db_gentop(Fact,Arity,Argno1,Rm,Ro,Buff,Lm,Lo,U). $db_gentopinst(T,Argno,Ri,Ro,Buff,Li,Lo,U) :- var(T), T='$var'(Argno,U), Ri = Ro, Li = Lo ; nonvar(T), ($atom(T) -> ((T = [] -> ($db_putbuffop(5,Buff,Li,Li1), /* getnil(Argno) */ $db_putbuffbyte(Argno,Buff,Li1,Lo) ) ; ($db_putbuffop(4,Buff,Li,Li1), /* getcon(T,Argno) */ $db_putbuffbyte(Argno,Buff,Li1,Li2), $db_putbuffptr(T,Buff,Li2,Lo) ) ), Ri = Ro ) ; ($integer(T) -> /* getnumcon(T,Argno) */ ($db_putbuffop(14,Buff,Li,Li1), $db_putbuffbyte(Argno,Buff,Li1,Li2), $db_putbuffnum(T,Buff,Li2,Lo), Ri = Ro ) ; ($real(T) -> /* getfloatcon(T,Argno) */ ($db_putbuffop(32,Buff,Li,Li1), $db_putbuffbyte(Argno,Buff,Li1,Li2), $db_putbuffloat(T,Buff,Li2,Lo), Ri = Ro ) ; ((T='$var'(Rt,Un), nonvar(Un), Un=U ) -> /* gettval(Rt,Argno) */ ($db_putbuffope(3,Buff,Li,Li1), $db_putbuffbyte(Rt,Buff,Li1,Li2), $db_putbuffbyte(Argno,Buff,Li2,Lo), Ri = Ro ) ; $db_genterms([Argno,T],Ri,Ro,Buff,Li,Lo,U) ) ) ) ). $db_genterms([],R,R,_,L,L,_). $db_genterms([R,T|Ts],Ri,Ro,Buff,Li,Lo,U) :- $db_genstruc(T,R,Buff,Ri,Rm,Li,Lm2,Substrs,U), $db_genterms(Substrs,Rm,Rm2,Buff,Lm2,Lm3,U), $db_genterms(Ts,Rm2,Ro,Buff,Lm3,Lo,U). $db_genstruc((A1,A2),R,Buff,Ri,Ro,Li,Lo,[],U) :- var(A1),var(A2),not(A1==A2),!,A1 = '$var'(Ri,U), Rm1 is Ri+1, A2 = '$var'(Rm1,U), Ro is Rm1+1, /* generate a getcomma_tvar_tvar */ $db_putbuffop(74,Buff,Li,Lm1), $db_putbuffbyte(R,Buff,Lm1,Lm2), $db_putbuffbyte(Ri,Buff,Lm2,Lm3), $db_putbuffbyte(Rm1,Buff,Lm3,Lo). $db_genstruc([A1|A2],R,Buff,Ri,Ro,Li,Lo,[],U) :- var(A1),var(A2),not(A1==A2),!,A1 = '$var'(Ri,U), Rm1 is Ri+1, A2 = '$var'(Rm1,U), Ro is Rm1+1, /* generate a getlist_tvar_tvar */ $db_putbuffop(72,Buff,Li,Lm1), $db_putbuffbyte(R,Buff,Lm1,Lm2), $db_putbuffbyte(Ri,Buff,Lm2,Lm3), $db_putbuffbyte(Rm1,Buff,Lm3,Lo). $db_genstruc(T,R,Buff,Ri,Rm,Li,Lo,Substrs,U) :- $db_genget(T,R,Buff,Li,Lm1),$arity(T,Arity), $db_dosubs(T,0,Arity,Ri,Rm,Buff,Lm1,Lo,Substrs,[],U). $db_genget([_|_],R,Buff,Li,Lo) :- !, /* getlist(R) */ $db_putbuffop(7,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). $db_genget((_,_),R,Buff,Li,Lo) :- /* not(T=[_|_]) */ !, /* getcomma(R) */ $db_putbuffop(73,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). $db_genget(T,R,Buff,Li,Lo) :- /* not(T=(_,_)),not(T=[_|_]) */ /* functor(T,F,Arity), getstr((F,Arity),R) */ $db_putbuffop(6,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Li2), $db_putbuffpsc(T,Buff,Li2,Lo). $db_dosubs(T,I,Arity,Ri,Ro,Buff,Li,Lo,Si,So,U) :- I < Arity, I1 is I+1, $arg(I1,T,Sub), $db_geninst(Sub,Ri,Rm,Si,Sm,Buff,Li,Lm,U), $db_dosubs(T,I1,Arity,Rm,Ro,Buff,Lm,Lo,Sm,So,U) ; I >= Arity, /* just to avoid having to lay down a CP */ I = Arity,Ri = Ro,Li = Lo,Si = So. $db_geninst(Sub,Ri,Ro,Si,So,Buff,Li,Lo,U) :- var(Sub), Si = So, Ro is Ri+1, Sub='$var'(Ri,U), /* unitvar(Ri) */ $db_putbuffop(10,Buff,Li,Li1), $db_putbuffbyte(Ri,Buff,Li1,Lo) ; nonvar(Sub), ($atom(Sub) -> ((Sub=[] -> $db_putbuffope(13,Buff,Li,Lo) ; /* uninil */ ($db_putbuffope(12,Buff,Li,Li1), /* unicon(Sub) */ $db_putbuffptr(Sub,Buff,Li1,Lo)) ), Ri = Ro, Si = So) ; ($integer(Sub) -> /* uninumcon(Sub) */ ($db_putbuffope(30,Buff,Li,Li1), $db_putbuffnum(Sub,Buff,Li1,Lo), Ri = Ro, Si = So) ; ($real(Sub) -> /* unifloatcon(Sub) */ ($db_putbuffope(34,Buff,Li,Li1), $db_putbuffloat(Sub,Buff,Li1,Lo), Ri = Ro, Si = So) ; ((Sub='$var'(R,Un),nonvar(Un),Un=U) -> /* unitval(R) */ ($db_putbuffop(11,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo), Ri = Ro, Si = So) ; (Ro is Ri+1, /* unitvar(Ri) */ Si = [Ri,Sub|So], $db_putbuffop(10,Buff,Li,Li1), $db_putbuffbyte(Ri,Buff,Li1,Lo)) ) ) ) ). $db_genbod(true,0,1,Mvlst,Mvlst,R,R,Buff,Li,Lo,U) :- !, $db_putbuffope(235 /*proceed*/ ,Buff,Li,Lo). $db_genbod(Body,Arity,Argno,Mvlst,Mvlsto,Ri,Ro,Buff,Locin,Locout,U) :- $db_genbo1(Body,Arity,Argno,Mvlst,Mvlsto,Ri,Ro,Buff,Locin,Locout,U). $db_genbo1(Body,Arity,Argno,Mvlst,Mvlsto,Ri,Ro,Buff,Locin,Locout,U) :- Argno > Arity -> Mvlst=Mvlsto, $db_genmvs(Mvlst,Ri,Ro,Buff,Locin,Lm1), functor(Body,Bodyn,Arity), /* wnl(execute(Bodyn,Arity)), */ $db_putbuffope(236,Buff,Lm1,Lm2), $db_putbuffpsc(Body,Buff,Lm2,Locout) ; $arg(Argno,Body,T), $db_genaput(T,Argno,Mvlst,Mvlstm,Ri,Rm,Buff,Locin,Locm,U), Argno1 is Argno+1, $db_genbo1(Body,Arity,Argno1,Mvlstm,Mvlsto,Rm,Ro,Buff,Locm,Locout,U). $db_genaput(T,Argno,Mvlst,Mvlsto,Ri,Ro,Buff,Locin,Locout,U) :- var(T) -> Ro is Ri+1,Locout=Locin,Mvlsto=[puttvar(Tempvar),Argno|Mvlst], T='$var'(Tempvar,U) ; (T='$var'(Rt,U) -> (var(Rt) -> Mvlsto=[puttvar(Rt),Argno|Mvlst]; Mvlsto=[movreg(Rt),Argno|Mvlst]), Ro=Ri,Locout=Locin ; ($integer(T) -> Mvlsto=[putnumcon(T),Argno|Mvlst],Ro=Ri,Locout=Locin ; ($real(T) -> (Mvlsto=[putfloatcon(T),Argno|Mvlst],Ro=Ri,Locout=Locin) ; ($atom(T) -> (T=[] -> Mvlsto=[putnil,Argno|Mvlst]; Mvlsto=[putcon(T),Argno|Mvlst]), Ro=Ri,Locout=Locin ; Mvlsto=[movreg(Ri),Argno|Mvlst],Rm is Ri+1, $db_putterm(Ri,T,Rm,Ro,Buff,Locin,Locout,U) ) ) ) ). $db_putterm(R,T,Ri,Ro,Buff,Li,Lo,U) :- $arity(T,Arity), $db_putsubstr(T,0,Arity,Ri,Rm,Buff,Li,Lm1,[],Subterms,U), $db_genputstr(T,R,Buff,Lm1,Lm2), $db_putsubs(Subterms,Rm,Ro,Buff,Lm2,Lo). $db_genputstr([_|_],R,Buff,Li,Lo) :- !, /* wnl(putlist(R)), */ $db_putbuffop(23,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). /* $db_genputstr((_,_),R,Buff,Li,Lo) :- * not(T=[_|_]) * !, * getcomma(R) * $db_putbuffop(73,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). */ $db_genputstr(T,R,Buff,Li,Lo) :- /* not(T=(_,_)),not(T=[_|_]) */ /* functor(T,F,Arity), wnl(putstr((F,Arity),R)), */ $db_putbuffop(22,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Li2), $db_putbuffpsc(T,Buff,Li2,Lo). $db_putsubstr(T,I,Arity,Ri,Ro,Buff,Li,Lo,Si,So,U) :- I < Arity -> I1 is I+1, $arg(I1,T,Sub), $db_bldsubs(Sub,Ri,Rm,Si,Sm,Buff,Li,Lm,U), $db_putsubstr(T,I1,Arity,Rm,Ro,Buff,Lm,Lo,Sm,So,U) ; I = Arity,Ri = Ro,Li = Lo,Si = So. $db_bldsubs(Sub,Ri,Ro,Si,So,Buff,Li,Lo,U) :- var(Sub) -> So = [bldtvar(Ri)|Si], Ro is Ri+1, Li = Lo, Sub='$var'(Ri,U) /* bldtvar(Ri) */ ; ($atom(Sub) -> (Sub=[] -> So = [bldnil|Si]; /* bldnil */ So = [bldcon(Sub)|Si]), /* bldcon(Sub) */ Ri = Ro, Li = Lo ; ($integer(Sub) -> /* bldnumcon(Sub) */ So = [bldnumcon(Sub)|Si], Ri = Ro, Li = Lo ; ($real(Sub) -> /* bldfloatcon(Sub) */ (So = [bldfloatcon(Sub)|Si], Ri = Ro, Li = Lo) ; ((Sub='$var'(R,Un),nonvar(Un),Un=U) -> So = [bldtval(R)|Si], /* bldtval(R) */ Ri = Ro,Li = Lo ; Rm is Ri+1, /* bldtvar(Ri) */ So = [bldtval(Ri)|Si], $db_putterm(Ri,Sub,Rm,Ro,Buff,Li,Lo,U) ) ) ) ). $db_putsubs([],R,R,_,L,L). $db_putsubs([Bld|Rest],Ri,Ro,Buff,Li,Lo) :- $db_putsubs(Rest,Ri,Ro,Buff,Li,Lm), $db_bldinst(Bld,Buff,Lm,Lo). $db_bldinst(bldtvar(R),Buff,Li,Lo) :- /* wnl(bldtvar(R)), */ $db_putbuffop(26,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). $db_bldinst(bldnil,Buff,Li,Lo) :- /* wnl(bldnil), */ $db_putbuffope(29,Buff,Li,Lo). $db_bldinst(bldcon(Sub),Buff,Li,Lo) :- /* wnl(bldcon(Sub)), */ $db_putbuffope(28,Buff,Li,Li1), $db_putbuffptr(Sub,Buff,Li1,Lo). $db_bldinst(bldnumcon(Sub),Buff,Li,Lo) :- /* wnl(bldnumcon(Sub)), */ $db_putbuffope(31,Buff,Li,Li1), $db_putbuffnum(Sub,Buff,Li1,Lo). $db_bldinst(bldfloatcon(Sub),Buff,Li,Lo) :- /* wnl(bldfloatcon(Sub)), */ $db_putbuffope(35,Buff,Li,Li1), $db_putbuffloat(Sub,Buff,Li1,Lo). $db_bldinst(bldtval(R),Buff,Li,Lo) :- /* wnl(bldtval(R)), */ $db_putbuffop(27,Buff,Li,Li1), $db_putbuffbyte(R,Buff,Li1,Lo). /* this is a simple routine to generate a series of instructions to load a series of registers with constants or from other registers. It is given a list of Source,Target pairs. Target is always a register number. Source may be a putcon(con), putnumcon(num), putfloatcon(num), puttvar(reg), puttvar(Var), or movreg(reg). The registers can overlap in any way. $db_genmvs tries to generate a reasonably efficient series of instructions to load the indicated registers with the indicated values. */ $db_genmvs([],R,R,B,L,L). $db_genmvs([I,T|Rest],Ri,Ro,Buff,Li,Lo) :- $db_genmvs(I,T,Ri,Ro,Buff,Li,Lo,Rest). $db_genmvs(puttvar(R),T,Ri,Ro,Buff,Li,Lo,Rest) :- $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), (nonvar(R) -> /* wnl(movreg(R,T)), */ $db_putbuffope(209,Buff,Lm,Lm1), $db_putbuffbyte(R,Buff,Lm1,Lm2), $db_putbuffbyte(T,Buff,Lm2,Lo) ; R=T, /* wnl(puttvar(R,R)), */ $db_putbuffope(18,Buff,Lm,Lm1), $db_putbuffbyte(R,Buff,Lm1,Lm2), $db_putbuffbyte(R,Buff,Lm2,Lo) ). $db_genmvs(putcon(C),T,Ri,Ro,Buff,Li,Lo,Rest) :- !, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), /* wnl(putcon(T,C)), */ $db_putbuffop(20,Buff,Lm,Lm1), $db_putbuffbyte(T,Buff,Lm1,Lm2), $db_putbuffptr(C,Buff,Lm2,Lo). $db_genmvs(putnil,T,Ri,Ro,Buff,Li,Lo,Rest) :- !, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), /* wnl(putnil(T)), */ $db_putbuffop(21,Buff,Lm,Lm1), $db_putbuffbyte(T,Buff,Lm1,Lo). $db_genmvs(putnumcon(I),T,Ri,Ro,Buff,Li,Lo,Rest) :- !, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), /* wnl(putnumcon(T,I)), */ $db_putbuffop(15,Buff,Lm,Lm1), $db_putbuffbyte(T,Buff,Lm1,Lm2), $db_putbuffnum(I,Buff,Lm2,Lo). $db_genmvs(putfloatcon(I),T,Ri,Ro,Buff,Li,Lo,Rest) :- !, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), /* wnl(putfloatcon(T,I)), */ $db_putbuffop(33,Buff,Lm,Lm1), $db_putbuffbyte(T,Buff,Lm1,Lm2), $db_putbufffloat(I,Buff,Lm2,Lo). $db_genmvs(movreg(R),R,Ri,Ro,Buff,Li,Lo,Rest) :- !, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lo). $db_genmvs(movreg(S),T,Ri,Ro,Buff,Li,Lo,Rest) :- not($dbcmpl_frstmem(T,Rest)),!, /* wnl(movreg(S,T)), */ $db_putbuffope(209,Buff,Li,Lm1), $db_putbuffbyte(S,Buff,Lm1,Lm2), $db_putbuffbyte(T,Buff,Lm2,Lm), $db_genmvs(Rest,Ri,Ro,Buff,Lm,Lo). $db_genmvs(movreg(S),T,Ri,Ro,Buff,Li,Lo,Rest) :- not($dbcmpl_scndmem(S,Rest)),!, $db_genmvs(Rest,Ri,Ro,Buff,Li,Lm), /* wnl(movreg(S,T)), */ $db_putbuffope(209,Buff,Lm,Lm1), $db_putbuffbyte(S,Buff,Lm1,Lm2), $db_putbuffbyte(T,Buff,Lm2,Lo). $db_genmvs(movreg(S),T,Ri,Ro,Buff,Li,Lo,Rest) :- /* wnl(movreg(S,Ri)), */ $db_putbuffope(209,Buff,Li,Lm1), $db_putbuffbyte(S,Buff,Lm1,Lm2), $db_putbuffbyte(Ri,Buff,Lm2,Lm3), Rm is Ri+1, $db_genmvs(Rest,Rm,Ro,Buff,Lm3,Lm4), /* wnl(movreg(Ri,T)), */ $db_putbuffope(209,Buff,Lm4,Lm5), $db_putbuffbyte(Ri,Buff,Lm5,Lm6), $db_putbuffbyte(T,Buff,Lm6,Lo). /* wnl(X) :- write(X),nl. */ $dbcmpl_frstmem(T,[movreg(T),_|_]). $dbcmpl_frstmem(T,[_|Rest]) :- $dbcmpl_frstmem(T,Rest). $dbcmpl_scndmem(S,[_,S|_]). $dbcmpl_scndmem(S,[_|Rest]) :- $dbcmpl_scndmem(S,Rest). /* This is a kludge to fix up a problem with the depth-first traversal of arguments interacting in a bad way with the flattening of terms. The problem is that when translating arguments in the body, the depth first traversal doesn't take into account the fact that subterms may move forward due to flattening, thereby changing "first" and "subsequent" occurrences of variables. To make things work, though much less efficiently than before, I'm just going through an explicit flattening stage beforehand. I don't doubt there are more elegant solutions, I'm just a user who wants to use assert to do other things. */ $db_flatten(Term,NewTerm,Si,So) :- $structure(Term) -> (functor(Term,F,N), functor(NewTerm,F,N), $db_flatten1(Term,0,N,NewTerm,Si,So) ); (NewTerm = Term, Si = So). $db_flatten1(Term,N,Arity,NewTerm,Si,So) :- (N =:= Arity) -> (Si = So) ; (ArgNo is N + 1, arg(ArgNo,Term,OldArg), arg(ArgNo,NewTerm,NewArg), (($structure(OldArg), not(OldArg = '$var'(_,_))) -> (Sm0 = [NewArg,NewArg0|Si], $db_flatten(OldArg,NewArg0,Sm0,Sm1) ) ; (OldArg = NewArg, Sm1 = Si) ), N1 is N + 1, $db_flatten1(Term,N1,Arity,NewTerm,Sm1,So) ). $db_flcode([],R,R,_Buff,Loc,Loc,_). $db_flcode([Temp,Str|Rest],Ri,Ro,Buff,Li,Lo,U) :- Temp = '$var'(R,U), ((var(R), R = Ri, Rm0 is Ri+1) ; (nonvar(R), Rm0 = Ri) ), $db_putterm(R,Str,Rm0,Rm1,Buff,Li,Lm,U), $db_flcode(Rest,Rm1,Ro,Buff,Lm,Lo,U).