View Source cure_guard_refinement (cure v0.7.0)
Guard-Based Type Refinement
This module implements Phase 3 of the guard support implementation: type system integration for guard constraints.
Features
Guard Constraint Extraction
Extract constraints from function guards and convert them to refinement type predicates:
def abs(x: Int): Int when x >= 0 = x
% Refines x's type to: Int when x >= 0Flow-Sensitive Type Narrowing
Within a function body, parameters have their types refined based on the guard:
def process(x: Int) when x > 0 =
% Here, x has type: Int when x > 0 (i.e., Positive)
requires_positive(x)Cross-Clause Type Checking
Verify that all clauses of a multi-clause function have compatible return types:
def abs(x: Int): Int when x >= 0 = x
def abs(x: Int): Int when x < 0 = -x
% Return type unifies to: IntIntegration
This module integrates with:
cure_refinement_types- For creating refinement type predicatescure_typechecker- For enhancing function clause type checkingcure_guard_optimizer- For guard simplification and SMT encodingcure_smt_solver- For constraint verification
Implementation Approach
- Extract Guard Constraints: Parse guard expressions to identify parameter constraints
- Create Refinement Types: Convert guards to refinement type predicates
- Narrow Parameter Types: Replace parameter types with refined versions in function body scope
- Unify Return Types: Compute union type of all clause return types
- Verify Consistency: Use SMT to check guards are consistent and complete
Summary
Types
-type expr() :: #literal_expr{value :: term(), location :: term()} | #identifier_expr{name :: term(), location :: term()} | #function_call_expr{function :: term(), args :: term(), location :: term()} | #match_expr{expr :: term(), patterns :: term(), location :: term()} | #let_expr{bindings :: term(), body :: term(), location :: term()} | #binary_op_expr{op :: term(), left :: term(), right :: term(), location :: term()} | #unary_op_expr{op :: term(), operand :: term(), location :: term()} | #list_expr{elements :: term(), location :: term()} | #vector_expr{elements :: term(), location :: term()} | #tuple_expr{elements :: term(), location :: term()} | #record_expr{name :: term(), fields :: term(), location :: term()} | #field_access_expr{record :: term(), field :: term(), location :: term()} | #record_update_expr{name :: term(), base :: term(), fields :: term(), location :: term()} | #lambda_expr{params :: term(), body :: term(), location :: term()} | #forall_expr{variables :: term(), body :: term(), location :: term()} | #exists_expr{variables :: term(), body :: term(), location :: term()} | #fsm_spawn_expr{fsm_name :: term(), init_args :: term(), init_state :: term(), location :: term()} | #fsm_send_expr{target :: term(), message :: term(), location :: term()} | #fsm_receive_expr{patterns :: term(), timeout :: term(), location :: term()} | #fsm_state_expr{location :: term()} | #melquiades_send_expr{message :: term(), target :: term(), location :: term()} | #qualified_call_expr{trait_name :: term(), type_args :: term(), method_name :: term(), receiver :: term(), args :: term(), location :: term()}.
-type type_expr() :: #primitive_type{name :: term(), location :: term()} | #dependent_type{name :: term(), type_params :: term(), value_params :: term(), location :: term()} | #function_type{params :: term(), return_type :: term(), location :: term()} | #union_type{types :: term(), location :: term()} | #list_type{element_type :: term(), length :: term(), location :: term()} | #tuple_type{element_types :: term(), location :: term()} | #fsm_type{name :: term(), states :: term(), message_types :: term(), location :: term()} | #process_type{fsm_type :: term(), current_state :: term(), location :: term()} | #genserver_ref_type{variant :: term(), location :: term()}.
Functions
-spec check_clause_compatibility(#function_clause{params :: term(), return_type :: term(), constraint :: term(), body :: term(), location :: term()}, #function_clause{params :: term(), return_type :: term(), constraint :: term(), body :: term(), location :: term()}) -> compatible | overlapping | unreachable.