This is a homework question, i have pretty much the rest of the code done out, and the last part that i have to do is create an insert algorithm.
insert(I,T1,T2) - is true if T2 is the binary tree resulting from I being
inserted into binary tree T1.
so far my code for this part is...
insert(I,T1,T2) :- bTTree(T1(X,L,_), bTTree(T2(X,L,I).
insert(I,T1,T2) :- bTTree(T1(nil,nil,nil),bTTree(T2(I,nil,nil).
insert(I,T1,T2) :- bTTree(T1(X,L,_),bTTree(T2(X,L,I).
I don't know if i'm going in the right direction with this or not.
Any help would be greatly appreciated.
My completed Code (if you need it):
isempty(nil) :- !.
isempty(tree(nil,nil,nil)).
bTTree(tree(_,Left,Right)) :- binaryTree(Left), binaryTree(Right).
%traversals.
%preorder -- N,Left,Right
preorder(tree(N,_,_),N).
preorder(tree(_,Left,_),N) :- preorder(Left,N).
preorder(tree(_,_,Right),N) :- preorder(Right,N).
%inorder -- Left,N,Right.
inorder(tree(_,Left,_), N) :- inorder(Left,N).
inorder(tree(N,_,_), N).
inorder(tree(_,_,Right), N) :- inorder(Right,N).
%postorder -- Left,Right,N
postorder(tree(_,Left,_),N) :- postorder(Left,N).
postorder(tree(_,_,Right),N) :- postorder(Right,N).
postorder(tree(N,_,_),N).
search(t,I) :- bTTree(t(I,_,_)).
search(t,I) :- bTTree(t(_,I,_)).
search(t,I) :- bTTree(t(_,_,I)).
search(t,I) :- bTTree(t(_,N,_)), search(N,I).
search(t,I) :- bTTree(t(_,_,N)), search(N,I).
height(t,H) :- bTTree(t(nil,nil,nil)), H is 0.
height(t,H) :- bTTree(t(N,nil,nil)), H is 1.
height(t,H) :- bTTree(t(_,Left,Right)),
height(Left, H1),
height(Right, H2),
H is max(H1,H2) + 1.
insert(I,t1,t2) :- bTTree(t1(X,L,_)),
bTTree(t2(X,L,I)).
insert(I,t1,t2) :- bTTree(t1(nil,nil,nil)),
bTTree(t2(I,nil,nil)).
insert(I,t1,t2) :- bTTree(t1(X,L,_)),
bTTree(t2(X,L,I)).
bTTree(T1(X,L,_)) is a syntax error (apart in SWI-Prolog, after enabling the extension set_prolog_flag(allow_variable_name_as_functor, true) ).
Another problem is that bTTree/1 misses the base case, it will always fail after it completed the recursion. What's its purpose ? In Prolog usually functors are assumed as formally declared symbols, there is no point in having an 'indirection' like bBBtree/1 just to introduce a term like tree/3.
And of course, you should stick to the same representation for a data structure in a program: now you use tree, or t, or t1, or t2, ...
I think that before working on insertion those problems should be solved...
Related
I want to add in the DB a constant and a linked variable:
?- assertz(my(x, A))
So that in the future I can define A and get the only one entry. Sth like that:
?- assertz(my(x, A)), ..., A = 2.
?- my(A, B).
A = x,
B = 2.
Can this be done?
As I noted in the comments your idea of a link like a pointer is not the way to approach solving your problem.
A common solution is to walk the tree and construct a new tree as you walk the tree by replacing the leaf of the tree with a new leaf that contains the value from the input tree along with the associated value, what you are thinking should be linked.
Since you are somewhat new to Prolog I will do this with two examples. The first will just walk a tree and only return true when successfully walked. It can be used to understand how to walk a tree and run with gtrace to single step the code to understand it.
The second example will expand on the tree walk and add the type (link as you think) to the leaf item. The the old leaf for something simple like an atom a, will become a new leaf in the tree like (a,atom).
Also this was quickly written as a demonstration only. I am sure it will have problems if pressed into doing anything more than the single example.
:- module(example,
[
example/1
]).
example(walk) :-
Term = term_size(a(1,"Hello",'Atom',1+2,[a,$,T])),
walk(Term).
example(infer_type) :-
Term = term_size(a(1,"Hello",'Atom',1+2,[a,$,T])),
infer_type(Term,Is),
write(Is).
walk([]) :- !.
walk([T]) :- var(T), !.
walk(L) :- is_list(L), !, L = [H|T], walk(H), walk(T).
walk(T) :- compound(T), !, T =.. [_|Args], !, walk(Args).
walk(T) :- integer(T), !.
walk(T) :- var(T), !.
walk(T) :- atomic(T), !.
walk(T) :- T =.. [Arg|Args], !, walk(Arg), walk(Args).
infer_type([],[]) :- !.
infer_type([T],[(T,var)]) :- var(T), !.
infer_type(L,S) :- is_list(L), !, L = [H|T], infer_type(H,I), infer_type(T,Is), S = [I|Is].
infer_type(T,S) :- compound(T), !, T =.. [F|Args], !, infer_type(Args,Is), S =.. [F|Is].
infer_type(T,(T,integer)) :- integer(T), !.
infer_type(T,(T,var)) :- var(T), !.
infer_type(T,(T,atom)) :- atomic(T), !.
infer_type(T,S) :- T =.. [Arg|Args], !, infer_type(Arg,I), infer_type(Args,Is), S =.. [I|Is].
Example run
Note: I know there are warnings; it is a demo not production code.
Welcome to SWI-Prolog (threaded, 64 bits, version 8.5.3)
?- working_directory(_,'C:/Users/Groot').
true.
?- [example].
Warning: c:/users/Groot/example.pl:20:
Warning: Singleton variables: [T]
Warning: c:/users/Groot/example.pl:24:
Warning: Singleton variables: [T]
true.
?- example(walk).
true.
?- example(infer_type).
term_size(a((1,integer),(Hello,atom),(Atom,atom),(1,integer)+(2,integer),[(a,atom),(($),atom),(_25642,var)]))
true.
As an exercise I did not identify the string as a string, the change should be easy.
Basically when I try to transform a list into a polynomial or vice-versa, it always shows up with parenthesis (in case of the polynomials). Here is the code, the function not working is the poly2list, the other one are just to define what a monomial/polinomial is.
pvars([x,y,z]).
pvar(X):-pvars(V),member(X,V).
polinomial(X) :- monomial(X).
polinomial(P+M) :- monomial(M), polinomial(P).
monomial(X) :- pvar(X).
monomial(N) :- number(N).
monomial(X) :- power(X),!.
monomial(K*X) :- coefficient(K), power(X),!.
coefficient(N) :- number(N).
power(X) :- pvar(X),!.
power(X^Y) :- pvar(X), integer(Y), Y>1,!.
poly2list(X,[X]) :- monomial(X),!.
poly2list(X+P,[X|Y]) :- monomial(X), poly2list(P,Y).
For example, when i ask:
poly2list(X,[2*x^2,3,y]).
The result is:
X = 2*x^2+(3+y)
And I'm trying to get:
X = 2*x^2+3+y
Thanks in advance :)
I having a problem with predicate which creates list of list for example
?-listoflist([p v q, p, r], R).
R=[ [p,q],[p],[r] ]
So far i have:
:- op(500, xfy, v).
listoflist([],[]):-!.
listoflist([H], [[H]]):-!
listoflist([H|T], [Result]):-
change_to_list(H,Tmp),
listoflist(T, [Tmp|Result])..
change_to_list(X v Y, [X|List]):-
change_to_list(Y,List),!.
change_to_list(X,[X]).
For operator declarations, always look what Prolog already has and fit your own operators into it:
?- current_op(Pri,Fix,\/).
Pri = 500, Fix = yfx.
A left-associative operator makes much more sense here. Maybe you can reuse this, instead of defining your own? And in case you want your own, take the very same priorities.
:- op(500, yfx, v).
operands(Op) --> [Op], {functor(Op,Op,0)}.
operands(L v R) --> operands(L), operands(R).
expr_operands(Expr, Ops) :-
phrase(operands(Expr), Ops).
?- maplist(expr_operands, [p v q, p, r], R).
R = [[p,q],[p],[r]].
Your listoflists/2 should be simpler and doesn't need cuts:
listoflists([], []).
listoflists([X|Xs], [Y|Ys]) :-
change_to_list(X, Y),
listoflists(Xs, Ys).
The other predicate, change_to_list/2 seems fine to me.
Notice how you collect the results in the head of the clause, not in the recursive call!
I would like to find what is the most top synsets (highest level) in wordNet, How can I find them? and how can I know how many dauhter synsets below each of the top ones? Usually we use hyp relations to do it, I am trying to write:
hyp(I, J), %[I would like to write here, be sure that there is no parent for I].
Can you please help me with it please?
all top level facts:
root_hyp(H) :- hyp(H, _), \+ hyp(_, H).
leafs don't have children:
leaf_hyp(L) :- hyp(_, L), \+ hyp(L, _).
if your Prolog doesn't have library(aggregate), you can count elements with this snippet
count_synset_daughters(S, N) :-
s(S,_,_,_,_,_),
setof(D, hyp(S,D), L),
length(L, N).
then simply combine (join) them:
?- root_hyp(R), count_synset_daughters(R, N).
I'm interested in formulae made up from lots of conjunctions (part of a larger problem). I want to write a program that takes something like this:
:- get_params(conj(conj(a,b),c),X)
and returns a list of all the parameters of the conjunctions i.e. X=[a,b,c]. At the moment I can do
:- get_params(conj(a,b),X) to get X=[a,b]
using simple Prolog pattern matching but how would you go about doing things such as
:- get_params(conj(conj(a,b),c),X) to get X=[a,b,c]
It seems really simple but I've been struggling all day!
Since you are describing a list, consider using DCG notation:
params(conj(A,B)) --> !, params(A), params(B).
params(X) --> [X].
Example:
?- phrase(params(conj(conj(a,b),c)), Ps).
Ps = [a, b, c].
Assuming that all conj functors are binary:
get_params(X, Y, L) :-
get_params(X, L1),
get_params(Y, L2),
append(L1, L2, L).
get_params(conj(X, Y), L) :-
get_params(X, Y, L), !.
get_params(A, [A]).