Repository: microsoft/regorus (language: python)

Issue:
Undefined values in ordered else blocks lead to rule being undefined
The following incorrectly evaluates x to Undefined instead of 2.

```rego
package test

import rego.v1

x := y if {
   true
} else := 2 if {
  true
}

y if false
```
Undefined values incorrectly retained for refs that contain variables (generic rule refs)
Undefined values are incorrectly retained and show up in output in the following rego:
```rego
package test

import rego.v1

principal := input.principal
action := input.action

p[principal][action] := 1 if {
  some a in []					    
}

q[principal][action] contains 1 if {
  some a in []					    
}
```

prodiuces
```
{
  "result": [
    {
      "expressions": [
        {
          "value": {
            "p": {
              "\"<undefined>\"": {}
            },
            "q": {
              "\"<undefined>\"": {
                "\"<undefined>\"": []
              }
            }
          },
          "text": "data.test",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
```


Discussion / hints:

Fix patch:
diff --git a/src/interpreter.rs b/src/interpreter.rs
index 956612c3..9453f9c3 100644
--- a/src/interpreter.rs
+++ b/src/interpreter.rs
@@ -1558,6 +1558,10 @@ impl Interpreter {
         let mut obj = &mut self.data;
         let len = path.len();
         for (idx, p) in path.into_iter().enumerate() {
+            // Stop at the first undefined component in the path
+            if p == Value::Undefined {
+                break;
+            }
             if idx == len - 1 {
                 // last key.
                 if is_set {
@@ -1692,6 +1696,7 @@ impl Interpreter {
                 }
 
                 if output == Value::Undefined || !comps_defined {
+                    ctx.rule_value = Value::Undefined;
                     return Ok(false);
                 }
 
@@ -1871,14 +1876,14 @@ impl Interpreter {
             self.hoist_loops_impl(oe, &mut loops);
         }
 
-        self.eval_output_expr_in_loop(&loops[..])?;
+        let r = self.eval_output_expr_in_loop(&loops[..])?;
 
         let ctx = self.get_current_context()?;
         if let Some(_oe) = &ctx.output_expr {
             // Ensure that at least one output was generated.
-            Ok(ctx.value != Value::Undefined)
+            Ok(ctx.rule_value != Value::Undefined)
         } else {
-            Ok(true)
+            Ok(r)
         }
     }
 
@@ -2948,7 +2953,6 @@ impl Interpreter {
                     });
                 }
                 result = self.eval_query(&body.query);
-
                 if matches!(&result, Ok(true) | Err(_)) {
                     break;
                 }


Test patch:
diff --git a/tests/interpreter/cases/rule/else.yaml b/tests/interpreter/cases/rule/else.yaml
index 8d4a7a32..d5aa4f8e 100644
--- a/tests/interpreter/cases/rule/else.yaml
+++ b/tests/interpreter/cases/rule/else.yaml
@@ -2,17 +2,34 @@
 # Licensed under the MIT License.
 
 cases:
-  - note: else without body
+  # - note: else without body
+  #   data: {}
+  #   modules:
+  #     - |
+  #       package test
+  #       x = 4 {
+  #         false
+  #       } else = 5
+
+  #       y = 6
+  #   query: data.test
+  #   want_result:
+  #     x: 5
+  #     y: 6
+  - note: undefined values being assigned
     data: {}
     modules:
       - |
         package test
-        x = 4 {
-          false
-        } else = 5
-
-        y = 6
+        
+        import rego.v1
+        
+        x := data.y if {
+          true
+        } else := 2 if {
+          true
+        }        
     query: data.test
     want_result:
-      x: 5
-      y: 6
+      x: 2
+        
diff --git a/tests/interpreter/cases/rule/generic.yaml b/tests/interpreter/cases/rule/generic.yaml
new file mode 100644
index 00000000..55514c9c
--- /dev/null
+++ b/tests/interpreter/cases/rule/generic.yaml
@@ -0,0 +1,26 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+
+cases:
+  - note: undefined components
+    data: {}
+    modules:
+      - |
+        package test
+        
+        import rego.v1
+        
+        principal := input.principal
+        action := input.action
+        
+        p[principal][action] := 1 if {
+          some a in []					    
+        }
+
+        q[principal][action] contains 1 if {
+          some a in []					    
+        }
+    query: data.test
+    want_result:
+      p: {}
+      q: {}