Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 2773ab8093ebc7eed8a7fbbfedaadcd2f239a6c1)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -266,5 +266,5 @@
 			SemanticError( expr, "No reasonable alternatives for expression " );
 		}
-		if ( mode.resolveAssns || mode.prune ) {
+		if ( mode.satisfyAssns || mode.prune ) {
 			// trim candidates just to those where the assertions resolve
 			// - necessary pre-requisite to pruning
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 2773ab8093ebc7eed8a7fbbfedaadcd2f239a6c1)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -16,11 +16,96 @@
 #include "CandidateFinder.hpp"
 
+#include <sstream>
+
+#include "Candidate.hpp"
+#include "CompilationState.h"
+#include "SatisfyAssertions.hpp"
 #include "AST/Expr.hpp"
+#include "AST/Node.hpp"
+#include "AST/Pass.hpp"
+
+#define PRINT( text ) if ( resolvep ) { text }
 
 namespace ResolvExpr {
 
+namespace {
+
+	/// Actually visits expressions to find their candidate interpretations
+	struct Finder {
+		CandidateFinder & candFinder;
+		const ast::SymbolTable & symtab;
+		CandidateList & candidates;
+		const ast::TypeEnvironment & tenv;
+		ast::ptr< ast::Type > & targetType;
+
+		Finder( CandidateFinder & f )
+		: candFinder( f ), symtab( f.symtab ), candidates( f.candidates ), tenv( f.env ), 
+		  targetType( f.targetType ) {}
+		
+		#warning unimplemented
+	};
+
+	/// Prunes a list of candidates down to those that have the minimum conversion cost for a given 
+	/// return type. Skips ambiguous candidates.
+	CandidateList pruneCandidates( CandidateList & candidates ) {
+		#warning unimplemented
+		(void)candidates;
+		assert(false);
+		return {};
+	}
+
+} // anonymous namespace
+
 void CandidateFinder::find( const ast::Expr * expr, ResolvMode mode ) {
+	// Find alternatives for expression
+	ast::Pass<Finder> finder{ *this };
+	expr->accept( finder );
+
+	if ( mode.failFast && candidates.empty() ) {
+		SemanticError( expr, "No reasonable alternatives for expression " );
+	}
+
+	if ( mode.satisfyAssns || mode.prune ) {
+		// trim candidates to just those where the assertions are satisfiable
+		// - necessary pre-requisite to pruning
+		CandidateList satisfied;
+		std::vector< std::string > errors;
+		for ( auto & candidate : candidates ) {
+			satisfyAssertions( *candidate, symtab, satisfied, errors );
+		}
+
+		// fail early if none such
+		if ( mode.failFast && satisfied.empty() ) {
+			std::ostringstream stream;
+			stream << "No alternatives with satisfiable assertions for " << expr << "\n";
+			for ( const auto& err : errors ) {
+				stream << err;
+			}
+			SemanticError( expr->location, stream.str() );
+		}
+
+		// reset candidates
+		candidates = std::move( satisfied );
+	}
+
+	if ( mode.prune ) {
+		// trim candidates to single best one
+		auto oldsize = candidates.size();
+		PRINT(
+			std::cerr << "alternatives before prune:" << std::endl;
+			print( std::cerr, candidates );
+		)
+
+		CandidateList pruned = pruneCandidates( candidates );
+		if ( mode.failFast && pruned.empty() ) {
+			std::ostringstream stream;
+			CandidateList winners;
+			
+			#warning unimplemented
+			assert(false);
+		}
+	}
+
 	#warning unimplemented
-	(void)expr; (void)mode;
 	assert(false);
 }
@@ -31,7 +116,13 @@
 	std::vector< CandidateFinder > out;
 
-	#warning unimplemented
-	(void)xs;
-	assert(false);
+	for ( const auto & x : xs ) {
+		out.emplace_back( symtab, env );
+		out.back().find( x, ResolvMode::withAdjustment() );
+		
+		PRINT(
+			std::cerr << "findSubExprs" << std::endl;
+			print( std::cerr, out.back().candidates );
+		)
+	}
 
 	return out;
Index: src/ResolvExpr/CandidateFinder.hpp
===================================================================
--- src/ResolvExpr/CandidateFinder.hpp	(revision 2773ab8093ebc7eed8a7fbbfedaadcd2f239a6c1)
+++ src/ResolvExpr/CandidateFinder.hpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -19,4 +19,5 @@
 #include "ResolvMode.h"
 #include "AST/Fwd.hpp"
+#include "AST/Node.hpp"
 #include "AST/SymbolTable.hpp"
 #include "AST/TypeEnvironment.hpp"
@@ -29,5 +30,5 @@
 	const ast::SymbolTable & symtab;         ///< Symbol table to lookup candidates
 	const ast::TypeEnvironment & env;        ///< Substitutions performed in this resolution
-	const ast::Type * targetType = nullptr;  ///< Target type for resolution
+	ast::ptr< ast::Type > targetType = nullptr;  ///< Target type for resolution
 
 	CandidateFinder( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env )
Index: src/ResolvExpr/ResolvMode.h
===================================================================
--- src/ResolvExpr/ResolvMode.h	(revision 2773ab8093ebc7eed8a7fbbfedaadcd2f239a6c1)
+++ src/ResolvExpr/ResolvMode.h	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -22,13 +22,13 @@
 		const bool prune;            ///< Prune alternatives to min-cost per return type? [true]
 		const bool failFast;         ///< Fail on no resulting alternatives? [true]
-		const bool resolveAssns;     ///< Resolve assertions? [false]
+		const bool satisfyAssns;     ///< Satisfy assertions? [false]
 
 	private:
-		constexpr ResolvMode(bool a, bool p, bool ff, bool ra) 
-		: adjust(a), prune(p), failFast(ff), resolveAssns(ra) {}
+		constexpr ResolvMode(bool a, bool p, bool ff, bool sa) 
+		: adjust(a), prune(p), failFast(ff), satisfyAssns(sa) {}
 
 	public:
 		/// Default settings
-		constexpr ResolvMode() : adjust(false), prune(true), failFast(true), resolveAssns(false) {}
+		constexpr ResolvMode() : adjust(false), prune(true), failFast(true), satisfyAssns(false) {}
 		
 		/// With adjust flag set; turns array and function types into equivalent pointers
@@ -43,5 +43,5 @@
 		static constexpr ResolvMode withoutFailFast() { return { true, true, false, false }; }
 
-		/// The same mode, but with resolveAssns turned on; for top-level calls
+		/// The same mode, but with satisfyAssns turned on; for top-level calls
 		ResolvMode atTopLevel() const { return { adjust, prune, failFast, true }; }
 	};
Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -0,0 +1,37 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// SatisfyAssertions.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Mon Jun 10 17:45:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Mon Jun 10 17:45:00 2019
+// Update Count     : 1
+//
+
+#include "SatisfyAssertions.hpp"
+
+#include <cassert>
+
+namespace ResolvExpr {
+
+void satisfyAssertions( 
+	Candidate & alt, const ast::SymbolTable & symtab, CandidateList & out, 
+	std::vector<std::string> & errors
+) {
+	#warning unimplemented
+	(void)alt; (void)symtab; (void)out; (void)errors;
+	assert(false);
+}
+
+} // namespace ResolvExpr
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/SatisfyAssertions.hpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.hpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
+++ src/ResolvExpr/SatisfyAssertions.hpp	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -0,0 +1,40 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// SatisfyAssertions.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Mon Jun 10 17:45:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Mon Jun 10 17:45:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "Candidate.hpp"  // for Candidate, CandidateList
+
+namespace ast {
+	class SymbolTable;
+}
+
+namespace ResolvExpr {
+
+/// Recursively satisfies all assertions provided in a candidate; returns true if succeeds
+void satisfyAssertions( 
+	Candidate & alt, const ast::SymbolTable & symtab, CandidateList & out, 
+	std::vector<std::string> & errors );
+
+} // namespace ResolvExpr
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/module.mk
===================================================================
--- src/ResolvExpr/module.mk	(revision 2773ab8093ebc7eed8a7fbbfedaadcd2f239a6c1)
+++ src/ResolvExpr/module.mk	(revision 396037da5f2f734f97de7b80432deea29f7ed2b8)
@@ -35,4 +35,5 @@
       ResolvExpr/Resolver.cc \
       ResolvExpr/ResolveTypeof.cc \
+      ResolvExpr/SatisfyAssertions.cpp \
       ResolvExpr/SpecCost.cc \
       ResolvExpr/TypeEnvironment.cc \
