Disclaimer: this is a school assignment.
New-ish to Prolog and have a decent understanding of the basics. Assignment is to differentiate polynomials. This part is not the problem. I have devised an algorithm that works and implemented it in Prolog to my satisfaction. At this point, calling my diff_term predicate results in a properly differentiated polynomial term every time.
However, when I pass a full polynomial to my diff_poly predicate, whose job it is to parse the terms, pass them for differentiation, and recollect them into a list to return tot he user, things break down. My problem is recursively adding the returned polynomial terms (lists) to the fully-differentiated polynomial (another list). I have consulted numerous related Stackoverflow questions, finding this one particularly useful:
Prolog - recursive list building
I read it thoroughly and re-created the same program in order to understand it. The main difference, however, is that in my situation the values I am adding to the list are being returned by other predicates as opposed to being created within the same predicate as the list is being built in.
The following code consists of my diff_poly predicate, which then calls diff_term. diff_term then calls numerous other homemade predicates to perform the algorithm; however, none of that is an issue, and differentiation, as mentioned above, works well. You can likely understand what my algorithmic approach is by predicate names alone.
The diff_poly predicate is the only diff_poly that exists; there are no base cases or other variations, as I am able to assume (as per assignment specifications) that all input will be consistently and validly formatted. There are, however, a few other diff_term predicates for dealing with variations on term contents, all of which return proper term derivatives.
If I call diff_poly as is, I get 'false' as my return. If I comment out the last line of that predicate and uncomment the one previous to it, I get exactly one differentiated term returned to me, which is expected as their is no recursive call, and proves that the call to/return from diff_term works.
Essentially I just need some direction on how to build the list to be returned. I've tried appending, inserting, etc, but I think the head matching strategy (outlined in the question above) is the way to go, but that I am implementing something incorrectly. Any insight is appreciated.
% differentiates a polynomial with respect to given variable % polynomials are parsed into terms, and terms are passed to diff_term diff_poly([Term | Rest], DiffVar, DiffedPoly) :- diff_term(Term, DiffVar, DiffedTerm), % DiffedPoly = DiffedTerm. diff_poly(Rest, DiffVar, [DiffedTerm | DiffedPoly]). % term is a coefficient and at least one var/exp pair in its member variable list % term includes occurrence of variable to differentiate with respect to diff_term([Coef | Rest], DiffVar, Return) :- flatten(Rest, FlatList), member(DiffVar, FlatList), index_of(FlatList, DiffVar, Index), nth1(Index, FlatList, Exp), Exp > 1, NewCoef is Coef * Exp, NewExp is Exp - 1, remove_at(FlatList, Index, RemoveList), insert_at(NewExp, RemoveList, Index, InsertList), split_varlist(InsertList, DoneList), Return = [NewCoef | DoneList], !.