传播函数分布在propsearch.h、propsearch.c和proplit.c文件之中

  propsearch.h
 
#ifndef _propsearch_h_INCLUDED
#define _propsearch_h_INCLUDED

struct kissat;
struct clause;

struct clause *kissat_search_propagate (struct kissat *);

#endif

 

   

 

  propsearch.c
 
#define INLINE_ASSIGN

#include "inline.h"
#include "propsearch.h"
#include "bump.h"

// Keep this 'inlined' file separate:

#include "assign.c"

#define PROPAGATE_LITERAL search_propagate_literal
#define PROPAGATION_TYPE "search"

#include "proplit.h"

static inline void
update_search_propagation_statistics (kissat * solver,
                      unsigned previous_propagated_level)
{
  assert (previous_propagated_level <= solver->propagated);
  const unsigned propagated = solver->propagated - previous_propagated_level;

  LOG ("propagation took %" PRIu64 " propagations", propagated);
  LOG ("propagation took %" PRIu64 " ticks", solver->ticks);

  ADD (propagations, propagated);
  ADD (ticks, solver->ticks);

  ADD (search_propagations, propagated);
  ADD (search_ticks, solver->ticks);

  if (solver->stable)
    {
      ADD (stable_propagations, propagated);
      ADD (stable_ticks, solver->ticks);
    }
  else
    {
      ADD (focused_propagations, propagated);
      ADD (focused_ticks, solver->ticks);
    }
}

static inline void
update_consistently_assigned (kissat * solver)
{
  const unsigned assigned = kissat_assigned (solver);
  if (assigned != solver->consistently_assigned)
    {
      LOG ("updating consistently assigned from %u to %u",
       solver->consistently_assigned, assigned);
      solver->consistently_assigned = assigned;
    }
  else
    LOG ("keeping consistently assigned %u", assigned);
}

static clause *
search_propagate (kissat * solver)
{
  clause *res = 0;
  while (!res && solver->propagated < SIZE_STACK (solver->trail))
    {
      const unsigned lit = PEEK_STACK (solver->trail, solver->propagated);
      res = search_propagate_literal (solver, lit);
      solver->propagated++;
    }
  return res;
}




