From 0100c8ab9b1909cb7d2a35bdb8a459f528ca905a Mon Sep 17 00:00:00 2001
From: Damien Nguyen <damien1@huawei.com>
Date: Thu, 24 Oct 2019 14:50:54 +0200
Subject: [PATCH 1/3] Automate generation of documentation ReST files

---
 .gitignore                              |   1 +
 docs/conf.py                            | 181 +++++++++++++++++++---
 docs/package_description.py             | 167 ++++++++++++++++++++
 docs/projectq.backends.rst              |  20 ---
 docs/projectq.cengines.rst              |  33 ----
 docs/projectq.libs.math.rst             |  21 ---
 docs/projectq.libs.revkit.rst           |  34 ----
 docs/projectq.libs.rst                  |  20 ---
 docs/projectq.meta.rst                  |  32 ----
 docs/projectq.ops.rst                   |  67 --------
 docs/projectq.setups.decompositions.rst | 198 ------------------------
 docs/projectq.setups.rst                |  94 -----------
 docs/projectq.types.rst                 |  18 ---
 13 files changed, 329 insertions(+), 557 deletions(-)
 create mode 100644 docs/package_description.py
 delete mode 100755 docs/projectq.backends.rst
 delete mode 100755 docs/projectq.cengines.rst
 delete mode 100755 docs/projectq.libs.math.rst
 delete mode 100644 docs/projectq.libs.revkit.rst
 delete mode 100755 docs/projectq.libs.rst
 delete mode 100755 docs/projectq.meta.rst
 delete mode 100755 docs/projectq.ops.rst
 delete mode 100755 docs/projectq.setups.decompositions.rst
 delete mode 100755 docs/projectq.setups.rst
 delete mode 100755 docs/projectq.types.rst

diff --git a/.gitignore b/.gitignore
index c3957d2e0..436e3172b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 # python artifacts
 *.pyc
+docs/projectq.*.rst
diff --git a/docs/conf.py b/docs/conf.py
index 971cefd8d..354bef3d3 100755
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -21,6 +21,18 @@
 import sys
 sys.path.insert(0, os.path.abspath('..'))
 
+import projectq
+# Also import all the modules that are not automatically imported
+import projectq.libs.math
+import projectq.libs.revkit
+import projectq.setups.default
+import projectq.setups.grid
+import projectq.setups.ibm
+import projectq.setups.ibm16
+import projectq.setups.linear
+import projectq.setups.restrictedgateset
+import projectq.setups.decompositions
+
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
@@ -33,8 +45,11 @@
 import sphinx_rtd_theme
 
 extensions = [
-    'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.mathjax',
-    'sphinx.ext.autosummary', 'sphinx.ext.linkcode',
+    'sphinx.ext.autodoc',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.mathjax',
+    'sphinx.ext.autosummary',
+    'sphinx.ext.linkcode',
 ]
 
 autosummary_generate = True
@@ -125,7 +140,6 @@
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = False
 
-
 # -- Options for HTML output ----------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
@@ -271,8 +285,7 @@
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'projectq.tex', 'projectq Documentation',
-     'a', 'manual'),
+    (master_doc, 'projectq.tex', 'projectq Documentation', 'a', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -307,30 +320,24 @@
 #
 # latex_domain_indices = True
 
-
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    (master_doc, 'projectq', 'projectq Documentation',
-     [author], 1)
-]
+man_pages = [(master_doc, 'projectq', 'projectq Documentation', [author], 1)]
 
 # If true, show URL addresses after external links.
 #
 # man_show_urls = False
 
-
 # -- Options for Texinfo output -------------------------------------------
 
 # Grouping the document tree into Texinfo files. List of tuples
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'projectq', 'projectq Documentation',
-     author, 'projectq', 'One line description of project.',
-     'Miscellaneous'),
+    (master_doc, 'projectq', 'projectq Documentation', author, 'projectq',
+     'One line description of project.', 'Miscellaneous'),
 ]
 
 # Documents to append as an appendix to all manuals.
@@ -351,7 +358,6 @@
 
 # -- Options for sphinx.ext.linkcode --------------------------------------
 import inspect
-import projectq
 
 
 def linkcode_resolve(domain, info):
@@ -381,7 +387,7 @@ def linkcode_resolve(domain, info):
         return None
     else:
         try:
-            obj = eval(info['module'] + '.' + info['fullname'])
+                obj = eval(info['module'] + '.' + info['fullname'])
         except AttributeError:
             # Object might be a non-static attribute of a class, e.g.,
             # self.num_qubits, which would only exist after init was called.
