diff --git a/doc/mk_tactic_doc.py b/doc/mk_tactic_doc.py
index e4c71341a..6f4837cdd 100644
--- a/doc/mk_tactic_doc.py
+++ b/doc/mk_tactic_doc.py
@@ -53,13 +53,21 @@ def extract_tactic_doc(ous, f):
             if is_doc.search(line):
                 generate_tactic_doc(ous, f, ins)
 
+def find_tactic_name(path):
+    with open(path) as ins:
+        for line in ins:
+            m = is_tac_name.search(line)
+            if m:
+                return m.group(1)
+    return ""
+
 def presort_files():
     tac_files = []
     for root, dirs, files in os.walk(doc_path("../src")):
         for f in files:
             if f.endswith("tactic.h"):
                 tac_files += [(f, os.path.join(root, f))]
-    tac_files = sorted(tac_files, key = lambda x: x[0])
+    tac_files = sorted(tac_files, key = lambda x: find_tactic_name(x[1]))
     return tac_files
     
 def help(ous):
diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp
index 72f0266c1..58183287d 100644
--- a/src/tactic/bv/bv_bounds_tactic.cpp
+++ b/src/tactic/bv/bv_bounds_tactic.cpp
@@ -35,11 +35,12 @@ namespace {
     struct interval {
         // l < h: [l, h]
         // l > h: [0, h] U [l, UMAX_INT]
-        uint64_t l, h;
-        unsigned sz;
-        bool tight;
+        uint64_t l = 0, h = 0;
+        unsigned sz = 0;
+        bool tight = true;
 
         interval() {}
+
         interval(uint64_t l, uint64_t h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) {
             // canonicalize full set
             if (is_wrapped() && l == h + 1) {
@@ -50,8 +51,7 @@ namespace {
         }
 
         bool invariant() const {
-            return l <= uMaxInt(sz) && h <= uMaxInt(sz) &&
-                (!is_wrapped() || l != h+1);
+            return l <= uMaxInt(sz) && h <= uMaxInt(sz) && (!is_wrapped() || l != h+1);
         }
 
         bool is_full() const { return l == 0 && h == uMaxInt(sz); }
@@ -67,22 +67,17 @@ namespace {
         bool implies(const interval& b) const {
             if (b.is_full())
                 return true;
-            if (is_full())
+            else if (is_full())
                 return false;
-
-            if (is_wrapped()) {
+            else if (is_wrapped()) 
                 // l >= b.l >= b.h >= h
-                return b.is_wrapped() && h <= b.h && l >= b.l;
-            } 
-            else if (b.is_wrapped()) {
+                return b.is_wrapped() && h <= b.h && l >= b.l;            
+            else if (b.is_wrapped()) 
                 // b.l > b.h >= h >= l
                 // h >= l >= b.l > b.h
-                return h <= b.h || l >= b.l;
-            } 
-            else {
-                // 
-                return l >= b.l && h <= b.h;
-            }
+                return h <= b.h || l >= b.l;            
+            else 
+                return l >= b.l && h <= b.h;            
         }
 
         /// return false if intersection is unsat
@@ -98,28 +93,26 @@ namespace {
 
             if (is_wrapped()) {
                 if (b.is_wrapped()) {
-                    if (h >= b.l) {
+                    if (h >= b.l)
                         result = b;
-                    } else if (b.h >= l) {
+                    else if (b.h >= l)
                         result = *this;
-                    } else {
+                    else
                         result = interval(std::max(l, b.l), std::min(h, b.h), sz);
-                    }
-                } else {
-                    return b.intersect(*this, result);
                 }
+                else 
+                    return b.intersect(*this, result);                
             } 
             else if (b.is_wrapped()) {
                 // ... b.h ... l ... h ... b.l ..
-                if (h < b.l && l > b.h) {
-                    return false;
-                }
+                if (h < b.l && l > b.h)
+                    return false;                
                 // ... l ... b.l ... h ...
-                if (h >= b.l && l <= b.h) {
+                if (h >= b.l && l <= b.h)
                     result = b;
-                } else if (h >= b.l) {
+                else if (h >= b.l) 
                     result = interval(b.l, h, sz);
-                } else {
+                else {
                     // ... l .. b.h .. h .. b.l ...
                     SASSERT(l <= b.h);
                     result = interval(l, std::min(h, b.h), sz);
@@ -136,20 +129,16 @@ namespace {
 
         /// return false if negation is empty
         bool negate(interval& result) const {
-            if (!tight) {
+            if (!tight) 
                 result = interval(0, uMaxInt(sz), true);
-                return true;
-            }
-
-            if (is_full())
+            else if (is_full())
                 return false;
-            if (l == 0) {
+            else if (l == 0) 
                 result = interval(h + 1, uMaxInt(sz), sz);
-            } else if (uMaxInt(sz) == h) {
+            else if (uMaxInt(sz) == h) 
                 result = interval(0, l - 1, sz);
-            } else {
-                result = interval(h + 1, l - 1, sz);
-            }
+            else
+                result = interval(h + 1, l - 1, sz);            
             return true;
         }
     };
@@ -163,9 +152,9 @@ namespace {
 
 
     struct undo_bound {
-        expr* e { nullptr };
+        expr* e = nullptr;
         interval b;
-        bool fresh { false };
+        bool fresh = false;
         undo_bound(expr* e, const interval& b, bool fresh) : e(e), b(b), fresh(fresh) {}
     };
 
@@ -176,7 +165,7 @@ namespace {
 
         ast_manager&       m;
         params_ref         m_params;
-        bool               m_propagate_eq;
+        bool               m_propagate_eq = false;
         bv_util            m_bv;
         vector<undo_bound> m_scopes;
         map                m_bound;
@@ -224,7 +213,8 @@ namespace {
                     v = lhs;
                     return true;
                 }
-            } else if (m.is_eq(e, lhs, rhs)) {
+            } 
+            else if (m.is_eq(e, lhs, rhs)) {
                 if (is_number(lhs, n, sz)) {
                     if (m_bv.is_numeral(rhs))
                         return false;
@@ -252,7 +242,7 @@ namespace {
         }
 
         static void get_param_descrs(param_descrs& r) {
-            r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
+            r.insert("propagate-eq", CPK_BOOL, "propagate equalities from inequalities", "false");
         }
 
         ~bv_bounds_simplifier() override {
@@ -546,22 +536,19 @@ namespace {
         }
 
         static void get_param_descrs(param_descrs& r) {
-            r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
+            r.insert("propagate-eq", CPK_BOOL, "propagate equalities from inequalities", "false");
         }
 
         ~dom_bv_bounds_simplifier() override {
-            for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) {
-                dealloc(m_expr_vars[i]);
-            }
-            for (unsigned i = 0, e = m_bound_exprs.size(); i < e; ++i) {
-                dealloc(m_bound_exprs[i]);
-            }
+            for (auto* e : m_expr_vars)
+                dealloc(e);
+            for (auto* b : m_bound_exprs)
+                dealloc(b);
         }
 
         bool assert_expr(expr * t, bool sign) override {
-            while (m.is_not(t, t)) {
-                sign = !sign;
-            }
+            while (m.is_not(t, t)) 
+                sign = !sign;            
 
             interval b;
             expr* t1;
@@ -581,7 +568,8 @@ namespace {
                         return true;
                     m_scopes.push_back(undo_bound(t1, old, false));
                     old = intr;
-                } else {
+                } 
+                else {
                     m_bound.insert(t1, b);
                     m_scopes.push_back(undo_bound(t1, interval(), true));
                 }
@@ -602,9 +590,8 @@ namespace {
                 return;
 
             bool sign = false;
-            while (m.is_not(t, t)) {
-                sign = !sign;
-            }
+            while (m.is_not(t, t)) 
+                sign = !sign;            
 
             if (!is_bound(t, t1, b))
                 return;
@@ -619,27 +606,21 @@ namespace {
 
             interval ctx, intr;
             bool was_updated = true;
-            if (b.is_full() && b.tight) {
-                r = m.mk_true();
-            } 
+            if (b.is_full() && b.tight) 
+                r = m.mk_true();            
             else if (m_bound.find(t1, ctx)) {
-                if (ctx.implies(b)) {
-                    r = m.mk_true();
-                } 
-                else if (!b.intersect(ctx, intr)) {
-                    r = m.mk_false();
-                } 
-                else if (m_propagate_eq && intr.is_singleton()) {
+                if (ctx.implies(b)) 
+                    r = m.mk_true();                
+                else if (!b.intersect(ctx, intr))
+                    r = m.mk_false();                
+                else if (m_propagate_eq && intr.is_singleton()) 
                     r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()),
-                                                    t1->get_sort()));
-                }
-                else {
-                    was_updated = false;
-                }
-            }
-            else {
-                was_updated = false;
+                                                    t1->get_sort()));                
+                else 
+                    was_updated = false;                
             }
+            else 
+                was_updated = false;            
 
             TRACE("bv", tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";);
             if (sign && was_updated)
@@ -654,18 +635,16 @@ namespace {
             while (!todo.empty()) {
                 t = todo.back();
                 todo.pop_back();
-                if (mark.is_marked(t)) {
-                    continue;
-                }
+                if (mark.is_marked(t))
+                    continue;                
                 if (t == v) {
                     todo.reset();
                     return true;
                 }
                 mark.mark(t);
             
-                if (!is_app(t)) {
-                    continue;
-                }
+                if (!is_app(t)) 
+                    continue;                
                 app* a = to_app(t);
                 todo.append(a->get_num_args(), a->get_args());
             }
@@ -680,14 +659,11 @@ namespace {
             while (!todo.empty()) {
                 t = todo.back();
                 todo.pop_back();
-                if (mark1.is_marked(t)) {
-                    continue;
-                }
-                mark1.mark(t);
-            
-                if (!is_app(t)) {
-                    continue;
-                }
+                if (mark1.is_marked(t)) 
+                    continue;                
+                mark1.mark(t);            
+                if (!is_app(t)) 
+                    continue;                
                 interval b;
                 expr* e;
                 if (is_bound(t, e, b)) {
@@ -718,14 +694,13 @@ namespace {
                 m_scopes.reset();
                 return;
             }
-            for (unsigned i = m_scopes.size()-1; i >= target; --i) {
+            for (unsigned i = m_scopes.size(); i-- > target; ) {
                 undo_bound& undo = m_scopes[i];
                 SASSERT(m_bound.contains(undo.e));
-                if (undo.fresh) {
+                if (undo.fresh) 
                     m_bound.erase(undo.e);
-                } else {
-                    m_bound.insert(undo.e, undo.b);
-                }
+                else 
+                    m_bound.insert(undo.e, undo.b);                
             }
             m_scopes.shrink(target);
         }
diff --git a/src/tactic/bv/bv_bounds_tactic.h b/src/tactic/bv/bv_bounds_tactic.h
index 58de42199..325cca89e 100644
--- a/src/tactic/bv/bv_bounds_tactic.h
+++ b/src/tactic/bv/bv_bounds_tactic.h
@@ -5,15 +5,34 @@ Module Name:
 
     bv_bounds_tactic.h
 
-Abstract:
-
-    Contextual bounds simplification tactic.
-
 Author:
 
     Nuno Lopes (nlopes) 2016-2-12
     Nikolaj Bjorner (nbjorner)
 
+Tactic Documentation:
+
+## Tactic propagate-bv-bounds
+
+### Short Description
+
+Contextual bounds simplification tactic.
+
+### Example
+
+```z3
+(declare-const x (_ BitVec 32))
+(declare-const y (_ BitVec 32))
+(declare-const z (_ BitVec 32))
+(assert (bvule (_ bv4 32) x))
+(assert (bvule x (_ bv24 32)))
+(assert (or (bvule x (_ bv100 32)) (bvule (_ bv32 32) x)))
+(apply propagate-bv-bounds)
+```
+
+### Notes
+
+* assumes that bit-vector inequalities have been simplified to use bvule/bvsle
 
 --*/
 #pragma once
diff --git a/src/tactic/bv/bvarray2uf_tactic.h b/src/tactic/bv/bvarray2uf_tactic.h
index a22a78f86..393ab164c 100644
--- a/src/tactic/bv/bvarray2uf_tactic.h
+++ b/src/tactic/bv/bvarray2uf_tactic.h
@@ -3,18 +3,30 @@ Copyright (c) 2015 Microsoft Corporation
 
 Module Name:
 
-    bvarray2ufbvarray2uf_tactic.h
-
-Abstract:
-
-    Tactic that rewrites bit-vector arrays into bit-vector
-    (uninterpreted) functions.
+    bvarray2uf_tactic.h
 
 Author:
 
     Christoph (cwinter) 2015-11-04
 
-Notes:
+Tactic Documentation:
+
+## Tactic bvarray2uf
+
+### Short Description
+
+Tactic that rewrites bit-vector arrays into bit-vector
+(uninterpreted) functions.
+
+### Example
+
+```z3
+(declare-const a (Array (_ BitVec 32) (_ BitVec 32)))
+(declare-const b (_ BitVec 32))
+(declare-const c (_ BitVec 32))
+(assert (= (select a b) c))
+(apply bvarray2uf)
+```
 
 --*/
 #pragma once
diff --git a/src/tactic/bv/dt2bv_tactic.h b/src/tactic/bv/dt2bv_tactic.h
index 906386ed4..05713dfd6 100644
--- a/src/tactic/bv/dt2bv_tactic.h
+++ b/src/tactic/bv/dt2bv_tactic.h
@@ -5,15 +5,28 @@ Module Name:
 
     dt2bv_tactic.h
 
-Abstract:
-
-    Tactic that eliminates finite domain data-types.
-
 Author:
 
     nbjorner 2016-07-22
 
-Revision History:
+Tactic Documentation
+
+## Tactic dt2bv
+
+### Short Description
+
+Tactic that eliminates finite domain data-types.
+
+### Example
+
+```z3
+(declare-datatypes ((Color 0)) (((Red) (Blue) (Green) (DarkBlue) (MetallicBlack) (MetallicSilver) (Silver) (Black))))
+(declare-const x Color)
+(declare-const y Color)
+(assert (not (= x y)))
+(assert (not (= x Red)))
+(apply dt2bv)
+```
 
 --*/
 #pragma once
diff --git a/src/tactic/bv/elim_small_bv_tactic.h b/src/tactic/bv/elim_small_bv_tactic.h
index e4a91f70f..46e6dca39 100644
--- a/src/tactic/bv/elim_small_bv_tactic.h
+++ b/src/tactic/bv/elim_small_bv_tactic.h
@@ -15,6 +15,22 @@ Author:
 
 Revision History:
 
+Tactic Documentation
+
+## Tactic elim-small-bv
+
+### Short Description
+
+Eliminate small, quantified bit-vectors by expansion
+
+### Example
+
+```z3
+(declare-fun p ((_ BitVec 2)) Bool)
+(assert (forall ((x (_ BitVec 2))) (p x)))
+(apply elim-small-bv)
+```
+
 --*/
 #pragma once
 
diff --git a/src/tactic/bv/max_bv_sharing_tactic.h b/src/tactic/bv/max_bv_sharing_tactic.h
index bf14e9f14..2f21ee4b9 100644
--- a/src/tactic/bv/max_bv_sharing_tactic.h
+++ b/src/tactic/bv/max_bv_sharing_tactic.h
@@ -7,16 +7,26 @@ Module Name:
 
 Abstract:
 
-    Rewriter for "maximing" the number of shared terms.
-    The idea is to rewrite AC terms to maximize sharing.
-    This rewriter is particularly useful for reducing
-    the number of Adders and Multipliers before "bit-blasting".
+
 
 Author:
 
     Leonardo de Moura (leonardo) 2011-12-29.
 
-Revision History:
+Tactic Documentation
+
+## Tactic max-bv-sharing
+
+### Short Description
+
+Use heuristics to maximize the sharing of bit-vector expressions such as adders and multipliers
+
+### Long Description
+
+Rewriter for "maximing" the number of shared terms.
+The idea is to rewrite AC terms to maximize sharing.
+This rewriter is particularly useful for reducing
+the number of Adders and Multipliers before "bit-blasting".
 
 --*/
 #pragma once