#ifndef RAYFORCE_DATALOG_H
#define RAYFORCE_DATALOG_H
#include "rayforce.h"
#include "ops/ops.h"
#include <stdbool.h>
#include <stdint.h>
#define DL_POS 0
#define DL_NEG 1
#define DL_CMP 2
#define DL_ASSIGN 3
#define DL_BUILTIN 4
#define DL_INTERVAL 5
#define DL_AGG 6
#define DL_CMP_EQ 0
#define DL_CMP_NE 1
#define DL_CMP_LT 2
#define DL_CMP_LE 3
#define DL_CMP_GT 4
#define DL_CMP_GE 5
#define DL_AGG_COUNT 0
#define DL_AGG_SUM 1
#define DL_AGG_MIN 2
#define DL_AGG_MAX 3
#define DL_AGG_AVG 4
#define DL_AGG_MAX_KEYS 8
#define DL_OP_EQ 0
#define DL_BUILTIN_BEFORE 0
#define DL_BUILTIN_DURATION_SINCE 1
#define DL_BUILTIN_ABS 2
typedef enum {
DL_EXPR_CONST,
DL_EXPR_CONST_F64,
DL_EXPR_VAR,
DL_EXPR_BINOP,
} dl_expr_kind_t;
typedef struct dl_expr {
dl_expr_kind_t kind;
int64_t const_val;
double const_f64;
int var_idx;
int binop;
struct dl_expr *left;
struct dl_expr *right;
} dl_expr_t;
#define DL_CONST (-1)
#define DL_MAX_ARITY 16
#define DL_MAX_BODY 16
#define DL_MAX_RULES 128
#define DL_MAX_RELS 64
#define DL_MAX_STRATA 16
#define DL_FLAG_PROVENANCE (1 << 0)
typedef struct {
int type;
char pred[64];
int arity;
int vars[DL_MAX_ARITY];
int64_t const_vals[DL_MAX_ARITY];
int cmp_op;
int cmp_lhs;
int cmp_rhs;
int64_t cmp_const;
int assign_var;
dl_expr_t *assign_expr;
int builtin_id;
dl_expr_t *cmp_lhs_expr;
dl_expr_t *cmp_rhs_expr;
int interval_fact_var;
int interval_start_var;
int interval_end_var;
int agg_op;
int agg_target_var;
char agg_pred[64];
int agg_arity;
int agg_value_col;
int agg_n_group_keys;
int agg_group_key_vars[DL_AGG_MAX_KEYS];
int agg_group_key_cols[DL_AGG_MAX_KEYS];
} dl_body_t;
typedef struct {
char head_pred[64];
int head_arity;
int head_vars[DL_MAX_ARITY];
int64_t head_consts[DL_MAX_ARITY];
int8_t head_const_types[DL_MAX_ARITY];
int n_body;
dl_body_t body[DL_MAX_BODY];
int n_vars;
int stratum;
} dl_rule_t;
typedef struct {
char name[64];
ray_t* table;
int arity;
bool is_idb;
int64_t col_names[DL_MAX_ARITY];
ray_t* prov_col;
ray_t* prov_src_offsets;
ray_t* prov_src_data;
} dl_rel_t;
typedef struct {
dl_rel_t rels[DL_MAX_RELS];
int n_rels;
dl_rule_t rules[DL_MAX_RULES];
int n_rules;
int strata[DL_MAX_STRATA][DL_MAX_RELS];
int strata_sizes[DL_MAX_STRATA];
int n_strata;
uint32_t flags;
bool eval_err;
} dl_program_t;
dl_program_t* dl_program_new(void);
void dl_program_free(dl_program_t* prog);
void dl_append_global_rules(dl_program_t* prog);
int dl_add_edb(dl_program_t* prog, const char* name, ray_t* table, int arity);
int dl_add_rule(dl_program_t* prog, const dl_rule_t* rule);
int dl_stratify(dl_program_t* prog);
int dl_eval(dl_program_t* prog);
ray_t* dl_query(dl_program_t* prog, const char* pred_name);
ray_t* dl_get_provenance(dl_program_t* prog, const char* pred_name);
ray_t* dl_get_provenance_src_offsets(dl_program_t* prog, const char* pred_name);
ray_t* dl_get_provenance_src_data(dl_program_t* prog, const char* pred_name);
void dl_rule_init(dl_rule_t* rule, const char* head_pred, int head_arity);
void dl_rule_head_var(dl_rule_t* rule, int pos, int var_idx);
void dl_rule_head_const(dl_rule_t* rule, int pos, int64_t val);
void dl_rule_head_const_typed(dl_rule_t* rule, int pos, int64_t val, int8_t type);
void dl_rule_head_const_f64(dl_rule_t* rule, int pos, double val);
int dl_rule_add_atom(dl_rule_t* rule, const char* pred, int arity);
void dl_body_set_var(dl_rule_t* rule, int body_idx, int pos, int var_idx);
void dl_body_set_const(dl_rule_t* rule, int body_idx, int pos, int64_t val);
int dl_rule_add_neg(dl_rule_t* rule, const char* pred, int arity);
int dl_rule_add_cmp(dl_rule_t* rule, int cmp_op, int lhs_var, int rhs_var);
int dl_rule_add_cmp_const(dl_rule_t* rule, int cmp_op, int lhs_var, int64_t rhs_val);
int dl_rule_add_assign(dl_rule_t* rule, int target_var, int op, dl_expr_t* expr);
int dl_rule_add_builtin(dl_rule_t* rule, int builtin_id, int arity);
int dl_rule_add_cmp_expr(dl_rule_t* rule, int cmp_op, dl_expr_t* lhs, dl_expr_t* rhs);
int dl_rule_add_interval(dl_rule_t* rule, int fact_var, int start_var, int end_var);
int dl_rule_add_agg(dl_rule_t* rule, int op, int target_var,
const char* pred, int pred_arity, int value_col);
int dl_rule_agg_set_group(dl_rule_t* rule, int body_idx,
const int* key_vars, const int* key_cols, int n_keys);
dl_expr_t* dl_expr_const(int64_t val);
dl_expr_t* dl_expr_const_f64(double val);
dl_expr_t* dl_expr_var(int var_idx);
dl_expr_t* dl_expr_binop(int op, dl_expr_t* left, dl_expr_t* right);
int dl_find_rel(dl_program_t* prog, const char* name);
int dl_ensure_idb(dl_program_t* prog, const char* name, int arity);
ray_op_t* dl_compile_rule(dl_program_t* prog, dl_rule_t* rule,
int delta_pos, int rule_idx, ray_graph_t* g);
#endif