Commit eaa2aad3261f4fa4c6566fb021f58da8f693e305

Thomas de Grivel 2022-11-13T09:22:47

tag_is_bound_var

diff --git a/libc3/fact.c b/libc3/fact.c
index 41c650a..05c1d7c 100644
--- a/libc3/fact.c
+++ b/libc3/fact.c
@@ -35,7 +35,8 @@ s8 fact_compare (const s_fact *a, const s_fact *b)
   return r;
 }
 
-s8 fact_compare_var_count (const s_fact *a, const s_fact *b)
+s8 fact_compare_unbound_var_count (const s_fact *a,
+                                   const s_fact *b)
 {
   u8 ca;
   u8 cb;
@@ -47,17 +48,17 @@ s8 fact_compare_var_count (const s_fact *a, const s_fact *b)
     return 1;
   ca = 0;
   cb = 0;
-  if (tag_is_var(a->subject))
+  if (tag_is_unbound_var(a->subject))
     ca++;
-  if (tag_is_var(a->predicate))
+  if (tag_is_unbound_var(a->predicate))
     ca++;
-  if (tag_is_var(a->object))
+  if (tag_is_unbound_var(a->object))
     ca++;
-  if (tag_is_var(b->subject))
+  if (tag_is_unbound_var(b->subject))
     cb++;
-  if (tag_is_var(b->predicate))
+  if (tag_is_unbound_var(b->predicate))
     cb++;
-  if (tag_is_var(b->object))
+  if (tag_is_unbound_var(b->object))
     cb++;
   return u8_compare(ca, cb);
 }
diff --git a/libc3/fact.h b/libc3/fact.h
index c4a5315..00495c0 100644
--- a/libc3/fact.h
+++ b/libc3/fact.h
@@ -26,8 +26,8 @@ s_fact * fact_init (s_fact *fact, const s_tag *subject,
 s8               fact_compare (const s_fact *a, const s_fact *b);
 s8               fact_compare_pos (const s_fact *a, const s_fact *b);
 s8               fact_compare_osp (const s_fact *a, const s_fact *b);
-s8               fact_compare_var_count (const s_fact *a,
-                                         const s_fact *b);
+s8               fact_compare_unbound_var_count (const s_fact *a,
+                                                 const s_fact *b);
 s_fact *         fact_copy (const s_fact *src, s_fact *dest);
 t_hash_context * fact_hash_update (t_hash_context *context,
                                    const s_fact *fact);
diff --git a/libc3/facts_spec.c b/libc3/facts_spec.c
index ac4ac08..762d752 100644
--- a/libc3/facts_spec.c
+++ b/libc3/facts_spec.c
@@ -67,7 +67,8 @@ p_facts_spec facts_spec_sort (p_facts_spec spec)
       while (j < count - i - 1) {
         a = spec + j * 4;
         b = spec + (j + 1) * 4;
-        if (fact_compare_var_count((s_fact *) a, (s_fact *) b) > 0) {
+        if (fact_compare_unbound_var_count((s_fact *) a,
+                                           (s_fact *) b) > 0) {
           s_tag *swap[3];
           swap[0] = a[0];
           swap[1] = a[1];
diff --git a/libc3/facts_with.c b/libc3/facts_with.c
index f384e2b..04a6d1a 100644
--- a/libc3/facts_with.c
+++ b/libc3/facts_with.c
@@ -91,17 +91,20 @@ s_facts_cursor * facts_with_tags (const s_facts *facts,
                                   s_tag *predicate,
                                   s_tag *object)
 {
-  s_tag *var_subject;
-  s_tag *var_predicate;
-  s_tag *var_object;
+  s_tag *var_subject = NULL;
+  s_tag *var_predicate = NULL;
+  s_tag *var_object = NULL;
   assert(facts);
   assert(cursor);
   assert(subject);
   assert(predicate);
   assert(object);
-  var_subject = tag_is_var(subject) ? subject : NULL;
-  var_predicate = tag_is_var(predicate) ? predicate : NULL;
-  var_object = tag_is_var(object) ? object : NULL;
+  if (tag_is_unbound_var(subject))
+    var_subject = subject;
+  if (tag_is_unbound_var(predicate))
+    var_predicate = predicate;
+  if (tag_is_unbound_var(object))
+    var_object = object;
   if (var_subject && var_predicate && var_object)
     return facts_with_0(facts, cursor, var_subject, var_predicate,
                         var_object);
diff --git a/libc3/tag.c b/libc3/tag.c
index 37e6dd3..b408ff1 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -129,6 +129,10 @@ void tag_clean (s_tag *tag)
 }
 
 s8 tag_compare (const s_tag *a, const s_tag *b) {
+  if (tag_is_bound_var(a))
+    a = a->data.var;
+  if (tag_is_bound_var(b))
+    b = b->data.var;
   if (a == b)
     return 0;
   if (!a ||
@@ -609,6 +613,13 @@ s_tag * tag_integer_reduce (s_tag *tag)
   return tag;
 }
 
+e_bool tag_is_bound_var (const s_tag *tag)
+{
+  return (tag &&
+          tag->type.type == TAG_VAR &&
+          tag->data.var);
+}
+
 e_bool tag_is_number (const s_tag *tag)
 {
   assert(tag);
@@ -628,7 +639,7 @@ e_bool tag_is_number (const s_tag *tag)
   return false;
 }
 
-e_bool tag_is_var (const s_tag *tag)
+e_bool tag_is_unbound_var (const s_tag *tag)
 {
   return (tag &&
           tag->type.type == TAG_VAR &&
diff --git a/libc3/tag.h b/libc3/tag.h
index a29514b..f998c1d 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -91,8 +91,9 @@ uw               tag_hash (const s_tag *tag);
 t_hash_context * tag_hash_update (t_hash_context *context,
                                   const s_tag *tag);
 s_str *          tag_inspect (const s_tag *tag, s_str *dest);
+e_bool           tag_is_bound_var (const s_tag *tag);
 e_bool           tag_is_number (const s_tag *tag);
-e_bool           tag_is_var (const s_tag *tag);
+e_bool           tag_is_unbound_var (const s_tag *tag);
 s8               tag_number_compare (const s_tag *a, const s_tag *b);
 sw               tag_size (const s_tag *tag);
 sw               tag_type_size (e_tag_type type);