diff --git a/flake.nix b/flake.nix
index 17d5a3da8d6733fe3a0ee3e5d363a731b567e184..b02a825edcfa38ff4adf37d8e1469378c6e6cb95 100644
--- a/flake.nix
+++ b/flake.nix
@@ -16,10 +16,12 @@
     nix-filter,
     ...
   } @ inputs: let
-    load = p: n: {
+    load = final: p: n: {
       "${n}" =
-        p.callCabal2nixWithOptions n
-        (nix-filter.lib {root = "${self}/${n}";}) "" {};
+        final.haskell.lib.overrideCabal
+        (p.callCabal2nixWithOptions n (nix-filter.lib {root = "${self}/${n}";}) "" {}) {
+          doCheck = true;
+        };
     };
     packages = final: p:
       {
@@ -29,8 +31,8 @@
             doCheck = false;
           };
       }
-      // load p "rtree"
-      // load p "rtree-c";
+      // load final p "rtree"
+      // load final p "rtree-c";
     overlays = final: prev: {
       haskellPackages = prev.haskellPackages.extend (p: _: packages final p);
     };
@@ -67,8 +69,12 @@
           hpkgs.shellFor
           {
             name = "rtree-shells";
-            packages = p: [p.rtree p.rtree-c];
+            packages = p: [
+              p.rtree
+              p.rtree-c
+            ];
             doBenchmark = true;
+            doCheck = true;
             inherit nativeBuildInputs withHoogle;
           };
       };
diff --git a/rtree-c/src/ReduceC.hs b/rtree-c/src/ReduceC.hs
index a53768268de1152bae81b98bd4bdb994ca22e7cb..68a211a37a0c19fd718b1232ced76580a88e0e6f 100644
--- a/rtree-c/src/ReduceC.hs
+++ b/rtree-c/src/ReduceC.hs
@@ -121,7 +121,9 @@ reduceCExternalDeclaration r cont ctx = do
       | otherwise ->
           split ("remove function " <> maybe "" C.identToString (functionName fun), C.posOf r) (cont ctx) do
             r' <- C.CFDefExt <$> reduceCFunDef fun ctx
-            (r' :) <$> cont ctx
+            (r' :) <$> case functionName fun of
+              Just fid -> cont (addInlineExpr fid (C.CVar fid C.undefNode) ctx)
+              Nothing -> cont ctx
     C.CDeclExt result ->
       case result of
         -- A typedef
@@ -206,7 +208,7 @@ reduceCDeclarationItem d ma = case d of
             , addInlineExpr i (C.CVar i ni) ctx
             )
         )
-  C.CDeclarationItem (C.CDeclr (Just i) [] Nothing [] ni) Nothing Nothing -> do
+  C.CDeclarationItem (C.CDeclr (Just i) _ Nothing [] ni) Nothing Nothing -> do
     (ds, ctx) <- ma
     split
       ("remove variable " <> C.identToString i, C.posOf ni)
@@ -417,12 +419,14 @@ reduceCExpr expr ctx = case expr of
     Just $ split ("reduce to operant", C.posOf expr) elhs' do
       e <- elhs'
       pure $ C.CUnary o e ni
+  C.CCall e es ni -> do
+    re <- reduceCExpr e (addKeyword DisallowVariableInlining ctx)
+    Just $ do
+      e' <- re
+      es' <- traverse (`reduceCExprOrZero` ctx) es
+      pure $ C.CCall e' es' ni
   a -> error (show a)
 
---     C.CCall e es ni -> do
---       e' <- reduce e
---       es' <- traverse (fmap orZero reduce) es
---       pure $ C.CCall e' es' ni
 --     C.CCond ec et ef ni -> do
 --       ec' <- reduce ec
 --       ef' <- reduce ef