clause *
kissat_search_propagate (kissat * solver)
{
  assert (!solver->probing);
  assert (solver->watching);
  assert (!solver->inconsistent);

  START (propagate);

  solver->ticks = 0;
  const unsigned propagated = solver->propagated;
  clause *conflict = search_propagate (solver);
  update_search_propagation_statistics (solver, propagated);
  update_consistently_assigned (solver);
  if (conflict)
    INC (conflicts);
  STOP (propagate);

  // CHB
  if(solver->stable && solver->heuristic==1){
      int i = SIZE_STACK (solver->trail) - 1;
      unsigned lit = i>=0?PEEK_STACK (solver->trail, i):0;  
      while(i>=0 && LEVEL(lit)==solver->level){
        lit = PEEK_STACK (solver->trail, i);
            kissat_bump_chb(solver,IDX(lit), conflict? 1.0 : 0.9); 
        i--;        
      }
  }  
  if(solver->stable && solver->heuristic==1 && conflict) kissat_decay_chb(solver);

  return conflict;
}

 

   

 

  proplit.c
 
  1 static inline clause *
  2 PROPAGATE_LITERAL (kissat * solver,
  3 #if defined(HYPER_PROPAGATION) || defined(PROBING_PROPAGATION)
  4            const clause * ignore,
  5 #endif
  6            const unsigned lit)
  7 {
  8   assert (solver->watching);
  9   LOG (PROPAGATION_TYPE " propagating %s", LOGLIT (lit));
 10   assert (VALUE (lit) > 0);
 11   assert (EMPTY_STACK (solver->delayed));
 12 
 13   const word *arena = BEGIN_STACK (solver->arena);
 14   assigned *assigned = solver->assigned;
 15   value *values = solver->values;
 16 
 17   const unsigned not_lit = NOT (lit);
 18 #ifdef HYPER_PROPAGATION
 19   const bool hyper = GET_OPTION (hyper);
 20 #endif
 21   watches *watches = &WATCHES (not_lit);
 22   watch *begin_watches = BEGIN_WATCHES (*watches), *q = begin_watches;
 23   const watch *end_watches = END_WATCHES (*watches), *p = q;
 24   unsigneds *delayed = &solver->delayed;
 25 
 26   uint64_t ticks = kissat_cache_lines (watches->size, sizeof (watch));
 27 
 28   clause *res = 0;
 29 
 30   while (p != end_watches)
 31     {
 32       const watch head = *q++ = *p++;
 33       const unsigned blocking = head.blocking.lit;
 34       assert (VALID_INTERNAL_LITERAL (blocking));
 35       const value blocking_value = values[blocking];
 36       if (head.type.binary)
 37     {
 38       if (blocking_value > 0)
 39         continue;
 40       const bool redundant = head.binary.redundant;
 41       if (blocking_value < 0)
 42         {
 43           res = kissat_binary_conflict (solver, redundant,
 44                         not_lit, blocking);
 45           break;
 46         }
 47       else
 48         {
 49           assert (!blocking_value);
 50           kissat_assign_binary (solver, values, assigned,
 51                     redundant, blocking, not_lit);
 52         }
 53     }
 54       else
 55     {
 56       const watch tail = *q++ = *p++;
 57       if (blocking_value > 0)
 58         continue;
 59       const reference ref = tail.raw;
 60       assert (ref < SIZE_STACK (solver->arena));
 61       clause *c = (clause *) (arena + ref);
 62 #if defined(HYPER_PROPAGATION) || defined(PROBING_PROPAGATION)
 63       if (c == ignore)
 64         continue;
 65 #endif
 66       ticks++;
 67       if (c->garbage)
 68         {
 69           q -= 2;
 70           continue;
 71         }
 72       unsigned *lits = BEGIN_LITS (c);
 73       const unsigned other = lits[0] ^ lits[1] ^ not_lit;
 74       assert (lits[0] != lits[1]);
 75       assert (VALID_INTERNAL_LITERAL (other));
 76       assert (not_lit != other);
 77       assert (lit != other);
 78       const value other_value = values[other];
 79       if (other_value > 0)
 80         q[-2].blocking.lit = other;
 81       else
 82         {
 83           const unsigned *end_lits = lits + c->size;
 84           unsigned *searched = lits + c->searched;
 85           assert (c->lits + 2 <= searched);
 86           assert (searched < end_lits);
 87           unsigned *r, replacement = INVALID_LIT;
 88           value replacement_value = -1;
 89           for (r = searched; r != end_lits; r++)
 90         {
 91           replacement = *r;
 92           assert (VALID_INTERNAL_LITERAL (replacement));
 93           replacement_value = values[replacement];
 94           if (replacement_value >= 0)
 95             break;
 96         }
 97           if (replacement_value < 0)
 98         {
 99           for (r = lits + 2; r != searched; r++)
100             {
101               replacement = *r;
102               assert (VALID_INTERNAL_LITERAL (replacement));
103               replacement_value = values[replacement];
104               if (replacement_value >= 0)
105             break;
106             }
107         }
108 
109           if (replacement_value >= 0)
110         c->searched = r - c->lits;
111 
112           if (replacement_value > 0)
113         {
114           assert (replacement != INVALID_LIT);
115           q[-2].blocking.lit = replacement;
116         }
117           else if (!replacement_value)
118         {
119           assert (replacement != INVALID_LIT);
120           LOGREF (ref, "unwatching %s in", LOGLIT (not_lit));
121           q -= 2;  //移除head至tail两个观察元————第二个观察元时前一个的跟班
122           lits[0] = other;
123           lits[1] = replacement;
124           assert (lits[0] != lits[1]);
125           *r = not_lit;
126           kissat_delay_watching_large (solver, delayed,
127                            replacement, other, ref);//构造新观察元并加入对应堆栈
128           ticks++;
129         }
130           else if (other_value)
131         {
132           assert (replacement_value < 0);
133           assert (blocking_value < 0);
134           assert (other_value < 0);
135           LOGREF (ref, "conflicting");
136           res = c;
137           break;
138         }
139 #ifdef HYPER_PROPAGATION
140           else if (hyper)
141         {//larg子句确定能BCP出新文字时,如果hyper为真采用超二元归结代码段
142           assert (replacement_value < 0);
143           unsigned dom = kissat_find_dominator (solver, other, c);
144           if (dom != INVALID_LIT)
145             {
146               LOGBINARY (dom, other, "hyper binary resolvent");
147 
148               INC (hyper_binary_resolved);
149               INC (clauses_added);
150 
151               INC (hyper_binaries);
152               INC (clauses_redundant);
153 
154               CHECK_AND_ADD_BINARY (dom, other);
155               ADD_BINARY_TO_PROOF (dom, other);
156 
157               kissat_assign_binary (solver, values, assigned,
158                         true, other, dom);
159 
160               delay_watching_hyper (solver, delayed, dom, other);
161               delay_watching_hyper (solver, delayed, other, dom);
162 
163               kissat_delay_watching_large (solver, delayed,
164                            not_lit, other, ref);
165 
166               LOGREF (ref, "unwatching %s in", LOGLIT (not_lit));
167               q -= 2;
168             }
169           else
170             kissat_assign_reference (solver, values,
171                          assigned, other, ref, c);
172         }
173 #endif
174           else
175         {//不考虑超二元归结时的正常BCP新文字other
176           assert (replacement_value < 0);
177           kissat_assign_reference (solver, values,
178                        assigned, other, ref, c);
179         }
180         }
181     }
182     }
183   solver->ticks += ticks;
184 
185   while (p != end_watches)
186     *q++ = *p++;
187   SET_END_OF_WATCHES (*watches, q);
188 
189 #ifdef HYPER_PROPAGATION
190   watch_hyper_delayed (solver, delayed);
191 #else
192   kissat_watch_large_delayed (solver, delayed);
193 #endif
194 
195   return res;
196 }

 其中重点函数如下,其代码见后。

