The guitar fretboard is a never-ending landscape of interesting relationships ripe for exploration, so Prolog seems like a valuable tool to have at our arsenal as fretboard explorers

Got a link to this blob post. Nice read :slight_smile: 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 :stuck_out_tongue:

1 Like

Nice reading indeed.
Have modified the code for readability and to enable the ‘exploration mode’. Here it is:

/*  File:
    Author:  Carlo,,,
    Created: Apr 23 2020
    Purpose: comment on

:- 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


              % 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

1 Like

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.