diff --git a/rtree-c/test/cases/small/declaration.c b/rtree-c/test/cases/small/declaration.c
new file mode 100644
index 0000000000000000000000000000000000000000..392baeb124d08869c2c33f658b66bc949235acc7
--- /dev/null
+++ b/rtree-c/test/cases/small/declaration.c
@@ -0,0 +1,5 @@
+int printf(const char *, ...);
+
+int main () {
+  printf("Hello, World!");
+}
diff --git a/rtree-c/test/cases/small/definition.c b/rtree-c/test/cases/small/definition.c
new file mode 100644
index 0000000000000000000000000000000000000000..6f5c3c6b2f721732b5ed5f733c8004bfe5b1bdc8
--- /dev/null
+++ b/rtree-c/test/cases/small/definition.c
@@ -0,0 +1,7 @@
+int f() {
+  return 0;
+}
+
+int main() {
+  return f();
+}
diff --git a/rtree-c/test/expected/declaration/main.c b/rtree-c/test/expected/declaration/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..a4f172804d3cf7df7db49ad65b0fff7f7374012e
--- /dev/null
+++ b/rtree-c/test/expected/declaration/main.c
@@ -0,0 +1,5 @@
+int printf(const char *, ...);
+int main()
+{
+    printf("Hello, World!");
+}
diff --git a/rtree-c/test/expected/declaration/reduction/r000.c b/rtree-c/test/expected/declaration/reduction/r000.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f46ee7a1bba0bac7eda86aa14a682748fbd27a8
--- /dev/null
+++ b/rtree-c/test/expected/declaration/reduction/r000.c
@@ -0,0 +1,9 @@
+// 0 remove variable printf at ("test/cases/small/declaration.c": line 1)
+// 0 remove statement at ("test/cases/small/declaration.c": line 4)
+// 0 replace by zero at ("test/cases/small/declaration.c": line 4)
+
+int printf(const char *, ...);
+int main()
+{
+    printf("Hello, World!");
+}
diff --git a/rtree-c/test/expected/declaration/reduction/r001.c b/rtree-c/test/expected/declaration/reduction/r001.c
new file mode 100644
index 0000000000000000000000000000000000000000..bca00a78eb395a14248dae5865d1a0ae7c616f76
--- /dev/null
+++ b/rtree-c/test/expected/declaration/reduction/r001.c
@@ -0,0 +1,9 @@
+// 0 remove variable printf at ("test/cases/small/declaration.c": line 1)
+// 0 remove statement at ("test/cases/small/declaration.c": line 4)
+// 1 replace by zero at ("test/cases/small/declaration.c": line 4)
+
+int printf(const char *, ...);
+int main()
+{
+    printf(0);
+}
diff --git a/rtree-c/test/expected/declaration/reduction/r01.c b/rtree-c/test/expected/declaration/reduction/r01.c
new file mode 100644
index 0000000000000000000000000000000000000000..91b9bce6e8b713345fc077c5a2d6b41f89718262
--- /dev/null
+++ b/rtree-c/test/expected/declaration/reduction/r01.c
@@ -0,0 +1,7 @@
+// 0 remove variable printf at ("test/cases/small/declaration.c": line 1)
+// 1 remove statement at ("test/cases/small/declaration.c": line 4)
+
+int printf(const char *, ...);
+int main()
+{
+}
diff --git a/rtree-c/test/expected/declaration/reduction/r1.c b/rtree-c/test/expected/declaration/reduction/r1.c
new file mode 100644
index 0000000000000000000000000000000000000000..597b7b8d7a21090b7d9f40253cc5b5ef9e0afac9
--- /dev/null
+++ b/rtree-c/test/expected/declaration/reduction/r1.c
@@ -0,0 +1,5 @@
+// 1 remove variable printf at ("test/cases/small/declaration.c": line 1)
+
+int main()
+{
+}
diff --git a/rtree-c/test/expected/definition/main.c b/rtree-c/test/expected/definition/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab5b9c14b02a80a2549f6b965c5a5e4f6d46045d
--- /dev/null
+++ b/rtree-c/test/expected/definition/main.c
@@ -0,0 +1,8 @@
+int f()
+{
+    return 0;
+}
+int main()
+{
+    return f();
+}
diff --git a/rtree-c/test/expected/definition/reduction/r00000.c b/rtree-c/test/expected/definition/reduction/r00000.c
new file mode 100644
index 0000000000000000000000000000000000000000..6970d1522f618bd69b5deec826bed38df0f6f3db
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r00000.c
@@ -0,0 +1,14 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 0 replace by zero at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 0 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+    return f();
+}
diff --git a/rtree-c/test/expected/definition/reduction/r00001.c b/rtree-c/test/expected/definition/reduction/r00001.c
new file mode 100644
index 0000000000000000000000000000000000000000..59d0bfee399a7933e6064c447d95ab0580ac9ce5
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r00001.c
@@ -0,0 +1,14 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 0 replace by zero at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 1 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+    return 0;
+}
diff --git a/rtree-c/test/expected/definition/reduction/r0001.c b/rtree-c/test/expected/definition/reduction/r0001.c
new file mode 100644
index 0000000000000000000000000000000000000000..c6508aae16748796cc467f8eb5376442eff525a5
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r0001.c
@@ -0,0 +1,12 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 0 replace by zero at ("test/cases/small/definition.c": line 2)
+// 1 remove statement at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+}
diff --git a/rtree-c/test/expected/definition/reduction/r00100.c b/rtree-c/test/expected/definition/reduction/r00100.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a6c0ed1dde7370101099e6bf57bd7cb5a3d9374
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r00100.c
@@ -0,0 +1,14 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 1 replace by zero at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 0 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+    return f();
+}
diff --git a/rtree-c/test/expected/definition/reduction/r00101.c b/rtree-c/test/expected/definition/reduction/r00101.c
new file mode 100644
index 0000000000000000000000000000000000000000..153f431e1a5354a210227c4cf43d6d2964086106
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r00101.c
@@ -0,0 +1,14 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 1 replace by zero at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 1 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+    return 0;
+}
diff --git a/rtree-c/test/expected/definition/reduction/r0011.c b/rtree-c/test/expected/definition/reduction/r0011.c
new file mode 100644
index 0000000000000000000000000000000000000000..db521ec197e357c769d59a1857bab2b6a51afcb8
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r0011.c
@@ -0,0 +1,12 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 2)
+// 1 replace by zero at ("test/cases/small/definition.c": line 2)
+// 1 remove statement at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+    return 0;
+}
+int main()
+{
+}
diff --git a/rtree-c/test/expected/definition/reduction/r0100.c b/rtree-c/test/expected/definition/reduction/r0100.c
new file mode 100644
index 0000000000000000000000000000000000000000..5527e63cb89a758ded97e38fd259369b1e4c907a
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r0100.c
@@ -0,0 +1,12 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 1 remove statement at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 0 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+}
+int main()
+{
+    return f();
+}
diff --git a/rtree-c/test/expected/definition/reduction/r0101.c b/rtree-c/test/expected/definition/reduction/r0101.c
new file mode 100644
index 0000000000000000000000000000000000000000..473ba0fcf08b75fca33f0835b91e1580f32e4ff4
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r0101.c
@@ -0,0 +1,12 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 1 remove statement at ("test/cases/small/definition.c": line 2)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+// 1 replace by zero at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+}
+int main()
+{
+    return 0;
+}
diff --git a/rtree-c/test/expected/definition/reduction/r011.c b/rtree-c/test/expected/definition/reduction/r011.c
new file mode 100644
index 0000000000000000000000000000000000000000..19abfa72fe26d26d06687efe9959a7f4dd9581a5
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r011.c
@@ -0,0 +1,10 @@
+// 0 remove function f at ("test/cases/small/definition.c": line 1)
+// 1 remove statement at ("test/cases/small/definition.c": line 2)
+// 1 remove statement at ("test/cases/small/definition.c": line 6)
+
+int f()
+{
+}
+int main()
+{
+}
diff --git a/rtree-c/test/expected/definition/reduction/r10.c b/rtree-c/test/expected/definition/reduction/r10.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b79cd2f286328d6db2c212371487b48949a95b9
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r10.c
@@ -0,0 +1,7 @@
+// 1 remove function f at ("test/cases/small/definition.c": line 1)
+// 0 remove statement at ("test/cases/small/definition.c": line 6)
+
+int main()
+{
+    return 0;
+}
diff --git a/rtree-c/test/expected/definition/reduction/r11.c b/rtree-c/test/expected/definition/reduction/r11.c
new file mode 100644
index 0000000000000000000000000000000000000000..69ee6fef22fff40a5b19885b378bee1b074b36e2
--- /dev/null
+++ b/rtree-c/test/expected/definition/reduction/r11.c
@@ -0,0 +1,6 @@
+// 1 remove function f at ("test/cases/small/definition.c": line 1)
+// 1 remove statement at ("test/cases/small/definition.c": line 6)
+
+int main()
+{
+}