% trace code = 4000 domains i= integer r= real st= string lst= st* li= i* file= valores term = opr(st,lt);cons(st);var(st) lt = term* database - ter % - parentesis(abre,cierra) parentesis(i,i) % -(i,i),(o,o),(i,o),(o,i) database - ec database - aux % - contador auxiliar de proposito general. aux(i) % -(i),(o) % - se apoya con el predicado NUM(o). c0(st,r,r,st,r,r) % - primer auxiliar para el cruce por cero. ok(i) % - segundo auxiliar para el cruce por cero. database - valor % - Almacenador de los valores a evaluar. valor(r) % - (i),(o) database - vxy vxy(i,r,r) % -(#, Vx, Vy])- database - ejes % -[valores extremos del eje x] {ejes.{v} ejex(i,r,r) % -(#, px, gx) ejey(i,r,r) % -(#, py, gy) cero(i,st) % -(#, 0x) -- [cruce por cero] % - sqr(N) no es raIz cuadrada. predicates archivo(i,st) % -(i,o) busca(lst,lst) % -(i,o) cadena(lst,st,st) % -(i,i,o) conv(lst,lt) % -(i,o) cuadrada(lt) % - detecta si se inicia con "SQR". divide(lst,lst) % -(i,o) elemento(lst,st) % -(i,o) eval(lt,r) % -(i,o) existe_archivo % inverso(r,r) % -(i,i) - indica el avance de la evaluacion. item(r) % -(i) - Axiliar para guardar el valor % - del ciclo para iteraciones. nondeterm for(i,i,i) nondeterm for1(r,r,r,r) icia con "SQR". inicia inicia1(i) % -(i) interpola(i) lee_funcion(lst,lst) % -(i,o) make(li,lst) min_maxx min_max1(i) min_maxy(i,r) % -(i,i) numero(lst,lst) % -(i,o) nondeterm separar(lst,lst,lst) % -(*,*,*) es el append num(i) % -(o) incrementa aux(_,aux) remove(li) % -(i) rest(lst) % -(i) saca(i,r,r) % -(act,Vx,Vy) saca_cero(i) % -(act) saca_elem(lst,st,lst) % -(i,o,o) shift(li) % -(i) str_list(st,lst) % -(i,o) video video1 write1(i,i,st) % -(i,i,i) [ren,col,texto] % ------------------------------------------------------------------------ % % Programa: parser.pro % Objetivo: intErprete y evaluador de ecuaciones % Escuela de IngenierIa ElEctrica % U. M. S. N. H. % Ultima modificaciOn: {Abril/20/1993}{02:35} % ------------------------------------------------------------------------ clauses % --------------------------------------------------------------------------- % --------------------------- PARSER ------------------------------------ conv(["("|T],[K1]):- % =========== if Resto = "" retractall(_,ter),asserta( parentesis(0,0),ter), busca(["("|T],[]), !, separar(Termino, [")"], T), conv(Termino,[K1]). conv(["("|T],[opr(Opr,[K1,K2])]):- % =========== if Resto = "algo" retractall(_,ter),asserta( parentesis(0,0),ter), busca(["("|T],Tail), saca_elem(Tail, Opr, Resto), !, separar([_|Termino1], Tail, ["("|T]), separar(Termino, [")"], Termino1), conv(Termino,[K1]), conv(Resto,[K2]). conv(["("|T],[K1]):- % =========== if Resto = "" /* ((1)-(2)) caso especial en el que no existen terminos hacia la derecha y el parentesis que inicia indica el segundo termino del operador anterior. */ !, retractall(_,ter),asserta( parentesis(0,0),ter), busca(["("|T],Tail), separar([_|Termino1], Tail, ["("|T]), separar(Termino, [")"], Termino1), conv(Termino,[K1]). conv(["X"|T],[var("X")]):- % para el resto = nada. rest(T), !. conv(["X"|T],[opr(Opr,[var("X"),K1])]):- % para el resto = algo. saca_elem(T,Opr,Resto),conv(Resto,[K1]), !. conv(["-",H|T],[cons(Num)]):- % para el resto = nada. % [-numero] elemento(["0",".","1","2","3","4","5","6","7","8","9"],H), numero([H|T],Tail), rest(Tail), !, cadena([H|T],"",Num1), concat("-",Num1,Num), !. conv(["-",H|T],[opr(Opr,[cons(Num),K1])]):- % para el resto = algo % [-numero] elemento(["0",".","1","2","3","4","5","6","7","8","9"],H), !, numero([H|T],Tail), separar(Numero, Tail, [H|T]), cadena(Numero,"",Num1), concat("-",Num1,Num), saca_elem(Tail, Opr, Resto),conv(Resto,[K1]), !. conv(["-","X"|T],[var("-X")]):- % para el resto = nada. % [-variable] rest(T), !. conv(["-","X"|T],[opr(Opr,[var("-X"),K1])]):- % para el resto = algo. % [-variable] saca_elem(T,Opr,Resto),conv(Resto,[K1]), !. elemento(["S","C","T","A","E","X","G","Q","R","P","O","H","L","N"],H), !,lee_funcion([H|T],Resto), separar(Funcion,Resto,[H|T]),cadena(Funcion, "", Opr1), concat("-",Opr1,Opr), conv(Resto,[K1]). conv([H|T],[cons(Num)]):- % para el resto = nada. elemento(["0",".","1","2","3","4","5","6","7","8","9"],H), numero([H|T],Tail), rest(Tail), !, cadena([H|T],"",Num), !. conv([H|T],[opr(Opr,[cons(Num),K1])]):- % para el resto = algo. % [numerico] ascii(46)= . ascii(57)= 9 elemento(["0",".","1","2","3","4","5","6","7","8","9"],H), !, numero([H|T],Tail), separar(Numero, Tail, [H|T]), cadena(Numero,"",Num),saca_elem(Tail, Opr, Resto),conv(Resto,[K1]), !. % --------------------------------------------------------------------------- % ----------------- Funciones elevadas a una potencia f(x) -------------- % --------- -------- - --- -------- ---- conv([H|T],[opr("^",[opr(F,[K2]),K1])]):- % exponente variable de una funcion. elemento(["S","C","T","X","O","G","P","A","Q","R","E","H","L","N"],H), lee_funcion([H|T],["^"|Resto]), separar(Funcion,["^"|Resto],[H|T]),!, cadena(Funcion, "",F), divide(Resto,Arg), separar(Pot,Arg,Resto), conv(Pot,[K1]), conv(Arg,[K2]). % --------------------------------------------------------------------------- % ------------------ Funciones sin exponente ---------------------------- % --------- --- --------- conv([H|T],[opr(Opr,[K1])]):- elemento(["S","C","T","A","E","X","G","Q","R","P","O","H","L","N"],H), !,lee_funcion([H|T],Resto), separar(Funcion,Resto,[H|T]), cadena(Funcion, "", Opr),conv(Resto,[K1]). conv(_,[opr("",[])]):-!. % --------------------------------------------------------------------------- % ---------------------------- UtilerIas varias ------------------------- % --------- ------ rest([]):-!. elemento([H|_],H):-!. elemento([_|T],H):- !,elemento(T,H). busca([")"|Tail], Tail):- parentesis(Abre,Cierra), Cierra + 1 = Cierra1, retractall(_,ter), asserta(parentesis(Abre,Cierra1),ter), Abre = Cierra1, !. busca(["("|Tail], Resto):- parentesis(Abre,Cierra), Abre + 1 = Abre1, retractall(_,ter), asserta(parentesis(Abre1,Cierra),ter), !, busca(Tail, Resto). busca([_|Tail], Resto):- !, busca(Tail, Resto). numero([H|T],Resto):- str_int(H,_), !, numero(T,Resto). numero(["."|T],Resto):- !, numero(T,Resto). numero(T,T):-!. cadena([], Cad, Cad):-!. cadena([H|T],C,Cad):- !, concat(C,H,C1), cadena(T,C1,Cad). saca_elem([H|T],H,T):-!. %saca_elem(_,"",[""]):-!. divide([")","("|Tail],["("|Tail]):- !. divide([_|T],Arg):- !, divide(T,Arg). separar([],List,List). separar([X|List1],List2,[X|List3]):- separar(List1,List2,List3). % del argumento de la funcion(expresion) para cuando se usa % p.ej.: sen^(x*2)(x*3) lee_funcion([H|T],Resto):- str_char(H,Hst), char_int(Hst,Hasc), Hasc >= 65, Hasc <= 90, lee_funcion(T,Resto). lee_funcion(Resto,Resto):- !. archivo(1,"val1.{v}"):-!. archivo(2,"val2.{v}"):-!. archivo(3,"val3.{v}"):-!. archivo(4,"val4.{v}"):-!. cuadrada([opr("SQR",_)]):- retractall(_,sqr), asserta(sqr("S"),sqr), !; retractall(_,sqr), !. imagen(Num,X,Y):- sqr("S"), Bety = 0 - Y, assertz(vxy(Num,X,Bety),vxy), min_maxy(Num,Bety), !; !. % --------------------------------------------------------------------------- % ---------------------------- evaluador -------------------------------- % --------- valores(Num,Conv):- % -(Num_ec,Conv) cuadrada(Conv), ec(In,Fin,Inc,_,Num,_,_), asserta(ejey(Num,1000000,-1000000),ejes), for1(In,Fin,Inc,K), item(K), eval(Conv,Iteracion), assertz(vxy(Num,K,Iteracion),vxy), min_maxy(Num,Iteracion), imagen(Num,K,Iteracion), fail. valores(Num,Conv):- % -(Num_ec,Conv) ec(In,Fin,Inc,_,Num,_,_), asserta(ejey(Num,1000000,-1000000),ejes), for1(In,Fin,Inc,K), item(K), eval(Conv,Iteracion), assertz(vxy(Num,K,Iteracion),vxy), min_maxy(Num,Iteracion), imagen(Num,K,Iteracion), fail. valores(_,_):- !. item(Valor):- retractall(_,valor), asserta(valor(Valor),valor), !. % --------------------------------------------------------------------------- % ------------------------------- intErprete ----------------------------- % ---------- clauses eval([],0):- !. eval([opr("",T)],R):- !, eval(T,R). eval([opr(" ",T)],R):- !, eval(T,R). eval([opr("",_)],0):- !. % eval(T,_):- free(T), !, fail. eval([cons(T)|_],T1):- !, str_real(T,T1). eval([var("X")|_],T1):- valor(T1), !. eval([var("-X")|_],T1):- valor(T), !, 0 - T = T1. eval([var(_)|_],0):- !. eval([opr("+",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2), R = R1 + R2. eval([opr("-",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2), R = R1 - R2. eval([opr("*",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2), R = R1 * R2. eval([opr("/",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2), R2 >< 0, R = R1 / R2. eval([opr("/",[_,_])],R):- !, R = 1e100. % Es para evitar la divicion por 0. eval([opr("-",[T])],R):- !, eval([T],R1), R = -R1. eval([opr("ABS",[T])],R):- !, eval([T],R1), R = abs(R1). /* eval([opr("MOD",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2), R = R1 mod R2. <== OJO**** */ % El termino R2, no puede ser real. eval([opr("SENH",[T])],R):- !, eval([T],R1), R = (exp(R1)-exp(-R1))/2. eval([opr("-SENH",[T])],R):- !, eval([T],R1), R = 0-((exp(R1)-exp(-R1))/2). eval([opr("COSH",[T])],R):- !, eval([T],R1), R = (exp(R1)+exp(-R1))/2. eval([opr("-COSH",[T])],R):- !, eval([T],R1), R = 0-((exp(R1)+exp(-R1))/2). eval([opr("TANH",[T])],R):- !, eval([T],R1), X = exp(-R1), R = X / exp(R1) + X + X + 1. eval([opr("-TANH",[T])],R):- !, eval([T],R1), X = exp(-R1), R = 0-(X / exp(R1) + X + X + 1). eval([opr("SEN",[T])],R):- !, eval([T],R1), R = sin(R1). eval([opr("-SEN",[T])],R):- !, eval([T],R1), R = 0-sin(R1). eval([opr("COS",[T])],R):- !, eval([T],R1), R = cos(R1). eval([opr("-COS",[T])],R):- !, eval([T],R1), R = 0-cos(R1). eval([opr("TAN",[T])],R):- !, eval([T],R1), R = tan(R1). eval([opr("-TAN",[T])],R):- !, eval([T],R1), R = 0-tan(R1). % eval([opr("ASEN",[T])],R):- !, eval([T],R1), R = arctan(R1). % eval([opr("-ASEN",[T])],R):- !, eval([T],R1), R = 0-arctan(R1). % eval([opr("ACOS",[T])],R):- !, eval([T],R1), R = arctan(R1). % eval([opr("-ACOS",[T])],R):- !, eval([T],R1), R = 0-arctan(R1). eval([opr("ATAN",[T])],R):- !, eval([T],R1), R = arctan(R1). eval([opr("-ATAN",[T])],R):- !, eval([T],R1), R = 0-arctan(R1). eval([opr("EXP",[T])],R):- !, eval([T],R1), R = exp(R1). eval([opr("-EXP",[T])],R):- !, eval([T],R1), R = 0-exp(R1). eval([opr("LOG",[T])],R):- eval([T],R1), R1 > 0, !, R = log(R1). eval([opr("LOG",[_])],0):- !. eval([opr("-LOG",[T])],R):- eval([T],R1), R1 > 0, !, R = 0-log(R1). eval([opr("-LOG",[_])],0):- !. eval([opr("LN",[T])],R):- eval([T],R1), R1 > 0, !, R = ln(R1). eval([opr("LN",[_])],0):- !. eval([opr("-LN",[T])],R):- eval([T],R1), R1 > 0, !, R = 0-ln(R1). eval([opr("-LN",[_])],0):- !. ----------------------------------------------------------------- Solo debe haber un SQR ya que este genera 2 valores posibles. por ejemplo para que al graficar se trace una lInea vertical por ser una raIz imaginaria. eval([opr("SQR",[T])],R):- eval([T],R1), R1 >= 0, !, R = sqrt(R1). eval([opr("SQR",[T])],0):- !, eval([T],R1), 0 > R1. % antes eval([opr("SQR",[T])],R):- !, eval([T],R1), R2=abs(R1), R = 0 - sqrt(R2). eval([opr("-SQR",[T])],R):- eval([T],R1), R1 >= 0, !, R = 0-sqrt(R1). esta no eval([opr("-SQR",[T])],R):- !, eval([T],R1), R2=abs(R1), R = sqrt(R2). % eval([opr("NSQR",[T1,T2])],R):- !, eval([T1],R1), eval([T2],R2),R = sqrt(R1). % eval([opr("-NSQR",[T1,T2])],R):-!, eval([T1],R1), eval([T2],R2),R = 0-sqrt(R1). ----------------------------------------------------------------- eval([opr("^",[T1,T2])],R):- eval([T1],R1), R1 > 0, !, eval([T2],R2),R = exp(R2*ln(R1)). eval([opr("^",[_,T2])],R):- !, eval([T2],R2),R = exp(R2*ln(1)). % ___________________________________________________________________________ % -------------- obtenciOn de mAximos y mInimos ------------------------- % --------- -- ------- - ------- min_maxy(Num,Valor):- ejey(Num,Min,Max), Valor < Min, retractall(ejey(Num,Min,Max),ejes), asserta(ejey(Num,Valor,Max),ejes), fail. min_maxy(Num,Valor):- ejey(Num,Min,Max), Valor > Max, !, retractall(ejey(Num,Min,Max),ejes), asserta(ejey(Num,Min,Valor),ejes). min_maxy(_,_):- !. min_maxx:- control(1), consult("ec~.~",ec), fail. min_maxx:- for(1,4,Num), min_max1(Num), fail. min_maxx:- !. min_max1(Num):- ec(Px,Gx,_,_,Num,_,_), !, Num + 11 = Win, shift([Win]), field_str(0,0,1,"-"), assertz(ejex(Num,Px,Gx),ejes), sound(5,500), sound(5,500), sound(5,500), min_max1(Num):- !, Num + 11 = Win, shift([Win]), field_str(0,0,1,"-"), sound(5,500), sound(5,500), sound(5,500), % --------------------------------------------------------------------------- % ------------------ cAlculo del primer cruce por cero ------------------ % ------- --- ------ ----- --- ---- saca_cero(Act):- ejey(Act,Min,_), Min >= 0, !, % (+,+) assertz(cero(Act,"No existe"),ejes); ejey(Act,_,Max), Max <= 0, !, % (-,-) assertz(cero(Act,"No existe"),ejes). saca_cero(Act):- retractall(ok(_),aux), retractall(c0(_,_,_,_,_,_),aux), vxy(Act,Vx,Vy), saca(Act,Vx,Vy), fail. saca_cero(_):-!. saca(_,X,Y):- % [primer valor] not(c0(_,_,_,_,_,_)), Y < 0, !, asserta(c0("-",X,Y,"",0,0),aux); not(c0(_,_,_,_,_,_)), Y > 0, !, asserta(c0("+",X,Y,"",0,0),aux). saca(_,X,Y):- % (actualiza la referencia) c0("-",_,_,_,_,_), Y < 0, !, retractall(c0(_,_,_,_,_,_),aux), asserta(c0("-",X,Y,"",0,0),aux); c0("+",_,_,_,_,_), Y > 0, !, retractall(c0(_,_,_,_,_,_),aux), asserta(c0("+",X,Y,"",0,0),aux). saca(Act,X,Y):- c0("-",Cx,Cy,_,_,_), Y >= 0, !, retractall(c0(_,_,_,_,_,_),aux), asserta(c0("-",Cx,Cy,"+",X,Y),aux), interpola(Act); c0("+",Cx,Cy,_,_,_), Y <= 0, !, retractall(c0(_,_,_,_,_,_),aux), asserta(c0("+",Cx,Cy,"-",X,Y),aux), interpola(Act). interpola(Act):- not(ok(1)),c0(_,_,_,_,Cero,0),!,str_real(X0,Cero), assertz(cero(Act,X0),ejes), asserta(ok(1),aux). interpola(Act):- not(ok(1)), !, c0(_,Vx1,Vy1,_,Vx2,Vy2), Vx2 - Vx1 <> 0, (Vy2 - Vy1) / (Vx2 - Vx1) = M, Cero = ( (0 - Vy1) / M ) + Vx1, str_real(X0,Cero), assertz(cero(Act,X0),ejes), asserta(ok(1),aux). interpola(_):-!. % --------------------------------------------------------------------------- % ---------------------- utilerIas varias ------------------------------- % --------- ------ str_list("",[]):-!. str_list(S,[C|T]):- frontchar(S,C1,Resto), str_char(C,C1), !, str_list(Resto,T). existe_archivo:- existfile("ec~.~"), retractall(_,ec),retractall(_,valor), consult("ec~.~",ec ), retractall(control(_),aux), asserta(control(1),aux), retractall(aux(_),aux), asserta(aux(0),aux), video1. existe_archivo:- % ___________________________________________________________________________ % --------------------------------------------------------------------------- not(control(1)), retractall(control(_),aux), asserta(control(2),aux), retractall(_,ec), !, asserta(ec(0,30,0.1,"(1-((1-(0.27*X))*(EXP^(-0.27*X)(1))))",1,"",0),ec). existe_archivo:- !. inicia:- for(1,4,Ec), Ec * 2 + 1 = Win, shift([16]), field_attr(3,2,3,7), shift([2]), field_attr(6,4,5,112), shift([Win]), write1(0,1,"-"), inicia1(Ec), fail. inicia:-!. inicia1(Num):- retractall(_,vxy), ec(_,_,_,Ec,Num,_,_), Num * 2 + 1 = W1, W2 = W1 + 1, 16 + Num = W3, str_list(Ec,Lista), % -(i,o) shift([25]), window_attr(7), shift([24]), window_attr(112), conv(Lista,Conv), % -(i,o) archivo(Num,Archivo), % -(i,o) shift([24]), window_attr(7), shift([25]), window_attr(112), valores(Num,Conv), % -(i,i,i) shift([25]), window_attr(7), shift([W3]), field_str(0,0,1,"-"), shift([2]), field_attr(6,4,5,7), shift([16]), field_attr(3,2,3,112), save(Archivo,vxy), sound(10,1000),sound(10,1000),sound(10,1000), !. inicia1(Num):- archivo(Num,Archivo), !, save(Archivo,vxy), Num * 2 + 1 = W1, W2 = W1 + 1, 16 + Num = W3, shift([25]), window_attr(7), shift([24]), window_attr(112), shift([24]), window_attr(7), shift([25]), window_attr(112), shift([25]), window_attr(7), shift([W3]), field_str(0,0,1,"-"), shift([2]), field_attr(6,4,5,7), shift([16]), field_attr(3,2,3,112), sound(10,1000),sound(10,1000),sound(10,1000), !. video:- M6 = "̹̹ͺ",M7 = "̹ȼͺ", make([1,0,7,0,0,25,80,2,7,7,5,1,14,18],[M1,M2]), field_str(6,4,5,"eje y"), field_attr(6,4,5,112), field_str(1,15,1,"1"), field_str(4,15,1,"2"), field_str(7,15,1,"3"), field_str(10,15,1,"4"), make([3,7,7,6,19,3,7,4,7,7,6,26,3,7,5,7,7,9,19,3,7,6,7,7,9,26,3,7],[M3,M4,M3,M4]), make([7,7,7,12,19,3,7,8,7,7,12,26,3,7,9,7,7,15,19,3,7,10,7,7,15,26,3,7],[M3,M4,M3,M4]), make([11,7,7,8,35,9,10],[M2]), field_str(0,7,1,"1"), field_str(2,7,1,"2"), field_str(4,7,1,"3"), field_str(6,7,1,"4"), field_str(3,1,5,"eje x"), make([12,7,7,8,45,3,3,13,7,7,10,45,3,3,14,7,7,12,45,3,3,15,7,7,14,45,3,3],[M5,M6,M6,M7]), make([16,7,7,8,50,9,10],[M2]), write("\nc\nr\nu\nc\ne"), field_str(0,7,1,"1"), field_str(2,7,1,"2"), field_str(4,7,1,"3"), field_str(6,7,1,"4"), field_str(3,2,3,"x 0"), make([17,7,7,8,60,3,3,18,7,7,10,60,3,3,19,7,7,12,60,3,3,20,7,7,14,60,3,3],[M5,M6,M6,M7]), make([21,7,7,21,39,4,41],["ɹʼͺ"]), write(" Escuela de IngenierIa ElEctrica"),nl, make([22,7,7,0,0,5,80],[M5]), field_str(1,20,35,"IntErprete y evaluador de funciones"), field_attr(1,20,35,112), make([23,0,7,19,2,3,25,24,7,0,20,5,1,10],[M2,""]), write("convierte"), make([25,7,0,20,19,1,7],[""]), write("evalUa"). % --------------------------------------------------------------------------- video1:- ec(A,B,C,Ec,0,D,E), num(Ec_), retractall(ec(A,B,C,Ec,0,D,E),ec), assertz(ec(A,B,C,Ec,Ec_,D,E),ec), fail. video1:- save("ec~.~",ec), !. write1(X,Y,M):- cursor(X,Y), write(M),!. for(Val,_,Val). for(A,B,I):- B > A, A + 1 = A1, for(A1,B,I). for1(Val,_,_,Val). for1(In,Fin,Inc,Val):- Fin > In, In + Inc = In1, for1(In1,Fin,Inc,Val). remove([]):-!. remove([H|L]):- shift([H]),removewindow(), !,remove(L). shift([]):-!. shift([H|L]):- shiftwindow(H), !, shift(L). make([],[]):- !. make([N,A1,A2,V1,V2,V3,V4|T],[M|Tm]):- makewindow(N,A1,A2,"",V1,V2,V3,V4,1,255,M), !, make(T,Tm). num(Num):- aux(V1), V1 + 1 = Num, retractall(aux(_),aux), asserta(aux(Num),aux), !. % --------------------------------------------------------------------------- % ----------------------------- FIN ---------------------------------------------- % --- goal video, existe_archivo, retractall(_,ejes), inicia, shift([24]), window_attr(7), shift([25]), window_attr(7), shift([2]), field_attr(6,4,5,7), shift([16]), field_attr(3,2,3,7), shift([11]), field_attr(3,1,5,112), min_maxx, shift([11]), field_attr(3,1,5,7), save("ejes.{v}",ejes), remove([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]), sound(10,100), sound(10,100), sound(10,100), !.