//构造新观察元并加入对应堆栈
1 static inline void
2 kissat_delay_watching_large (kissat * solver, unsigneds * delayed,
3                  unsigned lit, unsigned other, reference ref)
4 {
5   const watch watch = kissat_blocking_watch (other);
6   PUSH_STACK (*delayed, lit);
7   PUSH_STACK (*delayed, watch.raw);
8   PUSH_STACK (*delayed, ref);
9 }

 

 
//正常BCP新文字other
//assign.h
1 void kissat_assign_unit (struct kissat *, unsigned lit);
2 void kissat_assign_decision (struct kissat *, unsigned lit);
3 
4 void kissat_assign_binary (struct kissat *, bool, unsigned, unsigned);
5 
6 void kissat_assign_reference (struct kissat *, unsigned lit,
7                   reference, struct clause *);


//上面line177调用函数kissat_assign_reference (solver, values,assigned, other, ref, c);
参数说明:BCP新文字other,所在子句在观察体系内存位置参考点ref及子句指针c

 

//assign.c

 1   void
 2 kissat_assign_reference (kissat * solver,
 3 #ifdef INLINE_ASSIGN
 4              value * values, assigned * assigned,
 5 #endif
 6              unsigned lit, reference ref, clause * reason)
 7 {
 8   assert (reason == kissat_dereference_clause (solver, ref));
 9 #ifndef INLINE_ASSIGN
10   assigned *assigned = solver->assigned;
11   value *values = solver->values;
12 #endif
13   const unsigned level =
14     kissat_assignment_level (solver, values, assigned, lit, reason);
15   assert (ref != DECISION);
16   assert (ref != UNIT);
17   kissat_assign (solver,
18 #ifdef INLINE_ASSIGN
19          values, assigned,
20 #endif
21          lit, false, false, level, ref);
22   LOGREF (ref, "assign %s reason", LOGLIT (lit));
23 }

 

  1 static inline void
  2 kissat_assign (kissat * solver,
  3 #ifdef INLINE_ASSIGN
  4            value * values, assigned * assigned,
  5 #endif
  6            unsigned lit,
  7            bool binary, bool redundant, unsigned level, unsigned reason)
