Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want to eliminate redundant parentheses, you will need to pass around some precedence information. For example, in Haskell, the <code>showsPrec</code> function embodies this pattern; it has type</p> <pre><code>showsPrec :: Show a =&gt; Int -&gt; a -&gt; String -&gt; String </code></pre> <p>where the first <code>Int</code> argument is the precedence of the current printing context. The extra <code>String</code> argument is a trick to get efficient list appending. I'll demonstrate how to write a similar function for your type, though admittedly in Haskell (since I know that language best) and without using the extra efficiency trick.</p> <p>The idea is to first build a string that has no top-level parentheses -- but does have all the parentheses needed to disambiguate subterms -- then add parentheses only if necessary. The <code>unbracketed</code> computation below does the first step. Then the only question is: when should we put parentheses around our term? Well, the answer to that is that things should be parenthesized when a low-precedence term is an argument to a high-precedence operator. So we need to compare the precedence of our immediate "parent" -- called <code>dCntxt</code> in the code below -- to the precedence of the term we're currently rendering -- called <code>dHere</code> in the code below. The <code>bracket</code> function below either adds parentheses or leaves the string alone based on the result of this comparison.</p> <pre><code>data Formula = Atom String | Neg Formula | Conj Formula Formula | Disj Formula Formula precedence :: Formula -&gt; Int precedence Atom{} = 4 precedence Neg {} = 3 precedence Conj{} = 2 precedence Disj{} = 1 displayPrec :: Int -&gt; Formula -&gt; String displayPrec dCntxt f = bracket unbracketed where dHere = precedence f recurse = displayPrec dHere unbracketed = case f of Atom s -&gt; s Neg p -&gt; "~ " ++ recurse p Conj p q -&gt; recurse p ++ " &amp; " ++ recurse q Disj p q -&gt; recurse p ++ " | " ++ recurse q bracket | dCntxt &gt; dHere = \s -&gt; "(" ++ s ++ ")" | otherwise = id display :: Formula -&gt; String display = displayPrec 0 </code></pre> <p>Here's how it looks in action.</p> <pre><code>*Main&gt; display (Neg (Conj (Disj (Conj (Atom "a") (Atom "b")) (Atom "c")) (Conj (Atom "d") (Atom "e")))) "~ ((a &amp; b | c) &amp; d &amp; e)" </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. 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.
 

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