52# ifndef TPL_CONSTRAINTS_H
53# define TPL_CONSTRAINTS_H
117 const std::string &
message =
"")
137 <<
"Constraint_Set::constraint(): invalid index " << i;
207 size_t remaining =
bindings.size() + 1;
208 while (
const auto * replacement =
lookup(current))
210 current = *replacement;
212 <<
"Compiler_Type_Substitution::resolve_alias(): cyclic alias chain";
246 <<
"Compiler_Type_Substitution::binding(): invalid index " << i;
257 for (
size_t i =
bindings.size(); i > 0; --i)
258 if (
bindings.access(i - 1).variable == variable)
259 return &
bindings.access(i - 1).replacement;
270 for (
size_t i =
bindings.size(); i > 0; --i)
271 if (
bindings.access(i - 1).variable == variable)
272 return &
bindings.access(i - 1).replacement;
290 bindings.append({variable, replacement});
309 const auto &
ty = ctx.
type(resolved);
320 for (
size_t i = 0; i <
ty.components.size(); ++i)
335 for (
size_t i = 0; i <
ty.components.size(); ++i)
364 std::ostringstream
out;
365 out <<
"Substitution\n";
366 for (
size_t i = 0; i <
bindings.size(); ++i)
368 const auto & b =
bindings.access(i);
414 while (
const auto * replacement =
subst.
lookup(current))
416 current = *replacement;
418 <<
"Compiler_Type_Unifier::resolve(): cyclic substitution";
429 if (resolved == variable)
445 return resolved == variable;
448 for (
size_t i = 0; i <
ty.components.size(); ++i)
454 for (
size_t i = 0; i <
ty.components.size(); ++i)
476 "cannot bind rigid type variable '"
483 "occurs check failed while binding '"
537 if (lhs == 0
or rhs == 0)
541 "cannot unify null type ids");
543 const auto left =
resolve(lhs);
544 const auto right =
resolve(rhs);
572 "built-in type mismatch between '"
581 "tuple arity mismatch between '"
585 for (
size_t i = 0; i <
lhs_type.components.size(); ++i)
589 return last = result;
597 "function arity mismatch between '"
601 for (
size_t i = 0; i <
lhs_type.components.size(); ++i)
605 return last = result;
613 "nominal type mismatch between '"
634 for (
size_t i = 0; i < constraints.
size(); ++i)
640 result.span = c.
span;
641 if (result.message.empty())
644 result.message +=
": " + c.
message;
Stable type graph for the compiler-support MVP.
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_unless(C)
Throws std::out_of_range if condition does NOT hold.
#define ah_logic_error_if(C)
Throws std::logic_error if condition holds.
Source file and span management utilities for compiler-style tooling.
size_t size_t int32_t * out
Context owning all compiler type nodes.
std::string to_string(const Compiler_Type_Id id) const
Renders one type to a deterministic human-readable string.
const Compiler_Type & type(const Compiler_Type_Id id) const
Returns type id.
Compiler_Type_Id make_tuple_type(const DynArray< Compiler_Type_Id > &members)
Creates a tuple type.
Compiler_Type_Id make_function_type(const DynArray< Compiler_Type_Id > ¶meters, const Compiler_Type_Id result)
Creates a function type.
Mutable substitution from type variables to replacement types.
void bind(const Compiler_Type_Id variable, const Compiler_Type_Id replacement)
Binds or updates one type-variable replacement.
const Compiler_Type_Id * lookup(const Compiler_Type_Id variable) const noexcept
Looks up a bound replacement for variable.
Compiler_Type_Id * lookup(const Compiler_Type_Id variable) noexcept
Looks up a bound replacement for variable.
DynArray< Binding > bindings
void clear() noexcept
Removes every binding.
Compiler_Type_Id resolve_alias(const Compiler_Type_Id id) const
Compiler_Type_Id apply(Compiler_Type_Context &ctx, const Compiler_Type_Id id) const
Applies the substitution to id.
size_t size() const noexcept
Returns the number of stored variable bindings.
std::string to_string(Compiler_Type_Context &ctx) const
Renders all bindings in insertion order.
const Binding & binding(const size_t i) const
Returns binding i.
bool empty() const noexcept
Returns whether the substitution is empty.
Structural unifier for compiler types.
std::string dump_substitution()
Dumps the current substitution in a deterministic format.
Compiler_Unify_Result unify(const Compiler_Type_Id lhs, const Compiler_Type_Id rhs)
Attempts to unify lhs and rhs.
bool occurs_in(const Compiler_Type_Id variable, const Compiler_Type_Id candidate)
Compiler_Type_Unifier(Compiler_Type_Context &ctx) noexcept
Constructs a unifier operating over ctx.
Compiler_Unify_Result fail(const Compiler_Unify_Result_Kind kind, const Compiler_Type_Id lhs, const Compiler_Type_Id rhs, const std::string &message, const Source_Span &span={}) noexcept
Compiler_Unify_Result solve(const Compiler_Type_Constraint_Set &constraints)
Solves a whole ordered set of type constraints.
Compiler_Unify_Result last
Compiler_Type_Substitution subst
Compiler_Unify_Result bind_variable(const Compiler_Type_Id variable, const Compiler_Type_Id replacement)
const Compiler_Unify_Result & last_result() const noexcept
Returns the last result produced by unify() or solve().
static Compiler_Unify_Result success() noexcept
Compiler_Type_Id apply(const Compiler_Type_Id id)
Applies the current substitution to id.
void clear() noexcept
Clears substitutions and the last stored result.
const Compiler_Type_Substitution & substitution() const noexcept
Returns the accumulated substitution.
Compiler_Type_Context * context
Compiler_Type_Id resolve(const Compiler_Type_Id id) const
Ordered collection of equality constraints.
size_t size() const noexcept
Returns the number of stored constraints.
bool empty() const noexcept
Returns whether the set has no constraints.
void clear() noexcept
Removes all stored constraints.
DynArray< Equality_Constraint< T > > constraints
size_t add(const T &lhs, const T &rhs, const Source_Span &span={}, const std::string &message="")
Appends an equality constraint.
const Equality_Constraint< T > & constraint(const size_t i) const
Returns one stored constraint.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
T & append()
Allocate a new entry to the end of array.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Main namespace for Aleph-w library functions.
void message(const char *file, int line, const char *format,...)
Print an informational message with file and line info.
std::decay_t< typename HeadC::Item_Type > T
Compiler_Unify_Result_Kind
Result category returned by type unification.
const char * compiler_unify_result_kind_name(const Compiler_Unify_Result_Kind kind) noexcept
Returns a stable debug name for one unification result kind.
One variable binding inside the substitution.
Compiler_Type_Id replacement
Replacing type id.
Compiler_Type_Id variable
Bound type-variable id.
Outcome of one type-unification attempt.
bool ok() const noexcept
Returns whether the result denotes a successful unification.
Compiler_Unify_Result_Kind kind
Compiler_Type_Id lhs
Left type involved in the result.
std::string message
Human-readable explanation.
Source_Span span
Constraint span, if solving a stored constraint.
Compiler_Type_Id rhs
Right type involved in the result.
Equality constraint between two values of type T.
Source_Span span
Optional source span attached by the caller.
std::string message
Optional caller-defined explanation.
Half-open byte range inside a source file.
Lazy and scalable dynamic array implementation.