As I don't know your application, lets use the following scenario:
Now I can create a Customer Product selection page for a Customer. On that page, I can have a DataView for Customer and 2 separate reference selectors: one which retrieves both family and single products and on that retrieves only single products. I can make those reference selectors visible based on the boolean attribute on the Customers entity. In this way, a single customer can only select single products and a family customer can select single and family products.
You could also do this check in a microflow when a product is selected. However, this is not a great approach, IMO. If I know, as the app developer, that a given customer cannot purchase certain products, why show those products in the first place?
There are other ways to accomplish this also, this is just the first one that comes to mind.
Hope that helps,
I agree with Mike's solution as one way to deal with this. Have you tried creating a validation rule on the commit of joining a Program? For example, create Program, but then create specializations of that Program with associations to the Diner, but then the specialized Program should have a validation rule on Commit that the Diner meets the criteria (or the Program meets it's own criteria). That's another way you could look at solving this I think.