Commit 18b2e34c by Maxime Perrotin

### Check fully boolean decision branches

parent d9967b59
 ... @@ -3496,7 +3496,7 @@ def decision(root, parent, context): ... @@ -3496,7 +3496,7 @@ def decision(root, parent, context): covered_ranges[ans].append(ans.inputString) covered_ranges[ans].append(ans.inputString) is_enum = True is_enum = True elif q_basic.kind == 'BooleanType': elif q_basic.kind == 'BooleanType': covered_ranges[ans].append(ans.inputString) covered_ranges[ans].append(ans.constant.value[0]) is_bool = True is_bool = True if not ans.constant.is_raw: if not ans.constant.is_raw: need_else = True need_else = True ... @@ -3633,8 +3633,10 @@ def decision(root, parent, context): ... @@ -3633,8 +3633,10 @@ def decision(root, parent, context): # (2) no gap in the coverage of the decision possible values # (2) no gap in the coverage of the decision possible values # (3) ELSE branch, if present, can be reached # (3) ELSE branch, if present, can be reached # (4) if an answer uses a non-ground expression an ELSE is there # (4) if an answer uses a non-ground expression an ELSE is there # (5) present() operator and enumerated question are fully covered # (5) boolean expressions are fully covered # (6) present() operator and enumerated question are fully covered # (1) no overlap between covered ranges in decision answers q_ranges = [(qmin, qmax)] if dec.question \ q_ranges = [(qmin, qmax)] if dec.question \ and is_numeric(dec.question.exprType) else [] and is_numeric(dec.question.exprType) else [] for each in combinations(covered_ranges.viewitems(), 2): for each in combinations(covered_ranges.viewitems(), 2): ... @@ -3690,7 +3692,14 @@ def decision(root, parent, context): ... @@ -3690,7 +3692,14 @@ def decision(root, parent, context): qwarn.append('Decision "{}": Missing ELSE branch' qwarn.append('Decision "{}": Missing ELSE branch' .format(dec.inputString)) .format(dec.inputString)) # (5) check coverage of enumerated types # (5) check coverage of boolean types # Rules: # a. exactly 2 answers # b. if one answer is not ground expression, other branch must be ELSE # c. if there is a ground expression G in a branch, the other branch # must evaluate to non-G or be ELSE # (6) check coverage of enumerated types if is_enum or is_bool: if is_enum or is_bool: # check duplicate answers # check duplicate answers answers = [a.lower() answers = [a.lower() ... @@ -3700,11 +3709,13 @@ def decision(root, parent, context): ... @@ -3700,11 +3709,13 @@ def decision(root, parent, context): qerr.append('Decision "{}": duplicate answers "{}"' qerr.append('Decision "{}": duplicate answers "{}"' .format(dec.inputString, '", "'.join(dupl))) .format(dec.inputString, '", "'.join(dupl))) if is_bool: if is_bool: # Boolean special case: values are just True and False enumerants = ['true', 'false'] enumerants = ['true', 'false'] if len(answers) + (1 if has_else else 0) != 2: qerr.append('Boolean decision "{}" must have exactly 2 answers' .format(dec.inputString)) else: else: enumerants = [en.replace('-', '_').lower() enumerants = [en.replace('-', '_').lower() for en in q_basic.EnumValues.keys()] for en in q_basic.EnumValues.keys()] # check for missing answers # check for missing answers if set(answers) != set(enumerants) and not has_else: if set(answers) != set(enumerants) and not has_else: qerr.append('Decision "{}": Missing branches for answer(s) "{}"' qerr.append('Decision "{}": Missing branches for answer(s) "{}"' ... ...
 [ERROR] Decision "var6": No answer to cover range -5.0 .. 10.0 [ERROR] Boolean decision "varbool" must have exactly 2 answers [ERROR] Decision "var6": answers >=10.0 and <=10.0 are overlapping in range 10.0 .. 10.0 [ERROR] Decision "var6": No answer to cover range 0.0 .. 0.1 [ERROR] Decision "var6": No answer to cover range 0.0 .. 0.1 [ERROR] Decision "var6": No answer to cover range 10.0 .. 10.5 [ERROR] Decision "var6": No answer to cover range 10.0 .. 10.5 [ERROR] Decision "var6": No answer to cover range -5.0 .. 10.0 [ERROR] Decision "var6": No answer to cover value 10.0 [ERROR] Decision "var6": No answer to cover value 10.0 [ERROR] Decision "var6": answers >=10.0 and <=10.0 are overlapping in range 10.0 .. 10.0 [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Decision "varbool": Missing branches for answer(s) "false" [ERROR] Too many errors, cannot generate code [ERROR] Too many errors, cannot generate code [INFO] Checking ['myfunction.pr', 'system_structure.pr'] [INFO] Checking ['myfunction.pr', 'system_structure.pr'] [INFO] Parsing complete. Summary, found 3 warnings and 7 errors [INFO] myfunction.pr [INFO] myfunction.pr [WARNING] Decision "var6": Range -10.0 .. -5.0 is unreachable [INFO] Parsing complete. Summary, found 3 warnings and 8 errors [WARNING] Decision "var6": Range 100.0 .. 150.0 is unreachable [WARNING] Decision "var6": Range 100.0 .. 150.0 is unreachable [WARNING] Decision "var6": Range -10.0 .. -5.0 is unreachable [WARNING] Decision "varbool": Missing ELSE branch [WARNING] Decision "varbool": Missing ELSE branch
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment