Index: src/AST/Chain.hpp
===================================================================
--- src/AST/Chain.hpp	(revision 4864a73f6af536425f476d1b447d232e82bd4edf)
+++ src/AST/Chain.hpp	(revision 4864a73f6af536425f476d1b447d232e82bd4edf)
@@ -0,0 +1,63 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Chain.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Wed Jun 05 14:11:52 2019
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "Node.hpp"
+
+namespace ast {
+
+template<typename T>
+struct _chain_mutator;
+
+template<typename node_t, Node::ref_type ref_t>
+struct _chain_mutator<ptr_base<node_t, ref_t>>;
+
+template<template <class...> class container_t, typename node_t, Node::ref_type ref_t>
+struct _chain_mutator<container_t<ptr_base<node_t, ref_t>>>;
+
+template<typename node_t, Node::ref_type ref_t>
+struct _chain_mutator<ptr_base<node_t, ref_t>> {
+	ptr_base<node_t, ref_t> & base;
+
+	template<typename actual_node_t, typename child_t>
+	auto operator()( child_t actual_node_t::*child ) {
+		auto n = mutate(base.get());
+		actual_node_t * node = strict_dynamic_cast<actual_node_t *>(n);
+		base = node;
+		return _chain_mutator< typename std::remove_reference< decltype(node->*child) >::type >{node->*child};
+	}
+
+	node_t * operator->() {
+		auto n = mutate(base.get());
+		base = n;
+		return n;
+	}
+};
+
+template<template <class...> class container_t, typename node_t, Node::ref_type ref_t>
+struct _chain_mutator<container_t<ptr_base<node_t, ref_t>>> {
+	container_t<ptr_base<node_t, ref_t>> & base;
+
+	auto operator[]( size_t i ) {
+		return _chain_mutator<ptr_base<node_t, ref_t>>{base[i]};
+	}
+};
+
+
+template< typename node_t, Node::ref_type ref_t >
+auto chain_mutate( ptr_base<node_t, ref_t> & base ) {
+	return _chain_mutator<ptr_base<node_t, ref_t>>{ base };
+}
+
+}
Index: src/AST/Node.cpp
===================================================================
--- src/AST/Node.cpp	(revision 2a8f0c1669168188e34b22dccd9a154ce2c7ba79)
+++ src/AST/Node.cpp	(revision 4864a73f6af536425f476d1b447d232e82bd4edf)
@@ -34,4 +34,7 @@
 template< typename node_t, enum ast::Node::ref_type ref_t >
 void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node ) { node->decrement(ref_t); }
+
+template< typename node_t, enum ast::Node::ref_type ref_t >
+void ast::ptr_base<node_t, ref_t>::_check() const { if(node) assert(node->was_ever_strong == false || node->strong_count > 0); }
 
 template< typename node_t, enum ast::Node::ref_type ref_t >
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 2a8f0c1669168188e34b22dccd9a154ce2c7ba79)
+++ src/AST/Node.hpp	(revision 4864a73f6af536425f476d1b447d232e82bd4edf)
@@ -46,4 +46,6 @@
 	};
 
+	bool unique() const { return strong_count == 1; }
+
 private:
 	/// Make a copy of this node; should be overridden in subclass with more precise return type
@@ -56,8 +58,9 @@
 	mutable size_t strong_count = 0;
 	mutable size_t weak_count = 0;
+	mutable bool was_ever_strong = false;
 
 	void increment(ref_type ref) const {
 		switch (ref) {
-			case ref_type::strong: strong_count++; break;
+			case ref_type::strong: strong_count++; was_ever_strong = true; break;
 			case ref_type::weak  : weak_count  ++; break;
 		}
@@ -176,13 +179,13 @@
 	}
 
-	const node_t * get() const { return  node; }
-	const node_t * operator->() const { return  node; }
-	const node_t & operator* () const { return *node; }
-	explicit operator bool() const { return node; }
-	operator const node_t * () const { return node; }
+	const node_t * get() const { _check(); return  node; }
+	const node_t * operator->() const { _check(); return  node; }
+	const node_t & operator* () const { _check(); return *node; }
+	explicit operator bool() const { _check(); return node; }
+	operator const node_t * () const { _check(); return node; }
 
 	/// wrapper for convenient access to dynamic_cast
 	template<typename o_node_t>
-	const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); }
+	const o_node_t * as() const { _check(); return dynamic_cast<const o_node_t *>(node); }
 
 	/// wrapper for convenient access to strict_dynamic_cast
@@ -208,4 +211,5 @@
 	void _inc( const node_t * other );
 	void _dec( const node_t * other );
+	void _check() const;
 
 protected:
