Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Is there any concrete performance benefit to using the Logic monad?</p> </blockquote> <p><strong>TL;DR</strong>: Not that I can find; it appears that <code>Maybe</code> outperforms <code>Logic</code> since it has less overhead.</p> <hr> <p>I decided to implement a simple benchmark to check the performance of <code>Logic</code> versus <code>Maybe</code>. In my test, I randomly construct 5000 CNFs with <code>n</code> clauses, each clause containing three literals. Performance is evaluated as the number of clauses <code>n</code> is varied.</p> <p>In my code, I modified <code>dpllLogic</code> as follows:</p> <pre><code>dpllLogic s = listToMaybe $ observeMany 1 $ dpll s </code></pre> <p>I also tested modifying <code>dpll</code> with <em>fair disjunction</em>, like so:</p> <pre><code>dpll goalClauses = dpll' $ S.empty :|-: goalClauses where dpll' sequent@(assms :|-: clauses) = do -- Fail early if falsum is a subgoal guard $ not (S.empty `member` clauses) case concatMap S.toList $ S.toList clauses of -- Return the assumptions if there are no subgoals left [] -&gt; return assms -- Otherwise try various tactics for resolving goals x:_ -&gt; msum [ pureRule sequent , oneRule sequent , return $ unitP x sequent , return $ unitP (neg x) sequent ] &gt;&gt;- dpll' </code></pre> <p>I then tested the using <code>Maybe</code>, <code>Logic</code>, and <code>Logic</code> with fair disjunction.</p> <p>Here are the benchmark results for this test: <img src="https://i.stack.imgur.com/5kdVw.png" alt="Maybe Monad v. Logic Monad v. Logic Monad with Fair Disjunction"></p> <p>As we can see, <code>Logic</code> with or without fair disjunction in this case makes no difference. The <code>dpll</code> solve using the <code>Maybe</code> monad appears to run in linear time in <code>n</code>, while using the <code>Logic</code> monad incurs additional overhead. It appears that the overhead incurred plateaus off. </p> <p>Here is the <code>Main.hs</code> file used to generate these test. Someone wishing to reproduce these benchmarks might wish to review <a href="http://www.haskell.org/ghc/docs/7.2.1/html/users_guide/profiling.html" rel="noreferrer">Haskell's notes on profiling</a>:</p> <pre><code>module Main where import DPLL import System.Environment (getArgs) import System.Random import Control.Monad (replicateM) import Data.Set (fromList) randLit = do let clauses = [ T p | p &lt;- ['a'..'f'] ] ++ [ F p | p &lt;- ['a'..'f'] ] r &lt;- randomRIO (0, (length clauses) - 1) return $ clauses !! r randClause n = fmap fromList $ replicateM n $ fmap fromList $ replicateM 3 randLit main = do args &lt;- getArgs let n = read (args !! 0) :: Int clauses &lt;- replicateM 5000 $ randClause n -- To use the Maybe monad --let satisfiable = filter (/= Nothing) $ map dpll clauses let satisfiable = filter (/= Nothing) $ map dpllLogic clauses putStrLn $ (show $ length satisfiable) ++ " satisfiable out of " ++ (show $ length clauses) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload