Ways to implement a decision making process involving complex rules I'm investigating different solutions for solving what looks like a decision making problem. Although the domain I'm working on is different, for the problem at hand, it's quite easy explaining with an example of online shopping cart.

Suppose you have a shopping cart like you have in every online retailer but this one checks some criteria and allow you to proceed only if the cart conforms to some criteria. Those criteria can depend on:


a property of the item you add to your cart (ex: minimum quantity allowed for the item you add)
combinations of the items you add (ex: if you have in your cart an item from sports category, you need to add an item from nutrition category)
properties of the cart itself (ex: option to give multiple orders from the same cart but only if certain type of items are in the cart)
and many other rules with exceptions...


So at a given time, your cart is in one of two states: valid or invalid. It starts with the state invalid: An empty cart. And at each action you take the state changes.

Some of the actions that change the state of the cart are:


adding an item to cart
changing a property of the item added, like color, size, quantity, etc
changing a property of the cart, like applying a discount code.


What I'm trying to achieve is to find a clean way to decide after every action, whether the cart is in a valid state or not. 

The current code base for this is a mess. A method of hundreds lines of code, taking 15 arguments and filled with ifs and fors.

I wonder what are the possible solution patterns I can use to refactor this into a cleaner and maintainable implementation.

I've investigated finite state machines but couldn't figure out how to represent this into states and actions. Decision making trees I've seen are for pretty simple flows when you can answer yes or no easily. And they were implemented with nested ifs and elses which is quite similar to the current (messy) solution. My investigation lead me to AI and expert systems but I stopped there. As you can guess, I have no previous experience dealing with these kind of problems. Maybe what I'm trying to solve is a complex one and it's ok to have complex solutions to complex problems. But maybe this is a generic problem where you can give some direction to focus my research.
It sounds to me like the techniques here are not a matter of science (e.g., clever algorithms) so much as engineering (e.g., program structuring).

The approach I would suggest is to have a list of validators.  Each validator is a function or object that, when passed a shopping cart, checks whether the cart satisfies a particular criterion.  You have one validator per criterion in your business rules.  Then, to check whether a shopping cart is valid, you can simply iterate over all the registered validator.

This lets you structure the program logic in a cleaner way.  Each criterion is separated out into its own function or subclass.  Thus, while you still might have hundreds of lines of code in general, this way there is some structure, and if you're lucky, most or all validators can be written in a fairly concise way, as each one deals with only a single concern/criterion.