Zadanie w Prologu

1

Witam,
Właśnie przygotowuje się (samemu) do zdania materiału z Prologa.

Natrafiłem na takie zadanie, które nie wiem jak ugryźć:

Zdefiniuj w Prologu program do wyznaczania wartości funkcji wykładniczej o podstawie e z rozwinięcia w szereg ex = 1 + x + x2/2! + x3/3! + ...

Może ktoś te "ustrojstwo" rozwiąże :)

Widać, że nie tylko ja nie mogę rozwiązać tego zadanka :(

0

No, ale z czym masz problem? Przecież tu wystarczą raptem 3 predykaty: jeden liczący silnie, drugi liczący potęge i trzeci który sumuje ci kolejne wyrazy szeregu.

0

Chodzi o to, że nie mam pomysłu jak to zliczać. Bo mam oczywiście predykaty:

silnia(0,1).
silnia(N,F) :-
  N>0,
  N1 is N-1,
  silnia(N1,F1),
  F is N*F1.

potega(_,0,0).
potega(A,1,A).
potega(X,Y,Z) :-
  Y>1,
  Y1 is Y-1,
  potega(X,Y1,Z1),
  Z is X*Z1.

Ale nie potrafię poskładać to tak, aby liczyło szereg :(

0

Coś w ten deseń:

 
    edoxtej(X,8,Wyn,Wyn).
    edoxtej(X, I, Acc, Wyn) :- 
         potega(X,I, XdoI), 
         silnia(I,SilI), 
         AccN is Acc + XdoI / SilI,
         Ip is I+1, 
         edoxtej(X, Ip, AccN, Wyn).

    edoxtej(X, Wyn) :- edoxtej(X, 0, 0, Wyn). 

Sorry za ewentualne literówki, kod napisano na szybko, możliwe, że potrzebne są jakieś odcięcia.
8 to ograniczenie na liczbę iteracji, możesz tam wpisać dowolną wartość (chociaż pewnie powyżej kilkunastu nie ma sensu).

0

Działa aż miło! :) Musiałem tylko poprawić edoxtej(X, 0, 1, Wyn). aby uwzględniał stałą jedynkę, bo liczył o 1 za mało.

Teraz nie wygląda to skomplikowanie, ale wtedy zaiste było. Pewnie jest to m.in. związane z tym, że od tygodnia mam styczność z Prologiem i nie mam jeszcze odpowiedniego "podejścia".

To nie tworząc nowego tematu miałbym jeszcze jedno zadanie.
Ten predykat odwraca liste:

reverse([],[]).
reverse([H|T],L) :-
  reverse(T,L1),
  append(L1,[H],L).

Tylko, że nie odwraca on list zagnieżdżonych. Możesz podać przykład jak to przerobić?

0

Ten predykat odwraca liste:

reverse([],[]).
reverse([H|T],L) :-
reverse(T,L1),
append(L1,[H],L).

Tylko, że nie odwraca on list zagnieżdżonych. Możesz podać przykład jak to przerobić?

To nie jedyny problem tego predykatu. Korzysta on z append-a przez co działa w czasie kwadratowym.
Proponuje ci najpierw napisać dla wprawki zwykłego reverse (który będzie n razy szybszy od tego powyżej)
tylko że bez appenda, za to z akumulatorem :)

Przerobienie tego co otrzymasz będzie już banalne, bo wystarczy jedynie oprócz odwracania ogona listy odwracać też głowę,
która być może będzie również listą. W ten sposób w ciele klauzuli będziesz miał dwa wywołania reverse, zamiast jednego.

0

Sorki, że się tak długo nie odzywałem, ale wypadło mi coś innego niż Prolog.
Dzisiaj wróciłem do tematu i mam coś takiego:

odwr2(L,R) :-
     odwr2(L,[],R).
odwr2([H|T],A,R) :-
     odwr2(T,[H|A],R).
odwr2([],A,A).

Wykorzystuje akumulator :) Tylko nadal nie wiem jak zrobić, że jeśli lista to ma jeszcze odwracać, a jeśli nie lista to nie rób nic. Nie potrafię zastosować tutaj "jeśli"

0

Robisz dokładnie to co ci napisałem tzn. wychodzisz od zwykłego rev-a:

 
rev([], A, A). 
rev([X|Xs], A, Y) :- 
    rev(Xs, [X|A], Y).

rev(X, Y) :- rev(X, [], Y). 

Następnie masz dwa przypadki. Albo głowa jest listą ( H = [|]), albo jest singletonem lub zwykłym termem (H != [|]),
co daje następujący kod (Zwróć uwagę na odcięcie, które jest tutaj szalenie ważne) :

deepRev([], A, A). 

deepRev([H|Xs], Acc, Y) :- 
	H = [_|_], !, deepRev(H, Hr), 
    deepRev(Xs, [Hr|Acc], Y).

deepRev([H|Xs], Acc, Y) :-  
    deepRev(Xs, [H|Acc], Y).

deepRev(X, Y) :- deepRev(X, [], Y).
 

Co prawda predykat już działa, ale zauważasz, że dwie środkowe klauzule można skleić w jedną, co skróci nieco kod:

deepRev2([], A, A). 

deepRev2([H|Xs], Acc, Y) :- 
	( 
	    H = [_|_], !, deepRev2(H, Hr) ; 
		Hr = H
	),  deepRev2(Xs, [Hr|Acc], Y).

deepRev2(X, Y) :- deepRev2(X, [], Y).
 

Tyle.

0

Dzięki! Dość logicznie to wygląda jednak za bardzo nie czuje Pologa.

P.S. Jednak Tobie Prolog idzie żwawo i dlatego miałbym pytanie(propozycje) - czy nie podjąłbyś się zrobienia projektu w Prologu? (temat w skrócie - rozszerzenie do sys. CarDiag [Nilsson, Małuszyński, r.9, ex. 9.3]).

0

Niestety nie znajde na to czasu, sam mam na plecach trzy średniej wielkości projekty. Jeśli bardzo ci zależy to wrzuć ogłoszenie do działu praca.

1 użytkowników online, w tym zalogowanych: 0, gości: 1