//注意:传递给reason的是调用处的ref
8 { 9 assert (binary || !redundant); 10 const unsigned not_lit = NOT (lit); 11 #ifndef INLINE_ASSIGN 12 value *values = solver->values; 13 assigned *assigned = solver->assigned; 14 #endif 15 assert (!values[lit]); 16 assert (!values[not_lit]); 17 18 values[lit] = 1; 19 values[not_lit] = -1; 20 21 assert (solver->unassigned > 0); 22 solver->unassigned--; 23 24 const unsigned idx = IDX (lit); 25 struct assigned *a = assigned + idx; 26 27 if (level) 28 { 29 a->level = level; 30 a->binary = binary; 31 a->redundant = redundant; 32 a->reason = reason; 33 } 34 else 35 { 36 a->level = 0; 37 a->binary = false; 38 a->redundant = false; 39 a->reason = UNIT; 40 } 41 42 if (!solver->probing) 43 { 44 const bool negated = NEGATED (lit); 45 const value value = BOOL_TO_VALUE (negated); 46 SAVED (idx) = value; 47 } 48 49 PUSH_STACK (solver->trail, lit); 50 51 if (!level) 52 { 53 kissat_mark_fixed_literal (solver, lit); 54 assert (solver->unflushed < UINT_MAX); 55 solver->unflushed++; 56 } 57 58 watches *watches = &WATCHES (not_lit); 59 if (!watches->size) 60 { 61 watch *w = BEGIN_WATCHES (*watches); 62 __builtin_prefetch (w, 0, 1); 63 } 64 } 65 66 static inline unsigned 67 kissat_assignment_level (kissat * solver, 68 value * values, assigned * assigned, 69 unsigned lit, clause * reason) 70 { 71 unsigned res = 0; 72 for (all_literals_in_clause (other, reason)) 73 { 74 if (other == lit) 75 continue; 76 assert (values[other] < 0), (void) values; 77 const unsigned other_idx = IDX (other); 78 struct assigned *a = assigned + other_idx; 79 const unsigned level = a->level; 80 if (res < level) 81 res = level; 82 } 83 #ifdef NDEBUG 84 (void) solver; 85 #endif 86 return res; 87 } 88 89 #ifndef INLINE_ASSIGN 90 91 void 92 kissat_assign_unit (kissat * solver, unsigned lit) 93 { 94 kissat_assign (solver, lit, false, false, 0, UNIT); 95 LOGUNARY (lit, "assign %s reason", LOGLIT (lit)); 96 } 97 98 void 99 kissat_assign_decision (kissat * solver, unsigned lit) 100 { 101 kissat_assign (solver, lit, false, false, solver->level, DECISION); 102 LOG ("assign %s decision", LOGLIT (lit)); 103 } 104 105 #endif 106 107 #ifdef INLINE_ASSIGN 108 static inline 109 #endif 110 void 111 kissat_assign_binary (kissat * solver, 112 #ifdef INLINE_ASSIGN 113 value * values, assigned * assigned, 114 #endif 115 bool redundant, unsigned lit, unsigned other) 116 { 117 assert (VALUE (other) < 0); 118 #ifndef INLINE_ASSIGN 119 assigned *assigned = solver->assigned; 120 #endif 121 const unsigned other_idx = IDX (other); 122 struct assigned *a = assigned + other_idx; 123 const unsigned level = a->level; 124 kissat_assign (solver, 125 #ifdef INLINE_ASSIGN 126 values, assigned, 127 #endif 128 lit, true, redundant, level, other); 129 LOGBINARY (lit, other, "assign %s %s reason", 130 LOGLIT (lit), redundant ? "redundant" : "irredundant"); 131 132 }

 

 
 
   
posted on 2023-05-03 14:19  海阔凭鱼跃越  阅读(61)  评论(0编辑  收藏  举报