Decisional tree with State Machine
Tags: fsm
Published: 2021-06-29 11:13:12

Dealing with decisional tree using FSM is a breeze.
Here is a simple Loan Checker.

Here are the rules for according a Loan to a person P:

```js
  P.age >= 18
  P.CC  == true  (Credit Card)
```
The benefits come when you have numerous conditions to test.
You simply have to add new rules, and add the corresponding transitions within the **fsm** and you are done.

The rules are tested in sequential order.

Again, no view library, you can test it here : [LoanRunner](https://flems.io/#0=N4IgtglgJlA2CmIBcBWAbAOgCwEYA0IAZhAgM7IDaoAdgIZiJIgYAWALmLCAQMYD21NvEHIQAHigQAbgAJoAXgDktAA4rFAPgA61GTJ1iA9JKnbqO7iFLwEPNhAHkmWJAAYQAXzw16jZgCtyXgEhESYIMBU+ACc2GX9aKVpSHmiIFTYAZTZaIQBZWh4WCGp4GUJovjB9EHY2FVIkQ0MeKGoMUgBrAE8VQs6MKHgpQwSklLSMgFpSHKEpsELi0q0QAG4dfmpZmWzc+AKikrL5eMTk1PSsuYOl443zagQ4yVIVWFpugAV4aNIBGSnAAUKgAlICzHooHweABXBiCDAAdzSQiBAAMdHoxCwAEwaAAyfFouiK8B4nRKAHNyjEZAASYAqDB0BgeIx4yEyHEAZg0AEEqWUkAymRhaEL2YYWHysdyZRoAMKKmQixnMvhI6jKqUKnTo0EPHSEWHUOwOXQ-P4CIHAGSs+B4GQSx0yTXalUecHAOVsYqkFm+QH23wPPR+iABl3Bl1hmQRgPu5XBpOKh4eHQ6Z4yPqw2DB0pImRW-7UW1yh0i1ZfWh51Z4OUukVYACcDd0bq1ypFbGisMdOi9RuoJrN9gBZIpgvgIO9coghBkIPFQpkGlOOAAHHOO3povA2LDorpVi6APIAaVWcY8Mhs1hkPt3Mn3h+PNVoACMYmxr3KM9QAHGqa5oTiw5KdMqs6PvOi7LqmgKnL2-Y7noe4HkeJ4gDwPCXn+Ha3veZRPmhMhbP8CAYLAfBUkCqyKjwMidHwqyGnK6FvlhX4-vhegAUBZqOHERIkocywnOUIHjroIK-KWqEyNmKjBiockCHG5FxIQpDVKcha7DcYnHOWz69iSpAQNJjQyBQ7FoXalY1JOnTTvW5SVGAVYgNQAjwG5bB8CKznTtBXh2XoDm+F5znKm5FRVF555Xtw8aBWR4EUlBYIyGFz4RSGDBeXwnQieYKXxZ5Tm4clToBV5pCwjh8CkKQqw5e2pH5Y5qzMaVcUeYl36xP5aWrPu-jkkIUBtblpEALodTlbEdq+mHlDp6bDppinEtQNZ5sGpVGaUIK1rAy3USS+2wBgfCftY0RSDOJFutQmSNTwzXWUC4LyBoMjQnCCJsMiqIzqsvJkR8LVKPuDWwGwZ6dJopXOk1GTwFAHKyiAoKLQIABK8ATXYmMij9EIAzC8LCCDKKWeD4gylDySkLDzV5mwF58Cju0vsTk2Y9j2i4+2Q6ZiOUkWjtJKKhlnRApd1DHfACnbbQsCwAAKtE5mWRapDBkrKviprOt61ZP1xoQdKKwe8a69s+sAnwi4a9rjsWVZCl6AuS7G3cpQYDwJJAmZTvSbVfaq6CL2kQHRylBQ4dexac0-XZAF8YOEujqBuhKwTpqlNEFMva87yfCWNq5udcZK3LEGK7t13LQJhfF78VsWMEkQkL8oifl+NiWNYthWaIrhuFMADsPJuJ43jeb4ojBy1lhbKEbCD7CbABboL19DA1IijgrgqAAHnGQ8UlSlSmlASB3-AwjWyEMwQAAXvAIq4lgl8aSPP8aIIooglCENEdMEtPy733kgV4X4EBQBgh2G+nQ758AfkgfcUANJ8GoiAmQn4PgUkAdaQhpprBsHTKPGwk0DaiBbEgHAKBPALRALAEonQnBUGXgwUQkA-RpC4AQI8XAmB1AaE0QwpoVDoODlUQwgiWDCIAAK4gwK4bASjLIqJIBgSA7RAiWDYL0PwEwrhsIIA6UQeQbD2GoFSAAYpkPInggA)

```js
import javascriptStateMachine from "https://cdn.skypack.dev/javascript-state-machine";
const StateMachine = javascriptStateMachine;

let displayPerson = (p) =>
  document.write(`
  <h2>Loan checking for ${p.name}</h2>
  <h3>Age : ${p.age}</h3>
  <h3>CC : ${p.ownCC}</h3>
`);

function Person({ name, age, ownCC }) {
  this.name = name;
  this.age = age;
  this.ownCC = ownCC;
}

let paul = new Person({
  name: "Paul",
  age: 49,
  ownCC: true,
});

// rule 1 : age >= 18
function checkAge(p) {
  if (p.age >= 18) {
    return "ageOK";
  } else {
    return "abort";
  }
}

// rule 2 : ownCC === true
function checkCC(p) {
  if (p.ownCC == true) {
    return "ccOK";
  } else {
    return "abort";
  }
}

const LoanMachine = function (person) {
  let p = person;
  const fsm = new StateMachine({
    transitions: [
      { name: "checkAge", from: "none", to: checkAge(p) },
      { name: "checkCC", from: "ageOK", to: checkCC(p) },
      { name: "okLoan", from: "ccOK", to: "success" },
      { name: "koLoan", from: "abort", to: "rejected" },
    ],
  });
  return fsm;
};

const loanPaul = LoanMachine(paul);
loanPaul.observe({
  onSuccess: () => document.write("<h3 class='resultOk'>Loan accepted</h3>"),
  onRejected: () => document.write("<h3 class='resultKo'>Loan rejected</h3>"),
});

function loanCheck(loanMachine) {
  const allTransitions = loanMachine.allTransitions();
  // transitions run in sequential order 
  // we first check if the transition is possible
  for (let transition of allTransitions) {
    if (loanMachine.can(transition, true)){
      loanMachine[transition]()
    }
  }
}

function loanRunner() {
  displayPerson(paul);
  loanCheck(loanPaul);
}

loanRunner();

```