#include "dldsl_defines.hh"

.decl TypeKind(id:number, name:symbol)
#define T(NAME, STR, ...) TypeKind(autoinc(), STR):-true.
DLDSL_TYPES(T)
#undef T

.decl OpKind(id:number, name:symbol, mn:number, mx:number)
#define T(NAME, STR, MN, MX, ...) OpKind(autoinc(), STR, MN, MX):-true.
DLDSL_OP_KIND(T)
#undef T

.decl Type(name:symbol, kind:number, alias:symbol, builtin_name:symbol)

.decl Rel(name:symbol)
.decl RelAlias(name:symbol, alias:symbol)

.decl Field(rel:symbol, index:number, name:symbol, type:symbol)

.decl TermExpr(id:number, rel:symbol)
.decl OpExpr(id:number, type:symbol, op:number)
.decl ExprConst(id:number, index:number, type:symbol, value:symbol)
.decl ExprVar(id:number, index:number, name:symbol)
.decl ExprExpr(id:number, index:number, expr:number)

.decl Rule(id:number, conc_expr:number)
.decl RulePrem(id:number, expr_id:number)
.decl RuleVar(id:number, name:symbol, type:symbol)
#include "dldsl_defines.hh" .decl TypeKind(id:number, name:symbol) #define T(NAME, STR, ...) TypeKind(autoinc(), STR):-true. DLDSL_TYPES(T) #undef T .decl OpKind(id:number, name:symbol, mn:number, mx:number) #define T(NAME, STR, MN, MX, ...) OpKind(autoinc(), STR, MN, MX):-true. DLDSL_OP_KIND(T) #undef T .decl Type(name:symbol, kind:number, alias:symbol, builtin_name:symbol) .decl Rel(name:symbol) .decl RelAlias(name:symbol, alias:symbol) .decl Field(rel:symbol, index:number, name:symbol, type:symbol) .decl TermExpr(id:number, rel:symbol) .decl OpExpr(id:number, type:symbol, op:number) .decl ExprConst(id:number, index:number, type:symbol, value:symbol) .decl ExprVar(id:number, index:number, name:symbol) .decl ExprExpr(id:number, index:number, expr:number) .decl Rule(id:number, conc_expr:number) .decl RulePrem(id:number, expr_id:number) .decl RuleVar(id:number, name:symbol, type:symbol)
# will produce following topological order and lifetimes:
    ---------------
    rel_order
    ===============
    0       i
    1       b
    1       a
    2       c
    2       d
    3       o
    ===============
    ---------------
    rel_lt
    ===============
    1       i
    2       b
    2       a
    3       o
    3       c
    3       d
    ===============

struct i (x : s32)
struct a (x : s32)
struct b (x : s32)
struct c (x : s32)
struct d (x : s32)
struct o (x : s32)

a x if (i x)

a x if (b x)
b x if (a x)

c x if (b x)
d x if (c x)
c x if (d x)

o x if (d x)
# will produce following topological order and lifetimes: --------------- rel_order =============== 0 i 1 b 1 a 2 c 2 d 3 o =============== --------------- rel_lt =============== 1 i 2 b 2 a 3 o 3 c 3 d =============== struct i (x : s32) struct a (x : s32) struct b (x : s32) struct c (x : s32) struct d (x : s32) struct o (x : s32) a x if (i x) a x if (b x) b x if (a x) c x if (b x) d x if (c x) c x if (d x) o x if (d x)
// topological order of relations
.decl rel_order(n:number, rel:symbol)
rel_order(i,rel) :- Rel(rel), scc(scc_id, rel),
    scc_order(i, scc_id).

// relation lifetime (after which order can we free this relation)
.decl rel_lt(n:number, rel:symbol)
rel_lt(i,rel) :- Rel(rel), scc(scc_id, rel),
    !scc_dep(_, scc_id),
    scc_order(i, scc_id).
rel_lt(mxi,rel) :- Rel(rel), scc(scc_id, rel),
    scc_dep(scc_user, scc_id),
    mxi = max i : {
        scc_order(i, scc_user)
    }.
// topological order of relations .decl rel_order(n:number, rel:symbol) rel_order(i,rel) :- Rel(rel), scc(scc_id, rel), scc_order(i, scc_id). // relation lifetime (after which order can we free this relation) .decl rel_lt(n:number, rel:symbol) rel_lt(i,rel) :- Rel(rel), scc(scc_id, rel), !scc_dep(_, scc_id), scc_order(i, scc_id). rel_lt(mxi,rel) :- Rel(rel), scc(scc_id, rel), scc_dep(scc_user, scc_id), mxi = max i : { scc_order(i, scc_user) }.