@@ -400,8 +406,8 @@ def linkcode_resolve(domain, info):
                 if len(new_higher_name) <= 1:
                     obj = eval(info['module'])
                 else:
-                    obj = eval(info['module'] + '.' +
-                               '.'.join(new_higher_name[:-1]))
+                    obj = eval(info['module'] + '.'
+                               + '.'.join(new_higher_name[:-1]))
                 filepath = inspect.getsourcefile(obj)
                 line_number = inspect.getsourcelines(obj)[1]
             except:
@@ -409,6 +415,141 @@ def linkcode_resolve(domain, info):
         # Only require relative path projectq/relative_path
         projectq_path = inspect.getsourcefile(projectq)[:-11]
         relative_path = os.path.relpath(filepath, projectq_path)
-        url = (github_url + github_tag + "/projectq/" + relative_path + "#L" +
-               str(line_number))
+        url = (github_url + github_tag + "/projectq/" + relative_path + "#L"
+               + str(line_number))
         return url
+
+
+# ------------------------------------------------------------------------------
+
+import importlib
+sys.path.append(os.path.abspath('.'))
+desc = importlib.import_module('package_description')
+
+PackageDescription = desc.PackageDescription
+
+# ------------------------------------------------------------------------------
+# Define the description of ProjectQ packages and their submodules below.
+#
+# In order for the automatic package recognition to work properly, it is
+# important that PackageDescription of sub-packages appear earlier in the list
+# than their parent package (see for example libs.math and libs.revkit
+# compared to libs).
+#
+# It is also possible to customize the presentation of submodules (see for
+# example the setups and setups.decompositions) or even to have private
+# sub-modules listed in the documentation page of a parent packages (see for
+# example the cengines package)
+
+descriptions = [
+    PackageDescription('backends'),
+
+
+    PackageDescription('cengines',
+                       desc='''
+The ProjectQ compiler engines package.
+'''),
+
+
+    PackageDescription('libs.math',
+                       desc='''
+A tiny math library which will be extended thoughout the next weeks. Right now, it only contains the math functions necessary to run Beauregard's implementation of Shor's algorithm.
+'''),
+
+
+    PackageDescription('libs.revkit',
+                       desc='''
+This library integrates `RevKit <https://msoeken.github.io/revkit.html>`_ into
+ProjectQ to allow some automatic synthesis routines for reversible logic.  The
+library adds the following operations that can be used to construct quantum
+circuits:
+
+- :class:`~projectq.libs.revkit.ControlFunctionOracle`: Synthesizes a reversible circuit from Boolean control function
+- :class:`~projectq.libs.revkit.PermutationOracle`: Synthesizes a reversible circuit for a permutation
+- :class:`~projectq.libs.revkit.PhaseOracle`: Synthesizes phase circuit from an arbitrary Boolean function
+
+RevKit can be installed from PyPi with `pip install revkit`.
+
+.. note::
+
+    The RevKit Python module must be installed in order to use this ProjectQ library.
+
+    There exist precompiled binaries in PyPi, as well as a source distribution.
+    Note that a C++ compiler with C++17 support is required to build the RevKit
+    python module from source.  Examples for compatible compilers are Clang
+    6.0, GCC 7.3, and GCC 8.1.
+
+The integration of RevKit into ProjectQ and other quantum programming languages is described in the paper
+
+    * Mathias Soeken, Thomas Haener, and Martin Roetteler "Programming Quantum Computers Using Design Automation," in: Design Automation and Test in Europe (2018) [`arXiv:1803.01022 <https://arxiv.org/abs/1803.01022>`_]
+''', module_special_members='__init__,__or__'),
+
+
+    PackageDescription('libs',
+                       desc='''
+The library collection of ProjectQ which, for now, consists of a tiny math library and an interface library to RevKit. Soon, more libraries will be added.
+'''),
+
+
+    PackageDescription('meta',
+                       desc='''
+Contains meta statements which allow more optimal code while making it easier for users to write their code.
+Examples are `with Compute`, followed by an automatic uncompute or `with Control`, which allows the user to condition an entire code block upon the state of a qubit.
+'''),
+
+
+    PackageDescription('ops',
+                       desc='''
+The operations collection consists of various default gates and is a work-in-progress, as users start to work with ProjectQ.
+''', module_special_members='__init__,__or__'),
+
+
+    PackageDescription('setups.decompositions',
+                       desc='''
+The decomposition package is a collection of gate decomposition / replacement rules which can be used by, e.g., the AutoReplacer engine.
+'''),
+
+
+    PackageDescription('setups',
+                       desc='''
+The setups package contains a collection of setups which can be loaded by the `MainEngine`. Each setup contains a `get_engine_list` function which returns a list of compiler engines:
+
+Example:
+    .. code-block:: python
+
+        import projectq.setups.ibm as ibm_setup
+        from projectq import MainEngine
+        eng = MainEngine(engine_list=ibm_setup.get_engine_list())
+        # eng uses the default Simulator backend
+
+The subpackage decompositions contains all the individual decomposition rules
+which can be given to, e.g., an `AutoReplacer`.
+''',
+                       submodules_desc='''
+Each of the submodules contains a setup which can be used to specify the
+`engine_list` used by the `MainEngine` :''',
+                       submodule_special_members='__init__'),
+
+
+    PackageDescription(
+        'types', '''
+The types package contains quantum types such as Qubit, Qureg, and WeakQubitRef. With further development of the math library, also quantum integers, quantum fixed point numbers etc. will be added.
+'''),
+]
+
+# ------------------------------------------------------------------------------
+# Automatically generate ReST files for each package of ProjectQ
+
+for desc in descriptions:
+    fname = os.path.join(os.path.dirname(os.path.abspath('__file__')),
+                         'projectq.{}.rst'.format(desc.name))
+    lines = None
+    if os.path.exists(fname):
+        with open(fname, 'r') as fd:
+            lines = [line[:-1] for line in fd.readlines()]
+
+    new_lines = desc.get_ReST()
+
+    if new_lines != lines:
+        with open(fname, 'w') as fd:
+            fd.write('\n'.join(desc.get_ReST()))
diff --git a/docs/package_description.py b/docs/package_description.py
new file mode 100644
index 000000000..afb18ba18
--- /dev/null
+++ b/docs/package_description.py
@@ -0,0 +1,167 @@
+import inspect
+import sys
+import os
+
+
+class PackageDescription(object):
+    package_list = []
+
+    def __init__(self, name, desc='', module_special_members='__init__',
+                 submodule_special_members='', submodules_desc='',
+                 helper_submodules=None):
+        """
+        Args:
+            name (str): Name of ProjectQ module
+            desc (str): (optional) Description of module
+            module_special_members (str): (optional) Special members to include
+                in the documentation of the module
+            submodule_special_members (str): (optional) Special members to
+                include in the documentation of submodules
+            submodules_desc (str): (optional) Description to print out before
+                the list of submodules
+            helper_submodules (list): (optional) List of tuples for helper
+                sub-modules to include in the documentation.
+                Tuples are (section_title, submodukle_name,
+                            automodule_properties)
+        """
+
+        self.name = name
+        self.desc = desc
+        if name not in PackageDescription.package_list:
+            PackageDescription.package_list.append(name)
+
+        self.module = sys.modules['projectq.{}'.format(self.name)]
+        self.module_special_members = module_special_members
+
+        self.submodule_special_members = module_special_members
+        self.submodules_desc = submodules_desc
+
+        self.helper_submodules = helper_submodules
+
+        module_root = os.path.dirname(self.module.__file__)
+        sub = [(name, obj) for name, obj in inspect.getmembers(
+            self.module,
+            lambda obj: inspect.ismodule(obj) and module_root in obj.__file__)
+               if name[0] != '_']
+
+        self.subpackages = []
+        self.submodules = []
+        for name, obj in sub:
+            if '{}.{}'.format(self.name,
+                              name) in PackageDescription.package_list:
+                self.subpackages.append((name, obj))
+            else:
+                self.submodules.append((name, obj))
+
+        self.subpackages.sort(key=lambda x: x[0].lower())
+        self.submodules.sort(key=lambda x: x[0].lower())
+
+        self.members = [(name, obj)
+                        for name, obj in inspect.getmembers(
+                                self.module,
+                                lambda obj: (inspect.isclass(obj)
+                                             or inspect.isfunction(obj)
+                                             or isinstance(obj, (int,
+                                                                 float,
+                                                                 tuple,
+                                                                 list,
+                                                                 dict,
+                                                                 set,
+                                                                 frozenset,
+                                                                 str))))
+                        if name[0] != '_']
+        self.members.sort(key=lambda x: x[0].lower())
+
+    def get_ReST(self):
+        new_lines = []
+        new_lines.append(self.name)
+        new_lines.append('=' * len(self.name))
+        new_lines.append('')
+
+        if self.desc:
+            new_lines.append(self.desc.strip())
+            new_lines.append('')
+
+        submodule_has_index = False
+
+        if self.subpackages:
+            new_lines.append('Subpackages')
+            new_lines.append('-' * len(new_lines[-1]))
+            new_lines.append('')
+            new_lines.append('.. toctree::')
+            new_lines.append('    :maxdepth: 1')
+            new_lines.append('')
+            for name, _ in self.subpackages:
+                new_lines.append('    projectq.{}.{}'.format(self.name, name))
+            new_lines.append('')
+        else:
+            submodule_has_index = True
+            new_lines.append('.. autosummary::')
+            new_lines.append('')
+            if self.submodules:
+                for name, _ in self.submodules:
+                    new_lines.append('\tprojectq.{}.{}'.format(self.name,
+                                                               name))
+                new_lines.append('')
+            if self.members:
+                for name, _ in self.members:
+                    new_lines.append('\tprojectq.{}.{}'.format(self.name,
+                                                               name))
+                new_lines.append('')
+
+        if self.submodules:
+            new_lines.append('Submodules')
+            new_lines.append('-' * len(new_lines[-1]))
+            new_lines.append('')
+            if self.submodules_desc:
+                new_lines.append(self.submodules_desc.strip())
+                new_lines.append('')
+
+            if not submodule_has_index:
+                new_lines.append('.. autosummary::')
+                new_lines.append('')
+                for name, _ in self.submodules:
+                    new_lines.append('    projectq.{}.{}'.format(self.name,
+                                                                 name))
+                new_lines.append('')
+
+            for name, _ in self.submodules:
+                new_lines.append(name)
+                new_lines.append('^' * len(new_lines[-1]))
+                new_lines.append('')
+                new_lines.append('.. automodule:: projectq.{}.{}'.format(
+                    self.name, name))
+                new_lines.append('    :members:')
+                if self.submodule_special_members:
+                    new_lines.append('    :special-members: {}'.format(
+                        self.submodule_special_members))
+                new_lines.append('    :undoc-members:')
+                new_lines.append('')
+
+        new_lines.append('Module contents')
+        new_lines.append('-' * len(new_lines[-1]))
+        new_lines.append('')
+        new_lines.append('.. automodule:: projectq.{}'.format(self.name))
+        new_lines.append('    :members:')
+        new_lines.append('    :undoc-members:')
+        new_lines.append('    :special-members: {}'.format(
+            self.module_special_members))
+        new_lines.append('    :imported-members:')
+        new_lines.append('')
+
+        if self.helper_submodules:
+            new_lines.append('Helper sub-modules')
+            new_lines.append('-' * len(new_lines[-1]))
+            new_lines.append('')
+            for title, name, params in self.helper_submodules:
+                new_lines.append(title)
+                new_lines.append('^' * len(title))
+                new_lines.append('')
+                new_lines.append('.. automodule:: projectq.{}.{}'.format(
+                    self.name, name))
+                for param in params:
+                    new_lines.append('    {}'.format(param))
+                new_lines.append('')
+
+        assert not new_lines[-1]
+        return new_lines[:-1]
diff --git a/docs/projectq.backends.rst b/docs/projectq.backends.rst
deleted file mode 100755
index 621f7ce86..000000000
--- a/docs/projectq.backends.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-backends
-========
-
-.. autosummary::
-	
-	projectq.backends.CommandPrinter
-	projectq.backends.CircuitDrawer
-	projectq.backends.Simulator
-	projectq.backends.ClassicalSimulator
-	projectq.backends.ResourceCounter
-	projectq.backends.IBMBackend
-
-
-Module contents
----------------
-
-.. automodule:: projectq.backends
-    :members:
-    :special-members: __init__
-    :imported-members:
diff --git a/docs/projectq.cengines.rst b/docs/projectq.cengines.rst
deleted file mode 100755
index 5a3c963a6..000000000
--- a/docs/projectq.cengines.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-cengines
-========
-
-The ProjectQ compiler engines package.
-
-.. autosummary::
-	projectq.cengines.AutoReplacer
-	projectq.cengines.BasicEngine
-	projectq.cengines.BasicMapper
-	projectq.cengines.CommandModifier
-	projectq.cengines.CompareEngine
-	projectq.cengines.DecompositionRule
-	projectq.cengines.DecompositionRuleSet
-	projectq.cengines.DummyEngine
-	projectq.cengines.ForwarderEngine
-	projectq.cengines.GridMapper
-	projectq.cengines.InstructionFilter
-	projectq.cengines.IBM5QubitMapper
-	projectq.cengines.LinearMapper
-	projectq.cengines.LocalOptimizer
-	projectq.cengines.ManualMapper
-	projectq.cengines.MainEngine
-  projectq.cengines.SwapAndCNOTFlipper
-	projectq.cengines.TagRemover
-
-
-Module contents
----------------
-
-.. automodule:: projectq.cengines
-    :members:
-    :special-members: __init__
-    :imported-members:
diff --git a/docs/projectq.libs.math.rst b/docs/projectq.libs.math.rst
deleted file mode 100755
index 1567978b5..000000000
--- a/docs/projectq.libs.math.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-math
-====
-
-A tiny math library which will be extended thoughout the next weeks. Right now, it only contains the math functions necessary to run Beauregard's implementation of Shor's algorithm.
-
-.. autosummary::
-
-	projectq.libs.math.all_defined_decomposition_rules
-	projectq.libs.math.AddConstant
-	projectq.libs.math.SubConstant
-	projectq.libs.math.AddConstantModN
-	projectq.libs.math.SubConstantModN
-	projectq.libs.math.MultiplyByConstantModN
-
-Module contents
----------------
-
-.. automodule:: projectq.libs.math
-    :members:
-    :special-members: __init__
-    :imported-members:
diff --git a/docs/projectq.libs.revkit.rst b/docs/projectq.libs.revkit.rst
deleted file mode 100644
index 90a2dbb18..000000000
--- a/docs/projectq.libs.revkit.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-revkit
-======
-
-This library integrates `RevKit <https://msoeken.github.io/revkit.html>`_ into
-ProjectQ to allow some automatic synthesis routines for reversible logic.  The
-library adds the following operations that can be used to construct quantum
-circuits:
-
-- :class:`~projectq.libs.revkit.ControlFunctionOracle`: Synthesizes a reversible circuit from Boolean control function
-- :class:`~projectq.libs.revkit.PermutationOracle`: Synthesizes a reversible circuit for a permutation
-- :class:`~projectq.libs.revkit.PhaseOracle`: Synthesizes phase circuit from an arbitrary Boolean function
-
-RevKit can be installed from PyPi with `pip install revkit`.
-
-.. note::
-
-    The RevKit Python module must be installed in order to use this ProjectQ library.
-
-    There exist precompiled binaries in PyPi, as well as a source distribution.
-    Note that a C++ compiler with C++17 support is required to build the RevKit
-    python module from source.  Examples for compatible compilers are Clang
-    6.0, GCC 7.3, and GCC 8.1.
-
-The integration of RevKit into ProjectQ and other quantum programming languages is described in the paper
-
-    * Mathias Soeken, Thomas Haener, and Martin Roetteler "Programming Quantum Computers Using Design Automation," in: Design Automation and Test in Europe (2018) [`arXiv:1803.01022 <https://arxiv.org/abs/1803.01022>`_]
-
-Module contents
----------------
-
-.. automodule:: projectq.libs.revkit
-    :members:
-    :special-members: __init__,__or__
-    :imported-members:
diff --git a/docs/projectq.libs.rst b/docs/projectq.libs.rst
deleted file mode 100755
index 9f2c8cd4b..000000000
--- a/docs/projectq.libs.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-libs
-====
-
-The library collection of ProjectQ which, for now, consists of a tiny math library and an interface library to RevKit. Soon, more libraries will be added.
-
-Subpackages
------------
-
-.. toctree::
-
-    projectq.libs.math
-    projectq.libs.revkit
-
-Module contents
----------------
-
-.. automodule:: projectq.libs
-    :members:
-    :special-members: __init__
-    :imported-members:
diff --git a/docs/projectq.meta.rst b/docs/projectq.meta.rst
deleted file mode 100755
index 14c3d9eea..000000000
--- a/docs/projectq.meta.rst
+++ /dev/null
@@ -1,32 +0,0 @@
-meta
-====
-
-Contains meta statements which allow more optimal code while making it easier for users to write their code.
-Examples are `with Compute`, followed by an automatic uncompute or `with Control`, which allows the user to condition an entire code block upon the state of a qubit.
-
-
-.. autosummary::
-
-	projectq.meta.DirtyQubitTag
-	projectq.meta.LogicalQubitIDTag
-	projectq.meta.LoopTag
-	projectq.meta.Loop
-	projectq.meta.Compute
-	projectq.meta.Uncompute
-	projectq.meta.CustomUncompute
-	projectq.meta.ComputeTag
-	projectq.meta.UncomputeTag
-	projectq.meta.Control
-	projectq.meta.get_control_count
-	projectq.meta.Dagger
-	projectq.meta.insert_engine
-	projectq.meta.drop_engine_after
-
-Module contents
----------------
-
-.. automodule:: projectq.meta
-    :members:
-    :undoc-members:
-    :special-members: __init__
-    :imported-members:
diff --git a/docs/projectq.ops.rst b/docs/projectq.ops.rst
deleted file mode 100755
index 6b9ec5936..000000000
--- a/docs/projectq.ops.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-ops
-===
-
-The operations collection consists of various default gates and is a work-in-progress, as users start to work with ProjectQ.
-
-.. autosummary::
-
-	projectq.ops.BasicGate
-	projectq.ops.MatrixGate
-	projectq.ops.SelfInverseGate
-	projectq.ops.BasicRotationGate
-	projectq.ops.BasicPhaseGate
-	projectq.ops.ClassicalInstructionGate
-	projectq.ops.FastForwardingGate
-	projectq.ops.BasicMathGate
-	projectq.ops.apply_command
-	projectq.ops.Command
-	projectq.ops.H
-	projectq.ops.X
-	projectq.ops.Y
-	projectq.ops.Z
-	projectq.ops.S
-	projectq.ops.Sdag
-	projectq.ops.T
-	projectq.ops.Tdag
-	projectq.ops.SqrtX
-	projectq.ops.Swap
-	projectq.ops.SqrtSwap
-	projectq.ops.Entangle
-	projectq.ops.Ph
-	projectq.ops.Rx
-	projectq.ops.Ry
-	projectq.ops.Rz
-	projectq.ops.R
-	projectq.ops.FlushGate
-	projectq.ops.MeasureGate
-	projectq.ops.Allocate
-	projectq.ops.Deallocate
-	projectq.ops.AllocateDirty
-	projectq.ops.Barrier
-	projectq.ops.DaggeredGate
-	projectq.ops.ControlledGate
-	projectq.ops.C
-	projectq.ops.All
-	projectq.ops.Tensor
-	projectq.ops.QFT
-	projectq.ops.QubitOperator
-	projectq.ops.CRz
-	projectq.ops.CNOT
-	projectq.ops.CZ
-	projectq.ops.Toffoli
-	projectq.ops.TimeEvolution
-	projectq.ops.UniformlyControlledRy
-	projectq.ops.UniformlyControlledRz
-	projectq.ops.StatePreparation
-	projectq.ops.QPE
-	projectq.ops.FlipBits
-	projectq.ops.QAA
-
-
-Module contents
----------------
-
-.. automodule:: projectq.ops
-    :members:
-    :special-members: __init__,__or__
-    :imported-members:
diff --git a/docs/projectq.setups.decompositions.rst b/docs/projectq.setups.decompositions.rst
deleted file mode 100755
index 26cd392fc..000000000
--- a/docs/projectq.setups.decompositions.rst
+++ /dev/null
@@ -1,198 +0,0 @@
-decompositions
-==============
-
-The decomposition package is a collection of gate decomposition / replacement rules which can be used by, e.g., the AutoReplacer engine.
-
-
-.. autosummary::
-
-    projectq.setups.decompositions.arb1qubit2rzandry
-    projectq.setups.decompositions.barrier
-    projectq.setups.decompositions.carb1qubit2cnotrzandry
-    projectq.setups.decompositions.cnot2cz
-    projectq.setups.decompositions.cnu2toffoliandcu
-    projectq.setups.decompositions.crz2cxandrz
-    projectq.setups.decompositions.entangle
-    projectq.setups.decompositions.globalphase
-    projectq.setups.decompositions.ph2r
-    projectq.setups.decompositions.qft2crandhadamard
-    projectq.setups.decompositions.qubitop2onequbit
-    projectq.setups.decompositions.r2rzandph
-    projectq.setups.decompositions.rx2rz
-    projectq.setups.decompositions.ry2rz
-    projectq.setups.decompositions.sqrtswap2cnot
-    projectq.setups.decompositions.stateprep2cnot
-    projectq.setups.decompositions.swap2cnot
-    projectq.setups.decompositions.time_evolution
-    projectq.setups.decompositions.toffoli2cnotandtgate
-    projectq.setups.decompositions.uniformlycontrolledr2cnot
-    projectq.setups.decompositions.phaseestimation
-    projectq.setups.decompositions.amplitudeamplification
-
-
-Submodules
-----------
-
-projectq.setups.decompositions.arb1qubit2rzandry module
--------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.arb1qubit2rzandry
-    :members:
-    :undoc-members:
-
-
-projectq.setups.decompositions.barrier module
----------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.barrier
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.carb1qubit2cnotrzandry module
-------------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.carb1qubit2cnotrzandry
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.cnot2cz module
----------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.cnot2cz
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.cnu2toffoliandcu module
-------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.cnu2toffoliandcu
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.crz2cxandrz module
--------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.crz2cxandrz
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.entangle module
-----------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.entangle
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.globalphase module
--------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.globalphase
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.ph2r module
-------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.ph2r
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.qft2crandhadamard module
--------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.qft2crandhadamard
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.qubitop2onequbit module
--------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.qubitop2onequbit
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.r2rzandph module
------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.r2rzandph
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.rx2rz module
--------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.rx2rz
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.ry2rz module
--------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.ry2rz
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.sqrtswap2cnot module
----------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.sqrtswap2cnot
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.stateprep2cnot module
-----------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.stateprep2cnot
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.swap2cnot module
------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.swap2cnot
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.time_evolution module
-----------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.time_evolution
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.toffoli2cnotandtgate module
-----------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.toffoli2cnotandtgate
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.uniformlycontrolledr2cnot module
----------------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.uniformlycontrolledr2cnot
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.phaseestimation module
----------------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.phaseestimation
-    :members:
-    :undoc-members:
-
-projectq.setups.decompositions.amplitudeamplification module
----------------------------------------------------------------
-
-.. automodule:: projectq.setups.decompositions.amplitudeamplification
-    :members:
-    :undoc-members:
-
-
-Module contents
----------------
-
-.. automodule:: projectq.setups.decompositions
-    :members:
-    :undoc-members:
-        :imported-members:
diff --git a/docs/projectq.setups.rst b/docs/projectq.setups.rst
deleted file mode 100755
index 058469f07..000000000
--- a/docs/projectq.setups.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-setups
-======
-
-The setups package contains a collection of setups which can be loaded by the `MainEngine`. Each setup contains a `get_engine_list` function which returns a list of compiler engines:
-
-Example:
-    .. code-block:: python
-
-        import projectq.setups.ibm as ibm_setup
-        from projectq import MainEngine
-        eng = MainEngine(engine_list=ibm_setup.get_engine_list())
-        # eng uses the default Simulator backend
-
-The subpackage decompositions contains all the individual decomposition rules
-which can be given to, e.g., an `AutoReplacer`.
-
-
-Subpackages
------------
-
-.. toctree::
-    :maxdepth: 1
-
-    projectq.setups.decompositions
-
-Submodules
-----------
-
-Each of the submodules contains a setup which can be used to specify the
-`engine_list` used by the `MainEngine` :
-
-.. autosummary::
-
-    projectq.setups.default
-    projectq.setups.grid
-    projectq.setups.ibm
-    projectq.setups.ibm16
-    projectq.setups.linear
-    projectq.setups.restrictedgateset
-
-default
--------
-
-.. automodule:: projectq.setups.default
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-grid
-----
-
-.. automodule:: projectq.setups.grid
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-ibm
----
-
-.. automodule:: projectq.setups.ibm
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-ibm16
------
-
-.. automodule:: projectq.setups.ibm16
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-linear
-------
-
-.. automodule:: projectq.setups.linear
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-restrictedgateset
------------------
-
-.. automodule:: projectq.setups.restrictedgateset
-    :members:
-    :special-members: __init__
-    :undoc-members:
-
-Module contents
----------------
-
-.. automodule:: projectq.setups
-    :members:
-    :special-members: __init__
diff --git a/docs/projectq.types.rst b/docs/projectq.types.rst
deleted file mode 100755
index 4f26edc9d..000000000
--- a/docs/projectq.types.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-types
-=====
-
-The types package contains quantum types such as Qubit, Qureg, and WeakQubitRef. With further development of the math library, also quantum integers, quantum fixed point numbers etc. will be added.
-
-.. autosummary::
-	projectq.types.BasicQubit
-	projectq.types.Qubit
-	projectq.types.Qureg
-	projectq.types.WeakQubitRef
-
-Module contents
----------------
-
-.. automodule:: projectq.types
-    :members:
-    :special-members:
-    :imported-members:

