//-------------------------------------------------------------------------------- // Code generated by jFuzzyLogic //-------------------------------------------------------------------------------- function ruleAccumulationMethod_max(defuzzifierValue, valueToAggregate) { return (defuzzifierValue > valueToAggregate ? defuzzifierValue : valueToAggregate); } function ruleActivationMethod_min(degreeOfSupport, membership) { return (degreeOfSupport < membership ? degreeOfSupport : membership); } function ruleConnectionMethod_and(antecedent1, antecedent2) { return (antecedent1 < antecedent2 ? antecedent1 : antecedent2); } function ruleConnectionMethod_or(antecedent1, antecedent2) { return (antecedent1 > antecedent2 ? antecedent1 : antecedent2); } class FunctionBlock_tipper { // VAR_INPUT food; service; // VAR_OUTPUT tip; // FUZZIFY food food_delicious; food_rancid; // FUZZIFY service service_excellent; service_good; service_poor; // DEFUZZIFY tip defuzzify_tip; // Constructor constructor() { this.tip = 0.0; this.defuzzify_tip = new Array(1000); } // Calculate function block calc() { this.reset(); this.fuzzify(); this.calc_No1(); this.defuzzify(); } // RULEBLOCK No1 calc_No1() { // RULE 1 : IF (service IS poor) OR (food IS rancid) THEN tip IS cheap; let degreeOfSupport_1 = 1.0 * (ruleConnectionMethod_or(this.service_poor, this.food_rancid)); if (degreeOfSupport_1 > 0) { for (let i = 0; i < 1000; i++) { let x = 0.0 + i * 0.03; let membership = this.membership_tip_cheap(x); let y = ruleActivationMethod_min(degreeOfSupport_1 , membership); this.defuzzify_tip[i] = ruleAccumulationMethod_max(this.defuzzify_tip[i], y); } } // RULE 2 : IF service IS good THEN tip IS average; let degreeOfSupport_2 = 1.0 * (this.service_good); if (degreeOfSupport_2 > 0) { for (let i = 0; i < 1000; i++) { let x = 0.0 + i * 0.03; let membership = this.membership_tip_average(x); let y = ruleActivationMethod_min(degreeOfSupport_2 , membership); this.defuzzify_tip[i] = ruleAccumulationMethod_max(this.defuzzify_tip[i], y); } } // RULE 3 : IF (service IS excellent) AND (food IS delicious) THEN tip IS generous; let degreeOfSupport_3 = 1.0 * (ruleConnectionMethod_and(this.service_excellent, this.food_delicious)); if (degreeOfSupport_3 > 0) { for (let i = 0; i < 1000; i++) { let x = 0.0 + i * 0.03; let membership = this.membership_tip_generous(x); let y = ruleActivationMethod_min(degreeOfSupport_3 , membership); this.defuzzify_tip[i] = ruleAccumulationMethod_max(this.defuzzify_tip[i], y); } } } // Defuzzify defuzzify() { let sum_tip = 0.0; let wsum_tip = 0.0; let x; for (let i = 0; i < 1000; i++) { x = 0.0 + i * 0.03; sum_tip += this.defuzzify_tip[i]; wsum_tip += x * this.defuzzify_tip[i]; } this.tip = wsum_tip / sum_tip; } // Fuzzify all variables fuzzify() { this.food_delicious = this.membership_food_delicious(this.food); this.food_rancid = this.membership_food_rancid(this.food); this.service_excellent = this.membership_service_excellent(this.service); this.service_good = this.membership_service_good(this.service); this.service_poor = this.membership_service_poor(this.service); } // Membership functions membership_food_delicious(x) { if (x <= 7.0) return 0.0; if (x > 9.0) return 1.0; if (x <= 9.0) return 0.0 + (1.0 - 0.0) * ((x - 7.0) / (9.0 - 7.0)); } membership_food_rancid(x) { if (x <= 0.0) return 1.0; if (x > 3.0) return 0.0; if (x <= 1.0) return 1.0 + (1.0 - 1.0) * ((x - 0.0) / (1.0 - 0.0)); if (x <= 3.0) return 1.0 + (0.0 - 1.0) * ((x - 1.0) / (3.0 - 1.0)); } membership_service_excellent(x) { if (x <= 6.0) return 0.0; if (x > 9.0) return 1.0; if (x <= 9.0) return 0.0 + (1.0 - 0.0) * ((x - 6.0) / (9.0 - 6.0)); } membership_service_good(x) { if (x <= 1.0) return 0.0; if (x > 9.0) return 0.0; if (x <= 4.0) return 0.0 + (1.0 - 0.0) * ((x - 1.0) / (4.0 - 1.0)); if (x <= 6.0) return 1.0 + (1.0 - 1.0) * ((x - 4.0) / (6.0 - 4.0)); if (x <= 9.0) return 1.0 + (0.0 - 1.0) * ((x - 6.0) / (9.0 - 6.0)); } membership_service_poor(x) { if (x <= 0.0) return 1.0; if (x > 4.0) return 0.0; if (x <= 4.0) return 1.0 + (0.0 - 1.0) * ((x - 0.0) / (4.0 - 0.0)); } membership_tip_average(x) { if (x <= 10.0) return 0.0; if (x > 20.0) return 0.0; if (x <= 15.0) return 0.0 + (1.0 - 0.0) * ((x - 10.0) / (15.0 - 10.0)); if (x <= 20.0) return 1.0 + (0.0 - 1.0) * ((x - 15.0) / (20.0 - 15.0)); } membership_tip_cheap(x) { if (x <= 0.0) return 0.0; if (x > 10.0) return 0.0; if (x <= 5.0) return 0.0 + (1.0 - 0.0) * ((x - 0.0) / (5.0 - 0.0)); if (x <= 10.0) return 1.0 + (0.0 - 1.0) * ((x - 5.0) / (10.0 - 5.0)); } membership_tip_generous(x) { if (x <= 20.0) return 0.0; if (x > 30.0) return 0.0; if (x <= 25.0) return 0.0 + (1.0 - 0.0) * ((x - 20.0) / (25.0 - 20.0)); if (x <= 30.0) return 1.0 + (0.0 - 1.0) * ((x - 25.0) / (30.0 - 25.0)); } // Print print() { console.log("Function block tipper:\n"); console.log(" Input %s: %f\n", "food" , this.food); console.log(" %s: %f\n", "food_delicious" , this.food_delicious); console.log(" %s: %f\n", "food_rancid" , this.food_rancid); console.log(" Input %s: %f\n", "service" , this.service); console.log(" %s: %f\n", "service_excellent" , this.service_excellent); console.log(" %s: %f\n", "service_good" , this.service_good); console.log(" %s: %f\n", "service_poor" , this.service_poor); console.log(" Output %s: %f\n", "tip" , this.tip); } // Reset output reset() { for (let i = 0 ; i < 1000; i++) { this.defuzzify_tip[i] = 0.0; } } }; function main(food, service) { // Create function blocks const tipper = new FunctionBlock_tipper(); // Parse input tipper.food = food; tipper.service = service; // Calculate tipper.calc(); // Show results tipper.print(); return [tipper.tip]; }