Got a link to this blob post. Nice read Maybe someone can help with the next steps?
I just linked the author to these forums on Lobsters. I wanted to take a crack at the next steps, but I’m afraid I’m both too busy & too ignorant of music theory
Nice reading indeed.
Have modified the code for readability and to enable the ‘exploration mode’. Here it is:
/* File: voicing.pl
Author: Carlo,,,
Created: Apr 23 2020
Purpose: comment on
http://www.petecorey.com/blog/2020/04/21/guitar-chord-voicings-with-prolog/
*/
:- module(voicing, [
% from Pete Corey blog
voicing/4, % +Tuning, +Frets, ?Quality, ?Voicing
voicing/2, % ?Quality, ?Voicing
% readable notation
op(1,xf,#), % semitone
op(2,xfx,@), % octave indicator
pitch_note/2,
pitch_octave/2,
pitch_notation/2,
% give the numbers a name
guitar_tuning/3 % ?Label,?Tuning,?Frets
]).
%! voicing(?Tuning, ?Frets, ?Quality, ?Voicing) is semidet
%
% from Pete Corey blog, modified to use list-of-pairs instead
% of list of list-of-2-elements
%
voicing([], _, [], []).
voicing([String-Open|Tuning], Frets, Quality, [String-Fret|Voicing]) :-
between(0, Frets, Fret),
Pitch is (Open + Fret) mod 12,
%member(Pitch, Quality),
%subtract(Quality, [Pitch], RemainingQuality),
select(Pitch,Quality,RemainingQuality), % as suggested by @jamesnvc
voicing(Tuning, Frets, RemainingQuality, Voicing).
voicing([_|Tuning], Frets, Quality, Voicing) :-
voicing(Tuning, Frets, Quality, Voicing).
voicing(Quality, Voicing) :-
( var(Quality)
-> % enable exploration...
between(3, 4, CountNotes),
length(Quality, CountNotes)
; true
),
same_length(Quality, Voicing),
% introduce readability
guitar_tuning(standard, Tuning, Frets),
voicing(Tuning, Frets, Quality, Voicing).
%! pitch_note(+Pitch, ?Note) is det
%
% readibility interface, to know which Note is a Pitch number
%
pitch_note(Pitch, Note) :-
P is Pitch mod 12,
nth0(P, [c,c#,d,d#,e,f,f#,g,g#,a,a#,b,b#], Note).
%! pitch_octave(+Pitch, ?Octave) is det
%
% readibility interface, to know which Octave is a Pitch number
%
pitch_octave(Pitch, Octave) :-
Octave is Pitch // 12.
%! pitch_notation(?Pitch, ?Notation) is det
%
pitch_notation(Pitch, Note @ Octave) :-
pitch_note(Pitch, Note),
pitch_octave(Pitch, Octave).
%! guitar_tuning(?Label, ?Tuning, ?Frets) is semidet
%
guitar_tuning(standard, [0-40,1-45,2-50,3-55,4-59,5-64], 18).
guitar_tuning(lower_D, [0-38,1-45,2-50,3-55,4-59,5-64], 18).
It took a couple of minutes to answer
?- aggregate_all(count,voicing(_,_),N).
N = 47738640.
Just out of interest, the logician S. K. Langer wrote A Set of Postulates for the Logical Structure of Music back in 1929. The article was referenced in Potentials of General-Purpose Reasoning Assistant System EUODHILOS which was part of the Japanese 5th generation computing project. That system was written in Prolog (I believe).
Presumably that can be select/3
instead?
thanks, fixed
Thanks everyone! I’m happy you enjoyed the post. I’ve honestly been overwhelmed by how welcoming and helpful the Prolog community has been over the past few days.