literal := integer stage := integer taggedLiteral := (literal, stage) assignment := matcher | deduced $ $ as (taggedLiteral, multiset taggedLiteral) with | Deduced $e $es -> [(e, es)] | _ -> [] | guessed $ as (taggedLiteral) with | Guessed $e -> [e] | _ -> [] | whichever $ as (taggedLiteral) with | Deduced $e _ -> [e] | Guessed $e -> [e] | _ -> [] | _ as (something) with | $tgt -> [tgt] -- Data structure for CNF toCnf cs := map (\c -> (c, c)) cs fromCnf cs := map 2#%1 cs -- VSIDS initVars vs := map (\v -> (neg v, 0)) vs ++ map (\v -> (v, 0)) vs addVars vs vars := matchDFS (vs, vars) as (list literal, list (literal, integer)) with | ([], _) -> sort/fn (\xc yc -> compare (2#%2 yc) (2#%2 xc)) vars | ($v :: $vs', $hs ++ (#v, $c) :: $ts) -> addVars vs' (hs ++ (v, c + 1) :: ts) deleteVar v vars := matchDFS vars as multiset (literal, integer) with | (#v, _) :: (#(neg v), _) :: $vars' -> vars2 | _ -> "error: not matched in delete-var" -- Utility functions for literlas and cnfs getStage l trail := matchDFS trail as list assignment with | _ ++ whichever (#(neg l), $s) :: _ -> s | _ -> "error: not matched in get-stage" deleteLiteral l cnf := map (\c -> ( matchAllDFS 2#%1 c as multiset literal with | (!#l & $m) :: _ -> m , 2#%2 c )) cnf deleteClausesWith l cnf := matchAllDFS cnf as multiset (multiset literal, multiset literal) with | ((!(#l :: _), _) & $c) :: _ -> c assignTrue l cnf := deleteLiteral (neg l) (deleteClausesWith l cnf) unitPropagate stage cnf trail := unitPropagate' stage cnf trail trail unitPropagate' stage cnf trail otrail := matchDFS trail as list assignment with | whichever ($l, _) :: $trail' -> unitPropagate' stage (assignTrue l cnf) trail' otrail | [] -> unitPropagate'' stage (assignTrue l cnf) otrail unitPropagate'' stage cnf trail := matchDFS cnf as multiset (multiset literal, multiset literal) with -- empty literal | ([], _) :: _ -> (cnf, trail) -- 1-literal rule | ($l :: [], #l :: $rs) :: _ -> unitPropagate'' stage (assignTrue l cnf) (Deduced (l, stage) (map (\r -> (r, getStage r trail)) rs) :: trail) -- otherwise | _ -> (cnf, trail) learn stage cl trail := matchDFS (trail, cl) as (list assignment, multiset taggedLiteral) with -- not more than 2 literals from the current stage | (_, !((_, #stage) :: (_, #stage) :: _)) -> (minimum (map 2#%2 cl), map 2#%1 cl) -- otherwise | (_ ++ deduced ($l, #stage) $ds :: $trail', (#(neg l), #stage) :: $rs) -> learn stage (union rs ds) trail' backjump stage trail := matchDFS trail as list assignment with | _ ++ (guessed (_, #stage) :: _ & $trail') -> trail' | _ -> trail guess vars trail := matchDFS (vars, trail) as (list (literal, integer), list assignment) with | (_ ++ ($l, _) :: _, !(_ ++ whichever (#l | #(neg l), _) :: _)) -> neg l cdcl vars cnf := cdcl' 0 0 (initVars vars) (toCnf cnf) [] cdcl' count stage vars cnf trail := let (cnf', trail') := unitPropagate stage cnf trail in matchDFS cnf' as multiset (multiset literal, multiset literal) with | [] -> True | ([], $cc) :: _ -> matchDFS trail' as list assignment with | _ ++ guessed ($l, #stage) :: $trail'' -> let (s, lc) := learn stage (map (\l -> (l, getStage l trail')) cc) trail' trail''' := backjump s trail'' in cdcl' (count + 1) s (addVars lc vars) ((lc, lc) :: cnf) trail''' | _ -> False | _ -> let g := guess vars trail' in cdcl' (count + 1) (stage + 1) vars cnf (Guessed (g, stage + 1) :: trail') problem20 := [[4, -18, 19], [3, 18, -5], [-5, -8, -15], [-20, 7, -16], [10, -13, -7], [-12, -9, 17], [17, 19, 5], [-16, 9, 15], [11, -5, -14], [18, -10, 13], [-3, 11, 12], [-6, -17, -8], [-18, 14, 1], [-19, -15, 10], [12, 18, -19], [-8, 4, 7], [-8, -9, 4], [7, 17, -15], [12, -7, -14], [-10, -11, 8], [2, -15, -11], [9, 6, 1], [-11, 20, -17], [9, -15, 13], [12, -7, -17], [-18, -2, 20], [20, 12, 4], [19, 11, 14], [-16, 18, -4], [-1, -17, -19], [-13, 15, 10], [-12, -14, -13], [12, -14, -7], [-7, 16, 10], [6, 10, 7], [20, 14, -16], [-19, 17, 11], [-7, 1, -20], [-5, 12, 15], [-4, -9, -13], [12, -11, -7], [-5, 19, -8], [1, 16, 17], [20, -14, -15], [13, -4, 10], [14, 7, 10], [-5, 9, 20], [10, 1, -19], [-16, -15, -1], [16, 3, -11], [-15, -10, 4], [4, -15, -3], [-10, -16, 11], [-8, 12, -5], [14, -6, 12], [1, 6, 11], [-13, -5, -1], [-7, -2, 12], [1, -20, 19], [-2, -13, -8], [15, 18, 4], [-11, 14, 9], [-6, -15, -2], [5, -12, -15], [-6, 17, 5], [-13, 5, -19], [20, -1, 14], [9, -17, 15], [-5, 19, -18], [-12, 8, -10], [-18, 14, -4], [15, -9, 13], [9, -5, -1], [10, -19, -14], [20, 9, 4], [-9, -2, 19], [-5, 13, -17], [2, -10, -18], [-18, 3, 11], [7, -9, 17], [-15, -6, -3], [-2, 3, -13], [12, 3, -2], [-2, -3, 17], [20, -15, -16], [-5, -17, -19], [-20, -18, 11], [-9, 1, -5], [-19, 9, 17], [12, -2, 17], [4, -16, -5]] problem50 := [[18, -8, 29], [-16, 3, 18], [-36, -11, -30], [-50, 20, 32], [-6, 9, 35], [42, -38, 29], [43, -15, 10], [-48, -47, 1], [-45, -16, 33], [38, 42, 22], [-49, 41, -34], [12, 17, 35], [22, -49, 7], [-10, -11, -39], [-28, -36, -37], [-13, -46, -41], [21, -4, 9], [12, 48, 10], [24, 23, 15], [-8, -41, -43], [-44, -2, -35], [-27, 18, 31], [47, 35, 6], [-11, -27, 41], [-33, -47, -45], [-16, 36, -37], [27, -46, 2], [15, -28, 10], [-38, 46, -39], [-33, -4, 24], [-12, -45, 50], [-32, -21, -15], [8, 42, 24], [30, -49, 4], [45, -9, 28], [-33, -47, -1], [1, 27, -16], [-11, -17, -35], [-42, -15, 45], [-19, -27, 30], [3, 28, 12], [48, -11, -33], [-6, 37, -9], [-37, 13, -7], [-2, 26, 16], [46, -24, -38], [-13, -24, -8], [-36, -42, -21], [-37, -19, 3], [-31, -50, 35], [-7, -26, 29], [-42, -45, 29], [33, 25, -6], [-45, -5, 7], [-7, 28, -6], [-48, 31, -11], [32, 16, -37], [-24, 48, 1], [18, -46, 23], [-30, -50, 48], [-21, 39, -2], [24, 47, 42], [-36, 30, 4], [-5, 28, -1], [-47, 32, -42], [16, 37, -22], [-43, 42, -34], [-40, 39, -20], [-49, 29, 6], [-41, -3, 39], [-16, -12, 43], [24, 22, 3], [47, -45, 43], [45, -37, 46], [-9, 26, 5], [-3, 23, -13], [5, -34, 13], [12, 39, 13], [22, 50, 37], [19, 9, 46], [-24, 8, -27], [-28, 7, 21], [8, -25, 50], [20, 50, 4], [27, 36, 13], [26, 31, -25], [39, -44, -32], [-20, 41, -10], [49, -28, 35], [1, 44, 34], [39, 35, -11], [-50, -42, -7], [-24, 7, 47], [-13, 5, -48], [-9, -20, -23], [2, 17, -19], [11, 23, 21], [-45, 30, 15], [11, 26, -24], [38, 33, -13], [44, -27, -7], [41, 49, 2], [-18, 12, -37], [-2, 12, -26], [-19, 7, 32], [-22, 11, 33], [8, 12, -20], [16, 40, -48], [-2, -24, -11], [26, -17, 37], [-14, -19, 46], [5, 47, 36], [-29, -9, 19], [32, 4, 28], [-34, 20, -46], [-4, -36, -13], [-15, -37, 45], [-21, 29, 23], [-6, -40, 7], [-42, 31, -29], [-36, 24, 31], [-45, -37, -1], [3, -6, -29], [-28, -50, 27], [44, 26, 5], [-17, -48, 49], [12, -40, -7], [-12, 31, -48], [27, 32, -42], [-27, -10, 1], [6, -49, 10], [-24, 8, 43], [23, 31, 1], [11, -47, 38], [-28, 26, -13], [-40, 12, -42], [-3, 39, 46], [17, 41, 46], [23, 21, 13], [-14, -1, -38], [20, 18, 6], [-50, 20, -9], [10, -32, -18], [-21, 49, -34], [44, 23, -35], [40, -19, 34], [-1, 6, -12], [6, -2, -7], [32, -20, 34], [-12, 43, -29], [24, 2, -49], [10, -4, 40], [11, 5, 12], [-3, 47, -31], [43, -23, 21], [-41, -36, -50], [-8, -42, -24], [39, 45, 7], [7, 37, -45], [41, 40, 8], [-50, -10, -8], [-5, -39, -14], [-22, -24, -43], [-36, 40, 35], [17, 49, 41], [-32, 7, 24], [-30, -8, -9], [-41, -13, -10], [31, 26, -33], [17, -22, -39], [-21, 28, 3], [-14, 46, 23], [29, 16, 19], [42, -32, -44], [-24, 10, 23], [-1, -32, -21], [-8, -44, -39], [39, 11, 9], [19, 14, -46], [46, 44, -42], [37, 23, -29], [32, 25, 20], [14, -43, -12], [-36, -18, 46], [14, -26, -10], [-2, -30, 5], [6, -18, 46], [-26, 2, -44], [20, -8, -11], [-31, 3, 16], [-22, -9, 39], [-49, 44, -42], [-45, -44, 31], [-31, 50, -11], [-32, -46, 2], [-6, -7, 17], [19, -32, 48], [39, 20, -10], [-22, -37, 38], [-31, 9, -48], [40, 12, 7], [-24, -4, 9], [-22, 49, 33], [-12, 43, 10], [25, -30, -10], [46, 47, 31], [13, 27, -7], [-45, 32, -35], [-50, 34, 9], [2, 34, 30], [3, 16, 2], [-18, 45, -12], [33, 37, 10], [43, 7, -18], [-22, 44, -19], [-31, -27, -42], [-3, -40, 8], [-23, -31, 38]] assertEqual "cdcl" (cdcl (between 1 20) problem20) True -- 2.798 -- assertEqual "cdcl" (cdcl (between 1 50) problem50) False -- 1:10.74