
% convert a list list ((())) to prolog syntax, lowercase, n-ary 
% operators replaced by binary version

lisp_to_prolog(O,T):-
	name(O,P),!,
	tokeniseOnSpaceAndParen(P,Q), !,
	nestList(Q,R),!,
	repToTerm(R,[S]),!,
	n_ary_to_binary(S,T),!.

prolog_to_lisp_list([],[]):-!.
prolog_to_lisp_list([T|L],[C|CL]):-
	prolog_to_lisp(T,C),
	prolog_to_lisp_list(L,CL).


prolog_to_lisp(Fn,Fn):-
	var(Fn),
	get_nextvar(Fn).

prolog_to_lisp(Fn,Fn):-
	Fn =.. L,
	length(L,1),
	!.

prolog_to_lisp(Fn,LispTerm):-
	Fn =.. [FnSymbol|ArgsList],
	prolog_to_lisp_list(ArgsList,ArgsListLisp),
	concat_all([FnSymbol|ArgsListLisp],S0),
	concat('(',S0,S1),
	concat(S1,')',LispTerm).



n_ary_to_binary(T,RR):-
	T =.. [F,A|B],
	binary(F),
	length(B,Len),
	Len > 1,!,
	FB =.. [F|B],
	n_ary_to_binary(A,AA),
	n_ary_to_binary(FB,BB),
	RR =.. [F,AA,BB].

n_ary_to_binary(T,RR):-
	T =.. [F,A,B],
	binary(F),
	n_ary_to_binary(A,AA),
	n_ary_to_binary(B,BB),
	RR =.. [F,AA,BB].

n_ary_to_binary(T,R):-
	T =.. [F,A],
	unary(F),
	n_ary_to_binary(A,AA),
	R =.. [F,AA].

n_ary_to_binary(Fn,Fn):-
	Fn =.. L,
	length(L,1),!.

unary(not).
unary(defprimrole).
unary(defprimattribute).
binary(and).
binary(or).
binary(all).
binary(some).
binary(defconcept).
binary(defprimconcept).


lowercase(A,B):-
        name(A,AN),
        to_lowercase(AN,BN),
        name(B,BN).

to_lowercase([],[]):-!.
to_lowercase([X|L],[Y|M]):-
    is_uppercase(X),
    Y is X + 32,
    to_lowercase(L,M).
% change _ to -
to_lowercase([95|L],[45|M]):-
    to_lowercase(L,M).

to_lowercase([X|L],[X|M]):-
    to_lowercase(L,M).

is_uppercase(X):-
    X > 64,
    X < 91.


repToTerm([],[]):-!.
repToTerm([I|J],R):-
	not(is_list(I)),
	sublistToTerm(J,JJ),
	R =.. [I|JJ].

repToTerm([I|J],[II|JJ]):-
	repToTerm(I,II),
	repToTerm(J,JJ).

sublistToTerm([],[]):-!.
sublistToTerm([I|J],[II|K]):-
	is_list(I),
	repToTerm(I,II),
	sublistToTerm(J,K).

sublistToTerm([I|J],[I|K]):-
	sublistToTerm(J,K).


% nestList: from ( () ) => [ [] ]

nestList([],[]).
nestList(['('|A],[AN|BN]):-
	splitOnCParen(A,0,AH,AT),!,
	nestList(AH,AN),
	nestList(AT,BN).

nestList([I|A],[I|BN]):-
	nestList(A,BN).


splitOnCParen(['('|A],X,['('|C],D):-
	Y is X + 1,
	splitOnCParen(A,Y,C,D).
splitOnCParen([')'|A],0,[],A):-!.
splitOnCParen([')'|A],X,[')'|C],D):-
	Y is X - 1,
	splitOnCParen(A,Y,C,D).
splitOnCParen([I|A],X,[I|C],D):-
	splitOnCParen(A,X,C,D).



% given a list of tokens (i.e. from name) tokeniseOnSpaceAndParen

tokeniseOnSpaceAndParen(I,J):-
	tokeniseOnSpaceAndParen(I,[],J),!.

tokeniseOnSpaceAndParen([],[],[]):-!.

tokeniseOnSpaceAndParen([],In,[InN]):-
	reverse_lower(In,InR),
	name(InN,InR).

% ignore #$'
tokeniseOnSpaceAndParen([X|L],In,Out):-
	blankSym(X),
	tokeniseOnSpaceAndParen(L,In,Out).

tokeniseOnSpaceAndParen([32|L],[],Out):-
	tokeniseOnSpaceAndParen(L,[],Out).
tokeniseOnSpaceAndParen([32|L],In,[InN|Out]):-
	reverse_lower(In,InR),
	name(InN,InR),
	tokeniseOnSpaceAndParen(L,[],Out).
tokeniseOnSpaceAndParen([X|L],[],[SY|Out]):-
	endSym(X,SY),
	tokeniseOnSpaceAndParen(L,[],Out).
tokeniseOnSpaceAndParen([X|L],In,[InN,SY|Out]):-
	endSym(X,SY),
	reverse_lower(In,InR),
	name(InN,InR),
	tokeniseOnSpaceAndParen(L,[],Out).

tokeniseOnSpaceAndParen([I|L],In,Out):-
	tokeniseOnSpaceAndParen(L,[I|In],Out).

blankSym(13).
blankSym(35).
blankSym(36).
blankSym(39).
endSym(40,'(').
endSym(41,')').

reverse_lower(A,B):-
	reverse(A,C),
	to_lowercase(C,B),!.


concat_all([I],U):-
	I =.. [X,Y|IL],!,
	concat_all_nospace([X,'(',Y|IL],W),
	concat(W,')',U),!.

concat_all([I],I):-!.

concat_all([I|J],U):-
	I =.. [X,Y|IL],
	concat_all(J,S),!,
	concat(' ',S,T),
	concat_all_nospace([X,'(',Y|IL],ISTR),
	concat_all_nospace([ISTR,')',T],U),!.

concat_all([I|J],U):-
	concat_all(J,S),!,
	concat(' ',S,T),
	concat(I,T,U),!.

	
concat_all_nospace([I],I):-!.

concat_all_nospace([I|J],U):-
	concat_all_nospace(J,S),
	concat(I,S,U).
	

/*
concat(A,B,C):- 
	number(A),
	number(B),
	number_chars(A,L),
	number_chars(B,M),
	concat_all_nospace(L,AA),
	concat_all_nospace(M,BB),
	str_cat(AA,BB,C).
concat(A,B,C):- 
	number(A),
	number_chars(A,L),
	concat_all_nospace(L,AA),
	str_cat(AA,B,C).
concat(A,B,C):- 
	number(B),
	number_chars(B,L),
	concat_all_nospace(L,BB),
	str_cat(A,BB,C).
concat(A,B,C):- str_cat(A,B,C).

*/
