How can I do this the right way
The right way is to take context into account, and the note reduction decisions are usually somewhat artistic choices. Your program has to be able to look at the song and understand what the essential point is. What does the picture represent?
Context means things like:
- What key is it in? How does each chord turn the harmonic balance away from the tonic, or back to tonic?
- What comes before and after each chord? Is there a voice stepping/leading going somewhere. Like Am - Ammaj7 - Am7 - Am6. If you reduce this to Am - Am - Am - Am, you keep the bass, but lose the descending A - G# - G - F# line. A reduction to Am - E - C - D has an aspect of that line, but not the bass.
- Is there a chord-rhythm pattern, or song form of some kind? If the changes or harmonic turns form e.g. an A-A-B-A structure, you might want to keep that intact. Is it a 12-bar blues? Sometimes, there's a chord change such as C - Csus - C - Csus just to have a chord change, any change as long as there is a change. If you remove such changes in the name of simplification, you throw away the rhythmic events that harmonic changes have. If you have to "simplify" the Csus, then maybe even a Dm would do the job, even though normally you wouldn't consider Dm a substitute for Csus.
- What does the melody do? If there is a melody. Maybe the melody handles some of the chord tones, so you can leave such a note out somewhere, if it allowes you to use a simpler chord.
- Are there "out-of-scale" notes in the chords, perhaps doing a modulation or modal interchange? Is your "Gm7" really just a fancy C7 chord? Or is it better to replace it with Gm?
- If there's a dim7 chord, what is it essentially doing, if you had to explain it in terms of tonic-subdominant-dominant? Is it a jazzy substitution for a dominant chord, or maybe a minor chord? (Try to do this for example with Chaplin's "Smile") Dominant-tonic kind of motion of a different key, like a secondary dominant?
Do you want the generated reduction to (a) be easy to play, or (b) sound right and truthful to the original? What elements of the original song do you want to preserve? Which elements are essential to that song?
I would think that plain and simple C might be a better three-note reduction of Am7/C than your suggested Am. If someone wrote a bass inversion, maybe they did it for a purpose. The lowest note might be important to preserve, particularly if there's a bass motion. If there's a progression like: Am7 - Am7/C - D - E, then Am - C - D - E is a much better reduction than Am - Am - D - E. The original had a steady equal-time-per-chord chord rhythm, but Am - Am - D - E has the same chord stay for two steps! So it's missing a chord change. Different chord rhythm and different bass motion.
If there's Am - Bm7-5 - E - Am, then you have two possible reductions for the Bm7-5 chord: Dm and Bdim. "Bm" would be WRONG because it has an F# note. It is absolutely essential to keep the "-5", which is an F. It would be nice to keep the B bass note too, so Bdim would be better. But maybe it's a strange chord for your "beginners"? In that case, Dm is the only correct choice for an easier reduction. In the key of Am.
To sum this up: to make a good chord simplification/reduction, you need to look at the whole harmonic progression, how it turns. You select the most important harmony-turning notes from each chord and select a "simple" chord which preserves these important notes.
It might be possible to program this as a very large bank of special case rules, if you can figure out the key. If you can create an engine where it's easy to add more refined logic rules, then ... why not. But still, you'd have to add some sort of heuristic factors and fuzzy stuff like "what is the song structure", and write an evaluation function which assigns a "beauty factor" for each candidate reduction choice. :) Might be a fun project for a computer science student?
The algorithm could be something like:
- "Realize" each chord symbol as notes. From now on you'll be handling chords as note combinations (like note stacks in staff music), not textual symbols.
- Generate a number of candidate reductions for each chord, with triads or whatever "simple" chords you want to produce.
- Select the "best" combination of candidates for the song, by evaluating a HowGoodIsThisReduction() function. Either for individual chords, or entire reduced songs.
- Convert each selected best candidate chord back to a textual chord symbol.
How well this works, depends on the HowGoodIsThisReduction() function. If it only looks at individual chords like HowGoodIsThisReduction(OriginalChord, ReducedChord), then it cannot retain any information about movement and song structure. But if it's like HowGoodIsThisReduction(OriginalSong, ReducedSong), then it might give extra points for keeping song structure, voice leading and harmonic turns intact.
The GenerateCandidateReductionsForChord() function might operate by simply leaving out notes. Or it could take the key of the song into account and suggest E major as a candidate replacement for Am maj7. And then let the evaluator function decide if Am - Am - Am - Am is a better reduction than Am - E - C - D for the chord progression Am - Am maj7 - Am7 - Am6. The choice between these two reduction styles could be user-configurable.