Hone logo
Hone
Problems

Implementing Basic Type Inference in Python

Type inference is a powerful feature in many programming languages where the compiler or interpreter automatically deduces the data type of a variable or expression based on its usage. While Python is dynamically typed, this challenge asks you to implement a simplified type inference system for a subset of Python expressions. This exercise will help you understand the underlying principles of type inference and how it can be applied to improve code clarity and potentially performance.

Problem Description

You are tasked with creating a function infer_type(expression, context) that takes a Python expression (represented as a string) and a context dictionary as input and returns the inferred type of the expression as a string. The context dictionary maps variable names to their inferred types. The supported expressions are limited to simple assignments and arithmetic operations involving integers and floats.

Supported Expressions:

  • Variable Assignment: x = 10 or y = 3.14
  • Integer Literals: 10, -5
  • Float Literals: 3.14, -2.5
  • Addition: x + y (where x and y are variables or literals)
  • Subtraction: x - y (where x and y are variables or literals)
  • Multiplication: x * y (where x and y are variables or literals)
  • Division: x / y (where x and y are variables or literals)

Key Requirements:

  • The function must correctly infer the type of the expression based on the literals and the context.
  • If an expression involves a variable, the function should look up its type in the context. If the variable is not in the context, it should return "Unknown".
  • The type inference rules are as follows:
    • Integer literals have type "int".
    • Float literals have type "float".
    • If both operands of an arithmetic operation are integers, the result is an integer.
    • If either operand of an arithmetic operation is a float, the result is a float.
  • The function should handle invalid expressions gracefully by returning "Invalid Expression".

Expected Behavior:

The function should return a string representing the inferred type. Valid types are "int" and "float".

Edge Cases to Consider:

  • Variables not present in the context.
  • Invalid expression syntax (e.g., x = +10).
  • Division by zero (should not be explicitly checked, but the expression should still be parsed).
  • Expressions with unsupported operators (e.g., exponentiation).

Examples

Example 1:

Input: expression = "x = 10", context = {"x": None}
Output: "int"
Explanation: The expression assigns the integer literal 10 to the variable x. Since x is not in the context, we infer its type as int.

Example 2:

Input: expression = "y = 3.14", context = {"y": None}
Output: "float"
Explanation: The expression assigns the float literal 3.14 to the variable y. Since y is not in the context, we infer its type as float.

Example 3:

Input: expression = "x + y", context = {"x": "int", "y": "float"}
Output: "float"
Explanation: The expression adds x and y. x is an integer and y is a float.  The result of adding an integer and a float is a float.

Example 4:

Input: expression = "z + 10", context = {"z": "int"}
Output: "int"
Explanation: The expression adds z and 10. z is an integer and 10 is an integer. The result of adding two integers is an integer.

Example 5:

Input: expression = "a + b", context = {"a": "int"}
Output: "Unknown"
Explanation: The expression adds a and b. a is an integer, but b is not defined in the context.

Constraints

  • The expression string will be at most 256 characters long.
  • The context dictionary will contain at most 10 key-value pairs.
  • Variable names will consist of lowercase letters.
  • The function must return the type as a string: "int" or "float".
  • The function should not raise exceptions; it should handle errors gracefully and return "Invalid Expression".

Notes

  • You don't need to implement a full-fledged parser. A simple string parsing approach is sufficient.
  • Focus on the core logic of type inference based on the provided rules.
  • Consider using regular expressions or string splitting to extract the relevant information from the expression.
  • The context dictionary is used to store the types of variables that have already been inferred.
  • This is a simplified version of type inference. Real-world type inference systems are much more complex.
Loading editor...
python