views:

251

answers:

6

Hi,

i have to create a program for a kind of complex proces. Well, the process is not complex, but there are a lot of variables which control the process. I can't in detail tell about the process, so i've made up one, which has the same load of IF's:

the process is: should we stop the iron melt oven or not. We've got these parameters: if the temp goes above 800 degrees celcius, stop it Except, when we expect cool water to be available from oven 2 in the next 20 minutes, we can continue

Except, when the temp rises 10 degrees in the next 10 minutes, we can't wait another 10 minutes for the cold water, so we have to stop.

Except, when the temp goes down for some reason to 790-800 degrees for 5 minutes, we add an extra 5 minutes to the time we need the extra cool water.

Except, when the temp goes down for some reason to 780-790 degrees for 5 minutes, we add an extra 5 minutes to the time we need the extra cool water.

etc. etc.

You can all think of another 20 except / if / then's

in our process we have > 50 situations, all for one goal: should the machine stop or not.

I must say i normally don't have that many situations for one goal/issue (namely: stop the machine or not), and it is also timebound: if this is happening for 10 minutes then...., and we have to calculate the situation every minute again.

Is there a way to program this in a smart way?

(and also unit test, because we have loads and loads of combinations which are all seperate unit tests i guess?)

+7  A: 

Instead of manually working out all the situations in which you must stop the oven based on your knowledge of how an oven works, you could get the computer to do this for you.

Try to program a model for how an oven works and at each time point you can run a simulation of what will happen in the next 10 minutes or so. If the simulation shows that a serious problem will occur soon then you can stop the oven now, otherwise let it run for a minute, read the inputs and run the simulation again.

Coding an accurate model will require some effort, but as your requirement change slightly (for example your over was upgraded or repaired) it will be relatively easy to update the model - in the best case you just modify the model parameters or update a single formula.

With your current approach if you modified the oven slightly you would have to first calculate manually what effects that will have, and then go through all the code line-by-line updating the different conditions.


Regarding unit testing - ideally you should test your model on data from a real oven in a variety of situations and check that your simulation predicts the actual measured results (with some tolerance allowed for reading inaccuracies). If this is not possible then you can hardcode some example scenarios and the expected result (e.g. overheating) and test that the simulation correctly predicts the result.

Mark Byers
+1 but that's going to be a serious change of strategy and if they're already into writing code it's probably too late
annakata
this answer is sinking in my brains right now, how to build such a model
Michel
@Michel: You need to have some understanding of how the oven works. If the temperature is currently 400C and you set it to heat to 500C, the temperature doesn't instantaneously change. If you can find a formula that describes the rate of change of temperature you can use that to predict the temperature in 1 minute, 2 minutes, etc. If you don't know the formula you could look at some real data and find a formula that gives a good fit, or else ask someone with understanding of the physical processes to help you derive a formula.
Mark Byers
This is the right approach. Ideally you should get an engineer involved. Someone who is familiar with https://secure.wikimedia.org/wikipedia/en/wiki/Control_engineering. Building a model is hard, especially trying to prove that it acurately matches reality. Fortunately it is not, as negative feedback can compensate. You need to read up on feed back theory, system stability. Also have a look at fuzzy logic if you really want an IF based approach.
David Roussel
+6  A: 

Some problem spaces dont fit into the OOP principle very elegantly. It sounds your situation can be managed much better in a rule based paradigm (especially when rules change). Here is an exampe of a rule based framework for .NET: http://www.codeproject.com/KB/cs/Drools_NETPrimer.aspx

