View Source cure_dependent_types (cure v0.7.0)

Dependent Type Checking with SMT

This module implements type checking for dependent types, extending the base type checker with support for:

  • Value parameters in types (e.g., n: Nat in Vector(T, n))
  • Type-level expressions (arithmetic, comparisons)
  • Constraint generation and verification
  • SMT-based proof of type correctness

Architecture

Type Environment

The type environment is extended to track:

  • Type variables (T, U, etc.)
  • Value parameters (n: Nat, m: Int, etc.)
  • Accumulated constraints
  • SMT environment for verification

Verification Conditions

When checking a dependent type, we generate verification conditions (VCs):

  1. Well-formedness: Value parameters satisfy their constraints
  2. Subtyping: Type-level expressions respect subtyping relations
  3. Arithmetic: Type-level arithmetic is sound

Example

def concat<T, m: Nat, n: Nat>(
    v1: Vector(T, m),
    v2: Vector(T, n)
): Vector(T, m + n) = v1 ++ v2

% Verification conditions:
%   1. length(v1) == m (from v1's type)
%   2. length(v2) == n (from v2's type)
%   3. length(v1 ++ v2) == m + n (return type requirement)
%   4. Prove: length(v1 ++ v2) == length(v1) + length(v2) via SMT

Usage

% Check if type is well-formed
{ok, Env2} = cure_dependent_types:check_type(Type, Env),

% Generate verification conditions
VCs = cure_dependent_types:generate_vcs(Expr, Type, Env),

% Verify via SMT
{ok, _} = cure_dependent_types:verify_vcs(VCs, Env).

Summary

Functions

check_dependent_function/3

-spec check_dependent_function(#dependent_function_type{type_params :: term(),
                                                        params :: term(),
                                                        return_type :: term(),
                                                        constraints :: term(),
                                                        location :: term()},
                               term(),
                               map()) ->
                                  {ok, map()} | {error, term()}.

check_dependent_type/2

-spec check_dependent_type(term(), map()) -> {ok, map()} | {error, term()}.

check_type_level_expr/2

-spec check_type_level_expr(#type_level_expr{op :: term(),
                                             left :: term(),
                                             right :: term(),
                                             location :: term()},
                            map()) ->
                               {ok, term(), map()} | {error, term()}.

check_type_level_operand/2

extend_env_with_value_params(ValueParams, Env)

-spec extend_env_with_value_params([{atom(), term()}], map()) -> map().

generate_bounds_constraint/2

-spec generate_bounds_constraint(term(), {term(), term()}) -> term().

generate_length_constraint(VectorExpr, LengthExpr)

-spec generate_length_constraint(term(), term()) -> term().

generate_verification_conditions/3

-spec generate_verification_conditions(term(), term(), map()) -> [term()].

instantiate_dependent_type/2

-spec instantiate_dependent_type(#dependent_type{name :: term(),
                                                 type_params :: term(),
                                                 value_params :: term(),
                                                 location :: term()},
                                 [{atom(), term()}]) ->
                                    #dependent_type{name :: term(),
                                                    type_params :: term(),
                                                    value_params :: term(),
                                                    location :: term()}.

is_dependent_type/1

-spec is_dependent_type(term()) -> boolean().

lookup_value_param(Name, Env)

-spec lookup_value_param(atom(), map()) -> {ok, term()} | error.

substitute_value_params/2

-spec substitute_value_params(term(), [{atom(), term()}]) -> term().

verify_dependent_type(Type, Env)

-spec verify_dependent_type(term(), map()) -> {ok, map()} | {error, term()}.

verify_type_level_expr/2

-spec verify_type_level_expr(#type_level_expr{op :: term(),
                                              left :: term(),
                                              right :: term(),
                                              location :: term()},
                             map()) ->
                                {ok, term()} | {error, term()}.