:- use_module(library(lists)).
:- op(50,yf,#).


%chord(maj,[0,4,7]).
chord(maj7,[0,4,7,10]).
%chord(min,[0,3,7]).
chord(min7,[0,3,7,10]).
chord(sus,[0,5,7]).
chord(dim,[0,3,6]).
chord(aug,[0,4,8]).

scale(major,[0,2,4,5,7,9,11]).
scale(minor,[0,2,3,5,7,8,10]).
scale(harmonic_minor,[0,2,3,5,7,8,11]).
scale(blues6,[0,3,5,6,7,10]).
scale(blues7,[0,2,3,5,6,9,10]).


v(0,c).
v(1,c # ).
v(2,d   ).
v(3,d # ).
v(4,e   ).
v(5,f   ).
v(6,f # ).
v(7,g   ).
v(8,g # ).
v(9,a   ).
v(10,a # ).
v(11,b  ).

% numlist to notelist
% [num],[note]
% ?L1,?L2
numli2noteli([],[]).
numli2noteli([H1|T1],[H2|T2]):-
    v(H1,H2),numli2noteli(T1,T2).


% transpose list of notes  
% num,[note],[note]
% +Xv,+L2,-L1
tp(Xv,L2,L1):-
    numli2noteli(L2v,L2),
    tpnumli(Xv,L2v,L1v),
    numli2noteli(L1v,L1).

%transpose
% X is amount of transposition L1 is original notes , L2 result
% num,[num],[num]
tpnumli(_,[],[]).
tpnumli(X,[H|T],[H2|T2]):-
    H2 is (H+X) mod 12,
    tpnumli(X,T,T2).

    
% +L1,+ChordL,-L2,-Base
% [num],[num],[num],num
%ChordL: intervals of the Chord in normal form
%L2: transposed chord
%Base: root of the Chord 
comphelp(L1,ChordL,L2,Base):-
    member(L1m,L1),
    member(Chm,ChordL),
    Base is (L1m-Chm) mod 12,
    tpnumli(Base,ChordL,TpchL),
    subset(L1,TpchL),
    L2 = TpchL.

% complete chord    
% +L1,-L2,-Base,-Chname
% [notes],[notes],note-atom    
comp1(L1,L2,Base-Chname):-
    numli2noteli(L1num,L1),    
    chord(Chname,ChordL),
    comphelp(L1num,ChordL,L2num,Basenum),
    numli2noteli(L2num,L2),
    v(Basenum,Base).

% complete chord
% +L1,-L2,-Base,-Chname
% [notes],[notes],note-atom
comp(L1,Base-Chname-L2):-
    setof(L2-Base-Chname,comp1(L1,L2,Base-Chname),RL),
    member(L2-Base-Chname,RL).
    
scomp1(L1,L2,Base-Sname):-
    numli2noteli(L1num,L1),    
    scale(Sname,ChordL),
    comphelp(L1num,ChordL,L2num,Basenum),
    numli2noteli(L2num,L2),
    v(Basenum,Base).
    
scomp(L1,Base-Sname-L2):-
    setof(L2-Base-Sname,scomp1(L1,L2,Base-Sname),RL),
    member(L2-Base-Sname,RL).
    

/*
% searching a chord

36 ?- comp([c,e],X).
X = a-min7-[a, c, e, g] ;
X = c-maj7-[c, e, g, a#] ;
X = c-aug-[c, e, g#] ;
X = e-aug-[e, g#, c] ;
X = g# - aug-[g#, c, e].

 
% searching a scale

35 ?- scomp([c,d,e,f],X).
X = a-minor-[a, b, c, d, e, f, g] ;
X = a-harmonic_minor-[a, b, c, d, e, f, g#] ;
X = c-major-[c, d, e, f, g, a, b] ;
X = d-minor-[d, e, f, g, a, a#, c] ;
X = d-blues7-[d, e, f, g, g#, b, c] ;
X = f-major-[f, g, a, a#, c, d, e].

% transpose notes

9 ?- tp(1,[d,e,f,g],X).
X = [d#, f, f#, g#] ;
false.


*/