MrDosu
I might be wrong, but I can't help but feel that's just shifting the problem to the rules. As the then part of OP's question is really just start or stop, then you would probably end up with the very same rules he already had as if statements.
eglasius
The problem I see with the if constructs is maintainability and communication with the engineers. In my experience machine specifications are usually stated as state based rules and implementing a mechanism for converting those rules given as closely to the domain as possible should be preferred. It might be much easier to even enable the engineers to change rules based on changing environments given a strong model for all participants (e.g. engine/cooler...) without changing implementation detail of the application.
MrDosu
I agree with MrDosu. Legibility of code using if constructs will be difficult. Rules are 'flat' in the sense that you don't need to stack nested ifs in your mind to understand the impact of a rule.
StephaneT
eglasius
@MrDosu maybe it does support a different model and you intend it to be used a different way than in the link, if that's the case I suggest you update/mention it in your answer. @StephaneT I don't see the OP referring to a nested ifs issue / which is the arrow anti pattern.
eglasius
@eglasius I agree that the above link is not a very good explanation of rule based processing in general, but its the free rule engine implementation i know in .NET. The whole concept is quite complex and rules based programming is quite different then just when/then/end (which really are just scripted ifs), but it would likely kill the scope of a simple question/answer thread. The link i provided is an .NET port of the popular Drools engine and if you are interested in the topic their documentation is an interesting, although long, read (http://jboss.org/drools/).
MrDosu
@eglasius Drools also implements forms of Complex Event Processing http://en.wikipedia.org/wiki/Complex_event_processing, which is quite important when the rules start to rely on each other (and especially important when we are talking real-time systems).
MrDosu
ok, I think we are in agreement then. It was an important clarification. As mentioned in my answer, WF is another alternative to achieve the same.
eglasius
@MrDosu: good link, the 'en.wikipedia.org/wiki/Complex_event_processing' link
Michel
+2  A: 

+1 bump MrDosu's answer on rule engines. A simple rule engine like the WF rule engine may be enough for what you need. As long as you use .NET 3.0+ you can use this programmatically without using workflows.

EDIT: unit testing this should be easy, but laborious to create all the scenarios to test. The data (a class) that you send as input to the rule engine is the current state of the scenario. Create a number of states or scenarios and send these to the rule engine in a unit test. Or you could combine multiple states one after another in a single unit test to test a logical progression

EDIT2: some source code for using WF rulesets

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.ServiceModel.Description;  
using System.Xml.Schema;  
using System.Workflow.Activities.Rules;  
using System.Workflow.ComponentModel.Serialization;  

namespace ServiceMediation.Behaviors  
{  
    public class TransformingMessageServiceBehavior : IServiceBehavior  
    {  
        private string _ruleSetPath = null;  
        private RuleSet _ruleSet = null;  

        public TransformingMessageServiceBehavior(string ruleSet)
        {
            if (!string.IsNullOrWhiteSpace(ruleSet))
            {
                _ruleSetPath = ruleSet;
                WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
                XmlTextReader reader = new XmlTextReader(_ruleSetPath);
                RuleDefinitions rules = serializer.Deserialize(reader) 
                    as RuleDefinitions;
                _ruleSet = rules.RuleSets[0];
            }
        }
...

and then something like

RuleValidation validation = new RuleValidation(typeof(EvaluationData), null);
RuleExecution exec = new RuleExecution(validation, data);  
_ruleSet.Execute(exec);  

with EvaluationData = the data you give as input. The rules are typed to this data. It also serves as output result, check the result of executing the ruleset on a property of the data.

StephaneT
I have never thought about using the WF rules engine for simpler rules scenarios excluding the workflows. I will immediatly crunch some code :D. Thank you
MrDosu
@Steven - thanks for the formatting. I didn't know it was just a question of indenting. thx!
StephaneT
Just start a line of code with 4 spaces and you're good to go ;-)
Steven
+4  A: 

imho the way you are reasoning about the problem closely resembles a state machine.

So its more about modeling states and what you can do in each of those. WF was mentioned for a different use (actually its ruleset), but I'd look more at the state based workflows, as there you can focus on each of those states and how you can transition between then.

eglasius
A: 

Souds Like a State Design Pattern

saurabh
+1  A: 

Find a library that provide implementation for finite state machine and model your process as a fsm. There is a number of questions about fsms on stackoverflow: http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=fsm+site:stackoverflow.com.

Skarab