From 0b3eec96041853cdbd5fd4fd43bf2b21dc9dae02 Mon Sep 17 00:00:00 2001
From: Damien Nguyen <damien1@huawei.com>
Date: Thu, 24 Oct 2019 15:39:12 +0200
Subject: [PATCH 2/3] Fix error in conf.py

---
 docs/conf.py | 29 ++++++++---------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/docs/conf.py b/docs/conf.py
index 354bef3d3..ef791d9ae 100755
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -387,7 +387,11 @@ def linkcode_resolve(domain, info):
         return None
     else:
         try:
+            if ('module' in info and 'fullname' in info
+                and info['module'] and info['fullname']):
                 obj = eval(info['module'] + '.' + info['fullname'])
+            else:
+                return None
         except AttributeError:
             # Object might be a non-static attribute of a class, e.g.,
             # self.num_qubits, which would only exist after init was called.
@@ -443,20 +447,14 @@ def linkcode_resolve(domain, info):
 
 descriptions = [
     PackageDescription('backends'),
-
-
     PackageDescription('cengines',
                        desc='''
 The ProjectQ compiler engines package.
 '''),
-
-
     PackageDescription('libs.math',
                        desc='''
 A tiny math library which will be extended thoughout the next weeks. Right now, it only contains the math functions necessary to run Beauregard's implementation of Shor's algorithm.
 '''),
-
-
     PackageDescription('libs.revkit',
                        desc='''
 This library integrates `RevKit <https://msoeken.github.io/revkit.html>`_ into
@@ -482,34 +480,26 @@ def linkcode_resolve(domain, info):
 The integration of RevKit into ProjectQ and other quantum programming languages is described in the paper
 
     * Mathias Soeken, Thomas Haener, and Martin Roetteler "Programming Quantum Computers Using Design Automation," in: Design Automation and Test in Europe (2018) [`arXiv:1803.01022 <https://arxiv.org/abs/1803.01022>`_]
-''', module_special_members='__init__,__or__'),
-
-
+''',
+                       module_special_members='__init__,__or__'),
     PackageDescription('libs',
                        desc='''
 The library collection of ProjectQ which, for now, consists of a tiny math library and an interface library to RevKit. Soon, more libraries will be added.
 '''),
-
-
     PackageDescription('meta',
                        desc='''
 Contains meta statements which allow more optimal code while making it easier for users to write their code.
 Examples are `with Compute`, followed by an automatic uncompute or `with Control`, which allows the user to condition an entire code block upon the state of a qubit.
 '''),
-
-
     PackageDescription('ops',
                        desc='''
 The operations collection consists of various default gates and is a work-in-progress, as users start to work with ProjectQ.
-''', module_special_members='__init__,__or__'),
-
-
+''',
+                       module_special_members='__init__,__or__'),
     PackageDescription('setups.decompositions',
                        desc='''
 The decomposition package is a collection of gate decomposition / replacement rules which can be used by, e.g., the AutoReplacer engine.
 '''),
-
-
     PackageDescription('setups',
                        desc='''
 The setups package contains a collection of setups which can be loaded by the `MainEngine`. Each setup contains a `get_engine_list` function which returns a list of compiler engines:
@@ -529,14 +519,11 @@ def linkcode_resolve(domain, info):
 Each of the submodules contains a setup which can be used to specify the
 `engine_list` used by the `MainEngine` :''',
                        submodule_special_members='__init__'),
-
-
     PackageDescription(
         'types', '''
 The types package contains quantum types such as Qubit, Qureg, and WeakQubitRef. With further development of the math library, also quantum integers, quantum fixed point numbers etc. will be added.
 '''),
 ]
-
 # ------------------------------------------------------------------------------
 # Automatically generate ReST files for each package of ProjectQ
 

From 148214e1c843e7e34b2668127bc2971d30b824b6 Mon Sep 17 00:00:00 2001
From: Damien Nguyen <damien1@huawei.com>
Date: Wed, 5 Feb 2020 10:35:55 +0100
Subject: [PATCH 3/3] Adjust .gitignore

---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitignore b/.gitignore
index 436e3172b..c80e00ac7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
 # python artifacts
 *.pyc
 docs/projectq.*.rst
+*.so
+build/
+var/
