13

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?)

Michel
  • 23,085
  • 46
  • 152
  • 242
  • Is "Except" an object or it means as usual English? Because I see something like " stop it Except", "continue Except", and "Except, when the temp..." – vodkhang Sep 22 '10 at 08:37
  • @vodkhang: I think he just forgot a few periods. – Joren Sep 22 '10 at 08:45
  • 2
    As usual English, read it like 'do a, except when this is true, then do b, except when c is doing something for 10 minutes, then do c etc. – Michel Sep 22 '10 at 08:48
  • i think my [enters] don't show up :) i've put some extra ENTERS in the text – Michel Sep 22 '10 at 09:01
  • @Michel from the example you posted it seems its more about a lot of special conditions, but not so much about a 'lot of variables'. Is that the case in the real thing you are trying to address, perhaps you have > 50 situations but just < 10 variables? – eglasius Sep 22 '10 at 10:07
  • @eglasius, you're right, we have approx 15 variables – Michel Sep 23 '10 at 09:51
  • Personally, I find this discussion very interesting to follow, but I have zero knowledge about how to go about modeling such a system in code. Can anyone give me an example of what this would look like in an OO programming language? java/c++/C# whatever. Purely out of curiosity. thx – stombeur Sep 24 '10 at 09:54

5 Answers5

7

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
  • 811,555
  • 193
  • 1,581
  • 1,452
  • +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 Sep 22 '10 at 08:41
  • this answer is sinking in my brains right now, how to build such a model – Michel Sep 22 '10 at 09:03
  • @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 Sep 22 '10 at 09:23
  • 1
    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 Sep 22 '10 at 09:25
6

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
  • 3,427
  • 15
  • 18
  • 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 Sep 22 '10 at 09:58
  • 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 Sep 22 '10 at 10:40
  • 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. – stombeur Sep 22 '10 at 12:38
  • @MrDosu sure, but the linked framework doesn't look like that at all. The when / then constructs in it are basically if & {}, you want a state machine based on a model like the one in WF or something like @Mark's answer which is hard to pull off as he explains in his answer. The 'states' in that framework are just names as each require defining a when that is just like what you'd have in the if (given properly designed code). If instead you are saying when then end is better than if {} is just a religious argument pretty much like VB.net vs. c#. – eglasius Sep 22 '10 at 16:35
  • @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 Sep 22 '10 at 16:46
  • @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 Sep 22 '10 at 18:33
  • 2
    @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 Sep 22 '10 at 18:40
  • 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 Sep 22 '10 at 19:34
  • @MrDosu: good link, the 'en.wikipedia.org/wiki/Complex_event_processing' link – Michel Sep 23 '10 at 10:02
4

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
  • 35,831
  • 5
  • 65
  • 110
2

+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.

stombeur
  • 2,704
  • 22
  • 45
  • 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 Sep 22 '10 at 08:52
  • @Steven - thanks for the formatting. I didn't know it was just a question of indenting. thx! – stombeur Sep 22 '10 at 12:35
  • Just start a line of code with 4 spaces and you're good to go ;-) – Steven Sep 22 '10 at 13:36
1

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
  • 6,981
  • 13
  • 48
  • 86