diff --git a/.ikc3_history b/.ikc3_history
index ece84e2..7a1e2de 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,7 +1,3 @@
-server = Socket.listen("192.168.2.50", "58000")
-server_client = Socket.Buf.accept(server)
-req = HTTP.Request.buf_parse(server_client.buf_rw.r)
-%HTTP.Response{}
Struct.offset(%HTTP.Response{}, :message)
Sym.type_size(Str)
Struct.offset(%HTTP.Response{}, :message)
@@ -97,4 +93,7 @@ Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact); void })
Facts.with_tags(Facts.env_facts(), KC3, ?, ?, fn (fact) { puts(fact); void })
Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact); void })
Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
-
+Facts.with(Facts.env_facts(), [[KC3, :operator, ?]], fn (fact) { puts(fact.object); void })
+Facts.with(Facts.env_facts(), [[KC3, ?, ?]], fn (fact) { puts(fact.object); void })
+Facts.with(Facts.env_facts(), [[KC3, :load_time, ?]], fn (fact) { puts(fact.object); void })
+Facts.with(Facts.env_facts(), [[?, :load_time, ?]], fn (fact) { puts(fact.object); void })
diff --git a/lib/kc3/0.1/facts.kc3 b/lib/kc3/0.1/facts.kc3
index 8ef12d7..ab19de8 100644
--- a/lib/kc3/0.1/facts.kc3
+++ b/lib/kc3/0.1/facts.kc3
@@ -17,6 +17,10 @@ defmodule Facts do
# env_facts() -> facts
def env_facts = cfn Ptr "kc3_env_facts" ()
+ # with(facts, [[?, ?, ?]], fn (fact) {result}) -> result
+ def with = cfn Tag "kc3_facts_with" (Facts, List, Fn,
+ Result)
+
# with_tags(facts, subject, predicate, object,
# fn (fact) {result}) -> result
def with_tags = cfn Tag "kc3_facts_with_tags" (Facts, Tag, Tag, Tag,
diff --git a/libkc3/env.c b/libkc3/env.c
index 469160a..06e8c2c 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -2014,6 +2014,47 @@ s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
return dest;
}
+s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
+ s_fn *callback, s_tag *dest)
+{
+ s_list *arguments;
+ s_facts_with_cursor cursor = {0};
+ const s_fact *fact = NULL;
+ s_fact_w *fact_w = NULL;
+ s_tag tmp = {0};
+ if (! (arguments = list_new_struct(&g_sym_FactW, NULL)))
+ return NULL;
+ if (! struct_allocate(&arguments->tag.data.struct_))
+ return NULL;
+ fact_w = arguments->tag.data.struct_.data;
+ if (! facts_with_list(facts, &cursor, *spec))
+ return NULL;
+ while (1) {
+ if (! facts_with_cursor_next(&cursor, &fact))
+ goto clean;
+ if (! fact) {
+ goto ok;
+ }
+ tag_clean(&tmp);
+ fact_w_init_fact(fact_w, fact);
+ if (! env_eval_call_fn_args(env, callback, arguments, &tmp)) {
+ fact_w_clean(fact_w);
+ goto clean;
+ }
+ fact_w_clean(fact_w);
+ fact_w_init(fact_w);
+ }
+ ok:
+ list_delete_all(arguments);
+ *dest = tmp;
+ return dest;
+ clean:
+ tag_clean(&tmp);
+ fact_w_clean(fact_w);
+ list_delete_all(arguments);
+ return NULL;
+}
+
s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest)
diff --git a/libkc3/env.h b/libkc3/env.h
index 4e3e3f3..b683f0f 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -179,6 +179,8 @@ bool env_eval_tuple (s_env *env, const s_tuple *tuple,
bool env_eval_void (s_env *env, const void *_, s_tag *dest);
s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
s_fact_w *dest);
+s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
+ s_fn *callback, s_tag *dest);
s_tag * env_facts_with_tags (s_env *env, s_facts *facts,
s_tag *subject, s_tag *predicate,
s_tag *object, s_fn *callback,
diff --git a/libkc3/facts_spec.c b/libkc3/facts_spec.c
index d003e3e..d029e50 100644
--- a/libkc3/facts_spec.c
+++ b/libkc3/facts_spec.c
@@ -16,6 +16,7 @@
#include "fact.h"
#include "facts_spec.h"
#include "facts_spec_cursor.h"
+#include "list.h"
#include "tag.h"
uw facts_spec_count_facts (p_facts_spec spec)
@@ -56,6 +57,47 @@ p_facts_spec facts_spec_new_expand (p_facts_spec spec)
return NULL;
}
+p_facts_spec facts_spec_new_list (s_list *spec)
+{
+ uw c;
+ uw count = 1;
+ p_facts_spec new;
+ p_facts_spec n;
+ s_list *s;
+ s_list *t;
+ assert(spec);
+ if (! spec)
+ return NULL;
+ s = spec;
+ while (s) {
+ if (s->tag.type != TAG_LIST ||
+ (c = list_length(s->tag.data.list)) < 3 ||
+ (c - 1) % 2) {
+ err_puts("facts_spec_new_list: invalid spec");
+ assert(! "facts_spec_new_list: invalid spec");
+ return NULL;
+ }
+ count += c + 1;
+ s = list_next(s);
+ }
+ new = alloc(count * sizeof(s_tag *));
+ if (! new)
+ return NULL;
+ n = new;
+ s = spec;
+ while (s) {
+ t = s->tag.data.list;
+ while (t) {
+ *n++ = &t->tag;
+ t = list_next(t);
+ }
+ *n++ = NULL;
+ s = list_next(s);
+ }
+ *n = NULL;
+ return new;
+}
+
p_facts_spec facts_spec_sort (p_facts_spec spec)
{
s_tag **a;
diff --git a/libkc3/facts_spec.h b/libkc3/facts_spec.h
index b268545..dbea2f8 100644
--- a/libkc3/facts_spec.h
+++ b/libkc3/facts_spec.h
@@ -29,6 +29,7 @@
/* Constructors */
p_facts_spec facts_spec_new_expand (p_facts_spec spec);
+p_facts_spec facts_spec_new_list (s_list *spec);
/* Destructor */
#define facts_spec_delete free
diff --git a/libkc3/facts_with.c b/libkc3/facts_with.c
index 790e3b9..c34e1d3 100644
--- a/libkc3/facts_with.c
+++ b/libkc3/facts_with.c
@@ -142,6 +142,22 @@ s_facts_cursor * facts_with_3 (s_facts *facts,
return facts_cursor_init(facts, cursor, facts->index_spo, &fact, &fact);
}
+s_facts_with_cursor * facts_with_list (s_facts *facts,
+ s_facts_with_cursor *cursor,
+ s_list *spec)
+{
+ p_facts_spec s;
+ assert(facts);
+ assert(cursor);
+ assert(spec);
+ if (! (s = facts_spec_new_list(spec))) {
+ err_puts("facts_with_list: facts_spec_new_list");
+ assert(! "facts_with_list: facts_spec_new_list");
+ return NULL;
+ }
+ return facts_with(facts, cursor, s);
+}
+
s_facts_cursor * facts_with_tags (s_facts *facts,
s_facts_cursor *cursor,
s_tag *subject,
diff --git a/libkc3/facts_with.h b/libkc3/facts_with.h
index 072166f..793198a 100644
--- a/libkc3/facts_with.h
+++ b/libkc3/facts_with.h
@@ -40,6 +40,10 @@ s_facts_cursor * facts_with_3 (s_facts *facts,
const s_tag *predicate,
const s_tag *object);
+s_facts_with_cursor * facts_with_list (s_facts *facts,
+ s_facts_with_cursor *cursor,
+ s_list *spec);
+
s_facts_cursor * facts_with_tags (s_facts *facts,
s_facts_cursor *cursor,
s_tag *subject,
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index a877cef..560fecd 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -190,6 +190,12 @@ uw * kc3_facts_next_id (uw *dest)
return dest;
}
+s_tag * kc3_facts_with (s_facts *facts, s_list **spec,
+ s_fn *callback, s_tag *dest)
+{
+ return env_facts_with(&g_kc3_env, facts, spec, callback, dest);
+}
+
s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest)
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index c5d1777..25d2f7e 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -57,6 +57,8 @@ void ** kc3_dlopen (const s_str *path, void **dest);
s_facts * kc3_env_facts (void);
sw kc3_errno (void);
void kc3_exit (sw code);
+s_tag * kc3_facts_with (s_facts *facts, s_list **spec,
+ s_fn *callback, s_tag *dest);
s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest);