[Polly][Isl] Update isl to isl-0.24-47-g8853f375

This is needed for the new functions exposed in the C++ interface as used in https://reviews.llvm.org/D104994

Reviewed By: Meinersbur

Differential Revision: https://reviews.llvm.org/D105132

GitOrigin-RevId: 3f9bf9f42a9043e20c6d2a74dd4f47a90a7e2b41
diff --git a/lib/External/isl/AUTHORS b/lib/External/isl/AUTHORS
index 8c65c60..c6aa5cd 100644
--- a/lib/External/isl/AUTHORS
+++ b/lib/External/isl/AUTHORS
@@ -38,6 +38,7 @@
 Ray Donnelly
 Johannes Doerfert
 Andi Drebes
+Ron Estrin
 Clement Foyer
 Armin Groesslinger
 Tobias Grosser
@@ -47,11 +48,13 @@
 Michael Kruse
 Manjunath Kudlur
 Alexander Matz
+Chielo Newctle
 Sebastian Pop
 Louis-Noel Pouchet
 Benoit Pradelle
 Uday Bondhugula
 Andreas Simbuerger
+Tianjiao Sun
 Malhar Thakkar
 Sergei Trofimovich
 Miheer Vaidya
diff --git a/lib/External/isl/ChangeLog b/lib/External/isl/ChangeLog
index dd4a6b7..44acc42 100644
--- a/lib/External/isl/ChangeLog
+++ b/lib/External/isl/ChangeLog
@@ -1,3 +1,10 @@
+version: 0.24
+date: Sun 25 Apr 2021 03:56:37 PM CEST
+changes:
+	- improved (C++) bindings (inherit methods, renamed exports)
+	- initial templated C++ bindings
+	- detect bounds on constant polynomials as tight
+---
 version: 0.23
 date: Sun 01 Nov 2020 02:41:20 PM CET
 changes:
diff --git a/lib/External/isl/GIT_HEAD_ID b/lib/External/isl/GIT_HEAD_ID
index cdd3042..d82f0b9 100644
--- a/lib/External/isl/GIT_HEAD_ID
+++ b/lib/External/isl/GIT_HEAD_ID
@@ -1 +1 @@
-isl-0.23-61-g24e8cd12
+isl-0.24-47-g8853f375
diff --git a/lib/External/isl/Makefile.am b/lib/External/isl/Makefile.am
index b526126..d403e26 100644
--- a/lib/External/isl/Makefile.am
+++ b/lib/External/isl/Makefile.am
@@ -15,16 +15,17 @@
 lib_LTLIBRARIES = libisl.la
 noinst_PROGRAMS = isl_test isl_polyhedron_sample isl_pip \
 	isl_polyhedron_minimize isl_polytope_scan \
-	isl_polyhedron_detect_equalities isl_cat \
+	isl_polyhedron_detect_equalities \
+	isl_polyhedron_remove_redundant_equalities isl_cat \
 	isl_closure isl_bound isl_schedule isl_codegen isl_test_int \
 	isl_flow isl_flow_cmp isl_schedule_cmp
 TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh isl_test_int \
 	flow_test.sh schedule_test.sh
 if HAVE_CPP_ISL_H
-  CPP_H = include/isl/cpp.h
+  CPP_H = include/isl/cpp.h include/isl/typed_cpp.h
 if HAVE_CXX11
-  noinst_PROGRAMS += isl_test_cpp
-  TESTS += isl_test_cpp
+  noinst_PROGRAMS += isl_test2 isl_test_cpp
+  TESTS += isl_test2 isl_test_cpp isl_test_cpp_failed.sh
 endif
 endif
 if HAVE_CLANG
@@ -229,6 +230,12 @@
 isl_test_LDFLAGS = @MP_LDFLAGS@
 isl_test_LDADD = libisl.la @MP_LIBS@
 
+isl_test2_SOURCES = \
+	isl_test2.cc \
+	include/isl/cpp.h
+isl_test2_LDFLAGS = @MP_LDFLAGS@
+isl_test2_LDADD = libisl.la @MP_LIBS@
+
 isl_test_int_LDFLAGS = @MP_LDFLAGS@
 isl_test_int_LDADD = libisl.la @MP_LIBS@
 
@@ -289,6 +296,10 @@
 isl_polyhedron_detect_equalities_SOURCES = \
 	polyhedron_detect_equalities.c
 
+isl_polyhedron_remove_redundant_equalities_LDADD = libisl.la
+isl_polyhedron_remove_redundant_equalities_SOURCES = \
+	polyhedron_remove_redundant_equalities.c
+
 isl_cat_LDADD = libisl.la
 isl_cat_SOURCES = \
 	cat.c
@@ -297,12 +308,25 @@
 isl_closure_SOURCES = \
 	closure.c
 
+isl_test_cpp_CPPFLAGS = $(AM_CPPFLAGS) -UCOMPILE_ERROR
 isl_test_cpp_SOURCES = \
 	isl_test_cpp.cc \
 	include/isl/cpp.h
 isl_test_cpp_LDFLAGS = @MP_LDFLAGS@
 isl_test_cpp_LDADD = libisl.la @MP_LIBS@
 
+# This program is not meant to be compiled by default.
+# In fact it is meant not to be compilable.
+# It is identical to isl_test_cpp, except that it gets compiled
+# with the COMPILE_ERROR flag set.
+EXTRA_PROGRAMS = isl_test_cpp_failed
+isl_test_cpp_failed_CPPFLAGS = $(AM_CPPFLAGS) -DCOMPILE_ERROR
+isl_test_cpp_failed_SOURCES = \
+	isl_test_cpp.cc \
+	include/isl/cpp.h
+isl_test_cpp_failed_LDFLAGS = @MP_LDFLAGS@
+isl_test_cpp_failed_LDADD = libisl.la @MP_LIBS@
+
 isl_test_cpp_checked_SOURCES = \
 	isl_test_cpp-checked.cc \
 	include/isl/cpp-checked.h
@@ -332,20 +356,18 @@
 			> $@ || (rm $@ && false)
 
 include/isl/cpp.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
-		cpp/cpp.h.top cpp/cpp.h.pre cpp/cpp.h.bot
-	$(MKDIR_P) "include/isl/cpp" && \
-	(cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h \
-	    $(srcdir)/cpp/cpp.h.pre && \
+		cpp/cpp.h.top cpp/cpp.h.bot
+	$(MKDIR_P) "include/isl" && \
+	(cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h && \
 		interface/extract_interface$(BUILD_EXEEXT) --language=cpp \
 			$(includes) $(srcdir)/all.h && \
 		cat $(srcdir)/cpp/cpp.h.bot) \
 			> $@ || (rm $@ && false)
 
 include/isl/cpp-checked.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
-		cpp/cpp-checked.h.top \
-		cpp/cpp-checked.h.pre cpp/cpp-checked.h.bot
-	(cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h \
-	    $(srcdir)/cpp/cpp-checked.h.pre && \
+		cpp/cpp-checked.h.top cpp/cpp-checked.h.bot
+	$(MKDIR_P) "include/isl" && \
+	(cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h && \
 		interface/extract_interface$(BUILD_EXEEXT) \
 			--language=cpp-checked \
 			$(includes) $(srcdir)/all.h && \
@@ -357,12 +379,23 @@
 		libdep.a \
 		cpp/cpp-checked-conversion.h.top \
 		cpp/cpp-checked-conversion.h.bot
+	$(MKDIR_P) "include/isl" && \
 	(cat $(srcdir)/cpp/cpp-checked-conversion.h.top && \
 		interface/extract_interface$(BUILD_EXEEXT) \
 			--language=cpp-checked-conversion \
 			$(includes) $(srcdir)/all.h && \
 		cat $(srcdir)/cpp/cpp-checked-conversion.h.bot) \
 			> $@ || (rm $@ && false)
+
+include/isl/typed_cpp.h: interface/extract_interface$(BUILD_EXEEXT) \
+		libdep.a cpp/typed_cpp.h.top cpp/typed_cpp.h.bot
+	$(MKDIR_P) "include/isl" && \
+	(cat $(srcdir)/cpp/typed_cpp.h.top && \
+		interface/extract_interface$(BUILD_EXEEXT) \
+			--language=template-cpp \
+			$(includes) $(srcdir)/all.h && \
+		cat $(srcdir)/cpp/typed_cpp.h.bot) \
+			> $@ || (rm $@ && false)
 endif
 endif
 
@@ -435,7 +468,8 @@
     CPP_INTERFACES = \
 	include/isl/cpp.h \
 	include/isl/cpp-checked.h \
-	include/isl/cpp-checked-conversion.h
+	include/isl/cpp-checked-conversion.h \
+	include/isl/typed_cpp.h
 endif
 endif
 BUILT_SOURCES = gitversion.h $(CPP_INTERFACES)
@@ -478,6 +512,7 @@
 	isl_list_macro.h \
 	isl_list_templ.c \
 	isl_list_templ.h \
+	isl_list_read_templ.c \
 	isl_map_bound_templ.c \
 	isl_map_lexopt_templ.c \
 	isl_maybe_ast_graft_list.h \
@@ -524,6 +559,7 @@
 	isl_multi_unbind_params_templ.c \
 	isl_multi_union_add_templ.c \
 	isl_multi_zero_templ.c \
+	isl_multi_zero_space_templ.c \
 	isl_opt_mpa_templ.c \
 	opt_type.h \
 	print_templ.c \
@@ -549,6 +585,7 @@
 	isl_pw_neg_templ.c \
 	isl_pw_opt_templ.c \
 	isl_pw_pullback_templ.c \
+	isl_pw_range_tuple_id_templ.c \
 	isl_pw_sub_templ.c \
 	isl_pw_union_opt.c \
 	read_in_string_templ.c \
@@ -593,6 +630,7 @@
 	cpp \
 	python \
 	isl_test_cpp-generic.cc \
+	isl_test_cpp_failed.sh \
 	isl_test_python.py \
 	test_inputs
 
diff --git a/lib/External/isl/Makefile.in b/lib/External/isl/Makefile.in
index 0b72eb3..0abf9f2 100644
--- a/lib/External/isl/Makefile.in
+++ b/lib/External/isl/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -95,17 +95,19 @@
 noinst_PROGRAMS = isl_test$(EXEEXT) isl_polyhedron_sample$(EXEEXT) \
 	isl_pip$(EXEEXT) isl_polyhedron_minimize$(EXEEXT) \
 	isl_polytope_scan$(EXEEXT) \
-	isl_polyhedron_detect_equalities$(EXEEXT) isl_cat$(EXEEXT) \
-	isl_closure$(EXEEXT) isl_bound$(EXEEXT) isl_schedule$(EXEEXT) \
-	isl_codegen$(EXEEXT) isl_test_int$(EXEEXT) isl_flow$(EXEEXT) \
-	isl_flow_cmp$(EXEEXT) isl_schedule_cmp$(EXEEXT) \
-	$(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
+	isl_polyhedron_detect_equalities$(EXEEXT) \
+	isl_polyhedron_remove_redundant_equalities$(EXEEXT) \
+	isl_cat$(EXEEXT) isl_closure$(EXEEXT) isl_bound$(EXEEXT) \
+	isl_schedule$(EXEEXT) isl_codegen$(EXEEXT) \
+	isl_test_int$(EXEEXT) isl_flow$(EXEEXT) isl_flow_cmp$(EXEEXT) \
+	isl_schedule_cmp$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
+	$(am__EXEEXT_3)
 TESTS = isl_test$(EXEEXT) codegen_test.sh pip_test.sh bound_test.sh \
 	isl_test_int$(EXEEXT) flow_test.sh schedule_test.sh \
-	$(am__EXEEXT_1) $(am__EXEEXT_2) $(am__append_5) \
+	$(am__EXEEXT_4) $(am__EXEEXT_2) $(am__append_5) \
 	$(am__EXEEXT_3)
-@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_1 = isl_test_cpp
-@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_2 = isl_test_cpp
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_1 = isl_test2 isl_test_cpp
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__append_2 = isl_test2 isl_test_cpp isl_test_cpp_failed.sh
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__append_3 = isl_test_cpp-checked isl_test_cpp-checked-conversion
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__append_4 = isl_test_cpp-checked isl_test_cpp-checked-conversion
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE@am__append_5 = isl_test_python.py
@@ -116,6 +118,7 @@
 @IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_TRUE@	isl_val_sioimath.c
 
 @IMATH_FOR_MP_TRUE@@SMALL_INT_OPT_FALSE@am__append_9 = isl_val_imath.c
+EXTRA_PROGRAMS = isl_test_cpp_failed$(EXEEXT)
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
@@ -152,6 +155,7 @@
 	pip_test.sh flow_test.sh schedule_test.sh
 CONFIG_CLEAN_VPATH_FILES =
 @HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_1 =  \
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test2$(EXEEXT) \
 @HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp$(EXEEXT)
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_2 = isl_test_cpp-checked$(EXEEXT) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp-checked-conversion$(EXEEXT)
@@ -337,6 +341,11 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(AM_CFLAGS) $(CFLAGS) $(isl_polyhedron_minimize_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am_isl_polyhedron_remove_redundant_equalities_OBJECTS =  \
+	polyhedron_remove_redundant_equalities.$(OBJEXT)
+isl_polyhedron_remove_redundant_equalities_OBJECTS =  \
+	$(am_isl_polyhedron_remove_redundant_equalities_OBJECTS)
+isl_polyhedron_remove_redundant_equalities_DEPENDENCIES = libisl.la
 am_isl_polyhedron_sample_OBJECTS = polyhedron_sample.$(OBJEXT)
 isl_polyhedron_sample_OBJECTS = $(am_isl_polyhedron_sample_OBJECTS)
 isl_polyhedron_sample_DEPENDENCIES = libisl.la
@@ -362,7 +371,13 @@
 isl_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(isl_test_LDFLAGS) $(LDFLAGS) -o $@
-am_isl_test_cpp_OBJECTS = isl_test_cpp.$(OBJEXT)
+am_isl_test2_OBJECTS = isl_test2.$(OBJEXT)
+isl_test2_OBJECTS = $(am_isl_test2_OBJECTS)
+isl_test2_DEPENDENCIES = libisl.la
+isl_test2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(isl_test2_LDFLAGS) $(LDFLAGS) -o $@
+am_isl_test_cpp_OBJECTS = isl_test_cpp-isl_test_cpp.$(OBJEXT)
 isl_test_cpp_OBJECTS = $(am_isl_test_cpp_OBJECTS)
 isl_test_cpp_DEPENDENCIES = libisl.la
 isl_test_cpp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -384,6 +399,14 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
 	$(AM_CXXFLAGS) $(CXXFLAGS) \
 	$(isl_test_cpp_checked_conversion_LDFLAGS) $(LDFLAGS) -o $@
+am_isl_test_cpp_failed_OBJECTS =  \
+	isl_test_cpp_failed-isl_test_cpp.$(OBJEXT)
+isl_test_cpp_failed_OBJECTS = $(am_isl_test_cpp_failed_OBJECTS)
+isl_test_cpp_failed_DEPENDENCIES = libisl.la
+isl_test_cpp_failed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(isl_test_cpp_failed_LDFLAGS) \
+	$(LDFLAGS) -o $@
 isl_test_imath_SOURCES = isl_test_imath.c
 isl_test_imath_OBJECTS = isl_test_imath.$(OBJEXT)
 @IMATH_FOR_MP_TRUE@isl_test_imath_DEPENDENCIES = libisl.la
@@ -458,10 +481,12 @@
 	./$(DEPDIR)/isl_stream.Plo ./$(DEPDIR)/isl_stride.Plo \
 	./$(DEPDIR)/isl_tab.Plo ./$(DEPDIR)/isl_tab_pip.Plo \
 	./$(DEPDIR)/isl_tarjan.Plo ./$(DEPDIR)/isl_test.Po \
+	./$(DEPDIR)/isl_test2.Po \
 	./$(DEPDIR)/isl_test_cpp-checked-conversion.Po \
 	./$(DEPDIR)/isl_test_cpp-checked.Po \
-	./$(DEPDIR)/isl_test_cpp.Po ./$(DEPDIR)/isl_test_imath.Po \
-	./$(DEPDIR)/isl_test_int.Po \
+	./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po \
+	./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po \
+	./$(DEPDIR)/isl_test_imath.Po ./$(DEPDIR)/isl_test_int.Po \
 	./$(DEPDIR)/isl_transitive_closure.Plo \
 	./$(DEPDIR)/isl_union_map.Plo ./$(DEPDIR)/isl_val.Plo \
 	./$(DEPDIR)/isl_val_gmp.Plo ./$(DEPDIR)/isl_val_imath.Plo \
@@ -470,6 +495,7 @@
 	./$(DEPDIR)/mp_get_memory_functions.Plo ./$(DEPDIR)/pip.Po \
 	./$(DEPDIR)/polyhedron_detect_equalities.Po \
 	./$(DEPDIR)/polyhedron_minimize.Po \
+	./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po \
 	./$(DEPDIR)/polyhedron_sample.Po ./$(DEPDIR)/polytope_scan.Po \
 	./$(DEPDIR)/print.Plo ./$(DEPDIR)/schedule.Po \
 	./$(DEPDIR)/schedule_cmp.Po \
@@ -518,22 +544,26 @@
 	$(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \
 	$(isl_polyhedron_detect_equalities_SOURCES) \
 	$(isl_polyhedron_minimize_SOURCES) \
+	$(isl_polyhedron_remove_redundant_equalities_SOURCES) \
 	$(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \
 	$(isl_schedule_SOURCES) $(isl_schedule_cmp_SOURCES) isl_test.c \
-	$(isl_test_cpp_SOURCES) $(isl_test_cpp_checked_SOURCES) \
-	$(isl_test_cpp_checked_conversion_SOURCES) isl_test_imath.c \
-	isl_test_int.c
+	$(isl_test2_SOURCES) $(isl_test_cpp_SOURCES) \
+	$(isl_test_cpp_checked_SOURCES) \
+	$(isl_test_cpp_checked_conversion_SOURCES) \
+	$(isl_test_cpp_failed_SOURCES) isl_test_imath.c isl_test_int.c
 DIST_SOURCES = $(libdep_a_SOURCES) $(am__libisl_la_SOURCES_DIST) \
 	$(isl_bound_SOURCES) $(isl_cat_SOURCES) $(isl_closure_SOURCES) \
 	$(isl_codegen_SOURCES) $(isl_flow_SOURCES) \
 	$(isl_flow_cmp_SOURCES) $(isl_pip_SOURCES) \
 	$(isl_polyhedron_detect_equalities_SOURCES) \
 	$(isl_polyhedron_minimize_SOURCES) \
+	$(isl_polyhedron_remove_redundant_equalities_SOURCES) \
 	$(isl_polyhedron_sample_SOURCES) $(isl_polytope_scan_SOURCES) \
 	$(isl_schedule_SOURCES) $(isl_schedule_cmp_SOURCES) isl_test.c \
-	$(isl_test_cpp_SOURCES) $(isl_test_cpp_checked_SOURCES) \
-	$(isl_test_cpp_checked_conversion_SOURCES) isl_test_imath.c \
-	isl_test_int.c
+	$(isl_test2_SOURCES) $(isl_test_cpp_SOURCES) \
+	$(isl_test_cpp_checked_SOURCES) \
+	$(isl_test_cpp_checked_conversion_SOURCES) \
+	$(isl_test_cpp_failed_SOURCES) isl_test_imath.c isl_test_int.c
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
 	install-data-recursive install-dvi-recursive \
@@ -551,7 +581,8 @@
 am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
 py_compile = $(top_srcdir)/py-compile
 DATA = $(pkgconfig_DATA)
-am__pkginclude_HEADERS_DIST = include/isl/cpp.h include/isl/val_gmp.h \
+am__pkginclude_HEADERS_DIST = include/isl/cpp.h \
+	include/isl/typed_cpp.h include/isl/val_gmp.h \
 	include/isl/aff.h include/isl/aff_type.h include/isl/arg.h \
 	include/isl/ast.h include/isl/ast_type.h \
 	include/isl/ast_build.h include/isl/constraint.h \
@@ -588,8 +619,8 @@
 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
 	cscope check recheck distdir distdir-am dist dist-all \
 	distcheck
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-	$(LISP)isl_config.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+	isl_config.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -764,7 +795,12 @@
   bases='$(TEST_LOGS)'; \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
 RECHECK_LOGS = $(TEST_LOGS)
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@am__EXEEXT_4 =  \
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test2$(EXEEXT) \
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp$(EXEEXT) \
+@HAVE_CPP_ISL_H_TRUE@@HAVE_CXX11_TRUE@	isl_test_cpp_failed.sh
 TEST_SUITE_LOG = test-suite.log
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
@@ -827,6 +863,8 @@
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -977,7 +1015,6 @@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -994,7 +1031,7 @@
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = nostdinc subdir-objects
 lib_LTLIBRARIES = libisl.la
-@HAVE_CPP_ISL_H_TRUE@CPP_H = include/isl/cpp.h
+@HAVE_CPP_ISL_H_TRUE@CPP_H = include/isl/cpp.h include/isl/typed_cpp.h
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@@HAVE_PYTHON_TRUE@noinst_PYTHON = interface/isl.py
 TEST_EXTENSIONS = .py
 AM_TESTS_ENVIRONMENT = \
@@ -1159,6 +1196,12 @@
 
 isl_test_LDFLAGS = @MP_LDFLAGS@
 isl_test_LDADD = libisl.la @MP_LIBS@
+isl_test2_SOURCES = \
+	isl_test2.cc \
+	include/isl/cpp.h
+
+isl_test2_LDFLAGS = @MP_LDFLAGS@
+isl_test2_LDADD = libisl.la @MP_LIBS@
 isl_test_int_LDFLAGS = @MP_LDFLAGS@
 isl_test_int_LDADD = libisl.la @MP_LIBS@
 @IMATH_FOR_MP_TRUE@isl_test_imath_LDFLAGS = @MP_LDFLAGS@
@@ -1215,6 +1258,10 @@
 isl_polyhedron_detect_equalities_SOURCES = \
 	polyhedron_detect_equalities.c
 
+isl_polyhedron_remove_redundant_equalities_LDADD = libisl.la
+isl_polyhedron_remove_redundant_equalities_SOURCES = \
+	polyhedron_remove_redundant_equalities.c
+
 isl_cat_LDADD = libisl.la
 isl_cat_SOURCES = \
 	cat.c
@@ -1223,12 +1270,20 @@
 isl_closure_SOURCES = \
 	closure.c
 
+isl_test_cpp_CPPFLAGS = $(AM_CPPFLAGS) -UCOMPILE_ERROR
 isl_test_cpp_SOURCES = \
 	isl_test_cpp.cc \
 	include/isl/cpp.h
 
 isl_test_cpp_LDFLAGS = @MP_LDFLAGS@
 isl_test_cpp_LDADD = libisl.la @MP_LIBS@
+isl_test_cpp_failed_CPPFLAGS = $(AM_CPPFLAGS) -DCOMPILE_ERROR
+isl_test_cpp_failed_SOURCES = \
+	isl_test_cpp.cc \
+	include/isl/cpp.h
+
+isl_test_cpp_failed_LDFLAGS = @MP_LDFLAGS@
+isl_test_cpp_failed_LDADD = libisl.la @MP_LIBS@
 isl_test_cpp_checked_SOURCES = \
 	isl_test_cpp-checked.cc \
 	include/isl/cpp-checked.h
@@ -1314,7 +1369,8 @@
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@CPP_INTERFACES = \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp.h \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked.h \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked-conversion.h
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/cpp-checked-conversion.h \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	include/isl/typed_cpp.h
 
 BUILT_SOURCES = gitversion.h $(CPP_INTERFACES)
 CLEANFILES = \
@@ -1356,6 +1412,7 @@
 	isl_list_macro.h \
 	isl_list_templ.c \
 	isl_list_templ.h \
+	isl_list_read_templ.c \
 	isl_map_bound_templ.c \
 	isl_map_lexopt_templ.c \
 	isl_maybe_ast_graft_list.h \
@@ -1402,6 +1459,7 @@
 	isl_multi_unbind_params_templ.c \
 	isl_multi_union_add_templ.c \
 	isl_multi_zero_templ.c \
+	isl_multi_zero_space_templ.c \
 	isl_opt_mpa_templ.c \
 	opt_type.h \
 	print_templ.c \
@@ -1427,6 +1485,7 @@
 	isl_pw_neg_templ.c \
 	isl_pw_opt_templ.c \
 	isl_pw_pullback_templ.c \
+	isl_pw_range_tuple_id_templ.c \
 	isl_pw_sub_templ.c \
 	isl_pw_union_opt.c \
 	read_in_string_templ.c \
@@ -1471,6 +1530,7 @@
 	cpp \
 	python \
 	isl_test_cpp-generic.cc \
+	isl_test_cpp_failed.sh \
 	isl_test_python.py \
 	test_inputs
 
@@ -1645,6 +1705,10 @@
 	@rm -f isl_polyhedron_minimize$(EXEEXT)
 	$(AM_V_CCLD)$(isl_polyhedron_minimize_LINK) $(isl_polyhedron_minimize_OBJECTS) $(isl_polyhedron_minimize_LDADD) $(LIBS)
 
+isl_polyhedron_remove_redundant_equalities$(EXEEXT): $(isl_polyhedron_remove_redundant_equalities_OBJECTS) $(isl_polyhedron_remove_redundant_equalities_DEPENDENCIES) $(EXTRA_isl_polyhedron_remove_redundant_equalities_DEPENDENCIES) 
+	@rm -f isl_polyhedron_remove_redundant_equalities$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(isl_polyhedron_remove_redundant_equalities_OBJECTS) $(isl_polyhedron_remove_redundant_equalities_LDADD) $(LIBS)
+
 isl_polyhedron_sample$(EXEEXT): $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_DEPENDENCIES) $(EXTRA_isl_polyhedron_sample_DEPENDENCIES) 
 	@rm -f isl_polyhedron_sample$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(isl_polyhedron_sample_OBJECTS) $(isl_polyhedron_sample_LDADD) $(LIBS)
@@ -1665,6 +1729,10 @@
 	@rm -f isl_test$(EXEEXT)
 	$(AM_V_CCLD)$(isl_test_LINK) $(isl_test_OBJECTS) $(isl_test_LDADD) $(LIBS)
 
+isl_test2$(EXEEXT): $(isl_test2_OBJECTS) $(isl_test2_DEPENDENCIES) $(EXTRA_isl_test2_DEPENDENCIES) 
+	@rm -f isl_test2$(EXEEXT)
+	$(AM_V_CXXLD)$(isl_test2_LINK) $(isl_test2_OBJECTS) $(isl_test2_LDADD) $(LIBS)
+
 isl_test_cpp$(EXEEXT): $(isl_test_cpp_OBJECTS) $(isl_test_cpp_DEPENDENCIES) $(EXTRA_isl_test_cpp_DEPENDENCIES) 
 	@rm -f isl_test_cpp$(EXEEXT)
 	$(AM_V_CXXLD)$(isl_test_cpp_LINK) $(isl_test_cpp_OBJECTS) $(isl_test_cpp_LDADD) $(LIBS)
@@ -1677,6 +1745,10 @@
 	@rm -f isl_test_cpp-checked-conversion$(EXEEXT)
 	$(AM_V_CXXLD)$(isl_test_cpp_checked_conversion_LINK) $(isl_test_cpp_checked_conversion_OBJECTS) $(isl_test_cpp_checked_conversion_LDADD) $(LIBS)
 
+isl_test_cpp_failed$(EXEEXT): $(isl_test_cpp_failed_OBJECTS) $(isl_test_cpp_failed_DEPENDENCIES) $(EXTRA_isl_test_cpp_failed_DEPENDENCIES) 
+	@rm -f isl_test_cpp_failed$(EXEEXT)
+	$(AM_V_CXXLD)$(isl_test_cpp_failed_LINK) $(isl_test_cpp_failed_OBJECTS) $(isl_test_cpp_failed_LDADD) $(LIBS)
+
 isl_test_imath$(EXEEXT): $(isl_test_imath_OBJECTS) $(isl_test_imath_DEPENDENCIES) $(EXTRA_isl_test_imath_DEPENDENCIES) 
 	@rm -f isl_test_imath$(EXEEXT)
 	$(AM_V_CCLD)$(isl_test_imath_LINK) $(isl_test_imath_OBJECTS) $(isl_test_imath_LDADD) $(LIBS)
@@ -1774,9 +1846,11 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test2.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked-conversion.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-checked.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_imath.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_test_int.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_transitive_closure.Plo@am__quote@ # am--include-marker
@@ -1792,6 +1866,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pip.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_detect_equalities.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_minimize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedron_sample.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polytope_scan.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ # am--include-marker
@@ -1855,6 +1930,34 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
+isl_test_cpp-isl_test_cpp.o: isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp-isl_test_cpp.o -MD -MP -MF $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo -c -o isl_test_cpp-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc
+
+isl_test_cpp-isl_test_cpp.obj: isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp-isl_test_cpp.obj -MD -MP -MF $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo -c -o isl_test_cpp-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp-isl_test_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi`
+
+isl_test_cpp_failed-isl_test_cpp.o: isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp_failed-isl_test_cpp.o -MD -MP -MF $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo -c -o isl_test_cpp_failed-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp_failed-isl_test_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp_failed-isl_test_cpp.o `test -f 'isl_test_cpp.cc' || echo '$(srcdir)/'`isl_test_cpp.cc
+
+isl_test_cpp_failed-isl_test_cpp.obj: isl_test_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT isl_test_cpp_failed-isl_test_cpp.obj -MD -MP -MF $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo -c -o isl_test_cpp_failed-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Tpo $(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='isl_test_cpp.cc' object='isl_test_cpp_failed-isl_test_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(isl_test_cpp_failed_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o isl_test_cpp_failed-isl_test_cpp.obj `if test -f 'isl_test_cpp.cc'; then $(CYGPATH_W) 'isl_test_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/isl_test_cpp.cc'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -2141,7 +2244,7 @@
 	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
 	fi;								\
 	echo "$${col}$$br$${std}"; 					\
-	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}";	\
 	echo "$${col}$$br$${std}"; 					\
 	create_testsuite_report --maybe-color;				\
 	echo "$$col$$br$$std";						\
@@ -2224,6 +2327,13 @@
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+isl_test2.log: isl_test2$(EXEEXT)
+	@p='isl_test2$(EXEEXT)'; \
+	b='isl_test2'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 isl_test_cpp.log: isl_test_cpp$(EXEEXT)
 	@p='isl_test_cpp$(EXEEXT)'; \
 	b='isl_test_cpp'; \
@@ -2231,6 +2341,13 @@
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+isl_test_cpp_failed.sh.log: isl_test_cpp_failed.sh
+	@p='isl_test_cpp_failed.sh'; \
+	b='isl_test_cpp_failed.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 isl_test_cpp-checked.log: isl_test_cpp-checked$(EXEEXT)
 	@p='isl_test_cpp-checked$(EXEEXT)'; \
 	b='isl_test_cpp-checked'; \
@@ -2353,6 +2470,10 @@
 	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__post_remove_distdir)
 
+dist-zstd: distdir
+	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+	$(am__post_remove_distdir)
+
 dist-tarZ: distdir
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
@@ -2395,6 +2516,8 @@
 	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
+	*.tar.zst*) \
+	  zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
@@ -2410,7 +2533,7 @@
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
 	    --srcdir=../.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
-	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
 	  && $(MAKE) $(AM_MAKEFLAGS) install \
 	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -2474,7 +2597,8 @@
 	done
 install: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) install-recursive
-install-exec: install-exec-recursive
+install-exec: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-recursive
 install-data: install-data-recursive
 uninstall: uninstall-recursive
 
@@ -2599,9 +2723,11 @@
 	-rm -f ./$(DEPDIR)/isl_tab_pip.Plo
 	-rm -f ./$(DEPDIR)/isl_tarjan.Plo
 	-rm -f ./$(DEPDIR)/isl_test.Po
+	-rm -f ./$(DEPDIR)/isl_test2.Po
 	-rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po
 	-rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po
-	-rm -f ./$(DEPDIR)/isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po
 	-rm -f ./$(DEPDIR)/isl_test_imath.Po
 	-rm -f ./$(DEPDIR)/isl_test_int.Po
 	-rm -f ./$(DEPDIR)/isl_transitive_closure.Plo
@@ -2617,6 +2743,7 @@
 	-rm -f ./$(DEPDIR)/pip.Po
 	-rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po
 	-rm -f ./$(DEPDIR)/polyhedron_minimize.Po
+	-rm -f ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po
 	-rm -f ./$(DEPDIR)/polyhedron_sample.Po
 	-rm -f ./$(DEPDIR)/polytope_scan.Po
 	-rm -f ./$(DEPDIR)/print.Plo
@@ -2754,9 +2881,11 @@
 	-rm -f ./$(DEPDIR)/isl_tab_pip.Plo
 	-rm -f ./$(DEPDIR)/isl_tarjan.Plo
 	-rm -f ./$(DEPDIR)/isl_test.Po
+	-rm -f ./$(DEPDIR)/isl_test2.Po
 	-rm -f ./$(DEPDIR)/isl_test_cpp-checked-conversion.Po
 	-rm -f ./$(DEPDIR)/isl_test_cpp-checked.Po
-	-rm -f ./$(DEPDIR)/isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp-isl_test_cpp.Po
+	-rm -f ./$(DEPDIR)/isl_test_cpp_failed-isl_test_cpp.Po
 	-rm -f ./$(DEPDIR)/isl_test_imath.Po
 	-rm -f ./$(DEPDIR)/isl_test_int.Po
 	-rm -f ./$(DEPDIR)/isl_transitive_closure.Plo
@@ -2772,6 +2901,7 @@
 	-rm -f ./$(DEPDIR)/pip.Po
 	-rm -f ./$(DEPDIR)/polyhedron_detect_equalities.Po
 	-rm -f ./$(DEPDIR)/polyhedron_minimize.Po
+	-rm -f ./$(DEPDIR)/polyhedron_remove_redundant_equalities.Po
 	-rm -f ./$(DEPDIR)/polyhedron_sample.Po
 	-rm -f ./$(DEPDIR)/polytope_scan.Po
 	-rm -f ./$(DEPDIR)/print.Plo
@@ -2801,7 +2931,7 @@
 	uninstall-pkgincludeHEADERS
 
 .MAKE: $(am__recursive_targets) all check check-am install install-am \
-	install-strip
+	install-exec install-strip
 
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
 	am--depfiles am--refresh check check-TESTS check-am clean \
@@ -2809,7 +2939,7 @@
 	clean-noinstLIBRARIES clean-noinstPROGRAMS cscope \
 	cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
 	dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \
-	dist-zip distcheck distclean distclean-compile \
+	dist-zip dist-zstd distcheck distclean distclean-compile \
 	distclean-generic distclean-hdr distclean-libtool \
 	distclean-tags distcleancheck distdir distuninstallcheck dvi \
 	dvi-am html html-am info info-am install install-am \
@@ -2845,20 +2975,18 @@
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
 
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/cpp.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp.h.top cpp/cpp.h.pre cpp/cpp.h.bot
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl/cpp" && \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	    $(srcdir)/cpp/cpp.h.pre && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp.h.top cpp/cpp.h.bot
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp.h.top $(srcdir)/all.h && \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		interface/extract_interface$(BUILD_EXEEXT) --language=cpp \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			$(includes) $(srcdir)/all.h && \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cat $(srcdir)/cpp/cpp.h.bot) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
 
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/cpp-checked.h: interface/extract_interface$(BUILD_EXEEXT) libdep.a \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.top \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.pre cpp/cpp-checked.h.bot
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h \
-@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	    $(srcdir)/cpp/cpp-checked.h.pre && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked.h.top cpp/cpp-checked.h.bot
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp-checked.h.top $(srcdir)/all.h && \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		interface/extract_interface$(BUILD_EXEEXT) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			--language=cpp-checked \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			$(includes) $(srcdir)/all.h && \
@@ -2870,6 +2998,7 @@
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		libdep.a \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked-conversion.h.top \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cpp/cpp-checked-conversion.h.bot
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/cpp-checked-conversion.h.top && \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		interface/extract_interface$(BUILD_EXEEXT) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			--language=cpp-checked-conversion \
@@ -2877,6 +3006,16 @@
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cat $(srcdir)/cpp/cpp-checked-conversion.h.bot) \
 @HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
 
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@include/isl/typed_cpp.h: interface/extract_interface$(BUILD_EXEEXT) \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		libdep.a cpp/typed_cpp.h.top cpp/typed_cpp.h.bot
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	$(MKDIR_P) "include/isl" && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@	(cat $(srcdir)/cpp/typed_cpp.h.top && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		interface/extract_interface$(BUILD_EXEEXT) \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			--language=template-cpp \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			$(includes) $(srcdir)/all.h && \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@		cat $(srcdir)/cpp/typed_cpp.h.bot) \
+@HAVE_CLANG_TRUE@@HAVE_CXX11_TRUE@			> $@ || (rm $@ && false)
+
 dist-hook:
 	echo @GIT_HEAD_VERSION@ > $(distdir)/GIT_HEAD_ID
 	(cd doc; make manual.pdf)
diff --git a/lib/External/isl/aclocal.m4 b/lib/External/isl/aclocal.m4
index 8600931..8791b10 100644
--- a/lib/External/isl/aclocal.m4
+++ b/lib/External/isl/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,45 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+#   AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+#   been defined and thus are available for use.  This avoids random issues
+#   where a macro isn't expanded.  Instead the configure script emits a
+#   non-fatal:
+#
+#     ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+#   It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+#   Here's an example:
+#
+#     AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+#   Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+  m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
+
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -35,7 +73,7 @@
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.3], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +89,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.3])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +148,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +179,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,7 +370,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -371,7 +409,9 @@
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -398,7 +438,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -595,7 +635,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -616,7 +656,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -637,7 +677,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -680,7 +720,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -701,12 +741,7 @@
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -719,7 +754,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -748,7 +783,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -795,7 +830,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -878,12 +913,14 @@
     m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
   else
 
-  dnl Query Python for its version number.  Getting [:3] seems to be
-  dnl the best way to do this; it's what "site.py" does in the standard
-  dnl library.
+  dnl Query Python for its version number.  Although site.py simply uses
+  dnl sys.version[:3], printing that failed with Python 3.10, since the
+  dnl trailing zero was eliminated. So now we output just the major
+  dnl and minor version numbers, as numbers. Apparently the tertiary
+  dnl version is not of interest.
 
   AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
-    [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+    [am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`])
   AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
 
   dnl Use the values of $prefix and $exec_prefix for the corresponding
@@ -1033,7 +1070,7 @@
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1052,7 +1089,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1133,7 +1170,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1193,7 +1230,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1221,7 +1258,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1240,7 +1277,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/lib/External/isl/compile b/lib/External/isl/compile
index 99e5052..23fcba0 100755
--- a/lib/External/isl/compile
+++ b/lib/External/isl/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
 	  MINGW*)
 	    file_conv=mingw
 	    ;;
-	  CYGWIN*)
+	  CYGWIN* | MSYS*)
 	    file_conv=cygwin
 	    ;;
 	  *)
@@ -67,7 +67,7 @@
 	mingw/*)
 	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
 	  ;;
-	cygwin/*)
+	cygwin/* | msys/*)
 	  file=`cygpath -m "$file" || echo "$file"`
 	  ;;
 	wine/*)
diff --git a/lib/External/isl/config.guess b/lib/External/isl/config.guess
index f50dcdb..0fc11ed 100755
--- a/lib/External/isl/config.guess
+++ b/lib/External/isl/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2018-02-24'
+timestamp='2020-11-07'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 # Please send patches to <config-patches@gnu.org>.
 
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION]
@@ -50,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,8 +84,6 @@
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
-
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
 # temporary files to be created and, as you can see below, it is a
@@ -96,41 +94,47 @@
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > "$dummy.c" ;
-	for c in cc gcc c89 c99 ; do
-	  if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
-	     CC_FOR_BUILD="$c"; break ;
-	  fi ;
-	done ;
-	if test x"$CC_FOR_BUILD" = x ; then
-	  CC_FOR_BUILD=no_compiler_found ;
-	fi
-	;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+    # prevent multiple calls if $tmp is already set
+    test "$tmp" && return 0
+    : "${TMPDIR=/tmp}"
+    # shellcheck disable=SC2039
+    { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+    dummy=$tmp/dummy
+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+	,,)    echo "int x;" > "$dummy.c"
+	       for driver in cc gcc c89 c99 ; do
+		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+		       CC_FOR_BUILD="$driver"
+		       break
+		   fi
+	       done
+	       if test x"$CC_FOR_BUILD" = x ; then
+		   CC_FOR_BUILD=no_compiler_found
+	       fi
+	       ;;
+	,,*)   CC_FOR_BUILD=$CC ;;
+	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+    esac
+}
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
+UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
+UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
+UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
 
 case "$UNAME_SYSTEM" in
 Linux|GNU|GNU/*)
@@ -138,7 +142,7 @@
 	# We could probably try harder.
 	LIBC=gnu
 
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	cat <<-EOF > "$dummy.c"
 	#include <features.h>
 	#if defined(__UCLIBC__)
@@ -146,17 +150,15 @@
 	#elif defined(__dietlibc__)
 	LIBC=dietlibc
 	#else
+	#include <stdarg.h>
+	#ifdef __DEFINED_va_list
+	LIBC=musl
+	#else
 	LIBC=gnu
 	#endif
+	#endif
 	EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
-
-	# If ldd exists, use it to detect musl libc.
-	if command -v ldd >/dev/null && \
-		ldd --version 2>&1 | grep -q ^musl
-	then
-	    LIBC=musl
-	fi
+	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
 	;;
 esac
 
@@ -175,19 +177,20 @@
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
 	    "/sbin/$sysctl" 2>/dev/null || \
 	    "/usr/sbin/$sysctl" 2>/dev/null || \
-	    echo unknown)`
+	    echo unknown))
 	case "$UNAME_MACHINE_ARCH" in
+	    aarch64eb) machine=aarch64_be-unknown ;;
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
 	    earmv*)
-		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+		arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
+		endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
 		machine="${arch}${endian}"-unknown
 		;;
 	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
@@ -199,7 +202,7 @@
 		os=netbsdelf
 		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
 		then
@@ -218,7 +221,7 @@
 	case "$UNAME_MACHINE_ARCH" in
 	    earm*)
 		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+		abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
 		;;
 	esac
 	# The OS release
@@ -231,24 +234,24 @@
 		release='-gnu'
 		;;
 	    *)
-		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "$machine-${os}${release}${abi}"
+	echo "$machine-${os}${release}${abi-}"
 	exit ;;
     *:Bitrig:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
 	exit ;;
     *:OpenBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
 	exit ;;
     *:LibertyBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
 	exit ;;
     *:MidnightBSD:*:*)
@@ -260,6 +263,9 @@
     *:SolidBSD:*:*)
 	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
 	exit ;;
+    *:OS108:*:*)
+	echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
+	exit ;;
     macppc:MirBSD:*:*)
 	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
 	exit ;;
@@ -269,26 +275,29 @@
     *:Sortix:*:*)
 	echo "$UNAME_MACHINE"-unknown-sortix
 	exit ;;
+    *:Twizzler:*:*)
+	echo "$UNAME_MACHINE"-unknown-twizzler
+	exit ;;
     *:Redox:*:*)
 	echo "$UNAME_MACHINE"-unknown-redox
 	exit ;;
     mips:OSF1:*.*)
-        echo mips-dec-osf1
-        exit ;;
+	echo mips-dec-osf1
+	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
 		;;
 	*5.*)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
 		;;
 	esac
 	# According to Compaq, /usr/sbin/psrinfo has been available on
 	# OSF/1 and Tru64 systems produced since 1995.  I hope that
 	# covers most systems running today.  This code pipes the CPU
 	# types through head -n 1, so we only detect the type of CPU 0.
-	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1)
 	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
 		UNAME_MACHINE=alpha ;;
@@ -326,7 +335,7 @@
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
+	echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
 	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 	exitcode=$?
 	trap '' 0
@@ -360,7 +369,7 @@
 	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+	if test "$( (/bin/universe) 2>/dev/null)" = att ; then
 		echo pyramid-pyramid-sysv3
 	else
 		echo pyramid-pyramid-bsd
@@ -373,28 +382,28 @@
 	echo sparc-icl-nx6
 	exit ;;
     DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
-	case `/usr/bin/uname -p` in
+	case $(/usr/bin/uname -p) in
 	    sparc) echo sparc-icl-nx7; exit ;;
 	esac ;;
     s390x:SunOS:*:*)
-	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
 	exit ;;
     sun4H:SunOS:5.*:*)
-	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
 	exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
 	echo i386-pc-auroraux"$UNAME_RELEASE"
 	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
 		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
@@ -402,30 +411,30 @@
 		SUN_ARCH=x86_64
 	    fi
 	fi
-	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
-	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:*:*)
-	case "`/usr/bin/arch -k`" in
+	case "$(/usr/bin/arch -k)" in
 	    Series*|S4*)
-		UNAME_RELEASE=`uname -v`
+		UNAME_RELEASE=$(uname -v)
 		;;
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
-	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
+	echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
 	exit ;;
     sun3*:SunOS:*:*)
 	echo m68k-sun-sunos"$UNAME_RELEASE"
 	exit ;;
     sun*:*:4.2BSD:*)
-	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
 	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
-	case "`/bin/arch`" in
+	case "$(/bin/arch)" in
 	    sun3)
 		echo m68k-sun-sunos"$UNAME_RELEASE"
 		;;
@@ -482,7 +491,7 @@
 	echo clipper-intergraph-clix"$UNAME_RELEASE"
 	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -505,8 +514,8 @@
 	}
 EOF
 	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
-	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
+	  dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
+	  SYSTEM_NAME=$("$dummy" "$dummyarg") &&
 	    { echo "$SYSTEM_NAME"; exit; }
 	echo mips-mips-riscos"$UNAME_RELEASE"
 	exit ;;
@@ -533,11 +542,11 @@
 	exit ;;
     AViiON:dgux:*:*)
 	# DG/UX returns AViiON for all architectures
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+	UNAME_PROCESSOR=$(/usr/bin/uname -p)
+	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
 	then
-	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
-	       [ "$TARGET_BINARY_INTERFACE"x = x ]
+	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+	       test "$TARGET_BINARY_INTERFACE"x = x
 	    then
 		echo m88k-dg-dgux"$UNAME_RELEASE"
 	    else
@@ -561,17 +570,17 @@
 	echo m68k-tektronix-bsd
 	exit ;;
     *:IRIX*:*:*)
-	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
+	echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
 	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
 	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+	exit ;;               # Note that: echo "'$(uname -s)'" gives 'AIX '
     i*86:AIX:*:*)
 	echo i386-ibm-aix
 	exit ;;
     ia64:AIX:*:*)
-	if [ -x /usr/bin/oslevel ] ; then
-		IBM_REV=`/usr/bin/oslevel`
+	if test -x /usr/bin/oslevel ; then
+		IBM_REV=$(/usr/bin/oslevel)
 	else
 		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
@@ -579,7 +588,7 @@
 	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 
@@ -591,7 +600,7 @@
 			exit(0);
 			}
 EOF
-		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
+		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
 		then
 			echo "$SYSTEM_NAME"
 		else
@@ -604,15 +613,15 @@
 	fi
 	exit ;;
     *:AIX:*:[4567])
-	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
 	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if test -x /usr/bin/lslpp ; then
+		IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
 	else
 		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
@@ -640,14 +649,14 @@
 	echo m68k-hp-bsd4.4
 	exit ;;
     9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
 	case "$UNAME_MACHINE" in
 	    9000/31?)            HP_ARCH=m68000 ;;
 	    9000/[34]??)         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-		if [ -x /usr/bin/getconf ]; then
-		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		if test -x /usr/bin/getconf; then
+		    sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
+		    sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
 		    case "$sc_cpu_version" in
 		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
 		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
@@ -659,8 +668,8 @@
 			esac ;;
 		    esac
 		fi
-		if [ "$HP_ARCH" = "" ]; then
-		    eval "$set_cc_for_build"
+		if test "$HP_ARCH" = ""; then
+		    set_cc_for_build
 		    sed 's/^		//' << EOF > "$dummy.c"
 
 		#define _HPUX_SOURCE
@@ -694,13 +703,13 @@
 		    exit (0);
 		}
 EOF
-		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
+		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ "$HP_ARCH" = hppa2.0w ]
+	if test "$HP_ARCH" = hppa2.0w
 	then
-	    eval "$set_cc_for_build"
+	    set_cc_for_build
 
 	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
 	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -722,11 +731,11 @@
 	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
 	exit ;;
     ia64:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
 	echo ia64-hp-hpux"$HPUX_REV"
 	exit ;;
     3050*:HI-UX:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 	#include <unistd.h>
 	int
@@ -752,7 +761,7 @@
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
 		{ echo "$SYSTEM_NAME"; exit; }
 	echo unknown-hitachi-hiuxwe2
 	exit ;;
@@ -772,7 +781,7 @@
 	echo hppa1.0-hp-osf
 	exit ;;
     i*86:OSF1:*:*)
-	if [ -x /usr/sbin/sysversion ] ; then
+	if test -x /usr/sbin/sysversion ; then
 	    echo "$UNAME_MACHINE"-unknown-osf1mk
 	else
 	    echo "$UNAME_MACHINE"-unknown-osf1
@@ -821,14 +830,14 @@
 	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+	FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
+	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+	FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
 	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+	FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
 	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -840,15 +849,26 @@
     *:BSD/OS:*:*)
 	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
 	exit ;;
+    arm:FreeBSD:*:*)
+	UNAME_PROCESSOR=$(uname -p)
+	set_cc_for_build
+	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_PCS_VFP
+	then
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+	else
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+	fi
+	exit ;;
     *:FreeBSD:*:*)
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	UNAME_PROCESSOR=$(/usr/bin/uname -p)
 	case "$UNAME_PROCESSOR" in
 	    amd64)
 		UNAME_PROCESSOR=x86_64 ;;
 	    i386)
 		UNAME_PROCESSOR=i586 ;;
 	esac
-	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
 	exit ;;
     i*:CYGWIN*:*)
 	echo "$UNAME_MACHINE"-pc-cygwin
@@ -881,21 +901,21 @@
 	echo "$UNAME_MACHINE"-pc-uwin
 	exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
+	echo x86_64-pc-cygwin
 	exit ;;
     prep*:SunOS:5.*:*)
-	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     *:GNU:*:*)
 	# the GNU system
-	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
+	echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
 	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
+	echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
 	exit ;;
-    i*86:Minix:*:*)
-	echo "$UNAME_MACHINE"-pc-minix
+    *:Minix:*:*)
+	echo "$UNAME_MACHINE"-unknown-minix
 	exit ;;
     aarch64:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -905,7 +925,7 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
 	  EV56)  UNAME_MACHINE=alphaev56 ;;
 	  PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -922,7 +942,7 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     arm*:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 	    | grep -q __ARM_EABI__
 	then
@@ -971,23 +991,51 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
+	IS_GLIBC=0
+	test x"${LIBC}" = xgnu && IS_GLIBC=1
 	sed 's/^	//' << EOF > "$dummy.c"
 	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
+	#undef mips
+	#undef mipsel
+	#undef mips64
+	#undef mips64el
+	#if ${IS_GLIBC} && defined(_ABI64)
+	LIBCABI=gnuabi64
+	#else
+	#if ${IS_GLIBC} && defined(_ABIN32)
+	LIBCABI=gnuabin32
+	#else
+	LIBCABI=${LIBC}
+	#endif
+	#endif
+
+	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa64r6
+	#else
+	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa32r6
+	#else
+	#if defined(__mips64)
+	CPU=mips64
+	#else
+	CPU=mips
+	#endif
+	#endif
+	#endif
+
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
+	MIPS_ENDIAN=el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
+	MIPS_ENDIAN=
 	#else
-	CPU=
+	MIPS_ENDIAN=
 	#endif
 	#endif
 EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
-	test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
+	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
 	;;
     mips64el:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1006,7 +1054,7 @@
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
-	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
 	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
 	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
 	  *)    echo hppa-unknown-linux-"$LIBC" ;;
@@ -1046,11 +1094,17 @@
 	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
 	exit ;;
     x86_64:Linux:*:*)
-	if objdump -f /bin/sh | grep -q elf32-x86-64; then
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32
-	else
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+	set_cc_for_build
+	LIBCABI=$LIBC
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_X32 >/dev/null
+	    then
+		LIBCABI="$LIBC"x32
+	    fi
 	fi
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
 	exit ;;
     xtensa*:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1090,7 +1144,7 @@
 	echo "$UNAME_MACHINE"-pc-msdosdjgpp
 	exit ;;
     i*86:*:4.*:*)
-	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
+	UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
 		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
 	else
@@ -1099,19 +1153,19 @@
 	exit ;;
     i*86:*:5:[678]*)
 	# UnixWare 7.x, OpenUNIX and OpenServer 6.
-	case `/bin/uname -X | grep "^Machine"` in
+	case $(/bin/uname -X | grep "^Machine") in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
-	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
+	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
 	exit ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
-		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
 		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
 		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
 		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 			&& UNAME_MACHINE=i586
@@ -1161,7 +1215,7 @@
     3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
-	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	&& OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1172,7 +1226,7 @@
     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
 	OS_REL='.3'
 	test -r /etc/.relid \
-	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	    && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1205,7 +1259,7 @@
 	exit ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
-		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		UNAME_MACHINE=$( (uname -p) 2>/dev/null)
 		echo "$UNAME_MACHINE"-sni-sysv4
 	else
 		echo ns32k-sni-sysv
@@ -1239,7 +1293,7 @@
 	echo mips-sony-newsos6
 	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-	if [ -d /usr/nec ]; then
+	if test -d /usr/nec; then
 		echo mips-nec-sysv"$UNAME_RELEASE"
 	else
 		echo mips-unknown-sysv"$UNAME_RELEASE"
@@ -1287,44 +1341,48 @@
     *:Rhapsody:*:*)
 	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
 	exit ;;
+    arm64:Darwin:*:*)
+	echo aarch64-apple-darwin"$UNAME_RELEASE"
+	exit ;;
     *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	eval "$set_cc_for_build"
-	if test "$UNAME_PROCESSOR" = unknown ; then
-	    UNAME_PROCESSOR=powerpc
+	UNAME_PROCESSOR=$(uname -p)
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	if command -v xcode-select > /dev/null 2> /dev/null && \
+		! xcode-select --print-path > /dev/null 2> /dev/null ; then
+	    # Avoid executing cc if there is no toolchain installed as
+	    # cc will be a stub that puts up a graphical alert
+	    # prompting the user to install developer tools.
+	    CC_FOR_BUILD=no_compiler_found
+	else
+	    set_cc_for_build
 	fi
-	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
-		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
-		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_PPC >/dev/null
-		then
-		    UNAME_PROCESSOR=powerpc
-		fi
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
+	    fi
+	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_PPC >/dev/null
+	    then
+		UNAME_PROCESSOR=powerpc
 	    fi
 	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
+	    # uname -m returns i386 or x86_64
+	    UNAME_PROCESSOR=$UNAME_MACHINE
 	fi
 	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
 	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
-	UNAME_PROCESSOR=`uname -p`
+	UNAME_PROCESSOR=$(uname -p)
 	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
@@ -1362,6 +1420,7 @@
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
+	# shellcheck disable=SC2154
 	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
 	else
@@ -1391,10 +1450,10 @@
 	echo mips-sei-seiux"$UNAME_RELEASE"
 	exit ;;
     *:DragonFly:*:*)
-	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
 	exit ;;
     *:*VMS:*:*)
-	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	UNAME_MACHINE=$( (uname -p) 2>/dev/null)
 	case "$UNAME_MACHINE" in
 	    A*) echo alpha-dec-vms ; exit ;;
 	    I*) echo ia64-dec-vms ; exit ;;
@@ -1404,7 +1463,7 @@
 	echo i386-pc-xenix
 	exit ;;
     i*86:skyos:*:*)
-	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
+	echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
 	exit ;;
     i*86:rdos:*:*)
 	echo "$UNAME_MACHINE"-pc-rdos
@@ -1418,8 +1477,148 @@
     amd64:Isilon\ OneFS:*:*)
 	echo x86_64-unknown-onefs
 	exit ;;
+    *:Unleashed:*:*)
+	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
+	exit ;;
 esac
 
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+  "4"
+#else
+  ""
+#endif
+  ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+  struct utsname un;
+
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname un;
+  uname (&un);
+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname *un;
+  uname (&un);
+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
 echo "$0: unable to guess system type" >&2
 
 case "$UNAME_MACHINE:$UNAME_SYSTEM" in
@@ -1442,6 +1641,12 @@
   https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
   https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+EOF
+
+year=$(echo $timestamp | sed 's,-.*,,')
+# shellcheck disable=SC2003
+if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+   cat >&2 <<EOF
 
 If $0 has already been updated, send the following data and any
 information you think might be pertinent to config-patches@gnu.org to
@@ -1449,31 +1654,32 @@
 
 config.guess timestamp = $timestamp
 
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
+uname -m = $( (uname -m) 2>/dev/null || echo unknown)
+uname -r = $( (uname -r) 2>/dev/null || echo unknown)
+uname -s = $( (uname -s) 2>/dev/null || echo unknown)
+uname -v = $( (uname -v) 2>/dev/null || echo unknown)
 
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
+/bin/uname -X     = $( (/bin/uname -X) 2>/dev/null)
 
-hostinfo               = `(hostinfo) 2>/dev/null`
-/bin/universe          = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch              = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+hostinfo               = $( (hostinfo) 2>/dev/null)
+/bin/universe          = $( (/bin/universe) 2>/dev/null)
+/usr/bin/arch -k       = $( (/usr/bin/arch -k) 2>/dev/null)
+/bin/arch              = $( (/bin/arch) 2>/dev/null)
+/usr/bin/oslevel       = $( (/usr/bin/oslevel) 2>/dev/null)
+/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
 
 UNAME_MACHINE = "$UNAME_MACHINE"
 UNAME_RELEASE = "$UNAME_RELEASE"
 UNAME_SYSTEM  = "$UNAME_SYSTEM"
 UNAME_VERSION = "$UNAME_VERSION"
 EOF
+fi
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/lib/External/isl/config.sub b/lib/External/isl/config.sub
index 1d8e98b..c874b7a 100755
--- a/lib/External/isl/config.sub
+++ b/lib/External/isl/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2018-02-22'
+timestamp='2020-11-07'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@
 #	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 # It is wrong to echo any other type of specification.
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@@ -67,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -89,7 +89,7 @@
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -110,1223 +110,1167 @@
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		basic_os=$field3-$field4
 		;;
-	-bluegene*)
-		os=-cnk
+	*-*-*)
+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+		# parts
+		maybe_os=$field2-$field3
+		case $maybe_os in
+			nto-qnx* | linux-* | uclinux-uclibc* \
+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+			| storm-chaos* | os2-emx* | rtmk-nova*)
+				basic_machine=$field1
+				basic_os=$maybe_os
+				;;
+			android-linux)
+				basic_machine=$field1-unknown
+				basic_os=linux-android
+				;;
+			*)
+				basic_machine=$field1-$field2
+				basic_os=$field3
+				;;
+		esac
 		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
+	*-*)
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						basic_os=
+						;;
+					*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+				esac
+			;;
+		esac
 		;;
-	-scout)
-		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
-		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	*)
+		# Convert single-component short-hands not valid as part of
+		# multi-component configurations.
+		case $field1 in
+			386bsd)
+				basic_machine=i386-pc
+				basic_os=bsd
+				;;
+			a29khif)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			adobe68k)
+				basic_machine=m68010-adobe
+				basic_os=scout
+				;;
+			alliant)
+				basic_machine=fx80-alliant
+				basic_os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				basic_os=
+				;;
+			am29k)
+				basic_machine=a29k-none
+				basic_os=bsd
+				;;
+			amdahl)
+				basic_machine=580-amdahl
+				basic_os=sysv
+				;;
+			amiga)
+				basic_machine=m68k-unknown
+				basic_os=
+				;;
+			amigaos | amigados)
+				basic_machine=m68k-unknown
+				basic_os=amigaos
+				;;
+			amigaunix | amix)
+				basic_machine=m68k-unknown
+				basic_os=sysv4
+				;;
+			apollo68)
+				basic_machine=m68k-apollo
+				basic_os=sysv
+				;;
+			apollo68bsd)
+				basic_machine=m68k-apollo
+				basic_os=bsd
+				;;
+			aros)
+				basic_machine=i386-pc
+				basic_os=aros
+				;;
+			aux)
+				basic_machine=m68k-apple
+				basic_os=aux
+				;;
+			balance)
+				basic_machine=ns32k-sequent
+				basic_os=dynix
+				;;
+			blackfin)
+				basic_machine=bfin-unknown
+				basic_os=linux
+				;;
+			cegcc)
+				basic_machine=arm-unknown
+				basic_os=cegcc
+				;;
+			convex-c1)
+				basic_machine=c1-convex
+				basic_os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				basic_os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				basic_os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				basic_os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				basic_os=bsd
+				;;
+			cray)
+				basic_machine=j90-cray
+				basic_os=unicos
+				;;
+			crds | unos)
+				basic_machine=m68k-crds
+				basic_os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				basic_os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			delta88)
+				basic_machine=m88k-motorola
+				basic_os=sysv3
+				;;
+			dicos)
+				basic_machine=i686-pc
+				basic_os=dicos
+				;;
+			djgpp)
+				basic_machine=i586-pc
+				basic_os=msdosdjgpp
+				;;
+			ebmon29k)
+				basic_machine=a29k-amd
+				basic_os=ebmon
+				;;
+			es1800 | OSE68k | ose68k | ose | OSE)
+				basic_machine=m68k-ericsson
+				basic_os=ose
+				;;
+			gmicro)
+				basic_machine=tron-gmicro
+				basic_os=sysv
+				;;
+			go32)
+				basic_machine=i386-pc
+				basic_os=go32
+				;;
+			h8300hms)
+				basic_machine=h8300-hitachi
+				basic_os=hms
+				;;
+			h8300xray)
+				basic_machine=h8300-hitachi
+				basic_os=xray
+				;;
+			h8500hms)
+				basic_machine=h8500-hitachi
+				basic_os=hms
+				;;
+			harris)
+				basic_machine=m88k-harris
+				basic_os=sysv3
+				;;
+			hp300 | hp300hpux)
+				basic_machine=m68k-hp
+				basic_os=hpux
+				;;
+			hp300bsd)
+				basic_machine=m68k-hp
+				basic_os=bsd
+				;;
+			hppaosf)
+				basic_machine=hppa1.1-hp
+				basic_os=osf
+				;;
+			hppro)
+				basic_machine=hppa1.1-hp
+				basic_os=proelf
+				;;
+			i386mach)
+				basic_machine=i386-mach
+				basic_os=mach
+				;;
+			isi68 | isi)
+				basic_machine=m68k-isi
+				basic_os=sysv
+				;;
+			m68knommu)
+				basic_machine=m68k-unknown
+				basic_os=linux
+				;;
+			magnum | m3230)
+				basic_machine=mips-mips
+				basic_os=sysv
+				;;
+			merlin)
+				basic_machine=ns32k-utek
+				basic_os=sysv
+				;;
+			mingw64)
+				basic_machine=x86_64-pc
+				basic_os=mingw64
+				;;
+			mingw32)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			mingw32ce)
+				basic_machine=arm-unknown
+				basic_os=mingw32ce
+				;;
+			monitor)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			morphos)
+				basic_machine=powerpc-unknown
+				basic_os=morphos
+				;;
+			moxiebox)
+				basic_machine=moxie-unknown
+				basic_os=moxiebox
+				;;
+			msdos)
+				basic_machine=i386-pc
+				basic_os=msdos
+				;;
+			msys)
+				basic_machine=i686-pc
+				basic_os=msys
+				;;
+			mvs)
+				basic_machine=i370-ibm
+				basic_os=mvs
+				;;
+			nacl)
+				basic_machine=le32-unknown
+				basic_os=nacl
+				;;
+			ncr3000)
+				basic_machine=i486-ncr
+				basic_os=sysv4
+				;;
+			netbsd386)
+				basic_machine=i386-pc
+				basic_os=netbsd
+				;;
+			netwinder)
+				basic_machine=armv4l-rebel
+				basic_os=linux
+				;;
+			news | news700 | news800 | news900)
+				basic_machine=m68k-sony
+				basic_os=newsos
+				;;
+			news1000)
+				basic_machine=m68030-sony
+				basic_os=newsos
+				;;
+			necv70)
+				basic_machine=v70-nec
+				basic_os=sysv
+				;;
+			nh3000)
+				basic_machine=m68k-harris
+				basic_os=cxux
+				;;
+			nh[45]000)
+				basic_machine=m88k-harris
+				basic_os=cxux
+				;;
+			nindy960)
+				basic_machine=i960-intel
+				basic_os=nindy
+				;;
+			mon960)
+				basic_machine=i960-intel
+				basic_os=mon960
+				;;
+			nonstopux)
+				basic_machine=mips-compaq
+				basic_os=nonstopux
+				;;
+			os400)
+				basic_machine=powerpc-ibm
+				basic_os=os400
+				;;
+			OSE68000 | ose68000)
+				basic_machine=m68000-ericsson
+				basic_os=ose
+				;;
+			os68k)
+				basic_machine=m68k-none
+				basic_os=os68k
+				;;
+			paragon)
+				basic_machine=i860-intel
+				basic_os=osf
+				;;
+			parisc)
+				basic_machine=hppa-unknown
+				basic_os=linux
+				;;
+			psp)
+				basic_machine=mipsallegrexel-sony
+				basic_os=psp
+				;;
+			pw32)
+				basic_machine=i586-unknown
+				basic_os=pw32
+				;;
+			rdos | rdos64)
+				basic_machine=x86_64-pc
+				basic_os=rdos
+				;;
+			rdos32)
+				basic_machine=i386-pc
+				basic_os=rdos
+				;;
+			rom68k)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			sa29200)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			sei)
+				basic_machine=mips-sei
+				basic_os=seiux
+				;;
+			sequent)
+				basic_machine=i386-sequent
+				basic_os=
+				;;
+			sps7)
+				basic_machine=m68k-bull
+				basic_os=sysv2
+				;;
+			st2000)
+				basic_machine=m68k-tandem
+				basic_os=
+				;;
+			stratus)
+				basic_machine=i860-stratus
+				basic_os=sysv4
+				;;
+			sun2)
+				basic_machine=m68000-sun
+				basic_os=
+				;;
+			sun2os3)
+				basic_machine=m68000-sun
+				basic_os=sunos3
+				;;
+			sun2os4)
+				basic_machine=m68000-sun
+				basic_os=sunos4
+				;;
+			sun3)
+				basic_machine=m68k-sun
+				basic_os=
+				;;
+			sun3os3)
+				basic_machine=m68k-sun
+				basic_os=sunos3
+				;;
+			sun3os4)
+				basic_machine=m68k-sun
+				basic_os=sunos4
+				;;
+			sun4)
+				basic_machine=sparc-sun
+				basic_os=
+				;;
+			sun4os3)
+				basic_machine=sparc-sun
+				basic_os=sunos3
+				;;
+			sun4os4)
+				basic_machine=sparc-sun
+				basic_os=sunos4
+				;;
+			sun4sol2)
+				basic_machine=sparc-sun
+				basic_os=solaris2
+				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				basic_os=
+				;;
+			sv1)
+				basic_machine=sv1-cray
+				basic_os=unicos
+				;;
+			symmetry)
+				basic_machine=i386-sequent
+				basic_os=dynix
+				;;
+			t3e)
+				basic_machine=alphaev5-cray
+				basic_os=unicos
+				;;
+			t90)
+				basic_machine=t90-cray
+				basic_os=unicos
+				;;
+			toad1)
+				basic_machine=pdp10-xkl
+				basic_os=tops20
+				;;
+			tpf)
+				basic_machine=s390x-ibm
+				basic_os=tpf
+				;;
+			udi29k)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			ultra3)
+				basic_machine=a29k-nyu
+				basic_os=sym1
+				;;
+			v810 | necv810)
+				basic_machine=v810-nec
+				basic_os=none
+				;;
+			vaxv)
+				basic_machine=vax-dec
+				basic_os=sysv
+				;;
+			vms)
+				basic_machine=vax-dec
+				basic_os=vms
+				;;
+			vsta)
+				basic_machine=i386-pc
+				basic_os=vsta
+				;;
+			vxworks960)
+				basic_machine=i960-wrs
+				basic_os=vxworks
+				;;
+			vxworks68)
+				basic_machine=m68k-wrs
+				basic_os=vxworks
+				;;
+			vxworks29k)
+				basic_machine=a29k-wrs
+				basic_os=vxworks
+				;;
+			xbox)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			ymp)
+				basic_machine=ymp-cray
+				basic_os=unicos
+				;;
+			*)
+				basic_machine=$1
+				basic_os=
+				;;
+		esac
 		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
 		;;
-	c54x)
-		basic_machine=tic54x-unknown
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c55x)
-		basic_machine=tic55x-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c6x)
-		basic_machine=tic6x-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
+		;;
+	orion105)
+		cpu=clipper
+		vendor=highlevel
+		;;
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
+		;;
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
+		;;
+
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		cpu=m68000
+		vendor=att
+		;;
+	3b*)
+		cpu=we32k
+		vendor=att
+		;;
+	bluegene*)
+		cpu=powerpc
+		vendor=ibm
+		basic_os=cnk
+		;;
+	decsystem10* | dec10*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops10
+		;;
+	decsystem20* | dec20*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		cpu=m68k
+		vendor=motorola
+		;;
+	dpx2*)
+		cpu=m68k
+		vendor=bull
+		basic_os=sysv3
+		;;
+	encore | umax | mmax)
+		cpu=ns32k
+		vendor=encore
+		;;
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		basic_os=${basic_os:-bsd}
+		;;
+	fx2800)
+		cpu=i860
+		vendor=alliant
+		;;
+	genix)
+		cpu=ns32k
+		vendor=ns
+		;;
+	h3050r* | hiux*)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		cpu=m68000
+		vendor=hp
+		;;
+	hp9k3[2-9][0-9])
+		cpu=m68k
+		vendor=hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	i*86v32)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv32
+		;;
+	i*86v4*)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv4
+		;;
+	i*86v)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv
+		;;
+	i*86sol2)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=solaris2
+		;;
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		basic_os=${basic_os:-unicos}
+		;;
+	iris | iris4d)
+		cpu=mips
+		vendor=sgi
+		case $basic_os in
+		    irix*)
+			;;
+		    *)
+			basic_os=irix4
+			;;
+		esac
+		;;
+	miniframe)
+		cpu=m68000
+		vendor=convergent
+		;;
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		basic_os=mint
+		;;
+	news-3600 | risc-news)
+		cpu=mips
+		vendor=sony
+		basic_os=newsos
+		;;
+	next | m*-next)
+		cpu=m68k
+		vendor=next
+		case $basic_os in
+		    openstep*)
+		        ;;
+		    nextstep*)
+			;;
+		    ns2*)
+		      basic_os=nextstep2
+			;;
+		    *)
+		      basic_os=nextstep3
+			;;
+		esac
+		;;
+	np1)
+		cpu=np1
+		vendor=gould
+		;;
+	op50n-* | op60c-*)
+		cpu=hppa1.1
+		vendor=oki
+		basic_os=proelf
+		;;
+	pa-hitachi)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	pbd)
+		cpu=sparc
+		vendor=tti
+		;;
+	pbb)
+		cpu=m68k
+		vendor=tti
+		;;
+	pc532)
+		cpu=ns32k
+		vendor=pc532
+		;;
+	pn)
+		cpu=pn
+		vendor=gould
+		;;
+	power)
+		cpu=power
+		vendor=ibm
+		;;
+	ps2)
+		cpu=i386
+		vendor=ibm
+		;;
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
+		;;
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
+		;;
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		basic_os=${basic_os:-elf}
+		;;
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		basic_os=vxworks
+		;;
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
+		;;
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
+		;;
+	w65)
+		cpu=w65
+		vendor=wdc
+		;;
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		basic_os=proelf
+		;;
+	none)
+		cpu=none
+		vendor=none
 		;;
 	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
-		;;
-	ms1)
-		basic_machine=mt-unknown
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=$(echo "$basic_machine" | sed 's/-.*//')
 		;;
 
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
-		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
-		;;
-
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
 	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
-	# Recognize the various machine names and aliases which stand
-	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-pc
-		os=-bsd
-		;;
-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
-		;;
-	3b*)
-		basic_machine=we32k-att
-		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
-		;;
-	c54x-*)
-		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
-	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
-		;;
-	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
-		;;
-	delta | 3300 | motorola-3300 | motorola-delta \
-	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
-	dpx2*)
-		basic_machine=m68k-bull
-		os=-sysv3
-		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
-		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
-	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
-		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
-	fx2800)
-		basic_machine=i860-alliant
-		;;
-	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
-	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
-		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
-	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
-		;;
-	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
-		;;
-	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k78[0-9] | hp78[0-9])
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
-	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
-		;;
-	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
-		;;
-	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
-		;;
-	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
-		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
-	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
-			;;
-		    *)
-			os=-irix4
-			;;
-		esac
-		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
-	miniframe)
-		basic_machine=m68000-convergent
-		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
-	mips3*-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
-		;;
-	ms1-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
-		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
-	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
-	next | m*-next)
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
-			;;
-		    -ns2*)
-		      os=-nextstep2
-			;;
-		    *)
-		      os=-nextstep3
-			;;
-		esac
-		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
-		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
-	np1)
-		basic_machine=np1-gould
-		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
-		;;
-	nsv-tandem)
-		basic_machine=nsv-tandem
-		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
-		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
-		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	pbd)
-		basic_machine=sparc-tti
-		;;
-	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
 	pc98)
-		basic_machine=i386-pc
+		cpu=i386
+		vendor=pc
 		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		basic_os=${basic_os:-unicosmp}
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
+	c90-unknown | c90-cray)
+		vendor=cray
+		basic_os=${Basic_os:-unicos}
 		;;
-	pentium4)
-		basic_machine=i786-pc
+	fx80-unknown)
+		vendor=alliant
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	romp-unknown)
+		vendor=ibm
 		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	mmix-unknown)
+		vendor=knuth
 		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	pn)
-		basic_machine=pn-gould
+	vax-unknown)
+		vendor=dec
 		;;
-	power)	basic_machine=power-ibm
+	pdp11-unknown)
+		vendor=dec
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	we32k-unknown)
+		vendor=att
 		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
+	i370-ibm*)
+		vendor=ibm
 		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	orion-unknown)
+		vendor=highlevel
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
-		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
-		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ps2)
-		basic_machine=i386-ibm
-		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
-		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
-		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	rm[46]00)
-		basic_machine=mips-siemens
-		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
-		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
-		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
-		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
-	sequent)
-		basic_machine=i386-sequent
-		;;
-	sh5el)
-		basic_machine=sh5le-unknown
-		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
-		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
-		;;
-	spur)
-		basic_machine=spur-unknown
-		;;
-	st2000)
-		basic_machine=m68k-tandem
-		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
-		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	sun2)
-		basic_machine=m68000-sun
-		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
-		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
-		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
-		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
-		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
-		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
-		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
-		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
-		;;
-	sun4)
-		basic_machine=sparc-sun
-		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
-		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
-		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
-		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
-		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
-		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
-		;;
-	tx39)
-		basic_machine=mipstx39-unknown
-		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
-		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
-		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
-		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
-		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
-		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
-		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
-		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
-		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
-		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
-		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
-		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
-		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	x64)
-		basic_machine=x86_64-pc
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
-		;;
-	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
-		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		basic_os=${basic_os:-bosx}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	blackfin-*)
+		cpu=bfin
+		basic_os=linux
 		;;
-	romp)
-		basic_machine=romp-ibm
+	c54x-*)
+		cpu=tic54x
 		;;
-	mmix)
-		basic_machine=mmix-knuth
+	c55x-*)
+		cpu=tic55x
 		;;
-	rs6000)
-		basic_machine=rs6000-ibm
+	c6x-*)
+		cpu=tic6x
 		;;
-	vax)
-		basic_machine=vax-dec
+	e500v[12]-*)
+		cpu=powerpc
+		basic_os=${basic_os}"spe"
 		;;
-	pdp11)
-		basic_machine=pdp11-dec
+	mips3*-*)
+		cpu=mips64
 		;;
-	we32k)
-		basic_machine=we32k-att
+	ms1-*)
+		cpu=mt
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	m68knommu-*)
+		cpu=m68k
+		basic_os=linux
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	openrisc-*)
+		cpu=or32
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	parisc-*)
+		cpu=hppa
+		basic_os=linux
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
+	pentium4-*)
+		cpu=i786
+		;;
+	pc98-*)
+		cpu=i386
+		;;
+	ppc-* | ppcbe-*)
+		cpu=powerpc
+		;;
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
+		;;
+	ppc64-*)
+		cpu=powerpc64
+		;;
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
+		;;
+	sb1-*)
+		cpu=mipsisa64sb1
+		;;
+	sb1el-*)
+		cpu=mipsisa64sb1el
+		;;
+	sh5e[lb]-*)
+		cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
+		;;
+	spur-*)
+		cpu=spur
+		;;
+	strongarm-* | thumb-*)
+		cpu=arm
+		;;
+	tx39-*)
+		cpu=mipstx39
+		;;
+	tx39el-*)
+		cpu=mipstx39el
+		;;
+	x64-*)
+		cpu=x86_64
+		;;
+	xscale-* | xscalee[bl]-*)
+		cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+		;;
+	arm64-*)
+		cpu=aarch64
+		;;
+
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		basic_os=${basic_os:-elf}
+		;;
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
+		;;
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
+		;;
+	crx-*)
+		basic_os=${basic_os:-elf}
+		;;
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
+		;;
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
+		;;
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
+		;;
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
+		;;
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
+		;;
+	mipsallegrexel-sony)
+		cpu=mipsallegrexel
+		vendor=sony
+		;;
+	tile*-*)
+		basic_os=${basic_os:-linux-gnu}
+		;;
+
 	*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb \
+			| arm | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bpf | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64eb | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k | nvptx \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| picochip \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv64 \
+			| rl78 | romp | rs6000 | rx \
+			| s390 | s390x \
+			| score \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| w65 \
+			| wasm32 | wasm64 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1334,203 +1278,213 @@
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if test x$basic_os != x
 then
+
+# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+	gnu/linux*)
+		kernel=linux
+		os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+		;;
+	os2-emx)
+		kernel=os2
+		os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+		;;
+	nto-qnx*)
+		kernel=nto
+		os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+		;;
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+		;;
+	# Default OS when just kernel was specified
+	nto*)
+		kernel=nto
+		os=$(echo $basic_os | sed -e 's|nto|qnx|')
+		;;
+	linux*)
+		kernel=linux
+		os=$(echo $basic_os | sed -e 's|linux|gnu|')
+		;;
+	*)
+		kernel=
+		os=$basic_os
+		;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
 case $os in
 	# First match some system type aliases that might get confused
 	# with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
+	# solaris* is a basic system type, with this one exception.
+	auroraux)
+		os=auroraux
 		;;
-	-solaris1 | -solaris1.*)
-		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+	bluegene*)
+		os=cnk
 		;;
-	-solaris)
-		os=-solaris2
+	solaris1 | solaris1.*)
+		os=$(echo $os | sed -e 's|solaris1|sunos4|')
 		;;
-	-unixware*)
-		os=-sysv4.2uw
+	solaris)
+		os=solaris2
 		;;
-	-gnu/linux*)
-		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+	unixware*)
+		os=sysv4.2uw
 		;;
 	# es1800 is here to avoid being matched by es* (a different OS)
-	-es1800*)
-		os=-ose
+	es1800*)
+		os=ose
 		;;
-	# Now accept the basic system types.
-	# The portable systems comes first.
-	# Each alternative MUST end in a * to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
-	      | -midnightbsd*)
-	# Remember, each alternative MUST END IN *, to match a version number.
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
 		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
+	isc)
+		os=isc2.2
 		;;
-	-nto-qnx*)
+	sco6)
+		os=sco5v6
 		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+	sco5)
+		os=sco3.2v5
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sco4)
+		os=sco3.2v4
 		;;
-	-mac*)
-		os=`echo "$os" | sed -e 's|mac|macos|'`
+	sco3.2.[4-9]*)
+		os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	sco*v* | scout)
+		# Don't match below
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	sco*)
+		os=sco3.2v2
 		;;
-	-sunos5*)
-		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+	psos*)
+		os=psos
 		;;
-	-sunos6*)
-		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+	qnx*)
+		os=qnx
 		;;
-	-opened*)
-		os=-openedition
+	hiux*)
+		os=hiuxwe2
 		;;
-	-os400*)
-		os=-os400
+	lynx*178)
+		os=lynxos178
 		;;
-	-wince*)
-		os=-wince
+	lynx*5)
+		os=lynxos5
 		;;
-	-utek*)
-		os=-bsd
+	lynxos*)
+		# don't get caught up in next wildcard
 		;;
-	-dynix*)
-		os=-bsd
+	lynx*)
+		os=lynxos
 		;;
-	-acis*)
-		os=-aos
+	mac[0-9]*)
+		os=$(echo "$os" | sed -e 's|mac|macos|')
 		;;
-	-atheos*)
-		os=-atheos
+	opened*)
+		os=openedition
 		;;
-	-syllable*)
-		os=-syllable
+	os400*)
+		os=os400
 		;;
-	-386bsd)
-		os=-bsd
+	sunos5*)
+		os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	sunos6*)
+		os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
 		;;
-	-nova*)
-		os=-rtmk-nova
+	wince*)
+		os=wince
 		;;
-	-ns2)
-		os=-nextstep2
+	utek*)
+		os=bsd
 		;;
-	-nsk*)
-		os=-nsk
+	dynix*)
+		os=bsd
+		;;
+	acis*)
+		os=aos
+		;;
+	atheos*)
+		os=atheos
+		;;
+	syllable*)
+		os=syllable
+		;;
+	386bsd)
+		os=bsd
+		;;
+	ctix* | uts*)
+		os=sysv
+		;;
+	nova*)
+		os=rtmk-nova
+		;;
+	ns2)
+		os=nextstep2
 		;;
 	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
+	sinix5.*)
+		os=$(echo $os | sed -e 's|sinix|sysv|')
 		;;
-	-sinix*)
-		os=-sysv4
+	sinix*)
+		os=sysv4
 		;;
-	-tpf*)
-		os=-tpf
+	tpf*)
+		os=tpf
 		;;
-	-triton*)
-		os=-sysv3
+	triton*)
+		os=sysv3
 		;;
-	-oss*)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-svr4*)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	-svr3)
-		os=-sysv3
+	svr3)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	sysvr4)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	ose*)
+		os=ose
 		;;
-	-ose*)
-		os=-ose
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	dicos*)
+		os=dicos
 		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
-	-dicos*)
-		os=-dicos
-		;;
-	-pikeos*)
+	pikeos*)
 		# Until real need of OS specific support for
 		# particular features comes up, bare metal
 		# configurations are quite functional.
-		case $basic_machine in
+		case $cpu in
 		    arm*)
-			os=-eabi
+			os=eabi
 			;;
 		    *)
-			os=-elf
+			os=elf
 			;;
 		esac
 		;;
-	-nacl*)
-		;;
-	-ios)
-		;;
-	-none)
-		;;
 	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
-		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
-		exit 1
+		# No normalization, but not necessarily accepted, that comes below.
 		;;
 esac
+
 else
 
 # Here we handle the default operating systems that come with various machines.
@@ -1543,258 +1497,356 @@
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+kernel=
+case $cpu-$vendor in
 	score-*)
-		os=-elf
+		os=elf
 		;;
 	spu-*)
-		os=-elf
+		os=elf
 		;;
 	*-acorn)
-		os=-riscix1.2
+		os=riscix1.2
 		;;
 	arm*-rebel)
-		os=-linux
+		kernel=linux
+		os=gnu
 		;;
 	arm*-semi)
-		os=-aout
+		os=aout
 		;;
 	c4x-* | tic4x-*)
-		os=-coff
+		os=coff
 		;;
 	c8051-*)
-		os=-elf
+		os=elf
+		;;
+	clipper-intergraph)
+		os=clix
 		;;
 	hexagon-*)
-		os=-elf
+		os=elf
 		;;
 	tic54x-*)
-		os=-coff
+		os=coff
 		;;
 	tic55x-*)
-		os=-coff
+		os=coff
 		;;
 	tic6x-*)
-		os=-coff
+		os=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
-		os=-tops20
+		os=tops20
 		;;
 	pdp11-*)
-		os=-none
+		os=none
 		;;
 	*-dec | vax-*)
-		os=-ultrix4.2
+		os=ultrix4.2
 		;;
 	m68*-apollo)
-		os=-domain
+		os=domain
 		;;
 	i386-sun)
-		os=-sunos4.0.2
+		os=sunos4.0.2
 		;;
 	m68000-sun)
-		os=-sunos3
+		os=sunos3
 		;;
 	m68*-cisco)
-		os=-aout
+		os=aout
 		;;
 	mep-*)
-		os=-elf
+		os=elf
 		;;
 	mips*-cisco)
-		os=-elf
+		os=elf
 		;;
 	mips*-*)
-		os=-elf
+		os=elf
 		;;
 	or32-*)
-		os=-coff
+		os=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
+		os=sysv3
 		;;
 	sparc-* | *-sun)
-		os=-sunos4.1.1
+		os=sunos4.1.1
 		;;
 	pru-*)
-		os=-elf
+		os=elf
 		;;
 	*-be)
-		os=-beos
+		os=beos
 		;;
 	*-ibm)
-		os=-aix
+		os=aix
 		;;
 	*-knuth)
-		os=-mmixware
+		os=mmixware
 		;;
 	*-wec)
-		os=-proelf
+		os=proelf
 		;;
 	*-winbond)
-		os=-proelf
+		os=proelf
 		;;
 	*-oki)
-		os=-proelf
+		os=proelf
 		;;
 	*-hp)
-		os=-hpux
+		os=hpux
 		;;
 	*-hitachi)
-		os=-hiux
+		os=hiux
 		;;
 	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
+		os=sysv
 		;;
 	*-cbm)
-		os=-amigaos
+		os=amigaos
 		;;
 	*-dg)
-		os=-dgux
+		os=dgux
 		;;
 	*-dolphin)
-		os=-sysv3
+		os=sysv3
 		;;
 	m68k-ccur)
-		os=-rtu
+		os=rtu
 		;;
 	m88k-omron*)
-		os=-luna
+		os=luna
 		;;
 	*-next)
-		os=-nextstep
+		os=nextstep
 		;;
 	*-sequent)
-		os=-ptx
+		os=ptx
 		;;
 	*-crds)
-		os=-unos
+		os=unos
 		;;
 	*-ns)
-		os=-genix
+		os=genix
 		;;
 	i370-*)
-		os=-mvs
+		os=mvs
 		;;
 	*-gould)
-		os=-sysv
+		os=sysv
 		;;
 	*-highlevel)
-		os=-bsd
+		os=bsd
 		;;
 	*-encore)
-		os=-bsd
+		os=bsd
 		;;
 	*-sgi)
-		os=-irix
+		os=irix
 		;;
 	*-siemens)
-		os=-sysv4
+		os=sysv4
 		;;
 	*-masscomp)
-		os=-rtu
+		os=rtu
 		;;
 	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
+		os=uxpv
 		;;
 	*-rom68k)
-		os=-coff
+		os=coff
 		;;
 	*-*bug)
-		os=-coff
+		os=coff
 		;;
 	*-apple)
-		os=-macos
+		os=macos
 		;;
 	*-atari*)
-		os=-mint
+		os=mint
+		;;
+	*-wrs)
+		os=vxworks
 		;;
 	*)
-		os=-none
+		os=none
 		;;
 esac
+
 fi
 
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+	# Sometimes we do "kernel-abi", so those need to count as OSes.
+	musl* | newlib* | uclibc*)
+		;;
+	# Likewise for "kernel-libc"
+	eabi | eabihf | gnueabi | gnueabihf)
+		;;
+	# Now accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST end in a * to match a version number.
+	gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+	     | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \
+	     | hiux* | abug | nacl* | netware* | windows* \
+	     | os9* | macos* | osx* | ios* \
+	     | mpw* | magic* | mmixware* | mon960* | lnews* \
+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+	     | aos* | aros* | cloudabi* | sortix* | twizzler* \
+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+	     | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | udi* | lites* | ieee* | go32* | aux* | hcos* \
+	     | chorusrdb* | cegcc* | glidix* \
+	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | midipix* | mingw32* | mingw64* | mint* \
+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+	     | interix* | uwin* | mks* | rhapsody* | darwin* \
+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
+	     | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+	     | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+	     | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
+		;;
+	# This one is extra strict with allowed versions
+	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		;;
+	none)
+		;;
+	*)
+		echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+	linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
+		;;
+	uclinux-uclibc* )
+		;;
+	-dietlibc* | -newlib* | -musl* | -uclibc* )
+		# These are just libc implementations, not actual OSes, and thus
+		# require a kernel.
+		echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+		exit 1
+		;;
+	kfreebsd*-gnu* | kopensolaris*-gnu*)
+		;;
+	nto-qnx*)
+		;;
+	os2-emx)
+		;;
+	*-eabi* | *-gnueabi*)
+		;;
+	-*)
+		# Blank kernel with real OS is always fine.
+		;;
+	*-*)
+		echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+		exit 1
+		;;
+esac
+
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
-		case $os in
-			-riscix*)
+case $vendor in
+	unknown)
+		case $cpu-$os in
+			*-riscix*)
 				vendor=acorn
 				;;
-			-sunos*)
+			*-sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			*-cnk* | *-aix*)
 				vendor=ibm
 				;;
-			-beos*)
+			*-beos*)
 				vendor=be
 				;;
-			-hpux*)
+			*-hpux*)
 				vendor=hp
 				;;
-			-mpeix*)
+			*-mpeix*)
 				vendor=hp
 				;;
-			-hiux*)
+			*-hiux*)
 				vendor=hitachi
 				;;
-			-unos*)
+			*-unos*)
 				vendor=crds
 				;;
-			-dgux*)
+			*-dgux*)
 				vendor=dg
 				;;
-			-luna*)
+			*-luna*)
 				vendor=omron
 				;;
-			-genix*)
+			*-genix*)
 				vendor=ns
 				;;
-			-mvs* | -opened*)
+			*-clix*)
+				vendor=intergraph
+				;;
+			*-mvs* | *-opened*)
 				vendor=ibm
 				;;
-			-os400*)
+			*-os400*)
 				vendor=ibm
 				;;
-			-ptx*)
+			s390-* | s390x-*)
+				vendor=ibm
+				;;
+			*-ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
+			*-tpf*)
 				vendor=ibm
 				;;
-			-vxsim* | -vxworks* | -windiss*)
+			*-vxsim* | *-vxworks* | *-windiss*)
 				vendor=wrs
 				;;
-			-aux*)
+			*-aux*)
 				vendor=apple
 				;;
-			-hms*)
+			*-hms*)
 				vendor=hitachi
 				;;
-			-mpw* | -macos*)
+			*-mpw* | *-macos*)
 				vendor=apple
 				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
 				vendor=atari
 				;;
-			-vos*)
+			*-vos*)
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo "$basic_machine$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/lib/External/isl/configure b/lib/External/isl/configure
index 211a648..63f8c4d 100755
--- a/lib/External/isl/configure
+++ b/lib/External/isl/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for isl 0.23.
+# Generated by GNU Autoconf 2.69 for isl 0.24.
 #
 # Report bugs to <isl-development@googlegroups.com>.
 #
@@ -590,8 +590,8 @@
 # Identity of this package.
 PACKAGE_NAME='isl'
 PACKAGE_TARNAME='isl'
-PACKAGE_VERSION='0.23'
-PACKAGE_STRING='isl 0.23'
+PACKAGE_VERSION='0.24'
+PACKAGE_STRING='isl 0.24'
 PACKAGE_BUGREPORT='isl-development@googlegroups.com'
 PACKAGE_URL=''
 
@@ -790,7 +790,6 @@
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -888,7 +887,6 @@
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1141,15 +1139,6 @@
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1287,7 +1276,7 @@
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1400,7 +1389,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures isl 0.23 to adapt to many kinds of systems.
+\`configure' configures isl 0.24 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1440,7 +1429,6 @@
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1471,7 +1459,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of isl 0.23:";;
+     short | recursive ) echo "Configuration of isl 0.24:";;
    esac
   cat <<\_ACEOF
 
@@ -1602,7 +1590,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-isl configure 0.23
+isl configure 0.24
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2375,7 +2363,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by isl $as_me 0.23, which was
+It was created by isl $as_me 0.24, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2929,12 +2917,7 @@
 am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -3239,7 +3222,7 @@
 
 # Define the identity of the package.
  PACKAGE='isl'
- VERSION='0.23'
+ VERSION='0.24'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3372,7 +3355,7 @@
 AM_BACKSLASH='\'
 
 
-versioninfo=23:0:0
+versioninfo=24:0:1
 
 if test "x$prefix" != "xNONE"; then
 	prefix_wd=`cd $prefix && pwd`
@@ -8238,8 +8221,8 @@
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.6.42-b88ce-dirty'
+macro_revision='2.4.6.42'
 
 
 
@@ -9405,7 +9388,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd* | netbsdelf*-gnu)
+netbsd*)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
   else
@@ -9767,13 +9750,29 @@
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cr}
 
 
 
 
 
 
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because thats what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+
+
+
+
+
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+
 
 
 
@@ -10222,7 +10221,7 @@
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++,
+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
@@ -10268,8 +10267,11 @@
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
-    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -11488,8 +11490,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cr libconftest.a conftest.o" >&5
-      $AR cr libconftest.a conftest.o 2>&5
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -12025,8 +12027,8 @@
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
-# which needs '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC and
+# ICC, which need '.lib').
 libext=a
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -12491,12 +12493,6 @@
 	lt_prog_compiler_pic='-KPIC'
 	lt_prog_compiler_static='-static'
         ;;
-      # flang / f18. f95 an alias for gfortran or flang on Debian
-      flang* | f18* | f95*)
-	lt_prog_compiler_wl='-Wl,'
-	lt_prog_compiler_pic='-fPIC'
-	lt_prog_compiler_static='-static'
-        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -12959,23 +12955,20 @@
 
   case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
+    # Microsoft Visual C++ or Intel C++ Compiler.
     if test yes != "$GCC"; then
       with_gnu_ld=no
     fi
     ;;
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     ;;
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs=no
-    ;;
   esac
 
   ld_shlibs=yes
@@ -13134,6 +13127,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     interix[3-9]*)
@@ -13230,7 +13224,7 @@
       fi
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
@@ -13351,7 +13345,7 @@
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
 	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
@@ -13618,12 +13612,12 @@
 
     cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
+      # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       case $cc_basename in
-      cl*)
-	# Native MSVC
+      cl* | icl*)
+	# Native MSVC or ICC
 	hardcode_libdir_flag_spec=' '
 	allow_undefined_flag=unsupported
 	always_export_symbols=yes
@@ -13664,7 +13658,7 @@
           fi'
 	;;
       *)
-	# Assume MSVC wrapper
+	# Assume MSVC and ICC wrapper
 	hardcode_libdir_flag_spec=' '
 	allow_undefined_flag=unsupported
 	# Tell ltmain to make .lib files, not .a files.
@@ -13900,7 +13894,6 @@
 	if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
 	fi
-	link_all_deplibs=no
       else
 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -13922,7 +13915,7 @@
       esac
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
@@ -13989,6 +13982,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     osf3*)
@@ -14696,8 +14690,8 @@
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -14753,7 +14747,7 @@
     ;;
 
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -15037,18 +15031,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -15944,30 +15926,41 @@
 old_striplib=
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
 $as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if test -z "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-  darwin*)
-    if test -n "$STRIP"; then
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-    else
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+      fi
+      ;;
+    *)
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    fi
-    ;;
-  *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 
 
@@ -16439,7 +16432,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -16735,8 +16728,8 @@
 
       cygwin* | mingw* | pw32* | cegcc*)
 	case $GXX,$cc_basename in
-	,cl* | no,cl*)
-	  # Native MSVC
+	,cl* | no,cl* | ,icl* | no,icl*)
+	  # Native MSVC or ICC
 	  # hardcode_libdir_flag_spec is actually meaningless, as there is
 	  # no search path for DLLs.
 	  hardcode_libdir_flag_spec_CXX=' '
@@ -16866,6 +16859,7 @@
 	  emximp -o $lib $output_objdir/$libname.def'
 	old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
 	enable_shared_with_static_runtimes_CXX=yes
+	file_list_spec_CXX='@'
 	;;
 
       dgux*)
@@ -16931,7 +16925,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -16996,7 +16990,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -17335,7 +17329,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -17419,7 +17413,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -17430,7 +17424,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
 	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -17943,7 +17937,7 @@
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -18301,7 +18295,7 @@
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -18309,7 +18303,7 @@
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -18318,9 +18312,6 @@
       ;;
     esac
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs_CXX=no
-    ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -18674,8 +18665,8 @@
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -18731,7 +18722,7 @@
     ;;
 
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -19014,18 +19005,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -19566,7 +19545,7 @@
 if ${am_cv_python_version+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
+  am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[:2])"`
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
 $as_echo "$am_cv_python_version" >&6; }
@@ -20657,7 +20636,7 @@
   HAVE_CXX11_FALSE=
 fi
 
- if test "x$with_int" == "ximath-32"; then
+ if test "x$with_int" = "ximath-32"; then
   SMALL_INT_OPT_TRUE=
   SMALL_INT_OPT_FALSE='#'
 else
@@ -20665,7 +20644,7 @@
   SMALL_INT_OPT_FALSE=
 fi
 
-if test "x$with_int" == "ximath-32"; then :
+if test "x$with_int" = "ximath-32"; then :
 
 
 $as_echo "#define USE_SMALL_INT_OPT /**/" >>confdefs.h
@@ -21765,7 +21744,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by isl $as_me 0.23, which was
+This file was extended by isl $as_me 0.24, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21831,7 +21810,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-isl config.status 0.23
+isl config.status 0.24
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -22002,6 +21981,7 @@
 DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
 archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
 STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
@@ -22184,7 +22164,6 @@
 DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
-AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -23071,7 +23050,9 @@
     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
@@ -23241,8 +23222,11 @@
 # The archiver.
 AR=$lt_AR
 
+# Flags to create an archive (by configure).
+lt_ar_flags=$lt_ar_flags
+
 # Flags to create an archive.
-AR_FLAGS=$lt_AR_FLAGS
+AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
 
 # How to feed a file listing to the archiver.
 archiver_list_spec=$lt_archiver_list_spec
diff --git a/lib/External/isl/configure.ac b/lib/External/isl/configure.ac
index 0e28a8c..f082ed4 100644
--- a/lib/External/isl/configure.ac
+++ b/lib/External/isl/configure.ac
@@ -1,10 +1,10 @@
-AC_INIT([isl], [0.23], [isl-development@googlegroups.com])
+AC_INIT([isl], [0.24], [isl-development@googlegroups.com])
 AC_CONFIG_AUX_DIR([.])
 AC_CONFIG_MACRO_DIR([m4])
 AM_INIT_AUTOMAKE([foreign])
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 AC_SUBST(versioninfo)
-versioninfo=23:0:0
+versioninfo=24:0:1
 
 if test "x$prefix" != "xNONE"; then
 	prefix_wd=`cd $prefix && pwd`
@@ -83,8 +83,8 @@
 AM_CONDITIONAL(GMP_FOR_MP, test x$with_int = xgmp)
 
 AM_CONDITIONAL(HAVE_CXX11, test "x$HAVE_CXX11" = "x1")
-AM_CONDITIONAL(SMALL_INT_OPT, test "x$with_int" == "ximath-32")
-AS_IF([test "x$with_int" == "ximath-32"], [
+AM_CONDITIONAL(SMALL_INT_OPT, test "x$with_int" = "ximath-32")
+AS_IF([test "x$with_int" = "ximath-32"], [
 	AC_DEFINE([USE_SMALL_INT_OPT], [], [Use small integer optimization])
 ])
 
diff --git a/lib/External/isl/cpp/cpp-checked.h.pre b/lib/External/isl/cpp/cpp-checked.h.pre
deleted file mode 100644
index 988bedb..0000000
--- a/lib/External/isl/cpp/cpp-checked.h.pre
+++ /dev/null
@@ -1,180 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <functional>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <type_traits>
-
-namespace isl {
-namespace checked {
-
-#define ISLPP_STRINGIZE_(X) #X
-#define ISLPP_STRINGIZE(X) ISLPP_STRINGIZE_(X)
-
-#define ISLPP_ASSERT(test, message)                          \
-  do {                                                       \
-    if (test)                                                \
-      break;                                                 \
-    fputs("Assertion \"" #test "\" failed at " __FILE__      \
-      ":" ISLPP_STRINGIZE(__LINE__) "\n  " message "\n",     \
-      stderr);                                               \
-    abort();                                                 \
-  } while (0)
-
-/* Class used to check that isl::checked::boolean,
- * isl::checked::stat and isl::checked::size values are checked for errors.
- */
-struct checker {
-	bool checked = false;
-	~checker() {
-		ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state");
-	}
-};
-
-class boolean {
-private:
-  mutable std::shared_ptr<checker> check = std::make_shared<checker>();
-  isl_bool val;
-
-  friend boolean manage(isl_bool val);
-  boolean(isl_bool val): val(val) {}
-public:
-  static boolean error() {
-    return boolean(isl_bool_error);
-  }
-  boolean()
-      : val(isl_bool_error) {}
-
-  /* implicit */ boolean(bool val)
-      : val(val ? isl_bool_true : isl_bool_false) {}
-
-  isl_bool release() {
-    auto tmp = val;
-    val = isl_bool_error;
-    check->checked = true;
-    return tmp;
-  }
-
-  bool is_error() const { check->checked = true; return val == isl_bool_error; }
-  bool is_false() const { check->checked = true; return val == isl_bool_false; }
-  bool is_true() const { check->checked = true; return val == isl_bool_true; }
-
-  explicit operator bool() const {
-    ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state");
-    ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state");
-    return is_true();
-  }
-
-  boolean negate() {
-    if (val == isl_bool_true)
-      val = isl_bool_false;
-    else if (val == isl_bool_false)
-      val = isl_bool_true;
-    return *this;
-  }
-
-  boolean operator!() const {
-    return boolean(*this).negate();
-  }
-};
-
-inline boolean manage(isl_bool val) {
-  return boolean(val);
-}
-
-class ctx {
-  isl_ctx *ptr;
-public:
-  /* implicit */ ctx(isl_ctx *ctx)
-      : ptr(ctx) {}
-  isl_ctx *release() {
-    auto tmp = ptr;
-    ptr = nullptr;
-    return tmp;
-  }
-  isl_ctx *get() {
-    return ptr;
-  }
-};
-
-/* Class encapsulating an isl_stat value.
- */
-class stat {
-private:
-	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
-	isl_stat val;
-
-	friend stat manage(isl_stat val);
-	stat(isl_stat val) : val(val) {}
-public:
-	static stat ok() {
-		return stat(isl_stat_ok);
-	}
-	static stat error() {
-		return stat(isl_stat_error);
-	}
-	stat() : val(isl_stat_error) {}
-
-	isl_stat release() {
-		check->checked = true;
-		return val;
-	}
-
-	bool is_error() const {
-		check->checked = true;
-		return val == isl_stat_error;
-	}
-	bool is_ok() const {
-		check->checked = true;
-		return val == isl_stat_ok;
-	}
-};
-
-inline stat manage(isl_stat val)
-{
-	return stat(val);
-}
-
-/* Class encapsulating an isl_size value.
- */
-class size {
-private:
-	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
-	isl_size val;
-
-	friend size manage(isl_size val);
-	size(isl_size val) : val(val) {}
-public:
-	size() : val(isl_size_error) {}
-
-	isl_size release() {
-		auto tmp = val;
-		val = isl_size_error;
-		check->checked = true;
-		return tmp;
-	}
-
-	bool is_error() const {
-		check->checked = true;
-		return val == isl_size_error;
-	}
-
-	explicit operator unsigned() const {
-		ISLPP_ASSERT(check->checked,
-			    "IMPLEMENTATION ERROR: Unchecked error state");
-		ISLPP_ASSERT(!is_error(),
-			    "IMPLEMENTATION ERROR: Unhandled error state");
-		return val;
-	}
-};
-
-inline size manage(isl_size val)
-{
-	return size(val);
-}
-
-}
-} // namespace isl
diff --git a/lib/External/isl/cpp/cpp-checked.h.top b/lib/External/isl/cpp/cpp-checked.h.top
index d33ee35..be29b97 100644
--- a/lib/External/isl/cpp/cpp-checked.h.top
+++ b/lib/External/isl/cpp/cpp-checked.h.top
@@ -8,3 +8,183 @@
 #ifndef ISL_CPP_CHECKED
 #define ISL_CPP_CHECKED
 
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <functional>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <type_traits>
+
+namespace isl {
+namespace checked {
+
+#define ISLPP_STRINGIZE_(X) #X
+#define ISLPP_STRINGIZE(X) ISLPP_STRINGIZE_(X)
+
+#define ISLPP_ASSERT(test, message)                          \
+  do {                                                       \
+    if (test)                                                \
+      break;                                                 \
+    fputs("Assertion \"" #test "\" failed at " __FILE__      \
+      ":" ISLPP_STRINGIZE(__LINE__) "\n  " message "\n",     \
+      stderr);                                               \
+    abort();                                                 \
+  } while (0)
+
+/* Class used to check that isl::checked::boolean,
+ * isl::checked::stat and isl::checked::size values are checked for errors.
+ */
+struct checker {
+	bool checked = false;
+	~checker() {
+		ISLPP_ASSERT(checked, "IMPLEMENTATION ERROR: Unchecked state");
+	}
+};
+
+class boolean {
+private:
+  mutable std::shared_ptr<checker> check = std::make_shared<checker>();
+  isl_bool val;
+
+  friend boolean manage(isl_bool val);
+  boolean(isl_bool val): val(val) {}
+public:
+  static boolean error() {
+    return boolean(isl_bool_error);
+  }
+  boolean()
+      : val(isl_bool_error) {}
+
+  /* implicit */ boolean(bool val)
+      : val(val ? isl_bool_true : isl_bool_false) {}
+
+  isl_bool release() {
+    auto tmp = val;
+    val = isl_bool_error;
+    check->checked = true;
+    return tmp;
+  }
+
+  bool is_error() const { check->checked = true; return val == isl_bool_error; }
+  bool is_false() const { check->checked = true; return val == isl_bool_false; }
+  bool is_true() const { check->checked = true; return val == isl_bool_true; }
+
+  explicit operator bool() const {
+    ISLPP_ASSERT(check->checked, "IMPLEMENTATION ERROR: Unchecked error state");
+    ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state");
+    return is_true();
+  }
+
+  boolean negate() {
+    if (val == isl_bool_true)
+      val = isl_bool_false;
+    else if (val == isl_bool_false)
+      val = isl_bool_true;
+    return *this;
+  }
+
+  boolean operator!() const {
+    return boolean(*this).negate();
+  }
+};
+
+inline boolean manage(isl_bool val) {
+  return boolean(val);
+}
+
+class ctx {
+  isl_ctx *ptr;
+public:
+  /* implicit */ ctx(isl_ctx *ctx)
+      : ptr(ctx) {}
+  isl_ctx *release() {
+    auto tmp = ptr;
+    ptr = nullptr;
+    return tmp;
+  }
+  isl_ctx *get() {
+    return ptr;
+  }
+};
+
+/* Class encapsulating an isl_stat value.
+ */
+class stat {
+private:
+	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
+	isl_stat val;
+
+	friend stat manage(isl_stat val);
+	stat(isl_stat val) : val(val) {}
+public:
+	static stat ok() {
+		return stat(isl_stat_ok);
+	}
+	static stat error() {
+		return stat(isl_stat_error);
+	}
+	stat() : val(isl_stat_error) {}
+
+	isl_stat release() {
+		check->checked = true;
+		return val;
+	}
+
+	bool is_error() const {
+		check->checked = true;
+		return val == isl_stat_error;
+	}
+	bool is_ok() const {
+		check->checked = true;
+		return val == isl_stat_ok;
+	}
+};
+
+inline stat manage(isl_stat val)
+{
+	return stat(val);
+}
+
+/* Class encapsulating an isl_size value.
+ */
+class size {
+private:
+	mutable std::shared_ptr<checker> check = std::make_shared<checker>();
+	isl_size val;
+
+	friend size manage(isl_size val);
+	size(isl_size val) : val(val) {}
+public:
+	size() : val(isl_size_error) {}
+
+	isl_size release() {
+		auto tmp = val;
+		val = isl_size_error;
+		check->checked = true;
+		return tmp;
+	}
+
+	bool is_error() const {
+		check->checked = true;
+		return val == isl_size_error;
+	}
+
+	explicit operator unsigned() const {
+		ISLPP_ASSERT(check->checked,
+			    "IMPLEMENTATION ERROR: Unchecked error state");
+		ISLPP_ASSERT(!is_error(),
+			    "IMPLEMENTATION ERROR: Unhandled error state");
+		return val;
+	}
+};
+
+inline size manage(isl_size val)
+{
+	return size(val);
+}
+
+}
+} // namespace isl
+
diff --git a/lib/External/isl/cpp/cpp.h.pre b/lib/External/isl/cpp/cpp.h.pre
deleted file mode 100644
index 1ac70c5..0000000
--- a/lib/External/isl/cpp/cpp.h.pre
+++ /dev/null
@@ -1,246 +0,0 @@
-
-#include <isl/ctx.h>
-#include <isl/options.h>
-
-#include <functional>
-#include <memory>
-#include <ostream>
-#include <stdexcept>
-#include <string>
-#include <type_traits>
-
-/* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available.
- * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND.
- * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS.
- * If exceptions are not available, any error condition will result
- * in an abort.
- */
-#ifndef ISL_USE_EXCEPTIONS
-#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS)
-#define ISL_USE_EXCEPTIONS	1
-#else
-#define ISL_USE_EXCEPTIONS	0
-#endif
-#endif
-
-namespace isl {
-
-class ctx {
-	isl_ctx *ptr;
-public:
-	/* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {}
-	isl_ctx *release() {
-		auto tmp = ptr;
-		ptr = nullptr;
-		return tmp;
-	}
-	isl_ctx *get() {
-		return ptr;
-	}
-};
-
-/* Macros hiding try/catch.
- * If exceptions are not available, then no exceptions will be thrown and
- * there is nothing to catch.
- */
-#if ISL_USE_EXCEPTIONS
-#define ISL_CPP_TRY		try
-#define ISL_CPP_CATCH_ALL	catch (...)
-#else
-#define ISL_CPP_TRY		if (1)
-#define ISL_CPP_CATCH_ALL	if (0)
-#endif
-
-#if ISL_USE_EXCEPTIONS
-
-/* Class capturing isl errors.
- *
- * The what() return value is stored in a reference counted string
- * to ensure that the copy constructor and the assignment operator
- * do not throw any exceptions.
- */
-class exception : public std::exception {
-	std::shared_ptr<std::string> what_str;
-
-protected:
-	inline exception(const char *what_arg, const char *msg,
-		const char *file, int line);
-public:
-	exception() {}
-	exception(const char *what_arg) {
-		what_str = std::make_shared<std::string>(what_arg);
-	}
-	static inline void throw_error(enum isl_error error, const char *msg,
-		const char *file, int line);
-	virtual const char *what() const noexcept {
-		return what_str->c_str();
-	}
-
-	/* Default behavior on error conditions that occur inside isl calls
-	 * performed from inside the bindings.
-	 * In the case exceptions are available, isl should continue
-	 * without printing a warning since the warning message
-	 * will be included in the exception thrown from inside the bindings.
-	 */
-	static constexpr auto on_error = ISL_ON_ERROR_CONTINUE;
-	/* Wrapper for throwing an exception with the given message.
-	 */
-	static void throw_invalid(const char *msg, const char *file, int line) {
-		throw_error(isl_error_invalid, msg, file, line);
-	}
-	static inline void throw_last_error(ctx ctx);
-};
-
-/* Create an exception of a type described by "what_arg", with
- * error message "msg" in line "line" of file "file".
- *
- * Create a string holding the what() return value that
- * corresponds to what isl would have printed.
- * If no error message or no error file was set, then use "what_arg" instead.
- */
-exception::exception(const char *what_arg, const char *msg, const char *file,
-	int line)
-{
-	if (!msg || !file)
-		what_str = std::make_shared<std::string>(what_arg);
-	else
-		what_str = std::make_shared<std::string>(std::string(file) +
-				    ":" + std::to_string(line) + ": " + msg);
-}
-
-class exception_abort : public exception {
-	friend exception;
-	exception_abort(const char *msg, const char *file, int line) :
-		exception("execution aborted", msg, file, line) {}
-};
-
-class exception_alloc : public exception {
-	friend exception;
-	exception_alloc(const char *msg, const char *file, int line) :
-		exception("memory allocation failure", msg, file, line) {}
-};
-
-class exception_unknown : public exception {
-	friend exception;
-	exception_unknown(const char *msg, const char *file, int line) :
-		exception("unknown failure", msg, file, line) {}
-};
-
-class exception_internal : public exception {
-	friend exception;
-	exception_internal(const char *msg, const char *file, int line) :
-		exception("internal error", msg, file, line) {}
-};
-
-class exception_invalid : public exception {
-	friend exception;
-	exception_invalid(const char *msg, const char *file, int line) :
-		exception("invalid argument", msg, file, line) {}
-};
-
-class exception_quota : public exception {
-	friend exception;
-	exception_quota(const char *msg, const char *file, int line) :
-		exception("quota exceeded", msg, file, line) {}
-};
-
-class exception_unsupported : public exception {
-	friend exception;
-	exception_unsupported(const char *msg, const char *file, int line) :
-		exception("unsupported operation", msg, file, line) {}
-};
-
-/* Throw an exception of the class that corresponds to "error", with
- * error message "msg" in line "line" of file "file".
- *
- * isl_error_none is treated as an invalid error type.
- */
-void exception::throw_error(enum isl_error error, const char *msg,
-	const char *file, int line)
-{
-	switch (error) {
-	case isl_error_none:
-		break;
-	case isl_error_abort: throw exception_abort(msg, file, line);
-	case isl_error_alloc: throw exception_alloc(msg, file, line);
-	case isl_error_unknown: throw exception_unknown(msg, file, line);
-	case isl_error_internal: throw exception_internal(msg, file, line);
-	case isl_error_invalid: throw exception_invalid(msg, file, line);
-	case isl_error_quota: throw exception_quota(msg, file, line);
-	case isl_error_unsupported:
-				throw exception_unsupported(msg, file, line);
-	}
-
-	throw exception_invalid("invalid error type", file, line);
-}
-
-/* Throw an exception corresponding to the last error on "ctx" and
- * reset the error.
- *
- * If "ctx" is NULL or if it is not in an error state at the start,
- * then an invalid argument exception is thrown.
- */
-void exception::throw_last_error(ctx ctx)
-{
-	enum isl_error error;
-	const char *msg, *file;
-	int line;
-
-	error = isl_ctx_last_error(ctx.get());
-	msg = isl_ctx_last_error_msg(ctx.get());
-	file = isl_ctx_last_error_file(ctx.get());
-	line = isl_ctx_last_error_line(ctx.get());
-	isl_ctx_reset_error(ctx.get());
-
-	throw_error(error, msg, file, line);
-}
-
-#else
-
-#include <stdio.h>
-#include <stdlib.h>
-
-class exception {
-public:
-	/* Default behavior on error conditions that occur inside isl calls
-	 * performed from inside the bindings.
-	 * In the case exceptions are not available, isl should abort.
-	 */
-	static constexpr auto on_error = ISL_ON_ERROR_ABORT;
-	/* Wrapper for throwing an exception with the given message.
-	 * In the case exceptions are not available, print an error and abort.
-	 */
-	static void throw_invalid(const char *msg, const char *file, int line) {
-		fprintf(stderr, "%s:%d: %s\n", file, line, msg);
-		abort();
-	}
-	/* Throw an exception corresponding to the last
-	 * error on "ctx".
-	 * isl should already abort when an error condition occurs,
-	 * so this function should never be called.
-	 */
-	static void throw_last_error(ctx ctx) {
-		abort();
-	}
-};
-
-#endif
-
-/* Helper class for setting the on_error and resetting the option
- * to the original value when leaving the scope.
- */
-class options_scoped_set_on_error {
-	isl_ctx *ctx;
-	int saved_on_error;
-public:
-	options_scoped_set_on_error(class ctx ctx, int on_error) {
-		this->ctx = ctx.get();
-		saved_on_error = isl_options_get_on_error(this->ctx);
-		isl_options_set_on_error(this->ctx, on_error);
-	}
-	~options_scoped_set_on_error() {
-		isl_options_set_on_error(ctx, saved_on_error);
-	}
-};
-
-} // namespace isl
diff --git a/lib/External/isl/cpp/cpp.h.top b/lib/External/isl/cpp/cpp.h.top
index 793c0ef..15282b1 100644
--- a/lib/External/isl/cpp/cpp.h.top
+++ b/lib/External/isl/cpp/cpp.h.top
@@ -8,3 +8,249 @@
 #ifndef ISL_CPP
 #define ISL_CPP
 
+#include <isl/ctx.h>
+#include <isl/options.h>
+
+#include <functional>
+#include <memory>
+#include <ostream>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+
+/* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available.
+ * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND.
+ * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS.
+ * If exceptions are not available, any error condition will result
+ * in an abort.
+ */
+#ifndef ISL_USE_EXCEPTIONS
+#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS)
+#define ISL_USE_EXCEPTIONS	1
+#else
+#define ISL_USE_EXCEPTIONS	0
+#endif
+#endif
+
+namespace isl {
+
+class ctx {
+	isl_ctx *ptr;
+public:
+	/* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {}
+	isl_ctx *release() {
+		auto tmp = ptr;
+		ptr = nullptr;
+		return tmp;
+	}
+	isl_ctx *get() {
+		return ptr;
+	}
+};
+
+/* Macros hiding try/catch.
+ * If exceptions are not available, then no exceptions will be thrown and
+ * there is nothing to catch.
+ */
+#if ISL_USE_EXCEPTIONS
+#define ISL_CPP_TRY		try
+#define ISL_CPP_CATCH_ALL	catch (...)
+#else
+#define ISL_CPP_TRY		if (1)
+#define ISL_CPP_CATCH_ALL	if (0)
+#endif
+
+#if ISL_USE_EXCEPTIONS
+
+/* Class capturing isl errors.
+ *
+ * The what() return value is stored in a reference counted string
+ * to ensure that the copy constructor and the assignment operator
+ * do not throw any exceptions.
+ */
+class exception : public std::exception {
+	std::shared_ptr<std::string> what_str;
+
+protected:
+	inline exception(const char *what_arg, const char *msg,
+		const char *file, int line);
+public:
+	exception() {}
+	exception(const char *what_arg) {
+		what_str = std::make_shared<std::string>(what_arg);
+	}
+	static inline void throw_error(enum isl_error error, const char *msg,
+		const char *file, int line);
+	virtual const char *what() const noexcept {
+		return what_str->c_str();
+	}
+
+	/* Default behavior on error conditions that occur inside isl calls
+	 * performed from inside the bindings.
+	 * In the case exceptions are available, isl should continue
+	 * without printing a warning since the warning message
+	 * will be included in the exception thrown from inside the bindings.
+	 */
+	static constexpr auto on_error = ISL_ON_ERROR_CONTINUE;
+	/* Wrapper for throwing an exception with the given message.
+	 */
+	static void throw_invalid(const char *msg, const char *file, int line) {
+		throw_error(isl_error_invalid, msg, file, line);
+	}
+	static inline void throw_last_error(ctx ctx);
+};
+
+/* Create an exception of a type described by "what_arg", with
+ * error message "msg" in line "line" of file "file".
+ *
+ * Create a string holding the what() return value that
+ * corresponds to what isl would have printed.
+ * If no error message or no error file was set, then use "what_arg" instead.
+ */
+exception::exception(const char *what_arg, const char *msg, const char *file,
+	int line)
+{
+	if (!msg || !file)
+		what_str = std::make_shared<std::string>(what_arg);
+	else
+		what_str = std::make_shared<std::string>(std::string(file) +
+				    ":" + std::to_string(line) + ": " + msg);
+}
+
+class exception_abort : public exception {
+	friend exception;
+	exception_abort(const char *msg, const char *file, int line) :
+		exception("execution aborted", msg, file, line) {}
+};
+
+class exception_alloc : public exception {
+	friend exception;
+	exception_alloc(const char *msg, const char *file, int line) :
+		exception("memory allocation failure", msg, file, line) {}
+};
+
+class exception_unknown : public exception {
+	friend exception;
+	exception_unknown(const char *msg, const char *file, int line) :
+		exception("unknown failure", msg, file, line) {}
+};
+
+class exception_internal : public exception {
+	friend exception;
+	exception_internal(const char *msg, const char *file, int line) :
+		exception("internal error", msg, file, line) {}
+};
+
+class exception_invalid : public exception {
+	friend exception;
+	exception_invalid(const char *msg, const char *file, int line) :
+		exception("invalid argument", msg, file, line) {}
+};
+
+class exception_quota : public exception {
+	friend exception;
+	exception_quota(const char *msg, const char *file, int line) :
+		exception("quota exceeded", msg, file, line) {}
+};
+
+class exception_unsupported : public exception {
+	friend exception;
+	exception_unsupported(const char *msg, const char *file, int line) :
+		exception("unsupported operation", msg, file, line) {}
+};
+
+/* Throw an exception of the class that corresponds to "error", with
+ * error message "msg" in line "line" of file "file".
+ *
+ * isl_error_none is treated as an invalid error type.
+ */
+void exception::throw_error(enum isl_error error, const char *msg,
+	const char *file, int line)
+{
+	switch (error) {
+	case isl_error_none:
+		break;
+	case isl_error_abort: throw exception_abort(msg, file, line);
+	case isl_error_alloc: throw exception_alloc(msg, file, line);
+	case isl_error_unknown: throw exception_unknown(msg, file, line);
+	case isl_error_internal: throw exception_internal(msg, file, line);
+	case isl_error_invalid: throw exception_invalid(msg, file, line);
+	case isl_error_quota: throw exception_quota(msg, file, line);
+	case isl_error_unsupported:
+				throw exception_unsupported(msg, file, line);
+	}
+
+	throw exception_invalid("invalid error type", file, line);
+}
+
+/* Throw an exception corresponding to the last error on "ctx" and
+ * reset the error.
+ *
+ * If "ctx" is NULL or if it is not in an error state at the start,
+ * then an invalid argument exception is thrown.
+ */
+void exception::throw_last_error(ctx ctx)
+{
+	enum isl_error error;
+	const char *msg, *file;
+	int line;
+
+	error = isl_ctx_last_error(ctx.get());
+	msg = isl_ctx_last_error_msg(ctx.get());
+	file = isl_ctx_last_error_file(ctx.get());
+	line = isl_ctx_last_error_line(ctx.get());
+	isl_ctx_reset_error(ctx.get());
+
+	throw_error(error, msg, file, line);
+}
+
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+
+class exception {
+public:
+	/* Default behavior on error conditions that occur inside isl calls
+	 * performed from inside the bindings.
+	 * In the case exceptions are not available, isl should abort.
+	 */
+	static constexpr auto on_error = ISL_ON_ERROR_ABORT;
+	/* Wrapper for throwing an exception with the given message.
+	 * In the case exceptions are not available, print an error and abort.
+	 */
+	static void throw_invalid(const char *msg, const char *file, int line) {
+		fprintf(stderr, "%s:%d: %s\n", file, line, msg);
+		abort();
+	}
+	/* Throw an exception corresponding to the last
+	 * error on "ctx".
+	 * isl should already abort when an error condition occurs,
+	 * so this function should never be called.
+	 */
+	static void throw_last_error(ctx ctx) {
+		abort();
+	}
+};
+
+#endif
+
+/* Helper class for setting the on_error and resetting the option
+ * to the original value when leaving the scope.
+ */
+class options_scoped_set_on_error {
+	isl_ctx *ctx;
+	int saved_on_error;
+public:
+	options_scoped_set_on_error(class ctx ctx, int on_error) {
+		this->ctx = ctx.get();
+		saved_on_error = isl_options_get_on_error(this->ctx);
+		isl_options_set_on_error(this->ctx, on_error);
+	}
+	~options_scoped_set_on_error() {
+		isl_options_set_on_error(ctx, saved_on_error);
+	}
+};
+
+} // namespace isl
+
diff --git a/lib/External/isl/cpp/typed_cpp.h.bot b/lib/External/isl/cpp/typed_cpp.h.bot
new file mode 100644
index 0000000..af20081
--- /dev/null
+++ b/lib/External/isl/cpp/typed_cpp.h.bot
@@ -0,0 +1,5 @@
+
+} // namespace typed
+} // namespace isl
+
+#endif /* ISL_TYPED_CPP */
diff --git a/lib/External/isl/cpp/typed_cpp.h.top b/lib/External/isl/cpp/typed_cpp.h.top
new file mode 100644
index 0000000..d89eb41
--- /dev/null
+++ b/lib/External/isl/cpp/typed_cpp.h.top
@@ -0,0 +1,21 @@
+/// These are automatically generated templated C++ bindings for isl.
+///
+/// isl is a library for computing with integer sets and maps described by
+/// Presburger formulas. On top of this, isl provides various tools for
+/// polyhedral compilation, ranging from dependence analysis over scheduling
+/// to AST generation.
+
+#ifndef ISL_TYPED_CPP
+#define ISL_TYPED_CPP
+
+#include <type_traits>
+
+#include <isl/cpp.h>
+
+namespace isl {
+namespace typed {
+
+template <typename Domain, typename Range>
+struct pair {};
+
+struct Anonymous;
diff --git a/lib/External/isl/depcomp b/lib/External/isl/depcomp
index 65cbf70..6b39162 100755
--- a/lib/External/isl/depcomp
+++ b/lib/External/isl/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/lib/External/isl/doc/Makefile.in b/lib/External/isl/doc/Makefile.in
index 5efda3a..36dda7d 100644
--- a/lib/External/isl/doc/Makefile.in
+++ b/lib/External/isl/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -285,7 +285,6 @@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/lib/External/isl/doc/mypod2latex b/lib/External/isl/doc/mypod2latex
index 4583bd7..b11c059 100755
--- a/lib/External/isl/doc/mypod2latex
+++ b/lib/External/isl/doc/mypod2latex
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
 
 use strict;
 use Pod::LaTeX;
diff --git a/lib/External/isl/doc/user.pod b/lib/External/isl/doc/user.pod
index 6d3d9a5..743e881 100644
--- a/lib/External/isl/doc/user.pod
+++ b/lib/External/isl/doc/user.pod
@@ -1197,6 +1197,7 @@
 	#include <isl/set.h>
 	isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset,
 		enum isl_dim_type type);
+	isl_size isl_set_tuple_dim(__isl_keep isl_set *set);
 	isl_size isl_set_dim(__isl_keep isl_set *set,
 		enum isl_dim_type type);
 
@@ -1207,6 +1208,10 @@
 	#include <isl/map.h>
 	isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
 		enum isl_dim_type type);
+	isl_size isl_map_domain_tuple_dim(
+		__isl_keep isl_map *map);
+	isl_size isl_map_range_tuple_dim(
+		__isl_keep isl_map *map);
 	isl_size isl_map_dim(__isl_keep isl_map *map,
 		enum isl_dim_type type);
 
@@ -1588,14 +1593,28 @@
 using the following functions.
 
 	#include <isl/space.h>
+	__isl_give isl_space *isl_space_set_domain_tuple_id(
+		__isl_take isl_space *space,
+		__isl_take isl_id *id);
+	__isl_give isl_space *isl_space_set_range_tuple_id(
+		__isl_take isl_space *space,
+		__isl_take isl_id *id);
 	__isl_give isl_space *isl_space_set_tuple_id(
 		__isl_take isl_space *space,
 		enum isl_dim_type type, __isl_take isl_id *id);
 	__isl_give isl_space *isl_space_reset_tuple_id(
 		__isl_take isl_space *space, enum isl_dim_type type);
+	isl_bool isl_space_has_domain_tuple_id(
+		__isl_keep isl_space *space);
+	isl_bool isl_space_has_range_tuple_id(
+		__isl_keep isl_space *space);
 	isl_bool isl_space_has_tuple_id(
 		__isl_keep isl_space *space,
 		enum isl_dim_type type);
+	__isl_give isl_id *isl_space_get_domain_tuple_id(
+		__isl_keep isl_space *space);
+	__isl_give isl_id *isl_space_get_range_tuple_id(
+		__isl_keep isl_space *space);
 	__isl_give isl_id *isl_space_get_tuple_id(
 		__isl_keep isl_space *space, enum isl_dim_type type);
 	__isl_give isl_space *isl_space_set_tuple_name(
@@ -1638,13 +1657,25 @@
 	__isl_give isl_basic_map *isl_basic_map_set_tuple_id(
 		__isl_take isl_basic_map *bmap,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_map *isl_map_set_domain_tuple_id(
+		__isl_take isl_map *map, __isl_take isl_id *id);
+	__isl_give isl_map *isl_map_set_range_tuple_id(
+		__isl_take isl_map *map, __isl_take isl_id *id);
 	__isl_give isl_map *isl_map_set_tuple_id(
 		__isl_take isl_map *map, enum isl_dim_type type,
 		__isl_take isl_id *id);
 	__isl_give isl_map *isl_map_reset_tuple_id(
 		__isl_take isl_map *map, enum isl_dim_type type);
+	isl_bool isl_map_has_domain_tuple_id(
+		__isl_keep isl_map *map);
+	isl_bool isl_map_has_range_tuple_id(
+		__isl_keep isl_map *map);
 	isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map,
 		enum isl_dim_type type);
+	__isl_give isl_id *isl_map_get_domain_tuple_id(
+		__isl_keep isl_map *map);
+	__isl_give isl_id *isl_map_get_range_tuple_id(
+		__isl_keep isl_map *map);
 	__isl_give isl_id *isl_map_get_tuple_id(
 		__isl_keep isl_map *map, enum isl_dim_type type);
 	__isl_give isl_map *isl_map_set_tuple_name(
@@ -1663,12 +1694,22 @@
 		enum isl_dim_type type);
 
 	#include <isl/val.h>
+	__isl_give isl_multi_val *isl_multi_val_set_range_tuple_id(
+		__isl_take isl_multi_val *mv,
+		__isl_take isl_id *id);
 	__isl_give isl_multi_val *isl_multi_val_set_tuple_id(
 		__isl_take isl_multi_val *mv,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_multi_val *
+	isl_multi_val_reset_range_tuple_id(
+		__isl_take isl_multi_val *mv);
 	__isl_give isl_multi_val *isl_multi_val_reset_tuple_id(
 		__isl_take isl_multi_val *mv,
 		enum isl_dim_type type);
+	isl_bool isl_multi_val_has_range_tuple_id(
+		__isl_keep isl_multi_val *mv);
+	__isl_give isl_id *isl_multi_val_get_range_tuple_id(
+		__isl_keep isl_multi_val *mv);
 	isl_bool isl_multi_val_has_tuple_id(
 		__isl_keep isl_multi_val *mv,
 		enum isl_dim_type type);
@@ -1686,19 +1727,43 @@
 	__isl_give isl_aff *isl_aff_set_tuple_id(
 		__isl_take isl_aff *aff,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_multi_aff *isl_multi_aff_set_range_tuple_id(
+		__isl_take isl_multi_aff *ma,
+		__isl_take isl_id *id);
 	__isl_give isl_multi_aff *isl_multi_aff_set_tuple_id(
 		__isl_take isl_multi_aff *maff,
 		enum isl_dim_type type, __isl_take isl_id *id);
 	__isl_give isl_pw_aff *isl_pw_aff_set_tuple_id(
 		__isl_take isl_pw_aff *pwaff,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_pw_multi_aff *
+	isl_pw_multi_aff_set_range_tuple_id(
+		__isl_take isl_pw_multi_aff *pma,
+		__isl_take isl_id *id);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id(
 		__isl_take isl_pw_multi_aff *pma,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_multi_pw_aff *
+	isl_multi_pw_aff_set_range_tuple_id(
+		__isl_take isl_multi_pw_aff *mpa,
+		__isl_take isl_id *id);
+	__isl_give isl_multi_union_pw_aff *
+	isl_multi_union_pw_aff_set_range_tuple_id(
+		__isl_take isl_multi_union_pw_aff *mupa,
+		__isl_take isl_id *id);
 	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_set_tuple_id(
 		__isl_take isl_multi_union_pw_aff *mupa,
 		enum isl_dim_type type, __isl_take isl_id *id);
+	__isl_give isl_multi_aff *
+	isl_multi_aff_reset_range_tuple_id(
+		__isl_take isl_multi_aff *ma);
+	__isl_give isl_multi_pw_aff *
+	isl_multi_pw_aff_reset_range_tuple_id(
+		__isl_take isl_multi_pw_aff *mpa);
+	__isl_give isl_multi_union_pw_aff *
+	isl_multi_union_pw_aff_reset_range_tuple_id(
+		__isl_take isl_multi_union_pw_aff *mupa);
 	__isl_give isl_multi_aff *isl_multi_aff_reset_tuple_id(
 		__isl_take isl_multi_aff *ma,
 		enum isl_dim_type type);
@@ -1717,6 +1782,10 @@
 	isl_multi_union_pw_aff_reset_tuple_id(
 		__isl_take isl_multi_union_pw_aff *mupa,
 		enum isl_dim_type type);
+	isl_bool isl_multi_aff_has_range_tuple_id(
+		__isl_keep isl_multi_aff *ma);
+	__isl_give isl_id *isl_multi_aff_get_range_tuple_id(
+		__isl_keep isl_multi_aff *ma);
 	isl_bool isl_multi_aff_has_tuple_id(
 		__isl_keep isl_multi_aff *ma,
 		enum isl_dim_type type);
@@ -1728,18 +1797,31 @@
 	__isl_give isl_id *isl_pw_aff_get_tuple_id(
 		__isl_keep isl_pw_aff *pa,
 		enum isl_dim_type type);
+	isl_bool isl_pw_multi_aff_has_range_tuple_id(
+		__isl_keep isl_pw_multi_aff *pma);
 	isl_bool isl_pw_multi_aff_has_tuple_id(
 		__isl_keep isl_pw_multi_aff *pma,
 		enum isl_dim_type type);
+	__isl_give isl_id *isl_pw_multi_aff_get_range_tuple_id(
+		__isl_keep isl_pw_multi_aff *pma);
 	__isl_give isl_id *isl_pw_multi_aff_get_tuple_id(
 		__isl_keep isl_pw_multi_aff *pma,
 		enum isl_dim_type type);
+	isl_bool isl_multi_pw_aff_has_range_tuple_id(
+		__isl_keep isl_multi_pw_aff *mpa);
+	__isl_give isl_id *isl_multi_pw_aff_get_range_tuple_id(
+		__isl_keep isl_multi_pw_aff *mpa);
 	isl_bool isl_multi_pw_aff_has_tuple_id(
 		__isl_keep isl_multi_pw_aff *mpa,
 		enum isl_dim_type type);
 	__isl_give isl_id *isl_multi_pw_aff_get_tuple_id(
 		__isl_keep isl_multi_pw_aff *mpa,
 		enum isl_dim_type type);
+	isl_bool isl_multi_union_pw_aff_has_range_tuple_id(
+		__isl_keep isl_multi_union_pw_aff *mupa);
+	__isl_give isl_id *
+	isl_multi_union_pw_aff_get_range_tuple_id(
+		__isl_keep isl_multi_union_pw_aff *mupa);
 	isl_bool isl_multi_union_pw_aff_has_tuple_id(
 		__isl_keep isl_multi_union_pw_aff *mupa,
 		enum isl_dim_type type);
@@ -1950,19 +2032,35 @@
 
 =item * Universe sets and relations
 
+	#include <isl/set.h>
 	__isl_give isl_basic_set *isl_basic_set_universe(
 		__isl_take isl_space *space);
-	__isl_give isl_basic_map *isl_basic_map_universe(
-		__isl_take isl_space *space);
 	__isl_give isl_set *isl_set_universe(
 		__isl_take isl_space *space);
+	__isl_give isl_set *isl_space_universe_set(
+		__isl_take isl_space *space);
+
+	#include <isl/map.h>
+	__isl_give isl_basic_map *isl_basic_map_universe(
+		__isl_take isl_space *space);
 	__isl_give isl_map *isl_map_universe(
 		__isl_take isl_space *space);
+	__isl_give isl_map *isl_space_universe_map(
+		__isl_take isl_space *space);
+
+	#include <isl/union_set.h>
 	__isl_give isl_union_set *isl_union_set_universe(
 		__isl_take isl_union_set *uset);
+
+	#include <isl/union_map.h>
 	__isl_give isl_union_map *isl_union_map_universe(
 		__isl_take isl_union_map *umap);
 
+C<isl_set_universe> and C<isl_space_universe_set>
+perform the same operation.
+Similarly
+for the pair C<isl_map_universe> and C<isl_space_universe_map>.
+
 The sets and relations constructed by the functions above
 contain all integer values, while those constructed by the
 functions below only contain non-negative values.
@@ -2023,11 +2121,16 @@
 A basic set or relation can be converted to a set or relation
 using the following functions.
 
+	__isl_give isl_set *isl_basic_set_to_set(
+		__isl_take isl_basic_set *bset);
 	__isl_give isl_set *isl_set_from_basic_set(
 		__isl_take isl_basic_set *bset);
 	__isl_give isl_map *isl_map_from_basic_map(
 		__isl_take isl_basic_map *bmap);
 
+C<isl_basic_set_to_set> and C<isl_set_from_basic_set> perform
+the same operation.
+
 Sets and relations can be converted to union sets and relations
 using the following functions.
 
@@ -2035,11 +2138,19 @@
 		__isl_take isl_basic_set *bset);
 	__isl_give isl_union_map *isl_union_map_from_basic_map(
 		__isl_take isl_basic_map *bmap);
+	__isl_give isl_union_set *isl_set_to_union_set(
+		__isl_take isl_set *set);
 	__isl_give isl_union_set *isl_union_set_from_set(
 		__isl_take isl_set *set);
+	__isl_give isl_union_map *isl_map_to_union_map(
+		__isl_take isl_map *map);
 	__isl_give isl_union_map *isl_union_map_from_map(
 		__isl_take isl_map *map);
 
+C<isl_map_to_union_map> and C<isl_union_map_from_map> perform
+the same operation.
+Similarly for C<isl_set_to_union_set> and C<isl_union_set_from_set>.
+
 The inverse conversions below can only be used if the input
 union set or relation is known to contain elements in exactly one
 space.
@@ -2047,15 +2158,23 @@
 	#include <isl/union_set.h>
 	isl_bool isl_union_set_isa_set(
 		__isl_keep isl_union_set *uset);
+	__isl_give isl_set *isl_union_set_as_set(
+		__isl_take isl_union_set *uset);
 	__isl_give isl_set *isl_set_from_union_set(
 		__isl_take isl_union_set *uset);
 
 	#include <isl/union_map.h>
 	isl_bool isl_union_map_isa_map(
 		__isl_keep isl_union_map *umap);
+	__isl_give isl_map *isl_union_map_as_map(
+		__isl_take isl_union_map *umap);
 	__isl_give isl_map *isl_map_from_union_map(
 		__isl_take isl_union_map *umap);
 
+C<isl_union_map_as_map> and C<isl_map_from_union_map> perform
+the same operation.
+Similarly for C<isl_union_set_as_set> and C<isl_set_from_union_set>.
+
 Sets and relations can be copied and freed again using the following
 functions.
 
@@ -2219,6 +2338,8 @@
 	#include <isl/set.h>
 	__isl_give isl_basic_set *isl_basic_set_from_multi_aff(
 		__isl_take isl_multi_aff *ma);
+	__isl_give isl_set *isl_multi_aff_as_set(
+		__isl_take isl_multi_aff *ma);
 	__isl_give isl_set *isl_set_from_multi_aff(
 		__isl_take isl_multi_aff *ma);
 
@@ -2232,25 +2353,40 @@
 		__isl_take isl_aff_list *list);
 	__isl_give isl_basic_map *isl_basic_map_from_multi_aff(
 		__isl_take isl_multi_aff *maff)
+	__isl_give isl_map *isl_multi_aff_as_map(
+		__isl_take isl_multi_aff *ma);
 	__isl_give isl_map *isl_map_from_multi_aff(
 		__isl_take isl_multi_aff *maff)
 
 	#include <isl/aff.h>
 	__isl_give isl_set *isl_set_from_pw_aff(
 		__isl_take isl_pw_aff *pwaff);
+	__isl_give isl_map *isl_pw_aff_as_map(
+		__isl_take isl_pw_aff *pa);
 	__isl_give isl_map *isl_map_from_pw_aff(
 		__isl_take isl_pw_aff *pwaff);
+	__isl_give isl_set *isl_pw_multi_aff_as_set(
+		__isl_take isl_pw_multi_aff *pma);
 	__isl_give isl_set *isl_set_from_pw_multi_aff(
 		__isl_take isl_pw_multi_aff *pma);
+	__isl_give isl_map *isl_pw_multi_aff_as_map(
+		__isl_take isl_pw_multi_aff *pma);
 	__isl_give isl_map *isl_map_from_pw_multi_aff(
 		__isl_take isl_pw_multi_aff *pma);
+	__isl_give isl_set *isl_multi_pw_aff_as_set(
+		__isl_take isl_multi_pw_aff *mpa);
 	__isl_give isl_set *isl_set_from_multi_pw_aff(
 		__isl_take isl_multi_pw_aff *mpa);
+	__isl_give isl_map *isl_multi_pw_aff_as_map(
+		__isl_take isl_multi_pw_aff *mpa);
 	__isl_give isl_map *isl_map_from_multi_pw_aff(
 		__isl_take isl_multi_pw_aff *mpa);
 	__isl_give isl_union_map *isl_union_map_from_union_pw_aff(
 		__isl_take isl_union_pw_aff *upa);
 	__isl_give isl_union_map *
+	isl_union_pw_multi_aff_as_union_map(
+		__isl_take isl_union_pw_multi_aff *upma);
+	__isl_give isl_union_map *
 	isl_union_map_from_union_pw_multi_aff(
 		__isl_take isl_union_pw_multi_aff *upma);
 	__isl_give isl_union_map *
@@ -2263,6 +2399,17 @@
 The C<mupa> passed to C<isl_union_map_from_multi_union_pw_aff>
 is not allowed to be zero-dimensional.  The domain of the result
 is the shared domain of the union piecewise affine elements.
+C<isl_multi_aff_as_set> and C<isl_set_from_multi_aff> perform
+the same operation.
+Similarly for the pair C<isl_multi_aff_as_map> and C<isl_map_from_multi_aff>,
+for the pair C<isl_pw_aff_as_map> and C<isl_map_from_pw_aff>,
+for the pair C<isl_pw_multi_aff_as_set> and C<isl_set_from_pw_multi_aff>,
+for the pair C<isl_pw_multi_aff_as_map> and C<isl_map_from_pw_multi_aff>,
+the pair C<isl_multi_pw_aff_as_set> and C<isl_set_from_multi_pw_aff>,
+the pair C<isl_multi_pw_aff_as_map> and C<isl_map_from_multi_pw_aff>,
+and
+C<isl_union_pw_multi_aff_as_union_map> and
+C<isl_union_map_from_union_pw_multi_aff>.
 
 =head2 Inspecting Sets and Relations
 
@@ -2592,16 +2739,21 @@
 	__isl_null isl_point *isl_point_free(
 		__isl_take isl_point *pnt);
 
-A singleton set can be created from a point using
+A singleton set can be created from a point using the following functions.
 
 	__isl_give isl_basic_set *isl_basic_set_from_point(
 		__isl_take isl_point *pnt);
+	__isl_give isl_set *isl_point_to_set(
+		__isl_take isl_point *pnt);
 	__isl_give isl_set *isl_set_from_point(
 		__isl_take isl_point *pnt);
 	__isl_give isl_union_set *isl_union_set_from_point(
 		__isl_take isl_point *pnt);
 
-and a box can be created from two opposite extremal points using
+C<isl_point_to_set> and C<isl_set_from_point> perform
+the same operation.
+
+A box can be created from two opposite extremal points using
 
 	__isl_give isl_basic_set *isl_basic_set_box_from_points(
 		__isl_take isl_point *pnt1,
@@ -2711,6 +2863,8 @@
 	#include <isl/aff.h>
 	__isl_give isl_aff *isl_aff_zero_on_domain_space(
 		__isl_take isl_space *space);
+	__isl_give isl_aff *isl_space_zero_aff_on_domain(
+		__isl_take isl_space *space);
 	__isl_give isl_aff *isl_aff_zero_on_domain(
 		__isl_take isl_local_space *ls);
 	__isl_give isl_aff *isl_aff_val_on_domain_space(
@@ -2722,6 +2876,9 @@
 	__isl_give isl_aff *isl_aff_param_on_domain_space_id(
 		__isl_take isl_space *space,
 		__isl_take isl_id *id);
+	__isl_give isl_aff *isl_space_param_aff_on_domain_id(
+		__isl_take isl_space *space,
+		__isl_take isl_id *id);
 	__isl_give isl_aff *isl_aff_var_on_domain(
 		__isl_take isl_local_space *ls,
 		enum isl_dim_type type, unsigned pos);
@@ -2732,6 +2889,11 @@
 
 The space passed to C<isl_aff_param_on_domain_space_id>
 is required to have a parameter with the given identifier.
+C<isl_aff_param_on_domain_space_id> and
+C<isl_space_param_aff_on_domain_id> perform the same operation.
+
+C<isl_aff_zero_on_domain_space> and C<isl_space_zero_aff_on_domain>
+perform the same operation.
 
 Quasi affine expressions can be copied and freed using
 
@@ -2966,19 +3128,36 @@
 	#include <isl/val.h>
 	__isl_give isl_multi_val *isl_multi_val_zero(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_val *isl_space_zero_multi_val(
+		__isl_take isl_space *space);
 
 	#include <isl/aff.h>
 	__isl_give isl_multi_aff *isl_multi_aff_zero(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_aff *isl_space_zero_multi_aff(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_pw_aff *isl_space_zero_multi_pw_aff(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_zero(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_union_pw_aff *
+	isl_space_zero_multi_union_pw_aff(
+		__isl_take isl_space *space);
 
 Since there is no canonical way of representing a zero
 value of type C<isl_union_pw_aff>, the space passed
 to C<isl_multi_union_pw_aff_zero> needs to be zero-dimensional.
+C<isl_multi_val_zero> and C<isl_space_zero_multi_val>
+perform the same operation.
+Similarly
+for the pair C<isl_multi_aff_zero> and C<isl_space_zero_multi_aff>,
+for the pair C<isl_multi_pw_aff_zero> and C<isl_space_zero_multi_pw_aff> and
+for the pair C<isl_multi_union_pw_aff_zero> and
+C<isl_space_zero_multi_union_pw_aff>.
+
 
 An identity function can be created using the following
 functions.
@@ -2994,9 +3173,15 @@
 	__isl_give isl_multi_aff *
 	isl_multi_aff_identity_on_domain_space(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_aff *
+	isl_space_identity_multi_aff_on_domain(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_pw_aff *
 	isl_multi_pw_aff_identity_on_domain_space(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_pw_aff *
+	isl_space_identity_multi_pw_aff_on_domain(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_aff *isl_multi_aff_identity(
 		__isl_take isl_space *space);
 	__isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity(
@@ -3008,6 +3193,13 @@
 	isl_multi_pw_aff_identity_multi_pw_aff(
 		__isl_take isl_multi_pw_aff *mpa);
 
+C<isl_multi_aff_identity_on_domain_space> and
+C<isl_space_identity_multi_aff_on_domain>
+perform the same operation.
+Similarly
+for the pair C<isl_multi_pw_aff_identity_on_domain_space> and
+C<isl_space_identity_multi_pw_aff_on_domain>.
+
 A function that performs a projection on a universe
 relation or set can be created using the following functions.
 See also the corresponding
@@ -3016,13 +3208,22 @@
 	#include <isl/aff.h>
 	__isl_give isl_multi_aff *isl_multi_aff_domain_map(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_aff *isl_multi_aff_range_map(
 		__isl_take isl_space *space);
+	__isl_give isl_multi_aff *isl_space_range_map_multi_aff(
+		__isl_take isl_space *space);
 	__isl_give isl_multi_aff *isl_multi_aff_project_out_map(
 		__isl_take isl_space *space,
 		enum isl_dim_type type,
 		unsigned first, unsigned n);
 
+C<isl_multi_aff_domain_map> and C<isl_space_domain_map_multi_aff> perform
+the same operation.
+Similarly
+for the pair C<isl_multi_aff_range_map> and C<isl_space_range_map_multi_aff>.
+
 A multiple expression can be created from a single
 base expression using the following functions.
 The space of the created multiple expression is the same
@@ -3051,24 +3252,52 @@
 	__isl_give isl_multi_id *isl_multi_id_from_id_list(
 		__isl_take isl_space *space,
 		__isl_take isl_id_list *list);
+	__isl_give isl_multi_id *isl_space_multi_id(
+		__isl_take isl_space *space,
+		__isl_take isl_id_list *list);
 
 	#include <isl/val.h>
 	__isl_give isl_multi_val *isl_multi_val_from_val_list(
 		__isl_take isl_space *space,
 		__isl_take isl_val_list *list);
+	__isl_give isl_multi_val *isl_space_multi_val(
+		__isl_take isl_space *space,
+		__isl_take isl_val_list *list);
 
 	#include <isl/aff.h>
 	__isl_give isl_multi_aff *isl_multi_aff_from_aff_list(
 		__isl_take isl_space *space,
 		__isl_take isl_aff_list *list);
+	__isl_give isl_multi_aff *isl_space_multi_aff(
+		__isl_take isl_space *space,
+		__isl_take isl_aff_list *list);
 	__isl_give isl_multi_pw_aff *
 	isl_multi_pw_aff_from_pw_aff_list(
 		__isl_take isl_space *space,
 		__isl_take isl_pw_aff_list *list);
+	__isl_give isl_multi_pw_aff *
+	isl_space_multi_pw_aff(
+		__isl_take isl_space *space,
+		__isl_take isl_pw_aff_list *list);
 	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_from_union_pw_aff_list(
 		__isl_take isl_space *space,
 		__isl_take isl_union_pw_aff_list *list);
+	__isl_give isl_multi_union_pw_aff *
+	isl_space_multi_union_pw_aff(
+		__isl_take isl_space *space,
+		__isl_take isl_union_pw_aff_list *list);
+
+C<isl_multi_id_from_id_list> and C<isl_space_multi_id> perform
+the same operation.
+Similarly for the pair C<isl_multi_val_from_val_list> and
+C<isl_space_multi_val>,
+for the pair C<isl_multi_aff_from_aff_list> and
+C<isl_space_multi_aff>,
+for the pair C<isl_multi_pw_aff_from_pw_aff_list> and
+C<isl_space_multi_pw_aff> and
+for the pair C<isl_multi_union_pw_aff_from_union_pw_aff_list> and
+C<isl_space_multi_union_pw_aff>.
 
 As a convenience, a multiple piecewise expression can
 also be created from a multiple expression,
@@ -3080,9 +3309,15 @@
 	__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(
 		__isl_take isl_aff *aff);
 	__isl_give isl_multi_pw_aff *
+	isl_multi_aff_to_multi_pw_aff(
+		__isl_take isl_multi_aff *ma);
+	__isl_give isl_multi_pw_aff *
 	isl_multi_pw_aff_from_multi_aff(
 		__isl_take isl_multi_aff *ma);
 
+C<isl_multi_aff_to_multi_pw_aff> and
+C<isl_multi_pw_aff_from_multi_aff> perform the same operation.
+
 Similarly, a multiple union expression can be
 created from a multiple expression.
 
@@ -3091,19 +3326,37 @@
 	isl_multi_union_pw_aff_from_multi_aff(
 		__isl_take isl_multi_aff *ma);
 	__isl_give isl_multi_union_pw_aff *
+	isl_multi_aff_to_multi_union_pw_aff(
+		__isl_take isl_multi_aff *ma);
+	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_from_multi_pw_aff(
 		__isl_take isl_multi_pw_aff *mpa);
 
+C<isl_multi_aff_to_multi_union_pw_aff> and
+C<isl_multi_union_pw_aff_from_multi_aff> perform the same operation.
+
 A multiple quasi-affine expression can be created from
 a multiple value with a given domain space using the following
 function.
 
 	#include <isl/aff.h>
 	__isl_give isl_multi_aff *
+	isl_multi_aff_multi_val_on_domain_space(
+		__isl_take isl_space *space,
+		__isl_take isl_multi_val *mv);
+	__isl_give isl_multi_aff *
+	isl_space_multi_aff_on_domain_multi_val(
+		__isl_take isl_space *space,
+		__isl_take isl_multi_val *mv);
+	__isl_give isl_multi_aff *
 	isl_multi_aff_multi_val_on_space(
 		__isl_take isl_space *space,
 		__isl_take isl_multi_val *mv);
 
+C<isl_space_multi_aff_on_domain_multi_val> and
+C<isl_multi_aff_multi_val_on_space> are alternative names
+for C<isl_multi_aff_multi_val_on_domain_space>.
+
 Similarly,
 a multiple union piecewise affine expression can be created from
 a multiple value with a given domain or
@@ -3306,12 +3559,19 @@
 
 	#include <isl/aff.h>
 	__isl_give isl_multi_union_pw_aff *
+	isl_union_pw_multi_aff_as_multi_union_pw_aff(
+		__isl_take isl_union_pw_multi_aff *upma);
+	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_from_union_pw_multi_aff(
 		__isl_take isl_union_pw_multi_aff *upma);
 	__isl_give isl_union_pw_multi_aff *
 	isl_union_pw_multi_aff_from_multi_union_pw_aff(
 		__isl_take isl_multi_union_pw_aff *mupa);
 
+C<isl_union_pw_multi_aff_as_multi_union_pw_aff> and
+C<isl_multi_union_pw_aff_from_union_pw_multi_aff>
+perform the same operation.
+
 =head3 Piecewise Expressions
 
 A piecewise expression is an expression that is described
@@ -3360,6 +3620,9 @@
 	__isl_give isl_pw_aff *isl_pw_aff_from_aff(
 		__isl_take isl_aff *aff);
 	__isl_give isl_pw_multi_aff *
+	isl_multi_aff_to_pw_multi_aff(
+		__isl_take isl_multi_aff *ma);
+	__isl_give isl_pw_multi_aff *
 	isl_pw_multi_aff_from_multi_aff(
 		__isl_take isl_multi_aff *ma);
 
@@ -3371,6 +3634,9 @@
 	isl_pw_qpolynomial_fold_from_qpolynomial_fold(
 		__isl_take isl_qpolynomial_fold *fold);
 
+C<isl_multi_aff_to_pw_multi_aff> and C<isl_pw_multi_aff_from_multi_aff> perform
+the same operation.
+
 The inverse conversions below can only be used if the input
 expression is known to be defined over a single universe domain.
 
@@ -3378,6 +3644,10 @@
 	isl_bool isl_pw_aff_isa_aff(__isl_keep isl_pw_aff *pa);
 	__isl_give isl_aff *isl_pw_aff_as_aff(
 		__isl_take isl_pw_aff *pa);
+	isl_bool isl_multi_pw_aff_isa_multi_aff(
+		__isl_keep isl_multi_pw_aff *mpa);
+	__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
+		__isl_take isl_multi_pw_aff *mpa);
 	isl_bool isl_pw_multi_aff_isa_multi_aff(
 		__isl_keep isl_pw_multi_aff *pma);
 	__isl_give isl_multi_aff *isl_pw_multi_aff_as_multi_aff(
@@ -3428,13 +3698,22 @@
 	__isl_give isl_pw_multi_aff *
 	isl_pw_multi_aff_identity_on_domain_space(
 		__isl_take isl_space *space)
+	__isl_give isl_pw_multi_aff *
+	isl_space_identity_pw_multi_aff_on_domain(
+		__isl_take isl_space *space)
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
 		__isl_take isl_space *space);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
 		__isl_take isl_space *space);
+	__isl_give isl_pw_multi_aff *
+	isl_space_domain_map_pw_multi_aff(
+		__isl_take isl_space *space);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
 		__isl_take isl_space *space);
 	__isl_give isl_pw_multi_aff *
+	isl_space_range_map_pw_multi_aff(
+		__isl_take isl_space *space);
+	__isl_give isl_pw_multi_aff *
 	isl_pw_multi_aff_project_out_map(
 		__isl_take isl_space *space,
 		enum isl_dim_type type,
@@ -3444,6 +3723,15 @@
 	__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero(
 		__isl_take isl_space *space);
 
+C<isl_pw_multi_aff_identity_on_domain_space> and
+C<isl_space_identity_pw_multi_aff_on_domain>
+perform the same operation.
+Similarly
+for the pair C<isl_pw_multi_aff_domain_map> and
+C<isl_space_domain_map_pw_multi_aff> and
+for the pair C<isl_pw_multi_aff_range_map> and
+C<isl_space_range_map_pw_multi_aff>.
+
 The following convenience functions first create a base expression and
 then create a piecewise expression over a given domain.
 
@@ -3455,10 +3743,17 @@
 	isl_pw_multi_aff_multi_val_on_domain(
 		__isl_take isl_set *domain,
 		__isl_take isl_multi_val *mv);
+	__isl_give isl_pw_multi_aff *
+	isl_set_pw_multi_aff_on_domain_multi_val(
+		__isl_take isl_set *domain,
+		__isl_take isl_multi_val *mv);
 	__isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id(
 		__isl_take isl_set *domain,
 		__isl_take isl_id *id);
 
+C<isl_set_pw_multi_aff_on_domain_multi_val> is an alternative name
+for C<isl_pw_multi_aff_multi_val_on_domain>.
+
 As a convenience, a piecewise multiple expression can
 also be created from a piecewise expression.
 Each multiple expression in the result is derived
@@ -3588,9 +3883,14 @@
 using the following function.
 
 	#include <isl/aff.h>
+	__isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
+		__isl_keep isl_pw_multi_aff *pma, int pos);
 	__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
 		__isl_keep isl_pw_multi_aff *pma, int pos);
 
+C<isl_pw_multi_aff_get_pw_aff> is an alternative name for
+C<isl_pw_multi_aff_get_at>.
+
 These expressions can be replaced using the following function.
 
 	#include <isl/aff.h>
@@ -3615,9 +3915,15 @@
 	isl_pw_multi_aff_from_multi_pw_aff(
 		__isl_take isl_multi_pw_aff *mpa);
 	__isl_give isl_multi_pw_aff *
+	isl_pw_multi_aff_to_multi_pw_aff(
+		__isl_take isl_pw_multi_aff *pma);
+	__isl_give isl_multi_pw_aff *
 	isl_multi_pw_aff_from_pw_multi_aff(
 		__isl_take isl_pw_multi_aff *pma);
 
+C<isl_pw_multi_aff_to_multi_pw_aff> and
+C<isl_multi_pw_aff_from_pw_multi_aff> perform the same operation.
+
 =head3 Union Expressions
 
 A union expression collects base expressions defined
@@ -3677,19 +3983,45 @@
 
 	#include <isl/aff.h>
 	__isl_give isl_union_pw_aff *
+	isl_pw_aff_to_union_pw_aff(
+		__isl_take isl_pw_aff *pa);
+	__isl_give isl_union_pw_aff *
 	isl_union_pw_aff_from_pw_aff(
 		__isl_take isl_pw_aff *pa);
 	__isl_give isl_union_pw_multi_aff *
 	isl_union_pw_multi_aff_from_aff(
 		__isl_take isl_aff *aff);
 	__isl_give isl_union_pw_multi_aff *
+	isl_pw_multi_aff_to_union_pw_multi_aff(
+		__isl_take isl_pw_multi_aff *pma);
+	__isl_give isl_union_pw_multi_aff *
 	isl_union_pw_multi_aff_from_pw_multi_aff(
 		__isl_take isl_pw_multi_aff *pma);
 
 	#include <isl/polynomial.h>
 	__isl_give isl_union_pw_qpolynomial *
+	isl_pw_qpolynomial_to_union_pw_qpolynomial(
+		__isl_take isl_pw_qpolynomial *pwqp);
+	__isl_give isl_union_pw_qpolynomial *
 	isl_union_pw_qpolynomial_from_pw_qpolynomial(
 		__isl_take isl_pw_qpolynomial *pwqp);
+	__isl_give isl_union_pw_qpolynomial_fold *
+	isl_pw_qpolynomial_fold_to_union_pw_qpolynomial_fold(
+		__isl_take isl_pw_qpolynomial_fold *pwf);
+	__isl_give isl_union_pw_qpolynomial_fold *
+	isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(
+		__isl_take isl_pw_qpolynomial_fold *pwf);
+
+C<isl_pw_aff_to_union_pw_aff> and C<isl_union_pw_aff_from_pw_aff> perform
+the same operation.
+Similarly for C<isl_pw_multi_aff_to_union_pw_multi_aff> and
+C<isl_union_pw_multi_aff_from_pw_multi_aff>,
+for
+C<isl_pw_qpolynomial_to_union_pw_qpolynomial> and
+C<isl_union_pw_qpolynomial_from_pw_qpolynomial>, and
+for
+C<isl_pw_qpolynomial_fold_to_union_pw_qpolynomial_fold> and
+C<isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold>.
 
 The inverse conversions below can only be used if the input
 expression is known to live in exactly one space.
@@ -4447,6 +4779,10 @@
 
 =item * Stride
 
+Stride detection is based on heuristics.
+The strides returned by the functions below are always valid,
+but there may be larger valid strides that are not detected.
+
 	isl_stat isl_set_dim_residue_class_val(
 		__isl_keep isl_set *set,
 		int pos, __isl_give isl_val **modulo,
@@ -4470,6 +4806,9 @@
 	__isl_give isl_stride_info *
 	isl_map_get_range_stride_info(
 		__isl_keep isl_map *map, int pos);
+	__isl_give isl_fixed_box *
+	isl_map_get_range_lattice_tile(
+		__isl_keep isl_map *map);
 
 Check if the values of the given set dimension are equal to
 some affine expression of the other dimensions (the offset)
@@ -4481,6 +4820,17 @@
 is taken to be one and the offset is taken to be the zero expression.
 The function C<isl_set_get_stride> performs the same
 computation as C<isl_set_get_stride_info> but only returns the stride.
+The function C<isl_map_get_range_lattice_tile> collects the stride
+information over all output dimensions.
+In particular, it returns a tile of a rectangular lattice
+(possibly of size 1 in all directions)
+containing the output in terms of the parameters and the input dimensions.
+The size and the offset of this tile correspond to
+the strides and the offsets of the stride information and
+can be extracted from the returned
+C<isl_fixed_box> using the functions described under "Box hull" in
+L</"Unary Operations">.  Note that the C<isl_fixed_box> object returned by
+C<isl_map_get_range_lattice_tile> is always valid.
 For the other functions,
 the stride and offset can be extracted from the returned object
 using the following functions.
@@ -5746,8 +6096,12 @@
 range space.
 
 	#include <isl/aff.h>
+	__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(
+		__isl_take isl_set *set);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(
 		__isl_take isl_set *set);
+	__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(
+		__isl_take isl_map *map);
 	__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(
 		__isl_take isl_map *map);
 
@@ -5755,13 +6109,28 @@
 	isl_union_pw_multi_aff_from_union_set(
 		__isl_take isl_union_set *uset);
 	__isl_give isl_union_pw_multi_aff *
+	isl_union_map_as_union_pw_multi_aff(
+		__isl_take isl_union_map *umap);
+	__isl_give isl_union_pw_multi_aff *
 	isl_union_pw_multi_aff_from_union_map(
 		__isl_take isl_union_map *umap);
 
 	__isl_give isl_multi_union_pw_aff *
+	isl_union_map_as_multi_union_pw_aff(
+		__isl_take isl_union_map *umap);
+	__isl_give isl_multi_union_pw_aff *
 	isl_multi_union_pw_aff_from_union_map(
 		__isl_take isl_union_map *umap);
 
+C<isl_map_as_pw_multi_aff> and C<isl_pw_multi_aff_from_map> perform
+the same operation.
+Similarly for C<isl_set_as_pw_multi_aff> and
+C<isl_pw_multi_aff_from_set>,
+for C<isl_union_map_as_union_pw_multi_aff> and
+C<isl_union_pw_multi_aff_from_union_map> and
+for C<isl_union_map_as_multi_union_pw_aff> and
+C<isl_multi_union_pw_aff_from_union_map>.
+
 =item * Deltas
 
 	__isl_give isl_basic_set *isl_basic_map_deltas(
@@ -8938,6 +9307,8 @@
 Lists can be created, copied, modified and freed using the following functions.
 
 	#include <isl/set.h>
+	__isl_give isl_set_list *isl_set_to_list(
+		__isl_take isl_set *el);
 	__isl_give isl_set_list *isl_set_list_from_set(
 		__isl_take isl_set *el);
 	__isl_give isl_set_list *isl_set_list_alloc(
@@ -8982,7 +9353,8 @@
 C<isl_set_list_alloc> creates an empty list with an initial capacity
 for C<n> elements.  C<isl_set_list_insert> and C<isl_set_list_add>
 add elements to a list, increasing its capacity as needed.
-C<isl_set_list_from_set> creates a list with a single element.
+C<isl_set_to_list> creates a list with a single element.
+C<isl_set_list_from_set> performs the same operation.
 C<isl_set_list_clear> removes all elements from a list.
 C<isl_set_list_swap> swaps the elements at the specified locations.
 C<isl_set_list_reverse> reverses the elements in the list.
@@ -9008,7 +9380,8 @@
 		isl_bool (*follows)(__isl_keep isl_set *a,
 			__isl_keep isl_set *b, void *user),
 		void *follows_user,
-		isl_stat (*fn)(__isl_take isl_set *el, void *user),
+		isl_stat (*fn)(__isl_take isl_set_list *scc,
+			void *user),
 		void *fn_user);
 
 C<isl_set_list_n_set> is an alternative name for C<isl_set_list_size>.
@@ -9035,6 +9408,43 @@
 	__isl_give char *isl_set_list_to_str(
 		__isl_keep isl_set_list *list);
 
+An C<isl_val_list>, C<isl_id_list>,
+C<isl_aff_list>, C<isl_pw_aff_list>, C<isl_pw_multi_aff_list>,
+C<isl_union_pw_aff_list>,
+C<isl_map_list> or C<isl_union_set_list> object
+can also be read from input using the following functions.
+
+	#include <isl/val.h>
+	__isl_give isl_val_list *isl_val_list_read_from_str(
+		isl_ctx *ctx, const char *str);
+
+	#include <isl/id.h>
+	__isl_give isl_id_list *isl_id_list_read_from_str(
+		isl_ctx *ctx, const char *str);
+
+	#include <isl/aff.h>
+	__isl_give isl_aff_list *
+	isl_aff_list_read_from_str(isl_ctx *ctx,
+		const char *str);
+	__isl_give isl_pw_aff_list *
+	isl_pw_aff_list_read_from_str(isl_ctx *ctx,
+		const char *str);
+	__isl_give isl_pw_multi_aff_list *
+	isl_pw_multi_aff_list_read_from_str(isl_ctx *ctx,
+		const char *str);
+	__isl_give isl_union_pw_aff_list *
+	isl_union_pw_aff_list_read_from_str(isl_ctx *ctx,
+		const char *str);
+
+	#include <isl/map.h>
+	__isl_give isl_map_list *isl_map_list_read_from_str(
+		isl_ctx *ctx, const char *str);
+
+	#include <isl/union_set.h>
+	__isl_give isl_union_set_list *
+	isl_union_set_list_read_from_str(isl_ctx *ctx,
+		const char *str);
+
 =head2 Associative arrays
 
 Associative arrays map isl objects of a specific type to isl objects
diff --git a/lib/External/isl/include/isl/aff.h b/lib/External/isl/include/isl/aff.h
index ba77025..cfa0851 100644
--- a/lib/External/isl/include/isl/aff.h
+++ b/lib/External/isl/include/isl/aff.h
@@ -19,6 +19,8 @@
 
 __isl_overload
 __isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space);
+__isl_export
+__isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space);
 __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls);
 __isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space,
 	__isl_take isl_val *val);
@@ -30,6 +32,9 @@
 __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls);
 __isl_give isl_aff *isl_aff_param_on_domain_space_id(
 	__isl_take isl_space *space, __isl_take isl_id *id);
+__isl_overload
+__isl_give isl_aff *isl_space_param_aff_on_domain_id(
+	__isl_take isl_space *space, __isl_take isl_id *id);
 
 __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff);
 __isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff);
@@ -402,6 +407,8 @@
 __isl_export
 __isl_give isl_aff *isl_pw_aff_as_aff(__isl_take isl_pw_aff *pa);
 
+__isl_export
+__isl_give isl_map *isl_pw_aff_as_map(__isl_take isl_pw_aff *pa);
 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff);
 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff);
 
@@ -494,11 +501,23 @@
 __isl_export
 __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space);
 __isl_export
+__isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
+	__isl_take isl_space *space);
+__isl_export
 __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space);
+__isl_export
+__isl_give isl_multi_aff *isl_space_range_map_multi_aff(
+	__isl_take isl_space *space);
 __isl_give isl_multi_aff *isl_multi_aff_project_out_map(
 	__isl_take isl_space *space, enum isl_dim_type type,
 	unsigned first, unsigned n);
 
+__isl_overload
+__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space(
+	__isl_take isl_space *space, __isl_take isl_multi_val *mv);
+__isl_overload
+__isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val(
+	__isl_take isl_space *space, __isl_take isl_multi_val *mv);
 __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
 	__isl_take isl_space *space, __isl_take isl_multi_val *mv);
 
@@ -569,17 +588,29 @@
 __isl_overload
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
 	__isl_take isl_space *space);
+__isl_export
+__isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain(
+	__isl_take isl_space *space);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
 	__isl_take isl_space *space);
 __isl_export
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
 	__isl_take isl_space *space);
 __isl_export
+__isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff(
+	__isl_take isl_space *space);
+__isl_export
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
 	__isl_take isl_space *space);
+__isl_export
+__isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff(
+	__isl_take isl_space *space);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
 	__isl_take isl_space *space, enum isl_dim_type type,
 	unsigned first, unsigned n);
+__isl_export
+__isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff(
+	__isl_take isl_multi_aff *ma);
 __isl_constructor
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
 	__isl_take isl_multi_aff *ma);
@@ -601,6 +632,9 @@
 	__isl_keep isl_id *id);
 isl_bool isl_pw_multi_aff_involves_dims(__isl_keep isl_pw_multi_aff *pma,
 	enum isl_dim_type type, unsigned first, unsigned n);
+__isl_export
+__isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
+	__isl_keep isl_pw_multi_aff *pma, int pos);
 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
 	__isl_keep isl_pw_multi_aff *pma, int pos);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
@@ -617,13 +651,21 @@
 	enum isl_dim_type type);
 const char *isl_pw_multi_aff_get_tuple_name(__isl_keep isl_pw_multi_aff *pma,
 	enum isl_dim_type type);
+__isl_export
+__isl_give isl_id *isl_pw_multi_aff_get_range_tuple_id(
+	__isl_keep isl_pw_multi_aff *pma);
 __isl_give isl_id *isl_pw_multi_aff_get_tuple_id(
 	__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type);
+__isl_export
+isl_bool isl_pw_multi_aff_has_range_tuple_id(__isl_keep isl_pw_multi_aff *pma);
 isl_bool isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma,
 	enum isl_dim_type type);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id(
 	__isl_take isl_pw_multi_aff *pma,
 	enum isl_dim_type type, __isl_take isl_id *id);
+__isl_overload
+__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_range_tuple_id(
+	__isl_take isl_pw_multi_aff *pma, __isl_take isl_id *id);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_tuple_id(
 	__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user(
@@ -643,8 +685,12 @@
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
 	__isl_take isl_set *set);
 
+__isl_export
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
 	__isl_take isl_set *domain, __isl_take isl_multi_val *mv);
+__isl_overload
+__isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val(
+	__isl_take isl_set *domain, __isl_take isl_multi_val *mv);
 
 const char *isl_pw_multi_aff_get_dim_name(__isl_keep isl_pw_multi_aff *pma,
 	enum isl_dim_type type, unsigned pos);
@@ -780,14 +826,22 @@
 __isl_give isl_multi_aff *isl_pw_multi_aff_as_multi_aff(
 	__isl_take isl_pw_multi_aff *pma);
 
+__isl_export
+__isl_give isl_map *isl_pw_multi_aff_as_map(__isl_take isl_pw_multi_aff *pma);
 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma);
+__isl_export
+__isl_give isl_set *isl_pw_multi_aff_as_set(__isl_take isl_pw_multi_aff *pma);
 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma);
 
 __isl_give char *isl_pw_multi_aff_to_str(__isl_keep isl_pw_multi_aff *pma);
 __isl_give isl_printer *isl_printer_print_pw_multi_aff(__isl_take isl_printer *p,
 	__isl_keep isl_pw_multi_aff *pma);
 
+__isl_export
+__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set);
+__isl_export
+__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map);
 
 __isl_export
@@ -815,6 +869,9 @@
 __isl_constructor
 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_multi_aff(
 	__isl_take isl_multi_aff *ma);
+__isl_export
+__isl_give isl_union_pw_multi_aff *isl_pw_multi_aff_to_union_pw_multi_aff(
+	__isl_take isl_pw_multi_aff *pma);
 __isl_constructor
 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_pw_multi_aff(
 	__isl_take isl_pw_multi_aff *pma);
@@ -844,6 +901,7 @@
 __isl_export
 __isl_give isl_space *isl_union_pw_multi_aff_get_space(
 	__isl_keep isl_union_pw_multi_aff *upma);
+__isl_export
 __isl_give isl_pw_multi_aff_list *isl_union_pw_multi_aff_get_pw_multi_aff_list(
 	__isl_keep isl_union_pw_multi_aff *upma);
 
@@ -1004,6 +1062,9 @@
 	__isl_take isl_union_pw_multi_aff *upma,
 	__isl_take isl_union_set *uset);
 
+__isl_export
+__isl_give isl_union_map *isl_union_pw_multi_aff_as_union_map(
+	__isl_take isl_union_pw_multi_aff *upma);
 __isl_overload
 __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
 	__isl_take isl_union_pw_multi_aff *upma);
@@ -1013,6 +1074,9 @@
 
 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
 	__isl_take isl_union_set *uset);
+__isl_export
+__isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff(
+	__isl_take isl_union_map *umap);
 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
 	__isl_take isl_union_map *umap);
 
@@ -1027,6 +1091,9 @@
 
 __isl_constructor
 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff);
+__isl_export
+__isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff(
+	__isl_take isl_multi_aff *ma);
 __isl_constructor
 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
 	__isl_take isl_multi_aff *ma);
@@ -1074,10 +1141,23 @@
 	enum isl_dim_type dst_type, unsigned dst_pos,
 	enum isl_dim_type src_type, unsigned src_pos, unsigned n);
 
+__isl_export
+isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa);
+__isl_export
+__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
+	__isl_take isl_multi_pw_aff *mpa);
+
+__isl_export
+__isl_give isl_set *isl_multi_pw_aff_as_set(__isl_take isl_multi_pw_aff *mpa);
 __isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa);
+__isl_export
+__isl_give isl_map *isl_multi_pw_aff_as_map(__isl_take isl_multi_pw_aff *mpa);
 __isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
 	__isl_take isl_multi_pw_aff *mpa);
+__isl_export
+__isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff(
+	__isl_take isl_pw_multi_aff *pma);
 __isl_constructor
 __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
 	__isl_take isl_pw_multi_aff *pma);
@@ -1139,6 +1219,9 @@
 	__isl_take isl_space *space);
 __isl_constructor
 __isl_give isl_union_pw_aff *isl_union_pw_aff_from_aff(__isl_take isl_aff *aff);
+__isl_export
+__isl_give isl_union_pw_aff *isl_pw_aff_to_union_pw_aff(
+	__isl_take isl_pw_aff *pa);
 __isl_constructor
 __isl_give isl_union_pw_aff *isl_union_pw_aff_from_pw_aff(
 	__isl_take isl_pw_aff *pa);
@@ -1268,6 +1351,9 @@
 ISL_DECLARE_MULTI_DIM_ID(union_pw_aff)
 ISL_DECLARE_MULTI_TUPLE_ID(union_pw_aff)
 
+__isl_export
+__isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff(
+        __isl_take isl_multi_aff *ma);
 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
 	__isl_take isl_multi_aff *ma);
 __isl_constructor
@@ -1336,10 +1422,17 @@
 	__isl_take isl_multi_union_pw_aff *mupa1,
 	__isl_take isl_multi_union_pw_aff *mupa2);
 
+__isl_export
+__isl_give isl_multi_union_pw_aff *
+isl_union_pw_multi_aff_as_multi_union_pw_aff(
+	__isl_take isl_union_pw_multi_aff *upma);
 __isl_give isl_multi_union_pw_aff *
 isl_multi_union_pw_aff_from_union_pw_multi_aff(
 	__isl_take isl_union_pw_multi_aff *upma);
 
+__isl_export
+__isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff(
+	__isl_take isl_union_map *umap);
 __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
 	__isl_take isl_union_map *umap);
 __isl_overload
@@ -1366,9 +1459,13 @@
 void isl_multi_union_pw_aff_dump(__isl_keep isl_multi_union_pw_aff *mupa);
 
 ISL_DECLARE_EXPORTED_LIST_FN(aff)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(aff)
 ISL_DECLARE_EXPORTED_LIST_FN(pw_aff)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(pw_aff)
 ISL_DECLARE_EXPORTED_LIST_FN(pw_multi_aff)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(pw_multi_aff)
 ISL_DECLARE_EXPORTED_LIST_FN(union_pw_aff)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(union_pw_aff)
 ISL_DECLARE_LIST_FN(union_pw_multi_aff)
 
 #if defined(__cplusplus)
diff --git a/lib/External/isl/include/isl/cpp-checked-conversion.h b/lib/External/isl/include/isl/cpp-checked-conversion.h
index 20e422e..2575ce5 100644
--- a/lib/External/isl/include/isl/cpp-checked-conversion.h
+++ b/lib/External/isl/include/isl/cpp-checked-conversion.h
@@ -382,6 +382,14 @@
 	return manage(obj.copy());
 }
 
+checked::map_list check(map_list obj) {
+	return checked::manage(obj.copy());
+}
+
+map_list uncheck(checked::map_list obj) {
+	return manage(obj.copy());
+}
+
 checked::multi_aff check(multi_aff obj) {
 	return checked::manage(obj.copy());
 }
diff --git a/lib/External/isl/include/isl/cpp-checked.h b/lib/External/isl/include/isl/cpp-checked.h
index 3192225..c97cdb2 100644
--- a/lib/External/isl/include/isl/cpp-checked.h
+++ b/lib/External/isl/include/isl/cpp-checked.h
@@ -8,21 +8,6 @@
 #ifndef ISL_CPP_CHECKED
 #define ISL_CPP_CHECKED
 
-#include <isl/id.h>
-#include <isl/space.h>
-#include <isl/val.h>
-#include <isl/aff.h>
-#include <isl/set.h>
-#include <isl/map.h>
-#include <isl/ilp.h>
-#include <isl/union_set.h>
-#include <isl/union_map.h>
-#include <isl/flow.h>
-#include <isl/schedule.h>
-#include <isl/schedule_node.h>
-#include <isl/ast_build.h>
-#include <isl/fixed_box.h>
-
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -203,6 +188,21 @@
 }
 } // namespace isl
 
+#include <isl/id.h>
+#include <isl/space.h>
+#include <isl/val.h>
+#include <isl/aff.h>
+#include <isl/set.h>
+#include <isl/map.h>
+#include <isl/ilp.h>
+#include <isl/union_set.h>
+#include <isl/union_map.h>
+#include <isl/flow.h>
+#include <isl/schedule.h>
+#include <isl/schedule_node.h>
+#include <isl/ast_build.h>
+#include <isl/fixed_box.h>
+
 namespace isl {
 
 namespace checked {
@@ -254,6 +254,7 @@
 class id;
 class id_list;
 class map;
+class map_list;
 class multi_aff;
 class multi_id;
 class multi_pw_aff;
@@ -318,35 +319,158 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::aff add(isl::checked::aff aff2) const;
+  inline isl::checked::multi_aff add(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_aff add(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff add(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::aff add_constant(isl::checked::val v) const;
   inline isl::checked::aff add_constant(long v) const;
+  inline isl::checked::multi_aff add_constant(const isl::checked::multi_val &mv) const;
+  inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::aff as_aff() const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_aff as_multi_aff() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::union_map as_union_map() const;
+  inline isl::checked::aff at(int pos) const;
   inline isl::checked::basic_set bind(isl::checked::id id) const;
   inline isl::checked::basic_set bind(const std::string &id) const;
+  inline isl::checked::basic_set bind(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::pw_aff bind_domain(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::pw_aff bind_domain_wrapped_domain(const isl::checked::multi_id &tuple) const;
   inline isl::checked::aff ceil() const;
-  inline isl::checked::aff div(isl::checked::aff aff2) const;
-  inline isl::checked::set eq_set(isl::checked::aff aff2) const;
-  inline isl::checked::val eval(isl::checked::point pnt) const;
-  inline isl::checked::aff floor() const;
-  inline isl::checked::set ge_set(isl::checked::aff aff2) const;
+  inline isl::checked::pw_aff coalesce() const;
+  inline isl::checked::pw_aff cond(const isl::checked::pw_aff &pwaff_true, const isl::checked::pw_aff &pwaff_false) const;
+  inline isl::checked::multi_val constant_multi_val() const;
   inline isl::checked::val constant_val() const;
   inline isl::checked::val get_constant_val() const;
+  inline isl::checked::aff div(isl::checked::aff aff2) const;
+  inline isl::checked::pw_aff div(const isl::checked::pw_aff &pa2) const;
+  inline isl::checked::set domain() const;
+  inline isl::checked::set eq_set(isl::checked::aff aff2) const;
+  inline isl::checked::set eq_set(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::val eval(isl::checked::point pnt) const;
+  inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const;
+  inline isl::checked::multi_aff flat_range_product(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::aff floor() const;
+  inline stat foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const;
+  inline isl::checked::set ge_set(isl::checked::aff aff2) const;
+  inline isl::checked::set ge_set(const isl::checked::pw_aff &pwaff2) const;
   inline isl::checked::aff gist(isl::checked::set context) const;
+  inline isl::checked::union_pw_aff gist(const isl::checked::union_set &context) const;
+  inline isl::checked::aff gist(const isl::checked::basic_set &context) const;
+  inline isl::checked::aff gist(const isl::checked::point &context) const;
   inline isl::checked::set gt_set(isl::checked::aff aff2) const;
+  inline isl::checked::set gt_set(const isl::checked::pw_aff &pwaff2) const;
+  inline boolean has_range_tuple_id() const;
+  inline isl::checked::multi_aff identity() const;
+  inline isl::checked::pw_aff insert_domain(const isl::checked::space &domain) const;
+  inline isl::checked::pw_aff intersect_domain(const isl::checked::set &set) const;
+  inline isl::checked::union_pw_aff intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_aff intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_aff intersect_params(const isl::checked::set &set) const;
+  inline boolean involves_locals() const;
+  inline boolean involves_nan() const;
+  inline boolean involves_param(const isl::checked::id &id) const;
+  inline boolean involves_param(const std::string &id) const;
+  inline boolean involves_param(const isl::checked::id_list &list) const;
   inline boolean is_cst() const;
+  inline boolean isa_aff() const;
+  inline boolean isa_multi_aff() const;
+  inline boolean isa_pw_multi_aff() const;
   inline isl::checked::set le_set(isl::checked::aff aff2) const;
+  inline isl::checked::set le_set(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::aff_list list() const;
   inline isl::checked::set lt_set(isl::checked::aff aff2) const;
+  inline isl::checked::set lt_set(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::pw_aff max(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::multi_val max_multi_val() const;
+  inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::pw_aff min(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::multi_val min_multi_val() const;
   inline isl::checked::aff mod(isl::checked::val mod) const;
   inline isl::checked::aff mod(long mod) const;
   inline isl::checked::aff mul(isl::checked::aff aff2) const;
+  inline isl::checked::pw_aff mul(const isl::checked::pw_aff &pwaff2) const;
+  inline class size n_piece() const;
   inline isl::checked::set ne_set(isl::checked::aff aff2) const;
+  inline isl::checked::set ne_set(const isl::checked::pw_aff &pwaff2) const;
   inline isl::checked::aff neg() const;
+  inline boolean plain_is_empty() const;
+  inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff product(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const;
   inline isl::checked::aff pullback(isl::checked::multi_aff ma) const;
+  inline isl::checked::pw_aff pullback(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::pw_aff pullback(const isl::checked::pw_multi_aff &pma) const;
+  inline isl::checked::union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::aff pullback(const isl::checked::aff &ma) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::checked::pw_multi_aff range_factor_domain() const;
+  inline isl::checked::pw_multi_aff range_factor_range() const;
+  inline isl::checked::multi_aff range_product(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::multi_aff reset_range_tuple_id() const;
   inline isl::checked::aff scale(isl::checked::val v) const;
   inline isl::checked::aff scale(long v) const;
+  inline isl::checked::multi_aff scale(const isl::checked::multi_val &mv) const;
   inline isl::checked::aff scale_down(isl::checked::val v) const;
   inline isl::checked::aff scale_down(long v) const;
+  inline isl::checked::multi_aff scale_down(const isl::checked::multi_val &mv) const;
+  inline isl::checked::multi_aff set_at(int pos, const isl::checked::aff &el) const;
+  inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::multi_aff set_range_tuple(const isl::checked::id &id) const;
+  inline isl::checked::multi_aff set_range_tuple(const std::string &id) const;
+  inline class size size() const;
+  inline isl::checked::space space() const;
   inline isl::checked::aff sub(isl::checked::aff aff2) const;
+  inline isl::checked::multi_aff sub(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_aff sub(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff sub(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_aff subtract_domain(const isl::checked::set &set) const;
+  inline isl::checked::union_pw_aff subtract_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_aff subtract_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_aff tdiv_q(const isl::checked::pw_aff &pa2) const;
+  inline isl::checked::pw_aff tdiv_r(const isl::checked::pw_aff &pa2) const;
+  inline isl::checked::aff_list to_list() const;
+  inline isl::checked::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::checked::multi_union_pw_aff to_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff to_pw_multi_aff() const;
+  inline isl::checked::union_pw_aff to_union_pw_aff() const;
+  inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const;
   inline isl::checked::aff unbind_params_insert_domain(isl::checked::multi_id domain) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
+  inline isl::checked::pw_aff union_add(const isl::checked::pw_aff &pwaff2) const;
+  inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff union_add(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const;
   static inline isl::checked::aff zero_on_domain(isl::checked::space space);
 };
 
@@ -368,6 +492,7 @@
   inline /* implicit */ aff_list(const aff_list &obj);
   inline explicit aff_list(isl::checked::ctx ctx, int n);
   inline explicit aff_list(isl::checked::aff el);
+  inline explicit aff_list(isl::checked::ctx ctx, const std::string &str);
   inline aff_list &operator=(aff_list obj);
   inline ~aff_list();
   inline __isl_give isl_aff_list *copy() const &;
@@ -378,12 +503,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::aff_list add(isl::checked::aff el) const;
+  inline isl::checked::aff at(int index) const;
+  inline isl::checked::aff get_at(int index) const;
   inline isl::checked::aff_list clear() const;
   inline isl::checked::aff_list concat(isl::checked::aff_list list2) const;
   inline isl::checked::aff_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::aff)> &fn) const;
-  inline isl::checked::aff at(int index) const;
-  inline isl::checked::aff get_at(int index) const;
   inline isl::checked::aff_list insert(unsigned int pos, isl::checked::aff el) const;
   inline class size size() const;
 };
@@ -431,10 +556,10 @@
   inline isl::checked::ast_expr expr_from(isl::checked::pw_aff pa) const;
   inline isl::checked::ast_expr expr_from(isl::checked::set set) const;
   static inline isl::checked::ast_build from_context(isl::checked::set set);
-  inline isl::checked::union_map schedule() const;
-  inline isl::checked::union_map get_schedule() const;
   inline isl::checked::ast_node node_from(isl::checked::schedule schedule) const;
   inline isl::checked::ast_node node_from_schedule_map(isl::checked::union_map schedule) const;
+  inline isl::checked::union_map schedule() const;
+  inline isl::checked::union_map get_schedule() const;
 };
 
 // declarations for isl::ast_expr
@@ -1077,6 +1202,7 @@
   inline isl::checked::ctx ctx() const;
 
   inline std::string to_C_str() const;
+  inline isl::checked::ast_node_list to_list() const;
 };
 
 // declarations for isl::ast_node_block
@@ -1125,9 +1251,9 @@
   inline isl::checked::ast_expr get_inc() const;
   inline isl::checked::ast_expr init() const;
   inline isl::checked::ast_expr get_init() const;
+  inline boolean is_degenerate() const;
   inline isl::checked::ast_expr iterator() const;
   inline isl::checked::ast_expr get_iterator() const;
-  inline boolean is_degenerate() const;
 };
 
 // declarations for isl::ast_node_if
@@ -1151,9 +1277,9 @@
   inline isl::checked::ast_expr get_cond() const;
   inline isl::checked::ast_node else_node() const;
   inline isl::checked::ast_node get_else_node() const;
+  inline boolean has_else_node() const;
   inline isl::checked::ast_node then_node() const;
   inline isl::checked::ast_node get_then_node() const;
-  inline boolean has_else_node() const;
 };
 
 // declarations for isl::ast_node_list
@@ -1184,12 +1310,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::ast_node_list add(isl::checked::ast_node el) const;
+  inline isl::checked::ast_node at(int index) const;
+  inline isl::checked::ast_node get_at(int index) const;
   inline isl::checked::ast_node_list clear() const;
   inline isl::checked::ast_node_list concat(isl::checked::ast_node_list list2) const;
   inline isl::checked::ast_node_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::ast_node)> &fn) const;
-  inline isl::checked::ast_node at(int index) const;
-  inline isl::checked::ast_node get_at(int index) const;
   inline isl::checked::ast_node_list insert(unsigned int pos, isl::checked::ast_node el) const;
   inline class size size() const;
 };
@@ -1266,24 +1392,146 @@
 
   inline isl::checked::basic_map affine_hull() const;
   inline isl::checked::basic_map apply_domain(isl::checked::basic_map bmap2) const;
+  inline isl::checked::map apply_domain(const isl::checked::map &map2) const;
+  inline isl::checked::union_map apply_domain(const isl::checked::union_map &umap2) const;
   inline isl::checked::basic_map apply_range(isl::checked::basic_map bmap2) const;
+  inline isl::checked::map apply_range(const isl::checked::map &map2) const;
+  inline isl::checked::union_map apply_range(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const;
+  inline isl::checked::set bind_domain(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::set bind_range(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::map coalesce() const;
+  inline isl::checked::map complement() const;
+  inline isl::checked::union_map compute_divs() const;
+  inline isl::checked::map curry() const;
   inline isl::checked::basic_set deltas() const;
   inline isl::checked::basic_map detect_equalities() const;
+  inline isl::checked::set domain() const;
+  inline isl::checked::map domain_factor_domain() const;
+  inline isl::checked::map domain_factor_range() const;
+  inline isl::checked::union_map domain_map() const;
+  inline isl::checked::union_pw_multi_aff domain_map_union_pw_multi_aff() const;
+  inline isl::checked::map domain_product(const isl::checked::map &map2) const;
+  inline isl::checked::union_map domain_product(const isl::checked::union_map &umap2) const;
+  inline class size domain_tuple_dim() const;
+  inline isl::checked::id domain_tuple_id() const;
+  inline isl::checked::map eq_at(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::union_map eq_at(const isl::checked::multi_union_pw_aff &mupa) const;
+  inline boolean every_map(const std::function<boolean(isl::checked::map)> &test) const;
+  inline isl::checked::map extract_map(const isl::checked::space &space) const;
+  inline isl::checked::map factor_domain() const;
+  inline isl::checked::map factor_range() const;
+  inline isl::checked::union_map fixed_power(const isl::checked::val &exp) const;
+  inline isl::checked::union_map fixed_power(long exp) const;
   inline isl::checked::basic_map flatten() const;
   inline isl::checked::basic_map flatten_domain() const;
   inline isl::checked::basic_map flatten_range() const;
+  inline stat foreach_basic_map(const std::function<stat(isl::checked::basic_map)> &fn) const;
+  inline stat foreach_map(const std::function<stat(isl::checked::map)> &fn) const;
   inline isl::checked::basic_map gist(isl::checked::basic_map context) const;
+  inline isl::checked::map gist(const isl::checked::map &context) const;
+  inline isl::checked::union_map gist(const isl::checked::union_map &context) const;
+  inline isl::checked::map gist_domain(const isl::checked::set &context) const;
+  inline isl::checked::union_map gist_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_map gist_params(const isl::checked::set &set) const;
+  inline isl::checked::union_map gist_range(const isl::checked::union_set &uset) const;
+  inline boolean has_domain_tuple_id() const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::basic_map intersect(isl::checked::basic_map bmap2) const;
+  inline isl::checked::map intersect(const isl::checked::map &map2) const;
+  inline isl::checked::union_map intersect(const isl::checked::union_map &umap2) const;
   inline isl::checked::basic_map intersect_domain(isl::checked::basic_set bset) const;
+  inline isl::checked::map intersect_domain(const isl::checked::set &set) const;
+  inline isl::checked::union_map intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_map intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::basic_map intersect_domain(const isl::checked::point &bset) const;
+  inline isl::checked::map intersect_domain_factor_domain(const isl::checked::map &factor) const;
+  inline isl::checked::union_map intersect_domain_factor_domain(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_domain_factor_range(const isl::checked::map &factor) const;
+  inline isl::checked::union_map intersect_domain_factor_range(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_params(const isl::checked::set &params) const;
   inline isl::checked::basic_map intersect_range(isl::checked::basic_set bset) const;
+  inline isl::checked::map intersect_range(const isl::checked::set &set) const;
+  inline isl::checked::union_map intersect_range(const isl::checked::space &space) const;
+  inline isl::checked::union_map intersect_range(const isl::checked::union_set &uset) const;
+  inline isl::checked::basic_map intersect_range(const isl::checked::point &bset) const;
+  inline isl::checked::map intersect_range_factor_domain(const isl::checked::map &factor) const;
+  inline isl::checked::union_map intersect_range_factor_domain(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_range_factor_range(const isl::checked::map &factor) const;
+  inline isl::checked::union_map intersect_range_factor_range(const isl::checked::union_map &factor) const;
+  inline boolean is_bijective() const;
+  inline boolean is_disjoint(const isl::checked::map &map2) const;
+  inline boolean is_disjoint(const isl::checked::union_map &umap2) const;
   inline boolean is_empty() const;
   inline boolean is_equal(const isl::checked::basic_map &bmap2) const;
+  inline boolean is_equal(const isl::checked::map &map2) const;
+  inline boolean is_equal(const isl::checked::union_map &umap2) const;
+  inline boolean is_injective() const;
+  inline boolean is_single_valued() const;
+  inline boolean is_strict_subset(const isl::checked::map &map2) const;
+  inline boolean is_strict_subset(const isl::checked::union_map &umap2) const;
   inline boolean is_subset(const isl::checked::basic_map &bmap2) const;
+  inline boolean is_subset(const isl::checked::map &map2) const;
+  inline boolean is_subset(const isl::checked::union_map &umap2) const;
+  inline boolean isa_map() const;
+  inline isl::checked::map lex_ge_at(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::map lex_gt_at(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::map lex_le_at(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::map lex_lt_at(const isl::checked::multi_pw_aff &mpa) const;
   inline isl::checked::map lexmax() const;
+  inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::checked::map lexmin() const;
+  inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::checked::map lower_bound(const isl::checked::multi_pw_aff &lower) const;
+  inline isl::checked::map_list map_list() const;
+  inline isl::checked::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::checked::basic_map polyhedral_hull() const;
+  inline isl::checked::map preimage_domain(const isl::checked::multi_aff &ma) const;
+  inline isl::checked::map preimage_domain(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::map preimage_domain(const isl::checked::pw_multi_aff &pma) const;
+  inline isl::checked::union_map preimage_domain(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::map preimage_range(const isl::checked::multi_aff &ma) const;
+  inline isl::checked::map preimage_range(const isl::checked::pw_multi_aff &pma) const;
+  inline isl::checked::union_map preimage_range(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::map product(const isl::checked::map &map2) const;
+  inline isl::checked::union_map product(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map project_out_all_params() const;
+  inline isl::checked::set range() const;
+  inline isl::checked::map range_factor_domain() const;
+  inline isl::checked::map range_factor_range() const;
+  inline isl::checked::fixed_box range_lattice_tile() const;
+  inline isl::checked::union_map range_map() const;
+  inline isl::checked::map range_product(const isl::checked::map &map2) const;
+  inline isl::checked::union_map range_product(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map range_reverse() const;
+  inline isl::checked::fixed_box range_simple_fixed_box_hull() const;
+  inline class size range_tuple_dim() const;
+  inline isl::checked::id range_tuple_id() const;
   inline isl::checked::basic_map reverse() const;
   inline isl::checked::basic_map sample() const;
+  inline isl::checked::map set_domain_tuple(const isl::checked::id &id) const;
+  inline isl::checked::map set_domain_tuple(const std::string &id) const;
+  inline isl::checked::map set_range_tuple(const isl::checked::id &id) const;
+  inline isl::checked::map set_range_tuple(const std::string &id) const;
+  inline isl::checked::space space() const;
+  inline isl::checked::map subtract(const isl::checked::map &map2) const;
+  inline isl::checked::union_map subtract(const isl::checked::union_map &umap2) const;
+  inline isl::checked::union_map subtract_domain(const isl::checked::union_set &dom) const;
+  inline isl::checked::union_map subtract_range(const isl::checked::union_set &dom) const;
+  inline isl::checked::map_list to_list() const;
+  inline isl::checked::union_map to_union_map() const;
+  inline isl::checked::map uncurry() const;
   inline isl::checked::map unite(isl::checked::basic_map bmap2) const;
+  inline isl::checked::map unite(const isl::checked::map &map2) const;
+  inline isl::checked::union_map unite(const isl::checked::union_map &umap2) const;
+  inline isl::checked::basic_map unshifted_simple_hull() const;
+  inline isl::checked::map upper_bound(const isl::checked::multi_pw_aff &upper) const;
+  inline isl::checked::set wrap() const;
+  inline isl::checked::map zip() const;
 };
 
 // declarations for isl::basic_set
@@ -1315,22 +1563,100 @@
 
   inline isl::checked::basic_set affine_hull() const;
   inline isl::checked::basic_set apply(isl::checked::basic_map bmap) const;
+  inline isl::checked::set apply(const isl::checked::map &map) const;
+  inline isl::checked::union_set apply(const isl::checked::union_map &umap) const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::set bind(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::set coalesce() const;
+  inline isl::checked::set complement() const;
+  inline isl::checked::union_set compute_divs() const;
   inline isl::checked::basic_set detect_equalities() const;
   inline isl::checked::val dim_max_val(int pos) const;
+  inline isl::checked::val dim_min_val(int pos) const;
+  inline boolean every_set(const std::function<boolean(isl::checked::set)> &test) const;
+  inline isl::checked::set extract_set(const isl::checked::space &space) const;
   inline isl::checked::basic_set flatten() const;
+  inline stat foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const;
+  inline stat foreach_point(const std::function<stat(isl::checked::point)> &fn) const;
+  inline stat foreach_set(const std::function<stat(isl::checked::set)> &fn) const;
   inline isl::checked::basic_set gist(isl::checked::basic_set context) const;
+  inline isl::checked::set gist(const isl::checked::set &context) const;
+  inline isl::checked::union_set gist(const isl::checked::union_set &context) const;
+  inline isl::checked::basic_set gist(const isl::checked::point &context) const;
+  inline isl::checked::union_set gist_params(const isl::checked::set &set) const;
+  inline isl::checked::map identity() const;
+  inline isl::checked::pw_aff indicator_function() const;
+  inline isl::checked::map insert_domain(const isl::checked::space &domain) const;
   inline isl::checked::basic_set intersect(isl::checked::basic_set bset2) const;
+  inline isl::checked::set intersect(const isl::checked::set &set2) const;
+  inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const;
+  inline isl::checked::basic_set intersect(const isl::checked::point &bset2) const;
   inline isl::checked::basic_set intersect_params(isl::checked::basic_set bset2) const;
+  inline isl::checked::set intersect_params(const isl::checked::set &params) const;
+  inline isl::checked::basic_set intersect_params(const isl::checked::point &bset2) const;
+  inline boolean involves_locals() const;
+  inline boolean is_disjoint(const isl::checked::set &set2) const;
+  inline boolean is_disjoint(const isl::checked::union_set &uset2) const;
   inline boolean is_empty() const;
   inline boolean is_equal(const isl::checked::basic_set &bset2) const;
+  inline boolean is_equal(const isl::checked::set &set2) const;
+  inline boolean is_equal(const isl::checked::union_set &uset2) const;
+  inline boolean is_equal(const isl::checked::point &bset2) const;
+  inline boolean is_singleton() const;
+  inline boolean is_strict_subset(const isl::checked::set &set2) const;
+  inline boolean is_strict_subset(const isl::checked::union_set &uset2) const;
   inline boolean is_subset(const isl::checked::basic_set &bset2) const;
+  inline boolean is_subset(const isl::checked::set &set2) const;
+  inline boolean is_subset(const isl::checked::union_set &uset2) const;
+  inline boolean is_subset(const isl::checked::point &bset2) const;
   inline boolean is_wrapping() const;
+  inline boolean isa_set() const;
   inline isl::checked::set lexmax() const;
+  inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::checked::set lexmin() const;
+  inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::checked::set lower_bound(const isl::checked::multi_pw_aff &lower) const;
+  inline isl::checked::set lower_bound(const isl::checked::multi_val &lower) const;
+  inline isl::checked::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::checked::val max_val(const isl::checked::aff &obj) const;
+  inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::checked::val min_val(const isl::checked::aff &obj) const;
   inline isl::checked::basic_set params() const;
+  inline isl::checked::multi_val plain_multi_val_if_fixed() const;
+  inline isl::checked::basic_set polyhedral_hull() const;
+  inline isl::checked::set preimage(const isl::checked::multi_aff &ma) const;
+  inline isl::checked::set preimage(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::set preimage(const isl::checked::pw_multi_aff &pma) const;
+  inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::set product(const isl::checked::set &set2) const;
+  inline isl::checked::set project_out_all_params() const;
+  inline isl::checked::set project_out_param(const isl::checked::id &id) const;
+  inline isl::checked::set project_out_param(const std::string &id) const;
+  inline isl::checked::set project_out_param(const isl::checked::id_list &list) const;
+  inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const;
   inline isl::checked::basic_set sample() const;
   inline isl::checked::point sample_point() const;
+  inline isl::checked::fixed_box simple_fixed_box_hull() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::val stride(int pos) const;
+  inline isl::checked::set subtract(const isl::checked::set &set2) const;
+  inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const;
+  inline isl::checked::union_set_list to_list() const;
+  inline isl::checked::set to_set() const;
+  inline isl::checked::union_set to_union_set() const;
+  inline isl::checked::map translation() const;
+  inline class size tuple_dim() const;
+  inline isl::checked::set unbind_params(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::map unbind_params_insert_domain(const isl::checked::multi_id &domain) const;
   inline isl::checked::set unite(isl::checked::basic_set bset2) const;
+  inline isl::checked::set unite(const isl::checked::set &set2) const;
+  inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const;
+  inline isl::checked::set unite(const isl::checked::point &bset2) const;
+  inline isl::checked::basic_set unshifted_simple_hull() const;
+  inline isl::checked::map unwrap() const;
+  inline isl::checked::set upper_bound(const isl::checked::multi_pw_aff &upper) const;
+  inline isl::checked::set upper_bound(const isl::checked::multi_val &upper) const;
 };
 
 // declarations for isl::fixed_box
@@ -1358,13 +1684,13 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
+  inline boolean is_valid() const;
   inline isl::checked::multi_aff offset() const;
   inline isl::checked::multi_aff get_offset() const;
   inline isl::checked::multi_val size() const;
   inline isl::checked::multi_val get_size() const;
   inline isl::checked::space space() const;
   inline isl::checked::space get_space() const;
-  inline boolean is_valid() const;
 };
 
 // declarations for isl::id
@@ -1395,6 +1721,7 @@
 
   inline std::string name() const;
   inline std::string get_name() const;
+  inline isl::checked::id_list to_list() const;
 };
 
 // declarations for isl::id_list
@@ -1415,6 +1742,7 @@
   inline /* implicit */ id_list(const id_list &obj);
   inline explicit id_list(isl::checked::ctx ctx, int n);
   inline explicit id_list(isl::checked::id el);
+  inline explicit id_list(isl::checked::ctx ctx, const std::string &str);
   inline id_list &operator=(id_list obj);
   inline ~id_list();
   inline __isl_give isl_id_list *copy() const &;
@@ -1426,12 +1754,12 @@
 
   inline isl::checked::id_list add(isl::checked::id el) const;
   inline isl::checked::id_list add(const std::string &el) const;
+  inline isl::checked::id at(int index) const;
+  inline isl::checked::id get_at(int index) const;
   inline isl::checked::id_list clear() const;
   inline isl::checked::id_list concat(isl::checked::id_list list2) const;
   inline isl::checked::id_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::id)> &fn) const;
-  inline isl::checked::id at(int index) const;
-  inline isl::checked::id get_at(int index) const;
   inline isl::checked::id_list insert(unsigned int pos, isl::checked::id el) const;
   inline isl::checked::id_list insert(unsigned int pos, const std::string &el) const;
   inline class size size() const;
@@ -1466,48 +1794,106 @@
 
   inline isl::checked::basic_map affine_hull() const;
   inline isl::checked::map apply_domain(isl::checked::map map2) const;
+  inline isl::checked::union_map apply_domain(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map apply_domain(const isl::checked::basic_map &map2) const;
   inline isl::checked::map apply_range(isl::checked::map map2) const;
+  inline isl::checked::union_map apply_range(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map apply_range(const isl::checked::basic_map &map2) const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const;
   inline isl::checked::set bind_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::set bind_range(isl::checked::multi_id tuple) const;
   inline isl::checked::map coalesce() const;
   inline isl::checked::map complement() const;
+  inline isl::checked::union_map compute_divs() const;
   inline isl::checked::map curry() const;
   inline isl::checked::set deltas() const;
   inline isl::checked::map detect_equalities() const;
   inline isl::checked::set domain() const;
   inline isl::checked::map domain_factor_domain() const;
   inline isl::checked::map domain_factor_range() const;
+  inline isl::checked::union_map domain_map() const;
+  inline isl::checked::union_pw_multi_aff domain_map_union_pw_multi_aff() const;
   inline isl::checked::map domain_product(isl::checked::map map2) const;
+  inline isl::checked::union_map domain_product(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map domain_product(const isl::checked::basic_map &map2) const;
+  inline class size domain_tuple_dim() const;
+  inline isl::checked::id domain_tuple_id() const;
+  inline isl::checked::id get_domain_tuple_id() const;
   static inline isl::checked::map empty(isl::checked::space space);
   inline isl::checked::map eq_at(isl::checked::multi_pw_aff mpa) const;
+  inline isl::checked::union_map eq_at(const isl::checked::multi_union_pw_aff &mupa) const;
+  inline isl::checked::map eq_at(const isl::checked::aff &mpa) const;
+  inline isl::checked::map eq_at(const isl::checked::multi_aff &mpa) const;
+  inline isl::checked::map eq_at(const isl::checked::pw_aff &mpa) const;
+  inline isl::checked::map eq_at(const isl::checked::pw_multi_aff &mpa) const;
+  inline boolean every_map(const std::function<boolean(isl::checked::map)> &test) const;
+  inline isl::checked::map extract_map(const isl::checked::space &space) const;
   inline isl::checked::map factor_domain() const;
   inline isl::checked::map factor_range() const;
+  inline isl::checked::union_map fixed_power(const isl::checked::val &exp) const;
+  inline isl::checked::union_map fixed_power(long exp) const;
   inline isl::checked::map flatten() const;
   inline isl::checked::map flatten_domain() const;
   inline isl::checked::map flatten_range() const;
   inline stat foreach_basic_map(const std::function<stat(isl::checked::basic_map)> &fn) const;
-  inline isl::checked::fixed_box range_simple_fixed_box_hull() const;
-  inline isl::checked::fixed_box get_range_simple_fixed_box_hull() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
+  inline stat foreach_map(const std::function<stat(isl::checked::map)> &fn) const;
   inline isl::checked::map gist(isl::checked::map context) const;
+  inline isl::checked::union_map gist(const isl::checked::union_map &context) const;
+  inline isl::checked::map gist(const isl::checked::basic_map &context) const;
   inline isl::checked::map gist_domain(isl::checked::set context) const;
+  inline isl::checked::union_map gist_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::map gist_domain(const isl::checked::basic_set &context) const;
+  inline isl::checked::map gist_domain(const isl::checked::point &context) const;
+  inline isl::checked::union_map gist_params(const isl::checked::set &set) const;
+  inline isl::checked::union_map gist_range(const isl::checked::union_set &uset) const;
+  inline boolean has_domain_tuple_id() const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::map intersect(isl::checked::map map2) const;
+  inline isl::checked::union_map intersect(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map intersect(const isl::checked::basic_map &map2) const;
   inline isl::checked::map intersect_domain(isl::checked::set set) const;
+  inline isl::checked::union_map intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_map intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::map intersect_domain(const isl::checked::basic_set &set) const;
+  inline isl::checked::map intersect_domain(const isl::checked::point &set) const;
   inline isl::checked::map intersect_domain_factor_domain(isl::checked::map factor) const;
+  inline isl::checked::union_map intersect_domain_factor_domain(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_domain_factor_domain(const isl::checked::basic_map &factor) const;
   inline isl::checked::map intersect_domain_factor_range(isl::checked::map factor) const;
+  inline isl::checked::union_map intersect_domain_factor_range(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_domain_factor_range(const isl::checked::basic_map &factor) const;
   inline isl::checked::map intersect_params(isl::checked::set params) const;
   inline isl::checked::map intersect_range(isl::checked::set set) const;
+  inline isl::checked::union_map intersect_range(const isl::checked::space &space) const;
+  inline isl::checked::union_map intersect_range(const isl::checked::union_set &uset) const;
+  inline isl::checked::map intersect_range(const isl::checked::basic_set &set) const;
+  inline isl::checked::map intersect_range(const isl::checked::point &set) const;
   inline isl::checked::map intersect_range_factor_domain(isl::checked::map factor) const;
+  inline isl::checked::union_map intersect_range_factor_domain(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_range_factor_domain(const isl::checked::basic_map &factor) const;
   inline isl::checked::map intersect_range_factor_range(isl::checked::map factor) const;
+  inline isl::checked::union_map intersect_range_factor_range(const isl::checked::union_map &factor) const;
+  inline isl::checked::map intersect_range_factor_range(const isl::checked::basic_map &factor) const;
   inline boolean is_bijective() const;
   inline boolean is_disjoint(const isl::checked::map &map2) const;
+  inline boolean is_disjoint(const isl::checked::union_map &umap2) const;
+  inline boolean is_disjoint(const isl::checked::basic_map &map2) const;
   inline boolean is_empty() const;
   inline boolean is_equal(const isl::checked::map &map2) const;
+  inline boolean is_equal(const isl::checked::union_map &umap2) const;
+  inline boolean is_equal(const isl::checked::basic_map &map2) const;
   inline boolean is_injective() const;
   inline boolean is_single_valued() const;
   inline boolean is_strict_subset(const isl::checked::map &map2) const;
+  inline boolean is_strict_subset(const isl::checked::union_map &umap2) const;
+  inline boolean is_strict_subset(const isl::checked::basic_map &map2) const;
   inline boolean is_subset(const isl::checked::map &map2) const;
+  inline boolean is_subset(const isl::checked::union_map &umap2) const;
+  inline boolean is_subset(const isl::checked::basic_map &map2) const;
+  inline boolean isa_map() const;
   inline isl::checked::map lex_ge_at(isl::checked::multi_pw_aff mpa) const;
   inline isl::checked::map lex_gt_at(isl::checked::multi_pw_aff mpa) const;
   inline isl::checked::map lex_le_at(isl::checked::multi_pw_aff mpa) const;
@@ -1517,26 +1903,55 @@
   inline isl::checked::map lexmin() const;
   inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const;
   inline isl::checked::map lower_bound(isl::checked::multi_pw_aff lower) const;
+  inline isl::checked::map_list map_list() const;
   inline isl::checked::multi_pw_aff max_multi_pw_aff() const;
   inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
   inline isl::checked::basic_map polyhedral_hull() const;
   inline isl::checked::map preimage_domain(isl::checked::multi_aff ma) const;
   inline isl::checked::map preimage_domain(isl::checked::multi_pw_aff mpa) const;
   inline isl::checked::map preimage_domain(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::union_map preimage_domain(const isl::checked::union_pw_multi_aff &upma) const;
   inline isl::checked::map preimage_range(isl::checked::multi_aff ma) const;
   inline isl::checked::map preimage_range(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::union_map preimage_range(const isl::checked::union_pw_multi_aff &upma) const;
   inline isl::checked::map product(isl::checked::map map2) const;
+  inline isl::checked::union_map product(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map product(const isl::checked::basic_map &map2) const;
   inline isl::checked::map project_out_all_params() const;
   inline isl::checked::set range() const;
   inline isl::checked::map range_factor_domain() const;
   inline isl::checked::map range_factor_range() const;
+  inline isl::checked::fixed_box range_lattice_tile() const;
+  inline isl::checked::fixed_box get_range_lattice_tile() const;
+  inline isl::checked::union_map range_map() const;
   inline isl::checked::map range_product(isl::checked::map map2) const;
+  inline isl::checked::union_map range_product(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map range_product(const isl::checked::basic_map &map2) const;
   inline isl::checked::map range_reverse() const;
+  inline isl::checked::fixed_box range_simple_fixed_box_hull() const;
+  inline isl::checked::fixed_box get_range_simple_fixed_box_hull() const;
+  inline class size range_tuple_dim() const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
   inline isl::checked::map reverse() const;
   inline isl::checked::basic_map sample() const;
+  inline isl::checked::map set_domain_tuple(isl::checked::id id) const;
+  inline isl::checked::map set_domain_tuple(const std::string &id) const;
+  inline isl::checked::map set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::map set_range_tuple(const std::string &id) const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::map subtract(isl::checked::map map2) const;
+  inline isl::checked::union_map subtract(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map subtract(const isl::checked::basic_map &map2) const;
+  inline isl::checked::union_map subtract_domain(const isl::checked::union_set &dom) const;
+  inline isl::checked::union_map subtract_range(const isl::checked::union_set &dom) const;
+  inline isl::checked::map_list to_list() const;
+  inline isl::checked::union_map to_union_map() const;
   inline isl::checked::map uncurry() const;
   inline isl::checked::map unite(isl::checked::map map2) const;
+  inline isl::checked::union_map unite(const isl::checked::union_map &umap2) const;
+  inline isl::checked::map unite(const isl::checked::basic_map &map2) const;
   static inline isl::checked::map universe(isl::checked::space space);
   inline isl::checked::basic_map unshifted_simple_hull() const;
   inline isl::checked::map upper_bound(isl::checked::multi_pw_aff upper) const;
@@ -1544,6 +1959,45 @@
   inline isl::checked::map zip() const;
 };
 
+// declarations for isl::map_list
+inline map_list manage(__isl_take isl_map_list *ptr);
+inline map_list manage_copy(__isl_keep isl_map_list *ptr);
+
+class map_list {
+  friend inline map_list manage(__isl_take isl_map_list *ptr);
+  friend inline map_list manage_copy(__isl_keep isl_map_list *ptr);
+
+protected:
+  isl_map_list *ptr = nullptr;
+
+  inline explicit map_list(__isl_take isl_map_list *ptr);
+
+public:
+  inline /* implicit */ map_list();
+  inline /* implicit */ map_list(const map_list &obj);
+  inline explicit map_list(isl::checked::ctx ctx, int n);
+  inline explicit map_list(isl::checked::map el);
+  inline explicit map_list(isl::checked::ctx ctx, const std::string &str);
+  inline map_list &operator=(map_list obj);
+  inline ~map_list();
+  inline __isl_give isl_map_list *copy() const &;
+  inline __isl_give isl_map_list *copy() && = delete;
+  inline __isl_keep isl_map_list *get() const;
+  inline __isl_give isl_map_list *release();
+  inline bool is_null() const;
+  inline isl::checked::ctx ctx() const;
+
+  inline isl::checked::map_list add(isl::checked::map el) const;
+  inline isl::checked::map at(int index) const;
+  inline isl::checked::map get_at(int index) const;
+  inline isl::checked::map_list clear() const;
+  inline isl::checked::map_list concat(isl::checked::map_list list2) const;
+  inline isl::checked::map_list drop(unsigned int first, unsigned int n) const;
+  inline stat foreach(const std::function<stat(isl::checked::map)> &fn) const;
+  inline isl::checked::map_list insert(unsigned int pos, isl::checked::map el) const;
+  inline class size size() const;
+};
+
 // declarations for isl::multi_aff
 inline multi_aff manage(__isl_take isl_multi_aff *ptr);
 inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr);
@@ -1573,35 +2027,99 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::multi_aff add(isl::checked::multi_aff multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff add(const isl::checked::aff &multi2) const;
   inline isl::checked::multi_aff add_constant(isl::checked::multi_val mv) const;
   inline isl::checked::multi_aff add_constant(isl::checked::val v) const;
   inline isl::checked::multi_aff add_constant(long v) const;
+  inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_aff as_multi_aff() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::union_map as_union_map() const;
+  inline isl::checked::aff at(int pos) const;
+  inline isl::checked::aff get_at(int pos) const;
   inline isl::checked::basic_set bind(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_aff bind_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const;
-  static inline isl::checked::multi_aff domain_map(isl::checked::space space);
-  inline isl::checked::multi_aff flat_range_product(isl::checked::multi_aff multi2) const;
-  inline isl::checked::multi_aff floor() const;
-  inline isl::checked::aff at(int pos) const;
-  inline isl::checked::aff get_at(int pos) const;
+  inline isl::checked::pw_multi_aff coalesce() const;
   inline isl::checked::multi_val constant_multi_val() const;
   inline isl::checked::multi_val get_constant_multi_val() const;
-  inline isl::checked::aff_list list() const;
-  inline isl::checked::aff_list get_list() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
+  inline isl::checked::set domain() const;
+  static inline isl::checked::multi_aff domain_map(isl::checked::space space);
+  inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const;
+  inline isl::checked::multi_aff flat_range_product(isl::checked::multi_aff multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff flat_range_product(const isl::checked::aff &multi2) const;
+  inline isl::checked::multi_aff floor() const;
+  inline stat foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const;
   inline isl::checked::multi_aff gist(isl::checked::set context) const;
+  inline isl::checked::union_pw_multi_aff gist(const isl::checked::union_set &context) const;
+  inline isl::checked::multi_aff gist(const isl::checked::basic_set &context) const;
+  inline isl::checked::multi_aff gist(const isl::checked::point &context) const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::multi_aff identity() const;
   static inline isl::checked::multi_aff identity_on_domain(isl::checked::space space);
   inline isl::checked::multi_aff insert_domain(isl::checked::space domain) const;
+  inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::set &set) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_multi_aff intersect_params(const isl::checked::set &set) const;
   inline boolean involves_locals() const;
   inline boolean involves_nan() const;
+  inline boolean involves_param(const isl::checked::id &id) const;
+  inline boolean involves_param(const std::string &id) const;
+  inline boolean involves_param(const isl::checked::id_list &list) const;
+  inline boolean isa_multi_aff() const;
+  inline boolean isa_pw_multi_aff() const;
+  inline isl::checked::aff_list list() const;
+  inline isl::checked::aff_list get_list() const;
+  inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_val max_multi_val() const;
+  inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_val min_multi_val() const;
+  static inline isl::checked::multi_aff multi_val_on_domain(isl::checked::space space, isl::checked::multi_val mv);
+  inline class size n_piece() const;
   inline isl::checked::multi_aff neg() const;
+  inline boolean plain_is_empty() const;
   inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::aff &multi2) const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::multi_aff product(isl::checked::multi_aff multi2) const;
+  inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::multi_aff product(const isl::checked::aff &multi2) const;
   inline isl::checked::multi_aff pullback(isl::checked::multi_aff ma2) const;
+  inline isl::checked::multi_pw_aff pullback(const isl::checked::multi_pw_aff &mpa2) const;
+  inline isl::checked::pw_multi_aff pullback(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff pullback(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff pullback(const isl::checked::aff &ma2) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::checked::pw_multi_aff range_factor_domain() const;
+  inline isl::checked::pw_multi_aff range_factor_range() const;
   static inline isl::checked::multi_aff range_map(isl::checked::space space);
   inline isl::checked::multi_aff range_product(isl::checked::multi_aff multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff range_product(const isl::checked::aff &multi2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
+  inline isl::checked::multi_aff reset_range_tuple_id() const;
   inline isl::checked::multi_aff scale(isl::checked::multi_val mv) const;
   inline isl::checked::multi_aff scale(isl::checked::val v) const;
   inline isl::checked::multi_aff scale(long v) const;
@@ -1609,9 +2127,32 @@
   inline isl::checked::multi_aff scale_down(isl::checked::val v) const;
   inline isl::checked::multi_aff scale_down(long v) const;
   inline isl::checked::multi_aff set_at(int pos, isl::checked::aff el) const;
+  inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::multi_aff set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::multi_aff set_range_tuple(const std::string &id) const;
   inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::multi_aff sub(isl::checked::multi_aff multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_aff sub(const isl::checked::aff &multi2) const;
+  inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::set &set) const;
+  inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_multi_aff_list to_list() const;
+  inline isl::checked::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::checked::multi_union_pw_aff to_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff to_pw_multi_aff() const;
+  inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const;
   inline isl::checked::multi_aff unbind_params_insert_domain(isl::checked::multi_id domain) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
+  inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const;
   static inline isl::checked::multi_aff zero(isl::checked::space space);
 };
 
@@ -1642,18 +2183,18 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
-  inline isl::checked::multi_id flat_range_product(isl::checked::multi_id multi2) const;
   inline isl::checked::id at(int pos) const;
   inline isl::checked::id get_at(int pos) const;
+  inline isl::checked::multi_id flat_range_product(isl::checked::multi_id multi2) const;
   inline isl::checked::id_list list() const;
   inline isl::checked::id_list get_list() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline boolean plain_is_equal(const isl::checked::multi_id &multi2) const;
   inline isl::checked::multi_id range_product(isl::checked::multi_id multi2) const;
   inline isl::checked::multi_id set_at(int pos, isl::checked::id el) const;
   inline isl::checked::multi_id set_at(int pos, const std::string &el) const;
   inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
 };
 
 // declarations for isl::multi_pw_aff
@@ -1688,42 +2229,75 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::multi_pw_aff add(isl::checked::multi_pw_aff multi2) const;
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::aff &multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff add(const isl::checked::pw_multi_aff &multi2) const;
   inline isl::checked::multi_pw_aff add_constant(isl::checked::multi_val mv) const;
   inline isl::checked::multi_pw_aff add_constant(isl::checked::val v) const;
   inline isl::checked::multi_pw_aff add_constant(long v) const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_aff as_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::pw_aff at(int pos) const;
+  inline isl::checked::pw_aff get_at(int pos) const;
   inline isl::checked::set bind(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_pw_aff bind_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_pw_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_pw_aff coalesce() const;
   inline isl::checked::set domain() const;
   inline isl::checked::multi_pw_aff flat_range_product(isl::checked::multi_pw_aff multi2) const;
-  inline isl::checked::pw_aff at(int pos) const;
-  inline isl::checked::pw_aff get_at(int pos) const;
-  inline isl::checked::pw_aff_list list() const;
-  inline isl::checked::pw_aff_list get_list() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::aff &multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::pw_multi_aff &multi2) const;
   inline isl::checked::multi_pw_aff gist(isl::checked::set set) const;
+  inline isl::checked::multi_union_pw_aff gist(const isl::checked::union_set &context) const;
+  inline isl::checked::multi_pw_aff gist(const isl::checked::basic_set &set) const;
+  inline isl::checked::multi_pw_aff gist(const isl::checked::point &set) const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::multi_pw_aff identity() const;
   static inline isl::checked::multi_pw_aff identity_on_domain(isl::checked::space space);
   inline isl::checked::multi_pw_aff insert_domain(isl::checked::space domain) const;
   inline isl::checked::multi_pw_aff intersect_domain(isl::checked::set domain) const;
+  inline isl::checked::multi_union_pw_aff intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::multi_pw_aff intersect_domain(const isl::checked::basic_set &domain) const;
+  inline isl::checked::multi_pw_aff intersect_domain(const isl::checked::point &domain) const;
   inline isl::checked::multi_pw_aff intersect_params(isl::checked::set set) const;
   inline boolean involves_nan() const;
   inline boolean involves_param(const isl::checked::id &id) const;
   inline boolean involves_param(const std::string &id) const;
   inline boolean involves_param(const isl::checked::id_list &list) const;
+  inline boolean isa_multi_aff() const;
+  inline isl::checked::pw_aff_list list() const;
+  inline isl::checked::pw_aff_list get_list() const;
   inline isl::checked::multi_pw_aff max(isl::checked::multi_pw_aff multi2) const;
   inline isl::checked::multi_val max_multi_val() const;
   inline isl::checked::multi_pw_aff min(isl::checked::multi_pw_aff multi2) const;
   inline isl::checked::multi_val min_multi_val() const;
   inline isl::checked::multi_pw_aff neg() const;
   inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::pw_multi_aff &multi2) const;
   inline isl::checked::multi_pw_aff product(isl::checked::multi_pw_aff multi2) const;
   inline isl::checked::multi_pw_aff pullback(isl::checked::multi_aff ma) const;
   inline isl::checked::multi_pw_aff pullback(isl::checked::multi_pw_aff mpa2) const;
   inline isl::checked::multi_pw_aff pullback(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::multi_union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const;
   inline isl::checked::multi_pw_aff range_product(isl::checked::multi_pw_aff multi2) const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::aff &multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::pw_multi_aff &multi2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff reset_range_tuple_id() const;
   inline isl::checked::multi_pw_aff scale(isl::checked::multi_val mv) const;
   inline isl::checked::multi_pw_aff scale(isl::checked::val v) const;
   inline isl::checked::multi_pw_aff scale(long v) const;
@@ -1731,10 +2305,25 @@
   inline isl::checked::multi_pw_aff scale_down(isl::checked::val v) const;
   inline isl::checked::multi_pw_aff scale_down(long v) const;
   inline isl::checked::multi_pw_aff set_at(int pos, isl::checked::pw_aff el) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::multi_pw_aff set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::multi_pw_aff set_range_tuple(const std::string &id) const;
   inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::multi_pw_aff sub(isl::checked::multi_pw_aff multi2) const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::aff &multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::multi_aff &multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::pw_aff &multi2) const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::pw_multi_aff &multi2) const;
   inline isl::checked::multi_pw_aff unbind_params_insert_domain(isl::checked::multi_id domain) const;
   inline isl::checked::multi_pw_aff union_add(isl::checked::multi_pw_aff mpa2) const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::aff &mpa2) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_aff &mpa2) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::pw_aff &mpa2) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::pw_multi_aff &mpa2) const;
   static inline isl::checked::multi_pw_aff zero(isl::checked::space space);
 };
 
@@ -1768,24 +2357,26 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::multi_union_pw_aff add(isl::checked::multi_union_pw_aff multi2) const;
+  inline isl::checked::union_pw_aff at(int pos) const;
+  inline isl::checked::union_pw_aff get_at(int pos) const;
   inline isl::checked::union_set bind(isl::checked::multi_id tuple) const;
   inline isl::checked::multi_union_pw_aff coalesce() const;
   inline isl::checked::union_set domain() const;
   inline isl::checked::multi_union_pw_aff flat_range_product(isl::checked::multi_union_pw_aff multi2) const;
-  inline isl::checked::union_pw_aff at(int pos) const;
-  inline isl::checked::union_pw_aff get_at(int pos) const;
-  inline isl::checked::union_pw_aff_list list() const;
-  inline isl::checked::union_pw_aff_list get_list() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline isl::checked::multi_union_pw_aff gist(isl::checked::union_set context) const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::multi_union_pw_aff intersect_domain(isl::checked::union_set uset) const;
   inline isl::checked::multi_union_pw_aff intersect_params(isl::checked::set params) const;
   inline boolean involves_nan() const;
+  inline isl::checked::union_pw_aff_list list() const;
+  inline isl::checked::union_pw_aff_list get_list() const;
   inline isl::checked::multi_union_pw_aff neg() const;
   inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::multi_union_pw_aff pullback(isl::checked::union_pw_multi_aff upma) const;
   inline isl::checked::multi_union_pw_aff range_product(isl::checked::multi_union_pw_aff multi2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
+  inline isl::checked::multi_union_pw_aff reset_range_tuple_id() const;
   inline isl::checked::multi_union_pw_aff scale(isl::checked::multi_val mv) const;
   inline isl::checked::multi_union_pw_aff scale(isl::checked::val v) const;
   inline isl::checked::multi_union_pw_aff scale(long v) const;
@@ -1793,7 +2384,11 @@
   inline isl::checked::multi_union_pw_aff scale_down(isl::checked::val v) const;
   inline isl::checked::multi_union_pw_aff scale_down(long v) const;
   inline isl::checked::multi_union_pw_aff set_at(int pos, isl::checked::union_pw_aff el) const;
+  inline isl::checked::multi_union_pw_aff set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::multi_union_pw_aff set_range_tuple(const std::string &id) const;
   inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::multi_union_pw_aff sub(isl::checked::multi_union_pw_aff multi2) const;
   inline isl::checked::multi_union_pw_aff union_add(isl::checked::multi_union_pw_aff mupa2) const;
   static inline isl::checked::multi_union_pw_aff zero(isl::checked::space space);
@@ -1829,20 +2424,22 @@
   inline isl::checked::multi_val add(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val add(isl::checked::val v) const;
   inline isl::checked::multi_val add(long v) const;
-  inline isl::checked::multi_val flat_range_product(isl::checked::multi_val multi2) const;
   inline isl::checked::val at(int pos) const;
   inline isl::checked::val get_at(int pos) const;
+  inline isl::checked::multi_val flat_range_product(isl::checked::multi_val multi2) const;
+  inline boolean has_range_tuple_id() const;
+  inline boolean involves_nan() const;
   inline isl::checked::val_list list() const;
   inline isl::checked::val_list get_list() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
-  inline boolean involves_nan() const;
   inline isl::checked::multi_val max(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val min(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val neg() const;
   inline boolean plain_is_equal(const isl::checked::multi_val &multi2) const;
   inline isl::checked::multi_val product(isl::checked::multi_val multi2) const;
   inline isl::checked::multi_val range_product(isl::checked::multi_val multi2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
+  inline isl::checked::multi_val reset_range_tuple_id() const;
   inline isl::checked::multi_val scale(isl::checked::multi_val mv) const;
   inline isl::checked::multi_val scale(isl::checked::val v) const;
   inline isl::checked::multi_val scale(long v) const;
@@ -1851,7 +2448,11 @@
   inline isl::checked::multi_val scale_down(long v) const;
   inline isl::checked::multi_val set_at(int pos, isl::checked::val el) const;
   inline isl::checked::multi_val set_at(int pos, long el) const;
+  inline isl::checked::multi_val set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::multi_val set_range_tuple(const std::string &id) const;
   inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::multi_val sub(isl::checked::multi_val multi2) const;
   static inline isl::checked::multi_val zero(isl::checked::space space);
 };
@@ -1881,8 +2482,98 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
+  inline isl::checked::basic_set affine_hull() const;
+  inline isl::checked::basic_set apply(const isl::checked::basic_map &bmap) const;
+  inline isl::checked::set apply(const isl::checked::map &map) const;
+  inline isl::checked::union_set apply(const isl::checked::union_map &umap) const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::set bind(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::set coalesce() const;
+  inline isl::checked::set complement() const;
+  inline isl::checked::union_set compute_divs() const;
+  inline isl::checked::basic_set detect_equalities() const;
+  inline isl::checked::val dim_max_val(int pos) const;
+  inline isl::checked::val dim_min_val(int pos) const;
+  inline boolean every_set(const std::function<boolean(isl::checked::set)> &test) const;
+  inline isl::checked::set extract_set(const isl::checked::space &space) const;
+  inline isl::checked::basic_set flatten() const;
+  inline stat foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const;
+  inline stat foreach_point(const std::function<stat(isl::checked::point)> &fn) const;
+  inline stat foreach_set(const std::function<stat(isl::checked::set)> &fn) const;
+  inline isl::checked::basic_set gist(const isl::checked::basic_set &context) const;
+  inline isl::checked::set gist(const isl::checked::set &context) const;
+  inline isl::checked::union_set gist(const isl::checked::union_set &context) const;
+  inline isl::checked::union_set gist_params(const isl::checked::set &set) const;
+  inline isl::checked::map identity() const;
+  inline isl::checked::pw_aff indicator_function() const;
+  inline isl::checked::map insert_domain(const isl::checked::space &domain) const;
+  inline isl::checked::basic_set intersect(const isl::checked::basic_set &bset2) const;
+  inline isl::checked::set intersect(const isl::checked::set &set2) const;
+  inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const;
+  inline isl::checked::basic_set intersect_params(const isl::checked::basic_set &bset2) const;
+  inline isl::checked::set intersect_params(const isl::checked::set &params) const;
+  inline boolean involves_locals() const;
+  inline boolean is_disjoint(const isl::checked::set &set2) const;
+  inline boolean is_disjoint(const isl::checked::union_set &uset2) const;
+  inline boolean is_empty() const;
+  inline boolean is_equal(const isl::checked::basic_set &bset2) const;
+  inline boolean is_equal(const isl::checked::set &set2) const;
+  inline boolean is_equal(const isl::checked::union_set &uset2) const;
+  inline boolean is_singleton() const;
+  inline boolean is_strict_subset(const isl::checked::set &set2) const;
+  inline boolean is_strict_subset(const isl::checked::union_set &uset2) const;
+  inline boolean is_subset(const isl::checked::basic_set &bset2) const;
+  inline boolean is_subset(const isl::checked::set &set2) const;
+  inline boolean is_subset(const isl::checked::union_set &uset2) const;
+  inline boolean is_wrapping() const;
+  inline boolean isa_set() const;
+  inline isl::checked::set lexmax() const;
+  inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const;
+  inline isl::checked::set lexmin() const;
+  inline isl::checked::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::checked::set lower_bound(const isl::checked::multi_pw_aff &lower) const;
+  inline isl::checked::set lower_bound(const isl::checked::multi_val &lower) const;
+  inline isl::checked::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::checked::val max_val(const isl::checked::aff &obj) const;
+  inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::checked::val min_val(const isl::checked::aff &obj) const;
   inline isl::checked::multi_val multi_val() const;
   inline isl::checked::multi_val get_multi_val() const;
+  inline isl::checked::basic_set params() const;
+  inline isl::checked::multi_val plain_multi_val_if_fixed() const;
+  inline isl::checked::basic_set polyhedral_hull() const;
+  inline isl::checked::set preimage(const isl::checked::multi_aff &ma) const;
+  inline isl::checked::set preimage(const isl::checked::multi_pw_aff &mpa) const;
+  inline isl::checked::set preimage(const isl::checked::pw_multi_aff &pma) const;
+  inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::set product(const isl::checked::set &set2) const;
+  inline isl::checked::set project_out_all_params() const;
+  inline isl::checked::set project_out_param(const isl::checked::id &id) const;
+  inline isl::checked::set project_out_param(const std::string &id) const;
+  inline isl::checked::set project_out_param(const isl::checked::id_list &list) const;
+  inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const;
+  inline isl::checked::basic_set sample() const;
+  inline isl::checked::point sample_point() const;
+  inline isl::checked::fixed_box simple_fixed_box_hull() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::val stride(int pos) const;
+  inline isl::checked::set subtract(const isl::checked::set &set2) const;
+  inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const;
+  inline isl::checked::union_set_list to_list() const;
+  inline isl::checked::set to_set() const;
+  inline isl::checked::union_set to_union_set() const;
+  inline isl::checked::map translation() const;
+  inline class size tuple_dim() const;
+  inline isl::checked::set unbind_params(const isl::checked::multi_id &tuple) const;
+  inline isl::checked::map unbind_params_insert_domain(const isl::checked::multi_id &domain) const;
+  inline isl::checked::set unite(const isl::checked::basic_set &bset2) const;
+  inline isl::checked::set unite(const isl::checked::set &set2) const;
+  inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const;
+  inline isl::checked::basic_set unshifted_simple_hull() const;
+  inline isl::checked::map unwrap() const;
+  inline isl::checked::set upper_bound(const isl::checked::multi_pw_aff &upper) const;
+  inline isl::checked::set upper_bound(const isl::checked::multi_val &upper) const;
 };
 
 // declarations for isl::pw_aff
@@ -1912,10 +2603,26 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
+  inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_aff add(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_multi_aff add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff add(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_aff add(const isl::checked::aff &pwaff2) const;
   inline isl::checked::pw_aff add_constant(isl::checked::val v) const;
   inline isl::checked::pw_aff add_constant(long v) const;
+  inline isl::checked::pw_multi_aff add_constant(const isl::checked::multi_val &mv) const;
+  inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::aff as_aff() const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_aff as_multi_aff() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::union_map as_union_map() const;
+  inline isl::checked::pw_aff at(int pos) const;
+  inline isl::checked::set bind(const isl::checked::multi_id &tuple) const;
   inline isl::checked::set bind(isl::checked::id id) const;
   inline isl::checked::set bind(const std::string &id) const;
   inline isl::checked::pw_aff bind_domain(isl::checked::multi_id tuple) const;
@@ -1927,36 +2634,114 @@
   inline isl::checked::set domain() const;
   inline isl::checked::set eq_set(isl::checked::pw_aff pwaff2) const;
   inline isl::checked::val eval(isl::checked::point pnt) const;
+  inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::pw_aff floor() const;
+  inline stat foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const;
   inline isl::checked::set ge_set(isl::checked::pw_aff pwaff2) const;
   inline isl::checked::pw_aff gist(isl::checked::set context) const;
+  inline isl::checked::union_pw_aff gist(const isl::checked::union_set &context) const;
+  inline isl::checked::pw_aff gist(const isl::checked::basic_set &context) const;
+  inline isl::checked::pw_aff gist(const isl::checked::point &context) const;
   inline isl::checked::set gt_set(isl::checked::pw_aff pwaff2) const;
+  inline boolean has_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff identity() const;
   inline isl::checked::pw_aff insert_domain(isl::checked::space domain) const;
   inline isl::checked::pw_aff intersect_domain(isl::checked::set set) const;
+  inline isl::checked::union_pw_aff intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_aff intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_aff intersect_domain(const isl::checked::basic_set &set) const;
+  inline isl::checked::pw_aff intersect_domain(const isl::checked::point &set) const;
+  inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const;
   inline isl::checked::pw_aff intersect_params(isl::checked::set set) const;
+  inline boolean involves_locals() const;
+  inline boolean involves_nan() const;
+  inline boolean involves_param(const isl::checked::id &id) const;
+  inline boolean involves_param(const std::string &id) const;
+  inline boolean involves_param(const isl::checked::id_list &list) const;
   inline boolean isa_aff() const;
+  inline boolean isa_multi_aff() const;
+  inline boolean isa_pw_multi_aff() const;
   inline isl::checked::set le_set(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_aff_list list() const;
   inline isl::checked::set lt_set(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const;
   inline isl::checked::pw_aff max(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_aff max(const isl::checked::aff &pwaff2) const;
+  inline isl::checked::multi_val max_multi_val() const;
+  inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const;
   inline isl::checked::pw_aff min(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_aff min(const isl::checked::aff &pwaff2) const;
+  inline isl::checked::multi_val min_multi_val() const;
   inline isl::checked::pw_aff mod(isl::checked::val mod) const;
   inline isl::checked::pw_aff mod(long mod) const;
   inline isl::checked::pw_aff mul(isl::checked::pw_aff pwaff2) const;
+  inline class size n_piece() const;
   inline isl::checked::set ne_set(isl::checked::pw_aff pwaff2) const;
   inline isl::checked::pw_aff neg() const;
   static inline isl::checked::pw_aff param_on_domain(isl::checked::set domain, isl::checked::id id);
+  inline boolean plain_is_empty() const;
+  inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff product(const isl::checked::pw_multi_aff &pma2) const;
   inline isl::checked::pw_aff pullback(isl::checked::multi_aff ma) const;
   inline isl::checked::pw_aff pullback(isl::checked::multi_pw_aff mpa) const;
   inline isl::checked::pw_aff pullback(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::union_pw_aff pullback(const isl::checked::union_pw_multi_aff &upma) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::checked::pw_multi_aff range_factor_domain() const;
+  inline isl::checked::pw_multi_aff range_factor_range() const;
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::multi_pw_aff reset_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff scale(const isl::checked::multi_val &mv) const;
   inline isl::checked::pw_aff scale(isl::checked::val v) const;
   inline isl::checked::pw_aff scale(long v) const;
+  inline isl::checked::multi_pw_aff scale_down(const isl::checked::multi_val &mv) const;
   inline isl::checked::pw_aff scale_down(isl::checked::val f) const;
   inline isl::checked::pw_aff scale_down(long f) const;
+  inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::pw_multi_aff set_range_tuple(const isl::checked::id &id) const;
+  inline isl::checked::pw_multi_aff set_range_tuple(const std::string &id) const;
+  inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_aff sub(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_multi_aff sub(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff sub(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_aff sub(const isl::checked::aff &pwaff2) const;
   inline isl::checked::pw_aff subtract_domain(isl::checked::set set) const;
+  inline isl::checked::union_pw_aff subtract_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_aff subtract_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_aff subtract_domain(const isl::checked::basic_set &set) const;
+  inline isl::checked::pw_aff subtract_domain(const isl::checked::point &set) const;
   inline isl::checked::pw_aff tdiv_q(isl::checked::pw_aff pa2) const;
   inline isl::checked::pw_aff tdiv_r(isl::checked::pw_aff pa2) const;
+  inline isl::checked::pw_aff_list to_list() const;
+  inline isl::checked::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::checked::union_pw_aff to_union_pw_aff() const;
+  inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const;
+  inline isl::checked::multi_pw_aff unbind_params_insert_domain(const isl::checked::multi_id &domain) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
   inline isl::checked::pw_aff union_add(isl::checked::pw_aff pwaff2) const;
+  inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_multi_aff &pma2) const;
+  inline isl::checked::union_pw_aff union_add(const isl::checked::union_pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_aff union_add(const isl::checked::aff &pwaff2) const;
 };
 
 // declarations for isl::pw_aff_list
@@ -1977,6 +2762,7 @@
   inline /* implicit */ pw_aff_list(const pw_aff_list &obj);
   inline explicit pw_aff_list(isl::checked::ctx ctx, int n);
   inline explicit pw_aff_list(isl::checked::pw_aff el);
+  inline explicit pw_aff_list(isl::checked::ctx ctx, const std::string &str);
   inline pw_aff_list &operator=(pw_aff_list obj);
   inline ~pw_aff_list();
   inline __isl_give isl_pw_aff_list *copy() const &;
@@ -1987,12 +2773,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::pw_aff_list add(isl::checked::pw_aff el) const;
+  inline isl::checked::pw_aff at(int index) const;
+  inline isl::checked::pw_aff get_at(int index) const;
   inline isl::checked::pw_aff_list clear() const;
   inline isl::checked::pw_aff_list concat(isl::checked::pw_aff_list list2) const;
   inline isl::checked::pw_aff_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::pw_aff)> &fn) const;
-  inline isl::checked::pw_aff at(int index) const;
-  inline isl::checked::pw_aff get_at(int index) const;
   inline isl::checked::pw_aff_list insert(unsigned int pos, isl::checked::pw_aff el) const;
   inline class size size() const;
 };
@@ -2025,45 +2811,131 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
+  inline isl::checked::multi_pw_aff add(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff add(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff add(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff add(const isl::checked::pw_aff &pma2) const;
   inline isl::checked::pw_multi_aff add_constant(isl::checked::multi_val mv) const;
   inline isl::checked::pw_multi_aff add_constant(isl::checked::val v) const;
   inline isl::checked::pw_multi_aff add_constant(long v) const;
+  inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::map as_map() const;
   inline isl::checked::multi_aff as_multi_aff() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
+  inline isl::checked::union_map as_union_map() const;
+  inline isl::checked::pw_aff at(int pos) const;
+  inline isl::checked::pw_aff get_at(int pos) const;
+  inline isl::checked::set bind(const isl::checked::multi_id &tuple) const;
   inline isl::checked::pw_multi_aff bind_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::pw_multi_aff bind_domain_wrapped_domain(isl::checked::multi_id tuple) const;
   inline isl::checked::pw_multi_aff coalesce() const;
   inline isl::checked::set domain() const;
   static inline isl::checked::pw_multi_aff domain_map(isl::checked::space space);
+  inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const;
+  inline isl::checked::multi_pw_aff flat_range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff flat_range_product(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff flat_range_product(const isl::checked::pw_aff &pma2) const;
   inline stat foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline isl::checked::pw_multi_aff gist(isl::checked::set set) const;
+  inline isl::checked::union_pw_multi_aff gist(const isl::checked::union_set &context) const;
+  inline isl::checked::pw_multi_aff gist(const isl::checked::basic_set &set) const;
+  inline isl::checked::pw_multi_aff gist(const isl::checked::point &set) const;
+  inline boolean has_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff identity() const;
   static inline isl::checked::pw_multi_aff identity_on_domain(isl::checked::space space);
   inline isl::checked::pw_multi_aff insert_domain(isl::checked::space domain) const;
   inline isl::checked::pw_multi_aff intersect_domain(isl::checked::set set) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::basic_set &set) const;
+  inline isl::checked::pw_multi_aff intersect_domain(const isl::checked::point &set) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::union_pw_multi_aff intersect_domain_wrapped_range(const isl::checked::union_set &uset) const;
   inline isl::checked::pw_multi_aff intersect_params(isl::checked::set set) const;
   inline boolean involves_locals() const;
+  inline boolean involves_nan() const;
+  inline boolean involves_param(const isl::checked::id &id) const;
+  inline boolean involves_param(const std::string &id) const;
+  inline boolean involves_param(const isl::checked::id_list &list) const;
   inline boolean isa_multi_aff() const;
+  inline boolean isa_pw_multi_aff() const;
+  inline isl::checked::pw_aff_list list() const;
+  inline isl::checked::multi_pw_aff max(const isl::checked::multi_pw_aff &multi2) const;
   inline isl::checked::multi_val max_multi_val() const;
+  inline isl::checked::multi_pw_aff min(const isl::checked::multi_pw_aff &multi2) const;
   inline isl::checked::multi_val min_multi_val() const;
+  static inline isl::checked::pw_multi_aff multi_val_on_domain(isl::checked::set domain, isl::checked::multi_val mv);
   inline class size n_piece() const;
+  inline isl::checked::multi_pw_aff neg() const;
+  inline boolean plain_is_empty() const;
+  inline boolean plain_is_equal(const isl::checked::multi_pw_aff &multi2) const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::pw_aff &pma2) const;
+  inline isl::checked::multi_pw_aff product(const isl::checked::multi_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff product(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::pw_multi_aff product(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff product(const isl::checked::pw_aff &pma2) const;
+  inline isl::checked::multi_pw_aff pullback(const isl::checked::multi_pw_aff &mpa2) const;
   inline isl::checked::pw_multi_aff pullback(isl::checked::multi_aff ma) const;
   inline isl::checked::pw_multi_aff pullback(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff pullback(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
   inline isl::checked::pw_multi_aff range_factor_domain() const;
   inline isl::checked::pw_multi_aff range_factor_range() const;
   static inline isl::checked::pw_multi_aff range_map(isl::checked::space space);
+  inline isl::checked::multi_pw_aff range_product(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff range_product(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff range_product(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff range_product(const isl::checked::pw_aff &pma2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff reset_range_tuple_id() const;
+  inline isl::checked::multi_pw_aff scale(const isl::checked::multi_val &mv) const;
   inline isl::checked::pw_multi_aff scale(isl::checked::val v) const;
   inline isl::checked::pw_multi_aff scale(long v) const;
+  inline isl::checked::multi_pw_aff scale_down(const isl::checked::multi_val &mv) const;
   inline isl::checked::pw_multi_aff scale_down(isl::checked::val v) const;
   inline isl::checked::pw_multi_aff scale_down(long v) const;
+  inline isl::checked::multi_pw_aff set_at(int pos, const isl::checked::pw_aff &el) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::pw_multi_aff set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::pw_multi_aff set_range_tuple(const std::string &id) const;
+  inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
+  inline isl::checked::multi_pw_aff sub(const isl::checked::multi_pw_aff &multi2) const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::pw_multi_aff sub(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff sub(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff sub(const isl::checked::pw_aff &pma2) const;
   inline isl::checked::pw_multi_aff subtract_domain(isl::checked::set set) const;
+  inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::space &space) const;
+  inline isl::checked::union_pw_multi_aff subtract_domain(const isl::checked::union_set &uset) const;
+  inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::basic_set &set) const;
+  inline isl::checked::pw_multi_aff subtract_domain(const isl::checked::point &set) const;
+  inline isl::checked::pw_multi_aff_list to_list() const;
+  inline isl::checked::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::checked::union_pw_multi_aff to_union_pw_multi_aff() const;
+  inline isl::checked::multi_pw_aff unbind_params_insert_domain(const isl::checked::multi_id &domain) const;
+  inline isl::checked::multi_pw_aff union_add(const isl::checked::multi_pw_aff &mpa2) const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
   inline isl::checked::pw_multi_aff union_add(isl::checked::pw_multi_aff pma2) const;
+  inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::pw_multi_aff union_add(const isl::checked::multi_aff &pma2) const;
+  inline isl::checked::pw_multi_aff union_add(const isl::checked::pw_aff &pma2) const;
   static inline isl::checked::pw_multi_aff zero(isl::checked::space space);
 };
 
@@ -2085,6 +2957,7 @@
   inline /* implicit */ pw_multi_aff_list(const pw_multi_aff_list &obj);
   inline explicit pw_multi_aff_list(isl::checked::ctx ctx, int n);
   inline explicit pw_multi_aff_list(isl::checked::pw_multi_aff el);
+  inline explicit pw_multi_aff_list(isl::checked::ctx ctx, const std::string &str);
   inline pw_multi_aff_list &operator=(pw_multi_aff_list obj);
   inline ~pw_multi_aff_list();
   inline __isl_give isl_pw_multi_aff_list *copy() const &;
@@ -2095,12 +2968,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::pw_multi_aff_list add(isl::checked::pw_multi_aff el) const;
+  inline isl::checked::pw_multi_aff at(int index) const;
+  inline isl::checked::pw_multi_aff get_at(int index) const;
   inline isl::checked::pw_multi_aff_list clear() const;
   inline isl::checked::pw_multi_aff_list concat(isl::checked::pw_multi_aff_list list2) const;
   inline isl::checked::pw_multi_aff_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::pw_multi_aff)> &fn) const;
-  inline isl::checked::pw_multi_aff at(int index) const;
-  inline isl::checked::pw_multi_aff get_at(int index) const;
   inline isl::checked::pw_multi_aff_list insert(unsigned int pos, isl::checked::pw_multi_aff el) const;
   inline class size size() const;
 };
@@ -2131,14 +3004,14 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
-  static inline isl::checked::schedule from_domain(isl::checked::union_set domain);
   inline isl::checked::union_set domain() const;
   inline isl::checked::union_set get_domain() const;
+  static inline isl::checked::schedule from_domain(isl::checked::union_set domain);
   inline isl::checked::union_map map() const;
   inline isl::checked::union_map get_map() const;
+  inline isl::checked::schedule pullback(isl::checked::union_pw_multi_aff upma) const;
   inline isl::checked::schedule_node root() const;
   inline isl::checked::schedule_node get_root() const;
-  inline isl::checked::schedule pullback(isl::checked::union_pw_multi_aff upma) const;
 };
 
 // declarations for isl::schedule_constraints
@@ -2167,9 +3040,9 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
-  inline isl::checked::schedule compute_schedule() const;
   inline isl::checked::union_map coincidence() const;
   inline isl::checked::union_map get_coincidence() const;
+  inline isl::checked::schedule compute_schedule() const;
   inline isl::checked::union_map conditional_validity() const;
   inline isl::checked::union_map get_conditional_validity() const;
   inline isl::checked::union_map conditional_validity_condition() const;
@@ -2178,16 +3051,16 @@
   inline isl::checked::set get_context() const;
   inline isl::checked::union_set domain() const;
   inline isl::checked::union_set get_domain() const;
+  static inline isl::checked::schedule_constraints on_domain(isl::checked::union_set domain);
   inline isl::checked::union_map proximity() const;
   inline isl::checked::union_map get_proximity() const;
-  inline isl::checked::union_map validity() const;
-  inline isl::checked::union_map get_validity() const;
-  static inline isl::checked::schedule_constraints on_domain(isl::checked::union_set domain);
   inline isl::checked::schedule_constraints set_coincidence(isl::checked::union_map coincidence) const;
   inline isl::checked::schedule_constraints set_conditional_validity(isl::checked::union_map condition, isl::checked::union_map validity) const;
   inline isl::checked::schedule_constraints set_context(isl::checked::set context) const;
   inline isl::checked::schedule_constraints set_proximity(isl::checked::union_map proximity) const;
   inline isl::checked::schedule_constraints set_validity(isl::checked::union_map validity) const;
+  inline isl::checked::union_map validity() const;
+  inline isl::checked::union_map get_validity() const;
 };
 
 // declarations for isl::schedule_node
@@ -2225,29 +3098,17 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::schedule_node ancestor(int generation) const;
+  inline class size ancestor_child_position(const isl::checked::schedule_node &ancestor) const;
+  inline class size get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const;
   inline isl::checked::schedule_node child(int pos) const;
+  inline class size child_position() const;
+  inline class size get_child_position() const;
   inline boolean every_descendant(const std::function<boolean(isl::checked::schedule_node)> &test) const;
   inline isl::checked::schedule_node first_child() const;
   inline stat foreach_ancestor_top_down(const std::function<stat(isl::checked::schedule_node)> &fn) const;
   inline stat foreach_descendant_top_down(const std::function<boolean(isl::checked::schedule_node)> &fn) const;
   static inline isl::checked::schedule_node from_domain(isl::checked::union_set domain);
   static inline isl::checked::schedule_node from_extension(isl::checked::union_map extension);
-  inline class size ancestor_child_position(const isl::checked::schedule_node &ancestor) const;
-  inline class size get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const;
-  inline class size child_position() const;
-  inline class size get_child_position() const;
-  inline isl::checked::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const;
-  inline isl::checked::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const;
-  inline isl::checked::union_map prefix_schedule_union_map() const;
-  inline isl::checked::union_map get_prefix_schedule_union_map() const;
-  inline isl::checked::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const;
-  inline isl::checked::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const;
-  inline isl::checked::schedule schedule() const;
-  inline isl::checked::schedule get_schedule() const;
-  inline isl::checked::schedule_node shared_ancestor(const isl::checked::schedule_node &node2) const;
-  inline isl::checked::schedule_node get_shared_ancestor(const isl::checked::schedule_node &node2) const;
-  inline class size tree_depth() const;
-  inline class size get_tree_depth() const;
   inline isl::checked::schedule_node graft_after(isl::checked::schedule_node graft) const;
   inline isl::checked::schedule_node graft_before(isl::checked::schedule_node graft) const;
   inline boolean has_children() const;
@@ -2270,8 +3131,20 @@
   inline isl::checked::schedule_node order_after(isl::checked::union_set filter) const;
   inline isl::checked::schedule_node order_before(isl::checked::union_set filter) const;
   inline isl::checked::schedule_node parent() const;
+  inline isl::checked::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const;
+  inline isl::checked::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const;
+  inline isl::checked::union_map prefix_schedule_union_map() const;
+  inline isl::checked::union_map get_prefix_schedule_union_map() const;
+  inline isl::checked::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const;
+  inline isl::checked::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const;
   inline isl::checked::schedule_node previous_sibling() const;
   inline isl::checked::schedule_node root() const;
+  inline isl::checked::schedule schedule() const;
+  inline isl::checked::schedule get_schedule() const;
+  inline isl::checked::schedule_node shared_ancestor(const isl::checked::schedule_node &node2) const;
+  inline isl::checked::schedule_node get_shared_ancestor(const isl::checked::schedule_node &node2) const;
+  inline class size tree_depth() const;
+  inline class size get_tree_depth() const;
 };
 
 // declarations for isl::schedule_node_band
@@ -2295,14 +3168,14 @@
   inline isl::checked::union_set get_ast_build_options() const;
   inline isl::checked::set ast_isolate_option() const;
   inline isl::checked::set get_ast_isolate_option() const;
-  inline isl::checked::multi_union_pw_aff partial_schedule() const;
-  inline isl::checked::multi_union_pw_aff get_partial_schedule() const;
-  inline boolean permutable() const;
-  inline boolean get_permutable() const;
   inline boolean member_get_coincident(int pos) const;
   inline schedule_node_band member_set_coincident(int pos, int coincident) const;
   inline schedule_node_band mod(isl::checked::multi_val mv) const;
   inline class size n_member() const;
+  inline isl::checked::multi_union_pw_aff partial_schedule() const;
+  inline isl::checked::multi_union_pw_aff get_partial_schedule() const;
+  inline boolean permutable() const;
+  inline boolean get_permutable() const;
   inline schedule_node_band scale(isl::checked::multi_val mv) const;
   inline schedule_node_band scale_down(isl::checked::multi_val mv) const;
   inline schedule_node_band set_ast_build_options(isl::checked::union_set options) const;
@@ -2550,38 +3423,58 @@
 
   inline isl::checked::basic_set affine_hull() const;
   inline isl::checked::set apply(isl::checked::map map) const;
+  inline isl::checked::union_set apply(const isl::checked::union_map &umap) const;
+  inline isl::checked::set apply(const isl::checked::basic_map &map) const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::set as_set() const;
   inline isl::checked::set bind(isl::checked::multi_id tuple) const;
   inline isl::checked::set coalesce() const;
   inline isl::checked::set complement() const;
+  inline isl::checked::union_set compute_divs() const;
   inline isl::checked::set detect_equalities() const;
   inline isl::checked::val dim_max_val(int pos) const;
   inline isl::checked::val dim_min_val(int pos) const;
   static inline isl::checked::set empty(isl::checked::space space);
+  inline boolean every_set(const std::function<boolean(isl::checked::set)> &test) const;
+  inline isl::checked::set extract_set(const isl::checked::space &space) const;
   inline isl::checked::set flatten() const;
   inline stat foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const;
   inline stat foreach_point(const std::function<stat(isl::checked::point)> &fn) const;
-  inline isl::checked::multi_val plain_multi_val_if_fixed() const;
-  inline isl::checked::multi_val get_plain_multi_val_if_fixed() const;
-  inline isl::checked::fixed_box simple_fixed_box_hull() const;
-  inline isl::checked::fixed_box get_simple_fixed_box_hull() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
-  inline isl::checked::val stride(int pos) const;
-  inline isl::checked::val get_stride(int pos) const;
+  inline stat foreach_set(const std::function<stat(isl::checked::set)> &fn) const;
   inline isl::checked::set gist(isl::checked::set context) const;
+  inline isl::checked::union_set gist(const isl::checked::union_set &context) const;
+  inline isl::checked::set gist(const isl::checked::basic_set &context) const;
+  inline isl::checked::set gist(const isl::checked::point &context) const;
+  inline isl::checked::union_set gist_params(const isl::checked::set &set) const;
   inline isl::checked::map identity() const;
   inline isl::checked::pw_aff indicator_function() const;
   inline isl::checked::map insert_domain(isl::checked::space domain) const;
   inline isl::checked::set intersect(isl::checked::set set2) const;
+  inline isl::checked::union_set intersect(const isl::checked::union_set &uset2) const;
+  inline isl::checked::set intersect(const isl::checked::basic_set &set2) const;
+  inline isl::checked::set intersect(const isl::checked::point &set2) const;
   inline isl::checked::set intersect_params(isl::checked::set params) const;
   inline boolean involves_locals() const;
   inline boolean is_disjoint(const isl::checked::set &set2) const;
+  inline boolean is_disjoint(const isl::checked::union_set &uset2) const;
+  inline boolean is_disjoint(const isl::checked::basic_set &set2) const;
+  inline boolean is_disjoint(const isl::checked::point &set2) const;
   inline boolean is_empty() const;
   inline boolean is_equal(const isl::checked::set &set2) const;
+  inline boolean is_equal(const isl::checked::union_set &uset2) const;
+  inline boolean is_equal(const isl::checked::basic_set &set2) const;
+  inline boolean is_equal(const isl::checked::point &set2) const;
   inline boolean is_singleton() const;
   inline boolean is_strict_subset(const isl::checked::set &set2) const;
+  inline boolean is_strict_subset(const isl::checked::union_set &uset2) const;
+  inline boolean is_strict_subset(const isl::checked::basic_set &set2) const;
+  inline boolean is_strict_subset(const isl::checked::point &set2) const;
   inline boolean is_subset(const isl::checked::set &set2) const;
+  inline boolean is_subset(const isl::checked::union_set &uset2) const;
+  inline boolean is_subset(const isl::checked::basic_set &set2) const;
+  inline boolean is_subset(const isl::checked::point &set2) const;
   inline boolean is_wrapping() const;
+  inline boolean isa_set() const;
   inline isl::checked::set lexmax() const;
   inline isl::checked::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::checked::set lexmin() const;
@@ -2593,22 +3486,41 @@
   inline isl::checked::multi_pw_aff min_multi_pw_aff() const;
   inline isl::checked::val min_val(const isl::checked::aff &obj) const;
   inline isl::checked::set params() const;
+  inline isl::checked::multi_val plain_multi_val_if_fixed() const;
+  inline isl::checked::multi_val get_plain_multi_val_if_fixed() const;
   inline isl::checked::basic_set polyhedral_hull() const;
   inline isl::checked::set preimage(isl::checked::multi_aff ma) const;
   inline isl::checked::set preimage(isl::checked::multi_pw_aff mpa) const;
   inline isl::checked::set preimage(isl::checked::pw_multi_aff pma) const;
+  inline isl::checked::union_set preimage(const isl::checked::union_pw_multi_aff &upma) const;
   inline isl::checked::set product(isl::checked::set set2) const;
   inline isl::checked::set project_out_all_params() const;
   inline isl::checked::set project_out_param(isl::checked::id id) const;
   inline isl::checked::set project_out_param(const std::string &id) const;
   inline isl::checked::set project_out_param(isl::checked::id_list list) const;
+  inline isl::checked::pw_multi_aff pw_multi_aff_on_domain(isl::checked::multi_val mv) const;
   inline isl::checked::basic_set sample() const;
   inline isl::checked::point sample_point() const;
+  inline isl::checked::fixed_box simple_fixed_box_hull() const;
+  inline isl::checked::fixed_box get_simple_fixed_box_hull() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
+  inline isl::checked::val stride(int pos) const;
+  inline isl::checked::val get_stride(int pos) const;
   inline isl::checked::set subtract(isl::checked::set set2) const;
+  inline isl::checked::union_set subtract(const isl::checked::union_set &uset2) const;
+  inline isl::checked::set subtract(const isl::checked::basic_set &set2) const;
+  inline isl::checked::set subtract(const isl::checked::point &set2) const;
+  inline isl::checked::union_set_list to_list() const;
+  inline isl::checked::union_set to_union_set() const;
   inline isl::checked::map translation() const;
+  inline class size tuple_dim() const;
   inline isl::checked::set unbind_params(isl::checked::multi_id tuple) const;
   inline isl::checked::map unbind_params_insert_domain(isl::checked::multi_id domain) const;
   inline isl::checked::set unite(isl::checked::set set2) const;
+  inline isl::checked::union_set unite(const isl::checked::union_set &uset2) const;
+  inline isl::checked::set unite(const isl::checked::basic_set &set2) const;
+  inline isl::checked::set unite(const isl::checked::point &set2) const;
   static inline isl::checked::set universe(isl::checked::space space);
   inline isl::checked::basic_set unshifted_simple_hull() const;
   inline isl::checked::map unwrap() const;
@@ -2643,23 +3555,57 @@
 
   inline isl::checked::space add_named_tuple(isl::checked::id tuple_id, unsigned int dim) const;
   inline isl::checked::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
+  inline isl::checked::space add_param(isl::checked::id id) const;
+  inline isl::checked::space add_param(const std::string &id) const;
   inline isl::checked::space add_unnamed_tuple(unsigned int dim) const;
   inline isl::checked::space curry() const;
   inline isl::checked::space domain() const;
+  inline isl::checked::multi_aff domain_map_multi_aff() const;
+  inline isl::checked::pw_multi_aff domain_map_pw_multi_aff() const;
+  inline isl::checked::id domain_tuple_id() const;
+  inline isl::checked::id get_domain_tuple_id() const;
   inline isl::checked::space flatten_domain() const;
   inline isl::checked::space flatten_range() const;
+  inline boolean has_domain_tuple_id() const;
+  inline boolean has_range_tuple_id() const;
+  inline isl::checked::multi_aff identity_multi_aff_on_domain() const;
+  inline isl::checked::multi_pw_aff identity_multi_pw_aff_on_domain() const;
+  inline isl::checked::pw_multi_aff identity_pw_multi_aff_on_domain() const;
   inline boolean is_equal(const isl::checked::space &space2) const;
   inline boolean is_wrapping() const;
   inline isl::checked::space map_from_set() const;
+  inline isl::checked::multi_aff multi_aff(isl::checked::aff_list list) const;
+  inline isl::checked::multi_aff multi_aff_on_domain(isl::checked::multi_val mv) const;
+  inline isl::checked::multi_id multi_id(isl::checked::id_list list) const;
+  inline isl::checked::multi_pw_aff multi_pw_aff(isl::checked::pw_aff_list list) const;
+  inline isl::checked::multi_union_pw_aff multi_union_pw_aff(isl::checked::union_pw_aff_list list) const;
+  inline isl::checked::multi_val multi_val(isl::checked::val_list list) const;
+  inline isl::checked::aff param_aff_on_domain(isl::checked::id id) const;
+  inline isl::checked::aff param_aff_on_domain(const std::string &id) const;
   inline isl::checked::space params() const;
   inline isl::checked::space product(isl::checked::space right) const;
   inline isl::checked::space range() const;
+  inline isl::checked::multi_aff range_map_multi_aff() const;
+  inline isl::checked::pw_multi_aff range_map_pw_multi_aff() const;
   inline isl::checked::space range_reverse() const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::id get_range_tuple_id() const;
   inline isl::checked::space reverse() const;
+  inline isl::checked::space set_domain_tuple(isl::checked::id id) const;
+  inline isl::checked::space set_domain_tuple(const std::string &id) const;
+  inline isl::checked::space set_range_tuple(isl::checked::id id) const;
+  inline isl::checked::space set_range_tuple(const std::string &id) const;
   inline isl::checked::space uncurry() const;
   static inline isl::checked::space unit(isl::checked::ctx ctx);
+  inline isl::checked::map universe_map() const;
+  inline isl::checked::set universe_set() const;
   inline isl::checked::space unwrap() const;
   inline isl::checked::space wrap() const;
+  inline isl::checked::aff zero_aff_on_domain() const;
+  inline isl::checked::multi_aff zero_multi_aff() const;
+  inline isl::checked::multi_pw_aff zero_multi_pw_aff() const;
+  inline isl::checked::multi_union_pw_aff zero_multi_union_pw_aff() const;
+  inline isl::checked::multi_val zero_multi_val() const;
 };
 
 // declarations for isl::union_access_info
@@ -2766,6 +3712,9 @@
   inline isl::checked::union_map affine_hull() const;
   inline isl::checked::union_map apply_domain(isl::checked::union_map umap2) const;
   inline isl::checked::union_map apply_range(isl::checked::union_map umap2) const;
+  inline isl::checked::map as_map() const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::union_pw_multi_aff as_union_pw_multi_aff() const;
   inline isl::checked::union_set bind_range(isl::checked::multi_id tuple) const;
   inline isl::checked::union_map coalesce() const;
   inline isl::checked::union_map compute_divs() const;
@@ -2792,8 +3741,6 @@
   static inline isl::checked::union_map from_domain(isl::checked::union_set uset);
   static inline isl::checked::union_map from_domain_and_range(isl::checked::union_set domain, isl::checked::union_set range);
   static inline isl::checked::union_map from_range(isl::checked::union_set uset);
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline isl::checked::union_map gist(isl::checked::union_map context) const;
   inline isl::checked::union_map gist_domain(isl::checked::union_set uset) const;
   inline isl::checked::union_map gist_params(isl::checked::set set) const;
@@ -2819,6 +3766,8 @@
   inline boolean isa_map() const;
   inline isl::checked::union_map lexmax() const;
   inline isl::checked::union_map lexmin() const;
+  inline isl::checked::map_list map_list() const;
+  inline isl::checked::map_list get_map_list() const;
   inline isl::checked::union_map polyhedral_hull() const;
   inline isl::checked::union_map preimage_domain(isl::checked::multi_aff ma) const;
   inline isl::checked::union_map preimage_domain(isl::checked::multi_pw_aff mpa) const;
@@ -2836,6 +3785,8 @@
   inline isl::checked::union_map range_product(isl::checked::union_map umap2) const;
   inline isl::checked::union_map range_reverse() const;
   inline isl::checked::union_map reverse() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::union_map subtract(isl::checked::union_map umap2) const;
   inline isl::checked::union_map subtract_domain(isl::checked::union_set dom) const;
   inline isl::checked::union_map subtract_range(isl::checked::union_set dom) const;
@@ -2874,24 +3825,72 @@
   inline bool is_null() const;
   inline isl::checked::ctx ctx() const;
 
+  inline isl::checked::multi_union_pw_aff add(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::union_pw_aff add(isl::checked::union_pw_aff upa2) const;
+  inline isl::checked::union_pw_multi_aff add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::union_pw_aff add(const isl::checked::aff &upa2) const;
+  inline isl::checked::union_pw_aff add(const isl::checked::pw_aff &upa2) const;
+  inline isl::checked::union_pw_multi_aff apply(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::union_map as_union_map() const;
+  inline isl::checked::union_pw_aff at(int pos) const;
+  inline isl::checked::union_set bind(const isl::checked::multi_id &tuple) const;
   inline isl::checked::union_set bind(isl::checked::id id) const;
   inline isl::checked::union_set bind(const std::string &id) const;
   inline isl::checked::union_pw_aff coalesce() const;
   inline isl::checked::union_set domain() const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
+  inline isl::checked::pw_multi_aff extract_pw_multi_aff(const isl::checked::space &space) const;
+  inline isl::checked::multi_union_pw_aff flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::union_pw_multi_aff flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::union_pw_aff gist(isl::checked::union_set context) const;
+  inline boolean has_range_tuple_id() const;
   inline isl::checked::union_pw_aff intersect_domain(isl::checked::space space) const;
   inline isl::checked::union_pw_aff intersect_domain(isl::checked::union_set uset) const;
   inline isl::checked::union_pw_aff intersect_domain_wrapped_domain(isl::checked::union_set uset) const;
   inline isl::checked::union_pw_aff intersect_domain_wrapped_range(isl::checked::union_set uset) const;
   inline isl::checked::union_pw_aff intersect_params(isl::checked::set set) const;
+  inline boolean involves_locals() const;
+  inline boolean involves_nan() const;
+  inline boolean isa_pw_multi_aff() const;
+  inline isl::checked::union_pw_aff_list list() const;
+  inline isl::checked::multi_union_pw_aff neg() const;
+  inline boolean plain_is_empty() const;
+  inline boolean plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const;
   inline isl::checked::union_pw_aff pullback(isl::checked::union_pw_multi_aff upma) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::checked::union_pw_multi_aff range_factor_domain() const;
+  inline isl::checked::union_pw_multi_aff range_factor_range() const;
+  inline isl::checked::multi_union_pw_aff range_product(const isl::checked::multi_union_pw_aff &multi2) const;
+  inline isl::checked::union_pw_multi_aff range_product(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::id range_tuple_id() const;
+  inline isl::checked::multi_union_pw_aff reset_range_tuple_id() const;
+  inline isl::checked::multi_union_pw_aff scale(const isl::checked::multi_val &mv) const;
+  inline isl::checked::multi_union_pw_aff scale(const isl::checked::val &v) const;
+  inline isl::checked::multi_union_pw_aff scale(long v) const;
+  inline isl::checked::multi_union_pw_aff scale_down(const isl::checked::multi_val &mv) const;
+  inline isl::checked::multi_union_pw_aff scale_down(const isl::checked::val &v) const;
+  inline isl::checked::multi_union_pw_aff scale_down(long v) const;
+  inline isl::checked::multi_union_pw_aff set_at(int pos, const isl::checked::union_pw_aff &el) const;
+  inline isl::checked::multi_union_pw_aff set_range_tuple(const isl::checked::id &id) const;
+  inline isl::checked::multi_union_pw_aff set_range_tuple(const std::string &id) const;
+  inline class size size() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
+  inline isl::checked::multi_union_pw_aff sub(const isl::checked::multi_union_pw_aff &multi2) const;
   inline isl::checked::union_pw_aff sub(isl::checked::union_pw_aff upa2) const;
+  inline isl::checked::union_pw_multi_aff sub(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::union_pw_aff sub(const isl::checked::aff &upa2) const;
+  inline isl::checked::union_pw_aff sub(const isl::checked::pw_aff &upa2) const;
   inline isl::checked::union_pw_aff subtract_domain(isl::checked::space space) const;
   inline isl::checked::union_pw_aff subtract_domain(isl::checked::union_set uset) const;
+  inline isl::checked::union_pw_aff_list to_list() const;
+  inline isl::checked::multi_union_pw_aff union_add(const isl::checked::multi_union_pw_aff &mupa2) const;
   inline isl::checked::union_pw_aff union_add(isl::checked::union_pw_aff upa2) const;
+  inline isl::checked::union_pw_multi_aff union_add(const isl::checked::union_pw_multi_aff &upma2) const;
+  inline isl::checked::union_pw_aff union_add(const isl::checked::aff &upa2) const;
+  inline isl::checked::union_pw_aff union_add(const isl::checked::pw_aff &upa2) const;
 };
 
 // declarations for isl::union_pw_aff_list
@@ -2912,6 +3911,7 @@
   inline /* implicit */ union_pw_aff_list(const union_pw_aff_list &obj);
   inline explicit union_pw_aff_list(isl::checked::ctx ctx, int n);
   inline explicit union_pw_aff_list(isl::checked::union_pw_aff el);
+  inline explicit union_pw_aff_list(isl::checked::ctx ctx, const std::string &str);
   inline union_pw_aff_list &operator=(union_pw_aff_list obj);
   inline ~union_pw_aff_list();
   inline __isl_give isl_union_pw_aff_list *copy() const &;
@@ -2922,12 +3922,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::union_pw_aff_list add(isl::checked::union_pw_aff el) const;
+  inline isl::checked::union_pw_aff at(int index) const;
+  inline isl::checked::union_pw_aff get_at(int index) const;
   inline isl::checked::union_pw_aff_list clear() const;
   inline isl::checked::union_pw_aff_list concat(isl::checked::union_pw_aff_list list2) const;
   inline isl::checked::union_pw_aff_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::union_pw_aff)> &fn) const;
-  inline isl::checked::union_pw_aff at(int index) const;
-  inline isl::checked::union_pw_aff get_at(int index) const;
   inline isl::checked::union_pw_aff_list insert(unsigned int pos, isl::checked::union_pw_aff el) const;
   inline class size size() const;
 };
@@ -2963,14 +3963,14 @@
 
   inline isl::checked::union_pw_multi_aff add(isl::checked::union_pw_multi_aff upma2) const;
   inline isl::checked::union_pw_multi_aff apply(isl::checked::union_pw_multi_aff upma2) const;
+  inline isl::checked::multi_union_pw_aff as_multi_union_pw_aff() const;
   inline isl::checked::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::checked::union_map as_union_map() const;
   inline isl::checked::union_pw_multi_aff coalesce() const;
   inline isl::checked::union_set domain() const;
   static inline isl::checked::union_pw_multi_aff empty(isl::checked::ctx ctx);
   inline isl::checked::pw_multi_aff extract_pw_multi_aff(isl::checked::space space) const;
   inline isl::checked::union_pw_multi_aff flat_range_product(isl::checked::union_pw_multi_aff upma2) const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline isl::checked::union_pw_multi_aff gist(isl::checked::union_set context) const;
   inline isl::checked::union_pw_multi_aff intersect_domain(isl::checked::space space) const;
   inline isl::checked::union_pw_multi_aff intersect_domain(isl::checked::union_set uset) const;
@@ -2982,9 +3982,13 @@
   inline boolean plain_is_empty() const;
   inline isl::checked::union_pw_multi_aff preimage_domain_wrapped_domain(isl::checked::union_pw_multi_aff upma2) const;
   inline isl::checked::union_pw_multi_aff pullback(isl::checked::union_pw_multi_aff upma2) const;
+  inline isl::checked::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::checked::pw_multi_aff_list get_pw_multi_aff_list() const;
   inline isl::checked::union_pw_multi_aff range_factor_domain() const;
   inline isl::checked::union_pw_multi_aff range_factor_range() const;
   inline isl::checked::union_pw_multi_aff range_product(isl::checked::union_pw_multi_aff upma2) const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::union_pw_multi_aff sub(isl::checked::union_pw_multi_aff upma2) const;
   inline isl::checked::union_pw_multi_aff subtract_domain(isl::checked::space space) const;
   inline isl::checked::union_pw_multi_aff subtract_domain(isl::checked::union_set uset) const;
@@ -3022,6 +4026,7 @@
 
   inline isl::checked::union_set affine_hull() const;
   inline isl::checked::union_set apply(isl::checked::union_map umap) const;
+  inline isl::checked::set as_set() const;
   inline isl::checked::union_set coalesce() const;
   inline isl::checked::union_set compute_divs() const;
   inline isl::checked::union_set detect_equalities() const;
@@ -3030,8 +4035,6 @@
   inline isl::checked::set extract_set(isl::checked::space space) const;
   inline stat foreach_point(const std::function<stat(isl::checked::point)> &fn) const;
   inline stat foreach_set(const std::function<stat(isl::checked::set)> &fn) const;
-  inline isl::checked::space space() const;
-  inline isl::checked::space get_space() const;
   inline isl::checked::union_set gist(isl::checked::union_set context) const;
   inline isl::checked::union_set gist_params(isl::checked::set set) const;
   inline isl::checked::union_map identity() const;
@@ -3050,7 +4053,10 @@
   inline isl::checked::union_set preimage(isl::checked::pw_multi_aff pma) const;
   inline isl::checked::union_set preimage(isl::checked::union_pw_multi_aff upma) const;
   inline isl::checked::point sample_point() const;
+  inline isl::checked::space space() const;
+  inline isl::checked::space get_space() const;
   inline isl::checked::union_set subtract(isl::checked::union_set uset2) const;
+  inline isl::checked::union_set_list to_list() const;
   inline isl::checked::union_set unite(isl::checked::union_set uset2) const;
   inline isl::checked::union_set universe() const;
   inline isl::checked::union_map unwrap() const;
@@ -3074,6 +4080,7 @@
   inline /* implicit */ union_set_list(const union_set_list &obj);
   inline explicit union_set_list(isl::checked::ctx ctx, int n);
   inline explicit union_set_list(isl::checked::union_set el);
+  inline explicit union_set_list(isl::checked::ctx ctx, const std::string &str);
   inline union_set_list &operator=(union_set_list obj);
   inline ~union_set_list();
   inline __isl_give isl_union_set_list *copy() const &;
@@ -3084,12 +4091,12 @@
   inline isl::checked::ctx ctx() const;
 
   inline isl::checked::union_set_list add(isl::checked::union_set el) const;
+  inline isl::checked::union_set at(int index) const;
+  inline isl::checked::union_set get_at(int index) const;
   inline isl::checked::union_set_list clear() const;
   inline isl::checked::union_set_list concat(isl::checked::union_set_list list2) const;
   inline isl::checked::union_set_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::union_set)> &fn) const;
-  inline isl::checked::union_set at(int index) const;
-  inline isl::checked::union_set get_at(int index) const;
   inline isl::checked::union_set_list insert(unsigned int pos, isl::checked::union_set el) const;
   inline class size size() const;
 };
@@ -3128,6 +4135,8 @@
   inline isl::checked::val add(long v2) const;
   inline isl::checked::val ceil() const;
   inline int cmp_si(long i) const;
+  inline long den_si() const;
+  inline long get_den_si() const;
   inline isl::checked::val div(isl::checked::val v2) const;
   inline isl::checked::val div(long v2) const;
   inline boolean eq(const isl::checked::val &v2) const;
@@ -3137,10 +4146,6 @@
   inline isl::checked::val gcd(long v2) const;
   inline boolean ge(const isl::checked::val &v2) const;
   inline boolean ge(long v2) const;
-  inline long den_si() const;
-  inline long get_den_si() const;
-  inline long num_si() const;
-  inline long get_num_si() const;
   inline boolean gt(const isl::checked::val &v2) const;
   inline boolean gt(long v2) const;
   static inline isl::checked::val infty(isl::checked::ctx ctx);
@@ -3177,11 +4182,14 @@
   inline isl::checked::val neg() const;
   static inline isl::checked::val neginfty(isl::checked::ctx ctx);
   static inline isl::checked::val negone(isl::checked::ctx ctx);
+  inline long num_si() const;
+  inline long get_num_si() const;
   static inline isl::checked::val one(isl::checked::ctx ctx);
   inline isl::checked::val pow2() const;
   inline int sgn() const;
   inline isl::checked::val sub(isl::checked::val v2) const;
   inline isl::checked::val sub(long v2) const;
+  inline isl::checked::val_list to_list() const;
   inline isl::checked::val trunc() const;
   static inline isl::checked::val zero(isl::checked::ctx ctx);
 };
@@ -3204,6 +4212,7 @@
   inline /* implicit */ val_list(const val_list &obj);
   inline explicit val_list(isl::checked::ctx ctx, int n);
   inline explicit val_list(isl::checked::val el);
+  inline explicit val_list(isl::checked::ctx ctx, const std::string &str);
   inline val_list &operator=(val_list obj);
   inline ~val_list();
   inline __isl_give isl_val_list *copy() const &;
@@ -3215,12 +4224,12 @@
 
   inline isl::checked::val_list add(isl::checked::val el) const;
   inline isl::checked::val_list add(long el) const;
+  inline isl::checked::val at(int index) const;
+  inline isl::checked::val get_at(int index) const;
   inline isl::checked::val_list clear() const;
   inline isl::checked::val_list concat(isl::checked::val_list list2) const;
   inline isl::checked::val_list drop(unsigned int first, unsigned int n) const;
   inline stat foreach(const std::function<stat(isl::checked::val)> &fn) const;
-  inline isl::checked::val at(int index) const;
-  inline isl::checked::val get_at(int index) const;
   inline isl::checked::val_list insert(unsigned int pos, isl::checked::val el) const;
   inline isl::checked::val_list insert(unsigned int pos, long el) const;
   inline class size size() const;
@@ -3291,6 +4300,41 @@
   return manage(res);
 }
 
+isl::checked::multi_aff aff::add(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).add(multi2);
+}
+
+isl::checked::multi_pw_aff aff::add(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).add(multi2);
+}
+
+isl::checked::multi_union_pw_aff aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).add(multi2);
+}
+
+isl::checked::pw_aff aff::add(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).add(pwaff2);
+}
+
+isl::checked::pw_multi_aff aff::add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).add(pma2);
+}
+
+isl::checked::union_pw_aff aff::add(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::pw_aff(*this).add(upa2);
+}
+
+isl::checked::union_pw_multi_aff aff::add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).add(upma2);
+}
+
 isl::checked::aff aff::add_constant(isl::checked::val v) const
 {
   auto res = isl_aff_add_constant_val(copy(), v.release());
@@ -3302,6 +4346,56 @@
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_aff aff::add_constant(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_aff(*this).add_constant(mv);
+}
+
+isl::checked::union_pw_multi_aff aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).apply(upma2);
+}
+
+isl::checked::aff aff::as_aff() const
+{
+  return isl::checked::pw_aff(*this).as_aff();
+}
+
+isl::checked::map aff::as_map() const
+{
+  return isl::checked::pw_aff(*this).as_map();
+}
+
+isl::checked::multi_aff aff::as_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).as_multi_aff();
+}
+
+isl::checked::multi_union_pw_aff aff::as_multi_union_pw_aff() const
+{
+  return isl::checked::pw_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff aff::as_pw_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).as_pw_multi_aff();
+}
+
+isl::checked::set aff::as_set() const
+{
+  return isl::checked::multi_aff(*this).as_set();
+}
+
+isl::checked::union_map aff::as_union_map() const
+{
+  return isl::checked::pw_aff(*this).as_union_map();
+}
+
+isl::checked::aff aff::at(int pos) const
+{
+  return isl::checked::multi_aff(*this).at(pos);
+}
+
 isl::checked::basic_set aff::bind(isl::checked::id id) const
 {
   auto res = isl_aff_bind_id(copy(), id.release());
@@ -3313,40 +4407,40 @@
   return this->bind(isl::checked::id(ctx(), id));
 }
 
+isl::checked::basic_set aff::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::multi_aff(*this).bind(tuple);
+}
+
+isl::checked::pw_aff aff::bind_domain(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::pw_aff(*this).bind_domain(tuple);
+}
+
+isl::checked::pw_aff aff::bind_domain_wrapped_domain(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::pw_aff(*this).bind_domain_wrapped_domain(tuple);
+}
+
 isl::checked::aff aff::ceil() const
 {
   auto res = isl_aff_ceil(copy());
   return manage(res);
 }
 
-isl::checked::aff aff::div(isl::checked::aff aff2) const
+isl::checked::pw_aff aff::coalesce() const
 {
-  auto res = isl_aff_div(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).coalesce();
 }
 
-isl::checked::set aff::eq_set(isl::checked::aff aff2) const
+isl::checked::pw_aff aff::cond(const isl::checked::pw_aff &pwaff_true, const isl::checked::pw_aff &pwaff_false) const
 {
-  auto res = isl_aff_eq_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::pw_aff(*this).cond(pwaff_true, pwaff_false);
 }
 
-isl::checked::val aff::eval(isl::checked::point pnt) const
+isl::checked::multi_val aff::constant_multi_val() const
 {
-  auto res = isl_aff_eval(copy(), pnt.release());
-  return manage(res);
-}
-
-isl::checked::aff aff::floor() const
-{
-  auto res = isl_aff_floor(copy());
-  return manage(res);
-}
-
-isl::checked::set aff::ge_set(isl::checked::aff aff2) const
-{
-  auto res = isl_aff_ge_set(copy(), aff2.release());
-  return manage(res);
+  return isl::checked::multi_aff(*this).constant_multi_val();
 }
 
 isl::checked::val aff::constant_val() const
@@ -3360,36 +4454,271 @@
   return constant_val();
 }
 
+isl::checked::aff aff::div(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_div(copy(), aff2.release());
+  return manage(res);
+}
+
+isl::checked::pw_aff aff::div(const isl::checked::pw_aff &pa2) const
+{
+  return isl::checked::pw_aff(*this).div(pa2);
+}
+
+isl::checked::set aff::domain() const
+{
+  return isl::checked::pw_aff(*this).domain();
+}
+
+isl::checked::set aff::eq_set(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_eq_set(copy(), aff2.release());
+  return manage(res);
+}
+
+isl::checked::set aff::eq_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).eq_set(pwaff2);
+}
+
+isl::checked::val aff::eval(isl::checked::point pnt) const
+{
+  auto res = isl_aff_eval(copy(), pnt.release());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff aff::extract_pw_multi_aff(const isl::checked::space &space) const
+{
+  return isl::checked::pw_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::checked::multi_aff aff::flat_range_product(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_pw_aff aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::pw_multi_aff aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).flat_range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).flat_range_product(upma2);
+}
+
+isl::checked::aff aff::floor() const
+{
+  auto res = isl_aff_floor(copy());
+  return manage(res);
+}
+
+stat aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
+{
+  return isl::checked::pw_aff(*this).foreach_piece(fn);
+}
+
+isl::checked::set aff::ge_set(isl::checked::aff aff2) const
+{
+  auto res = isl_aff_ge_set(copy(), aff2.release());
+  return manage(res);
+}
+
+isl::checked::set aff::ge_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).ge_set(pwaff2);
+}
+
 isl::checked::aff aff::gist(isl::checked::set context) const
 {
   auto res = isl_aff_gist(copy(), context.release());
   return manage(res);
 }
 
+isl::checked::union_pw_aff aff::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::pw_aff(*this).gist(context);
+}
+
+isl::checked::aff aff::gist(const isl::checked::basic_set &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+isl::checked::aff aff::gist(const isl::checked::point &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
 isl::checked::set aff::gt_set(isl::checked::aff aff2) const
 {
   auto res = isl_aff_gt_set(copy(), aff2.release());
   return manage(res);
 }
 
+isl::checked::set aff::gt_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).gt_set(pwaff2);
+}
+
+boolean aff::has_range_tuple_id() const
+{
+  return isl::checked::multi_aff(*this).has_range_tuple_id();
+}
+
+isl::checked::multi_aff aff::identity() const
+{
+  return isl::checked::multi_aff(*this).identity();
+}
+
+isl::checked::pw_aff aff::insert_domain(const isl::checked::space &domain) const
+{
+  return isl::checked::pw_aff(*this).insert_domain(domain);
+}
+
+isl::checked::pw_aff aff::intersect_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain(set);
+}
+
+isl::checked::union_pw_aff aff::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain(space);
+}
+
+isl::checked::union_pw_aff aff::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain(uset);
+}
+
+isl::checked::union_pw_aff aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::checked::union_pw_aff aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
+isl::checked::pw_aff aff::intersect_params(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).intersect_params(set);
+}
+
+boolean aff::involves_locals() const
+{
+  return isl::checked::multi_aff(*this).involves_locals();
+}
+
+boolean aff::involves_nan() const
+{
+  return isl::checked::multi_aff(*this).involves_nan();
+}
+
+boolean aff::involves_param(const isl::checked::id &id) const
+{
+  return isl::checked::pw_aff(*this).involves_param(id);
+}
+
+boolean aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
+}
+
+boolean aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::pw_aff(*this).involves_param(list);
+}
+
 boolean aff::is_cst() const
 {
   auto res = isl_aff_is_cst(get());
   return manage(res);
 }
 
+boolean aff::isa_aff() const
+{
+  return isl::checked::pw_aff(*this).isa_aff();
+}
+
+boolean aff::isa_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).isa_multi_aff();
+}
+
+boolean aff::isa_pw_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).isa_pw_multi_aff();
+}
+
 isl::checked::set aff::le_set(isl::checked::aff aff2) const
 {
   auto res = isl_aff_le_set(copy(), aff2.release());
   return manage(res);
 }
 
+isl::checked::set aff::le_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).le_set(pwaff2);
+}
+
+isl::checked::aff_list aff::list() const
+{
+  return isl::checked::multi_aff(*this).list();
+}
+
 isl::checked::set aff::lt_set(isl::checked::aff aff2) const
 {
   auto res = isl_aff_lt_set(copy(), aff2.release());
   return manage(res);
 }
 
+isl::checked::set aff::lt_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).lt_set(pwaff2);
+}
+
+isl::checked::multi_pw_aff aff::max(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).max(multi2);
+}
+
+isl::checked::pw_aff aff::max(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).max(pwaff2);
+}
+
+isl::checked::multi_val aff::max_multi_val() const
+{
+  return isl::checked::pw_aff(*this).max_multi_val();
+}
+
+isl::checked::multi_pw_aff aff::min(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).min(multi2);
+}
+
+isl::checked::pw_aff aff::min(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).min(pwaff2);
+}
+
+isl::checked::multi_val aff::min_multi_val() const
+{
+  return isl::checked::pw_aff(*this).min_multi_val();
+}
+
 isl::checked::aff aff::mod(isl::checked::val mod) const
 {
   auto res = isl_aff_mod_val(copy(), mod.release());
@@ -3407,24 +4736,154 @@
   return manage(res);
 }
 
+isl::checked::pw_aff aff::mul(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).mul(pwaff2);
+}
+
+class size aff::n_piece() const
+{
+  return isl::checked::pw_aff(*this).n_piece();
+}
+
 isl::checked::set aff::ne_set(isl::checked::aff aff2) const
 {
   auto res = isl_aff_ne_set(copy(), aff2.release());
   return manage(res);
 }
 
+isl::checked::set aff::ne_set(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).ne_set(pwaff2);
+}
+
 isl::checked::aff aff::neg() const
 {
   auto res = isl_aff_neg(copy());
   return manage(res);
 }
 
+boolean aff::plain_is_empty() const
+{
+  return isl::checked::pw_aff(*this).plain_is_empty();
+}
+
+boolean aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).plain_is_equal(multi2);
+}
+
+boolean aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).plain_is_equal(multi2);
+}
+
+boolean aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::checked::pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::checked::union_pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::checked::multi_aff aff::product(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).product(multi2);
+}
+
+isl::checked::multi_pw_aff aff::product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).product(multi2);
+}
+
+isl::checked::pw_multi_aff aff::product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).product(pma2);
+}
+
 isl::checked::aff aff::pullback(isl::checked::multi_aff ma) const
 {
   auto res = isl_aff_pullback_multi_aff(copy(), ma.release());
   return manage(res);
 }
 
+isl::checked::pw_aff aff::pullback(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::pw_aff(*this).pullback(mpa);
+}
+
+isl::checked::pw_aff aff::pullback(const isl::checked::pw_multi_aff &pma) const
+{
+  return isl::checked::pw_aff(*this).pullback(pma);
+}
+
+isl::checked::union_pw_aff aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::pw_aff(*this).pullback(upma);
+}
+
+isl::checked::aff aff::pullback(const isl::checked::aff &ma) const
+{
+  return this->pullback(isl::checked::multi_aff(ma));
+}
+
+isl::checked::pw_multi_aff_list aff::pw_multi_aff_list() const
+{
+  return isl::checked::pw_aff(*this).pw_multi_aff_list();
+}
+
+isl::checked::pw_multi_aff aff::range_factor_domain() const
+{
+  return isl::checked::pw_aff(*this).range_factor_domain();
+}
+
+isl::checked::pw_multi_aff aff::range_factor_range() const
+{
+  return isl::checked::pw_aff(*this).range_factor_range();
+}
+
+isl::checked::multi_aff aff::range_product(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_pw_aff aff::range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::pw_multi_aff aff::range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).range_product(upma2);
+}
+
+isl::checked::id aff::range_tuple_id() const
+{
+  return isl::checked::multi_aff(*this).range_tuple_id();
+}
+
+isl::checked::multi_aff aff::reset_range_tuple_id() const
+{
+  return isl::checked::multi_aff(*this).reset_range_tuple_id();
+}
+
 isl::checked::aff aff::scale(isl::checked::val v) const
 {
   auto res = isl_aff_scale_val(copy(), v.release());
@@ -3436,6 +4895,11 @@
   return this->scale(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_aff aff::scale(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_aff(*this).scale(mv);
+}
+
 isl::checked::aff aff::scale_down(isl::checked::val v) const
 {
   auto res = isl_aff_scale_down_val(copy(), v.release());
@@ -3447,18 +4911,179 @@
   return this->scale_down(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_aff aff::scale_down(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_aff(*this).scale_down(mv);
+}
+
+isl::checked::multi_aff aff::set_at(int pos, const isl::checked::aff &el) const
+{
+  return isl::checked::multi_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_pw_aff aff::set_at(int pos, const isl::checked::pw_aff &el) const
+{
+  return isl::checked::pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_union_pw_aff aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_aff aff::set_range_tuple(const isl::checked::id &id) const
+{
+  return isl::checked::multi_aff(*this).set_range_tuple(id);
+}
+
+isl::checked::multi_aff aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+class size aff::size() const
+{
+  return isl::checked::multi_aff(*this).size();
+}
+
+isl::checked::space aff::space() const
+{
+  return isl::checked::multi_aff(*this).space();
+}
+
 isl::checked::aff aff::sub(isl::checked::aff aff2) const
 {
   auto res = isl_aff_sub(copy(), aff2.release());
   return manage(res);
 }
 
+isl::checked::multi_aff aff::sub(const isl::checked::multi_aff &multi2) const
+{
+  return isl::checked::multi_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_pw_aff aff::sub(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_union_pw_aff aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_aff(*this).sub(multi2);
+}
+
+isl::checked::pw_aff aff::sub(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).sub(pwaff2);
+}
+
+isl::checked::pw_multi_aff aff::sub(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).sub(pma2);
+}
+
+isl::checked::union_pw_aff aff::sub(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::pw_aff(*this).sub(upa2);
+}
+
+isl::checked::union_pw_multi_aff aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).sub(upma2);
+}
+
+isl::checked::pw_aff aff::subtract_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_aff(*this).subtract_domain(set);
+}
+
+isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_aff(*this).subtract_domain(space);
+}
+
+isl::checked::union_pw_aff aff::subtract_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_aff(*this).subtract_domain(uset);
+}
+
+isl::checked::pw_aff aff::tdiv_q(const isl::checked::pw_aff &pa2) const
+{
+  return isl::checked::pw_aff(*this).tdiv_q(pa2);
+}
+
+isl::checked::pw_aff aff::tdiv_r(const isl::checked::pw_aff &pa2) const
+{
+  return isl::checked::pw_aff(*this).tdiv_r(pa2);
+}
+
+isl::checked::aff_list aff::to_list() const
+{
+  auto res = isl_aff_to_list(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff aff::to_multi_pw_aff() const
+{
+  return isl::checked::multi_aff(*this).to_multi_pw_aff();
+}
+
+isl::checked::multi_union_pw_aff aff::to_multi_union_pw_aff() const
+{
+  return isl::checked::multi_aff(*this).to_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff aff::to_pw_multi_aff() const
+{
+  return isl::checked::multi_aff(*this).to_pw_multi_aff();
+}
+
+isl::checked::union_pw_aff aff::to_union_pw_aff() const
+{
+  return isl::checked::pw_aff(*this).to_union_pw_aff();
+}
+
+isl::checked::union_pw_multi_aff aff::to_union_pw_multi_aff() const
+{
+  return isl::checked::pw_aff(*this).to_union_pw_multi_aff();
+}
+
 isl::checked::aff aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
 {
   auto res = isl_aff_unbind_params_insert_domain(copy(), domain.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::pw_aff(*this).union_add(mpa2);
+}
+
+isl::checked::multi_union_pw_aff aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::pw_aff(*this).union_add(mupa2);
+}
+
+isl::checked::pw_aff aff::union_add(const isl::checked::pw_aff &pwaff2) const
+{
+  return isl::checked::pw_aff(*this).union_add(pwaff2);
+}
+
+isl::checked::pw_multi_aff aff::union_add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_aff(*this).union_add(pma2);
+}
+
+isl::checked::union_pw_aff aff::union_add(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::pw_aff(*this).union_add(upa2);
+}
+
+isl::checked::union_pw_multi_aff aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_aff(*this).union_add(upma2);
+}
+
 isl::checked::aff aff::zero_on_domain(isl::checked::space space)
 {
   auto res = isl_aff_zero_on_domain_space(space.release());
@@ -3510,6 +5135,12 @@
   ptr = res;
 }
 
+aff_list::aff_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_aff_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 aff_list &aff_list::operator=(aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -3548,6 +5179,17 @@
   return manage(res);
 }
 
+isl::checked::aff aff_list::at(int index) const
+{
+  auto res = isl_aff_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::aff aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::aff_list aff_list::clear() const
 {
   auto res = isl_aff_list_clear(copy());
@@ -3580,17 +5222,6 @@
   return manage(res);
 }
 
-isl::checked::aff aff_list::at(int index) const
-{
-  auto res = isl_aff_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::aff aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::aff_list aff_list::insert(unsigned int pos, isl::checked::aff el) const
 {
   auto res = isl_aff_list_insert(copy(), pos, el.release());
@@ -3747,17 +5378,6 @@
   return manage(res);
 }
 
-isl::checked::union_map ast_build::schedule() const
-{
-  auto res = isl_ast_build_get_schedule(get());
-  return manage(res);
-}
-
-isl::checked::union_map ast_build::get_schedule() const
-{
-  return schedule();
-}
-
 isl::checked::ast_node ast_build::node_from(isl::checked::schedule schedule) const
 {
   auto res = isl_ast_build_node_from_schedule(get(), schedule.release());
@@ -3770,6 +5390,17 @@
   return manage(res);
 }
 
+isl::checked::union_map ast_build::schedule() const
+{
+  auto res = isl_ast_build_get_schedule(get());
+  return manage(res);
+}
+
+isl::checked::union_map ast_build::get_schedule() const
+{
+  return schedule();
+}
+
 // implementations for isl::ast_expr
 ast_expr manage(__isl_take isl_ast_expr *ptr) {
   return ast_expr(ptr);
@@ -4965,6 +6596,12 @@
   return tmp;
 }
 
+isl::checked::ast_node_list ast_node::to_list() const
+{
+  auto res = isl_ast_node_to_list(copy());
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const ast_node &obj)
 {
   char *str = isl_ast_node_to_str(obj.get());
@@ -5086,6 +6723,12 @@
   return init();
 }
 
+boolean ast_node_for::is_degenerate() const
+{
+  auto res = isl_ast_node_for_is_degenerate(get());
+  return manage(res);
+}
+
 isl::checked::ast_expr ast_node_for::iterator() const
 {
   auto res = isl_ast_node_for_get_iterator(get());
@@ -5097,12 +6740,6 @@
   return iterator();
 }
 
-boolean ast_node_for::is_degenerate() const
-{
-  auto res = isl_ast_node_for_is_degenerate(get());
-  return manage(res);
-}
-
 inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
 {
   char *str = isl_ast_node_to_str(obj.get());
@@ -5158,6 +6795,12 @@
   return else_node();
 }
 
+boolean ast_node_if::has_else_node() const
+{
+  auto res = isl_ast_node_if_has_else_node(get());
+  return manage(res);
+}
+
 isl::checked::ast_node ast_node_if::then_node() const
 {
   auto res = isl_ast_node_if_get_then_node(get());
@@ -5169,12 +6812,6 @@
   return then_node();
 }
 
-boolean ast_node_if::has_else_node() const
-{
-  auto res = isl_ast_node_if_has_else_node(get());
-  return manage(res);
-}
-
 inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
 {
   char *str = isl_ast_node_to_str(obj.get());
@@ -5258,6 +6895,17 @@
   return manage(res);
 }
 
+isl::checked::ast_node ast_node_list::at(int index) const
+{
+  auto res = isl_ast_node_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::ast_node ast_node_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::ast_node_list ast_node_list::clear() const
 {
   auto res = isl_ast_node_list_clear(copy());
@@ -5290,17 +6938,6 @@
   return manage(res);
 }
 
-isl::checked::ast_node ast_node_list::at(int index) const
-{
-  auto res = isl_ast_node_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::ast_node ast_node_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::ast_node_list ast_node_list::insert(unsigned int pos, isl::checked::ast_node el) const
 {
   auto res = isl_ast_node_list_insert(copy(), pos, el.release());
@@ -5495,12 +7132,82 @@
   return manage(res);
 }
 
+isl::checked::map basic_map::apply_domain(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).apply_domain(map2);
+}
+
+isl::checked::union_map basic_map::apply_domain(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).apply_domain(umap2);
+}
+
 isl::checked::basic_map basic_map::apply_range(isl::checked::basic_map bmap2) const
 {
   auto res = isl_basic_map_apply_range(copy(), bmap2.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::apply_range(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).apply_range(map2);
+}
+
+isl::checked::union_map basic_map::apply_range(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).apply_range(umap2);
+}
+
+isl::checked::map basic_map::as_map() const
+{
+  return isl::checked::map(*this).as_map();
+}
+
+isl::checked::multi_union_pw_aff basic_map::as_multi_union_pw_aff() const
+{
+  return isl::checked::map(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff basic_map::as_pw_multi_aff() const
+{
+  return isl::checked::map(*this).as_pw_multi_aff();
+}
+
+isl::checked::union_pw_multi_aff basic_map::as_union_pw_multi_aff() const
+{
+  return isl::checked::map(*this).as_union_pw_multi_aff();
+}
+
+isl::checked::set basic_map::bind_domain(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::map(*this).bind_domain(tuple);
+}
+
+isl::checked::set basic_map::bind_range(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::map(*this).bind_range(tuple);
+}
+
+isl::checked::map basic_map::coalesce() const
+{
+  return isl::checked::map(*this).coalesce();
+}
+
+isl::checked::map basic_map::complement() const
+{
+  return isl::checked::map(*this).complement();
+}
+
+isl::checked::union_map basic_map::compute_divs() const
+{
+  return isl::checked::map(*this).compute_divs();
+}
+
+isl::checked::map basic_map::curry() const
+{
+  return isl::checked::map(*this).curry();
+}
+
 isl::checked::basic_set basic_map::deltas() const
 {
   auto res = isl_basic_map_deltas(copy());
@@ -5513,6 +7220,91 @@
   return manage(res);
 }
 
+isl::checked::set basic_map::domain() const
+{
+  return isl::checked::map(*this).domain();
+}
+
+isl::checked::map basic_map::domain_factor_domain() const
+{
+  return isl::checked::map(*this).domain_factor_domain();
+}
+
+isl::checked::map basic_map::domain_factor_range() const
+{
+  return isl::checked::map(*this).domain_factor_range();
+}
+
+isl::checked::union_map basic_map::domain_map() const
+{
+  return isl::checked::map(*this).domain_map();
+}
+
+isl::checked::union_pw_multi_aff basic_map::domain_map_union_pw_multi_aff() const
+{
+  return isl::checked::map(*this).domain_map_union_pw_multi_aff();
+}
+
+isl::checked::map basic_map::domain_product(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).domain_product(map2);
+}
+
+isl::checked::union_map basic_map::domain_product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).domain_product(umap2);
+}
+
+class size basic_map::domain_tuple_dim() const
+{
+  return isl::checked::map(*this).domain_tuple_dim();
+}
+
+isl::checked::id basic_map::domain_tuple_id() const
+{
+  return isl::checked::map(*this).domain_tuple_id();
+}
+
+isl::checked::map basic_map::eq_at(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).eq_at(mpa);
+}
+
+isl::checked::union_map basic_map::eq_at(const isl::checked::multi_union_pw_aff &mupa) const
+{
+  return isl::checked::map(*this).eq_at(mupa);
+}
+
+boolean basic_map::every_map(const std::function<boolean(isl::checked::map)> &test) const
+{
+  return isl::checked::map(*this).every_map(test);
+}
+
+isl::checked::map basic_map::extract_map(const isl::checked::space &space) const
+{
+  return isl::checked::map(*this).extract_map(space);
+}
+
+isl::checked::map basic_map::factor_domain() const
+{
+  return isl::checked::map(*this).factor_domain();
+}
+
+isl::checked::map basic_map::factor_range() const
+{
+  return isl::checked::map(*this).factor_range();
+}
+
+isl::checked::union_map basic_map::fixed_power(const isl::checked::val &exp) const
+{
+  return isl::checked::map(*this).fixed_power(exp);
+}
+
+isl::checked::union_map basic_map::fixed_power(long exp) const
+{
+  return this->fixed_power(isl::checked::val(ctx(), exp));
+}
+
 isl::checked::basic_map basic_map::flatten() const
 {
   auto res = isl_basic_map_flatten(copy());
@@ -5531,30 +7323,190 @@
   return manage(res);
 }
 
+stat basic_map::foreach_basic_map(const std::function<stat(isl::checked::basic_map)> &fn) const
+{
+  return isl::checked::map(*this).foreach_basic_map(fn);
+}
+
+stat basic_map::foreach_map(const std::function<stat(isl::checked::map)> &fn) const
+{
+  return isl::checked::map(*this).foreach_map(fn);
+}
+
 isl::checked::basic_map basic_map::gist(isl::checked::basic_map context) const
 {
   auto res = isl_basic_map_gist(copy(), context.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::gist(const isl::checked::map &context) const
+{
+  return isl::checked::map(*this).gist(context);
+}
+
+isl::checked::union_map basic_map::gist(const isl::checked::union_map &context) const
+{
+  return isl::checked::map(*this).gist(context);
+}
+
+isl::checked::map basic_map::gist_domain(const isl::checked::set &context) const
+{
+  return isl::checked::map(*this).gist_domain(context);
+}
+
+isl::checked::union_map basic_map::gist_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::map(*this).gist_domain(uset);
+}
+
+isl::checked::union_map basic_map::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::map(*this).gist_params(set);
+}
+
+isl::checked::union_map basic_map::gist_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::map(*this).gist_range(uset);
+}
+
+boolean basic_map::has_domain_tuple_id() const
+{
+  return isl::checked::map(*this).has_domain_tuple_id();
+}
+
+boolean basic_map::has_range_tuple_id() const
+{
+  return isl::checked::map(*this).has_range_tuple_id();
+}
+
 isl::checked::basic_map basic_map::intersect(isl::checked::basic_map bmap2) const
 {
   auto res = isl_basic_map_intersect(copy(), bmap2.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::intersect(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).intersect(map2);
+}
+
+isl::checked::union_map basic_map::intersect(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).intersect(umap2);
+}
+
 isl::checked::basic_map basic_map::intersect_domain(isl::checked::basic_set bset) const
 {
   auto res = isl_basic_map_intersect_domain(copy(), bset.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::intersect_domain(const isl::checked::set &set) const
+{
+  return isl::checked::map(*this).intersect_domain(set);
+}
+
+isl::checked::union_map basic_map::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::map(*this).intersect_domain(space);
+}
+
+isl::checked::union_map basic_map::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::map(*this).intersect_domain(uset);
+}
+
+isl::checked::basic_map basic_map::intersect_domain(const isl::checked::point &bset) const
+{
+  return this->intersect_domain(isl::checked::basic_set(bset));
+}
+
+isl::checked::map basic_map::intersect_domain_factor_domain(const isl::checked::map &factor) const
+{
+  return isl::checked::map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::checked::union_map basic_map::intersect_domain_factor_domain(const isl::checked::union_map &factor) const
+{
+  return isl::checked::map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::checked::map basic_map::intersect_domain_factor_range(const isl::checked::map &factor) const
+{
+  return isl::checked::map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::checked::union_map basic_map::intersect_domain_factor_range(const isl::checked::union_map &factor) const
+{
+  return isl::checked::map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::checked::map basic_map::intersect_params(const isl::checked::set &params) const
+{
+  return isl::checked::map(*this).intersect_params(params);
+}
+
 isl::checked::basic_map basic_map::intersect_range(isl::checked::basic_set bset) const
 {
   auto res = isl_basic_map_intersect_range(copy(), bset.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::intersect_range(const isl::checked::set &set) const
+{
+  return isl::checked::map(*this).intersect_range(set);
+}
+
+isl::checked::union_map basic_map::intersect_range(const isl::checked::space &space) const
+{
+  return isl::checked::map(*this).intersect_range(space);
+}
+
+isl::checked::union_map basic_map::intersect_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::map(*this).intersect_range(uset);
+}
+
+isl::checked::basic_map basic_map::intersect_range(const isl::checked::point &bset) const
+{
+  return this->intersect_range(isl::checked::basic_set(bset));
+}
+
+isl::checked::map basic_map::intersect_range_factor_domain(const isl::checked::map &factor) const
+{
+  return isl::checked::map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::checked::union_map basic_map::intersect_range_factor_domain(const isl::checked::union_map &factor) const
+{
+  return isl::checked::map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::checked::map basic_map::intersect_range_factor_range(const isl::checked::map &factor) const
+{
+  return isl::checked::map(*this).intersect_range_factor_range(factor);
+}
+
+isl::checked::union_map basic_map::intersect_range_factor_range(const isl::checked::union_map &factor) const
+{
+  return isl::checked::map(*this).intersect_range_factor_range(factor);
+}
+
+boolean basic_map::is_bijective() const
+{
+  return isl::checked::map(*this).is_bijective();
+}
+
+boolean basic_map::is_disjoint(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).is_disjoint(map2);
+}
+
+boolean basic_map::is_disjoint(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).is_disjoint(umap2);
+}
+
 boolean basic_map::is_empty() const
 {
   auto res = isl_basic_map_is_empty(get());
@@ -5567,24 +7519,229 @@
   return manage(res);
 }
 
+boolean basic_map::is_equal(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).is_equal(map2);
+}
+
+boolean basic_map::is_equal(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).is_equal(umap2);
+}
+
+boolean basic_map::is_injective() const
+{
+  return isl::checked::map(*this).is_injective();
+}
+
+boolean basic_map::is_single_valued() const
+{
+  return isl::checked::map(*this).is_single_valued();
+}
+
+boolean basic_map::is_strict_subset(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).is_strict_subset(map2);
+}
+
+boolean basic_map::is_strict_subset(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).is_strict_subset(umap2);
+}
+
 boolean basic_map::is_subset(const isl::checked::basic_map &bmap2) const
 {
   auto res = isl_basic_map_is_subset(get(), bmap2.get());
   return manage(res);
 }
 
+boolean basic_map::is_subset(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).is_subset(map2);
+}
+
+boolean basic_map::is_subset(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).is_subset(umap2);
+}
+
+boolean basic_map::isa_map() const
+{
+  return isl::checked::map(*this).isa_map();
+}
+
+isl::checked::map basic_map::lex_ge_at(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).lex_ge_at(mpa);
+}
+
+isl::checked::map basic_map::lex_gt_at(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).lex_gt_at(mpa);
+}
+
+isl::checked::map basic_map::lex_le_at(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).lex_le_at(mpa);
+}
+
+isl::checked::map basic_map::lex_lt_at(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).lex_lt_at(mpa);
+}
+
 isl::checked::map basic_map::lexmax() const
 {
   auto res = isl_basic_map_lexmax(copy());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff basic_map::lexmax_pw_multi_aff() const
+{
+  return isl::checked::map(*this).lexmax_pw_multi_aff();
+}
+
 isl::checked::map basic_map::lexmin() const
 {
   auto res = isl_basic_map_lexmin(copy());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff basic_map::lexmin_pw_multi_aff() const
+{
+  return isl::checked::map(*this).lexmin_pw_multi_aff();
+}
+
+isl::checked::map basic_map::lower_bound(const isl::checked::multi_pw_aff &lower) const
+{
+  return isl::checked::map(*this).lower_bound(lower);
+}
+
+isl::checked::map_list basic_map::map_list() const
+{
+  return isl::checked::map(*this).map_list();
+}
+
+isl::checked::multi_pw_aff basic_map::max_multi_pw_aff() const
+{
+  return isl::checked::map(*this).max_multi_pw_aff();
+}
+
+isl::checked::multi_pw_aff basic_map::min_multi_pw_aff() const
+{
+  return isl::checked::map(*this).min_multi_pw_aff();
+}
+
+isl::checked::basic_map basic_map::polyhedral_hull() const
+{
+  return isl::checked::map(*this).polyhedral_hull();
+}
+
+isl::checked::map basic_map::preimage_domain(const isl::checked::multi_aff &ma) const
+{
+  return isl::checked::map(*this).preimage_domain(ma);
+}
+
+isl::checked::map basic_map::preimage_domain(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::map(*this).preimage_domain(mpa);
+}
+
+isl::checked::map basic_map::preimage_domain(const isl::checked::pw_multi_aff &pma) const
+{
+  return isl::checked::map(*this).preimage_domain(pma);
+}
+
+isl::checked::union_map basic_map::preimage_domain(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::map(*this).preimage_domain(upma);
+}
+
+isl::checked::map basic_map::preimage_range(const isl::checked::multi_aff &ma) const
+{
+  return isl::checked::map(*this).preimage_range(ma);
+}
+
+isl::checked::map basic_map::preimage_range(const isl::checked::pw_multi_aff &pma) const
+{
+  return isl::checked::map(*this).preimage_range(pma);
+}
+
+isl::checked::union_map basic_map::preimage_range(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::map(*this).preimage_range(upma);
+}
+
+isl::checked::map basic_map::product(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).product(map2);
+}
+
+isl::checked::union_map basic_map::product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).product(umap2);
+}
+
+isl::checked::map basic_map::project_out_all_params() const
+{
+  return isl::checked::map(*this).project_out_all_params();
+}
+
+isl::checked::set basic_map::range() const
+{
+  return isl::checked::map(*this).range();
+}
+
+isl::checked::map basic_map::range_factor_domain() const
+{
+  return isl::checked::map(*this).range_factor_domain();
+}
+
+isl::checked::map basic_map::range_factor_range() const
+{
+  return isl::checked::map(*this).range_factor_range();
+}
+
+isl::checked::fixed_box basic_map::range_lattice_tile() const
+{
+  return isl::checked::map(*this).range_lattice_tile();
+}
+
+isl::checked::union_map basic_map::range_map() const
+{
+  return isl::checked::map(*this).range_map();
+}
+
+isl::checked::map basic_map::range_product(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).range_product(map2);
+}
+
+isl::checked::union_map basic_map::range_product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).range_product(umap2);
+}
+
+isl::checked::map basic_map::range_reverse() const
+{
+  return isl::checked::map(*this).range_reverse();
+}
+
+isl::checked::fixed_box basic_map::range_simple_fixed_box_hull() const
+{
+  return isl::checked::map(*this).range_simple_fixed_box_hull();
+}
+
+class size basic_map::range_tuple_dim() const
+{
+  return isl::checked::map(*this).range_tuple_dim();
+}
+
+isl::checked::id basic_map::range_tuple_id() const
+{
+  return isl::checked::map(*this).range_tuple_id();
+}
+
 isl::checked::basic_map basic_map::reverse() const
 {
   auto res = isl_basic_map_reverse(copy());
@@ -5597,12 +7754,102 @@
   return manage(res);
 }
 
+isl::checked::map basic_map::set_domain_tuple(const isl::checked::id &id) const
+{
+  return isl::checked::map(*this).set_domain_tuple(id);
+}
+
+isl::checked::map basic_map::set_domain_tuple(const std::string &id) const
+{
+  return this->set_domain_tuple(isl::checked::id(ctx(), id));
+}
+
+isl::checked::map basic_map::set_range_tuple(const isl::checked::id &id) const
+{
+  return isl::checked::map(*this).set_range_tuple(id);
+}
+
+isl::checked::map basic_map::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+isl::checked::space basic_map::space() const
+{
+  return isl::checked::map(*this).space();
+}
+
+isl::checked::map basic_map::subtract(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).subtract(map2);
+}
+
+isl::checked::union_map basic_map::subtract(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).subtract(umap2);
+}
+
+isl::checked::union_map basic_map::subtract_domain(const isl::checked::union_set &dom) const
+{
+  return isl::checked::map(*this).subtract_domain(dom);
+}
+
+isl::checked::union_map basic_map::subtract_range(const isl::checked::union_set &dom) const
+{
+  return isl::checked::map(*this).subtract_range(dom);
+}
+
+isl::checked::map_list basic_map::to_list() const
+{
+  return isl::checked::map(*this).to_list();
+}
+
+isl::checked::union_map basic_map::to_union_map() const
+{
+  return isl::checked::map(*this).to_union_map();
+}
+
+isl::checked::map basic_map::uncurry() const
+{
+  return isl::checked::map(*this).uncurry();
+}
+
 isl::checked::map basic_map::unite(isl::checked::basic_map bmap2) const
 {
   auto res = isl_basic_map_union(copy(), bmap2.release());
   return manage(res);
 }
 
+isl::checked::map basic_map::unite(const isl::checked::map &map2) const
+{
+  return isl::checked::map(*this).unite(map2);
+}
+
+isl::checked::union_map basic_map::unite(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::map(*this).unite(umap2);
+}
+
+isl::checked::basic_map basic_map::unshifted_simple_hull() const
+{
+  return isl::checked::map(*this).unshifted_simple_hull();
+}
+
+isl::checked::map basic_map::upper_bound(const isl::checked::multi_pw_aff &upper) const
+{
+  return isl::checked::map(*this).upper_bound(upper);
+}
+
+isl::checked::set basic_map::wrap() const
+{
+  return isl::checked::map(*this).wrap();
+}
+
+isl::checked::map basic_map::zip() const
+{
+  return isl::checked::map(*this).zip();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const basic_map &obj)
 {
   char *str = isl_basic_map_to_str(obj.get());
@@ -5692,6 +7939,46 @@
   return manage(res);
 }
 
+isl::checked::set basic_set::apply(const isl::checked::map &map) const
+{
+  return isl::checked::set(*this).apply(map);
+}
+
+isl::checked::union_set basic_set::apply(const isl::checked::union_map &umap) const
+{
+  return isl::checked::set(*this).apply(umap);
+}
+
+isl::checked::pw_multi_aff basic_set::as_pw_multi_aff() const
+{
+  return isl::checked::set(*this).as_pw_multi_aff();
+}
+
+isl::checked::set basic_set::as_set() const
+{
+  return isl::checked::set(*this).as_set();
+}
+
+isl::checked::set basic_set::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::set(*this).bind(tuple);
+}
+
+isl::checked::set basic_set::coalesce() const
+{
+  return isl::checked::set(*this).coalesce();
+}
+
+isl::checked::set basic_set::complement() const
+{
+  return isl::checked::set(*this).complement();
+}
+
+isl::checked::union_set basic_set::compute_divs() const
+{
+  return isl::checked::set(*this).compute_divs();
+}
+
 isl::checked::basic_set basic_set::detect_equalities() const
 {
   auto res = isl_basic_set_detect_equalities(copy());
@@ -5704,30 +7991,135 @@
   return manage(res);
 }
 
+isl::checked::val basic_set::dim_min_val(int pos) const
+{
+  return isl::checked::set(*this).dim_min_val(pos);
+}
+
+boolean basic_set::every_set(const std::function<boolean(isl::checked::set)> &test) const
+{
+  return isl::checked::set(*this).every_set(test);
+}
+
+isl::checked::set basic_set::extract_set(const isl::checked::space &space) const
+{
+  return isl::checked::set(*this).extract_set(space);
+}
+
 isl::checked::basic_set basic_set::flatten() const
 {
   auto res = isl_basic_set_flatten(copy());
   return manage(res);
 }
 
+stat basic_set::foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const
+{
+  return isl::checked::set(*this).foreach_basic_set(fn);
+}
+
+stat basic_set::foreach_point(const std::function<stat(isl::checked::point)> &fn) const
+{
+  return isl::checked::set(*this).foreach_point(fn);
+}
+
+stat basic_set::foreach_set(const std::function<stat(isl::checked::set)> &fn) const
+{
+  return isl::checked::set(*this).foreach_set(fn);
+}
+
 isl::checked::basic_set basic_set::gist(isl::checked::basic_set context) const
 {
   auto res = isl_basic_set_gist(copy(), context.release());
   return manage(res);
 }
 
+isl::checked::set basic_set::gist(const isl::checked::set &context) const
+{
+  return isl::checked::set(*this).gist(context);
+}
+
+isl::checked::union_set basic_set::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::set(*this).gist(context);
+}
+
+isl::checked::basic_set basic_set::gist(const isl::checked::point &context) const
+{
+  return this->gist(isl::checked::basic_set(context));
+}
+
+isl::checked::union_set basic_set::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::set(*this).gist_params(set);
+}
+
+isl::checked::map basic_set::identity() const
+{
+  return isl::checked::set(*this).identity();
+}
+
+isl::checked::pw_aff basic_set::indicator_function() const
+{
+  return isl::checked::set(*this).indicator_function();
+}
+
+isl::checked::map basic_set::insert_domain(const isl::checked::space &domain) const
+{
+  return isl::checked::set(*this).insert_domain(domain);
+}
+
 isl::checked::basic_set basic_set::intersect(isl::checked::basic_set bset2) const
 {
   auto res = isl_basic_set_intersect(copy(), bset2.release());
   return manage(res);
 }
 
+isl::checked::set basic_set::intersect(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).intersect(set2);
+}
+
+isl::checked::union_set basic_set::intersect(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).intersect(uset2);
+}
+
+isl::checked::basic_set basic_set::intersect(const isl::checked::point &bset2) const
+{
+  return this->intersect(isl::checked::basic_set(bset2));
+}
+
 isl::checked::basic_set basic_set::intersect_params(isl::checked::basic_set bset2) const
 {
   auto res = isl_basic_set_intersect_params(copy(), bset2.release());
   return manage(res);
 }
 
+isl::checked::set basic_set::intersect_params(const isl::checked::set &params) const
+{
+  return isl::checked::set(*this).intersect_params(params);
+}
+
+isl::checked::basic_set basic_set::intersect_params(const isl::checked::point &bset2) const
+{
+  return this->intersect_params(isl::checked::basic_set(bset2));
+}
+
+boolean basic_set::involves_locals() const
+{
+  return isl::checked::set(*this).involves_locals();
+}
+
+boolean basic_set::is_disjoint(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).is_disjoint(set2);
+}
+
+boolean basic_set::is_disjoint(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).is_disjoint(uset2);
+}
+
 boolean basic_set::is_empty() const
 {
   auto res = isl_basic_set_is_empty(get());
@@ -5740,36 +8132,186 @@
   return manage(res);
 }
 
+boolean basic_set::is_equal(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).is_equal(set2);
+}
+
+boolean basic_set::is_equal(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).is_equal(uset2);
+}
+
+boolean basic_set::is_equal(const isl::checked::point &bset2) const
+{
+  return this->is_equal(isl::checked::basic_set(bset2));
+}
+
+boolean basic_set::is_singleton() const
+{
+  return isl::checked::set(*this).is_singleton();
+}
+
+boolean basic_set::is_strict_subset(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).is_strict_subset(set2);
+}
+
+boolean basic_set::is_strict_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).is_strict_subset(uset2);
+}
+
 boolean basic_set::is_subset(const isl::checked::basic_set &bset2) const
 {
   auto res = isl_basic_set_is_subset(get(), bset2.get());
   return manage(res);
 }
 
+boolean basic_set::is_subset(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).is_subset(set2);
+}
+
+boolean basic_set::is_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).is_subset(uset2);
+}
+
+boolean basic_set::is_subset(const isl::checked::point &bset2) const
+{
+  return this->is_subset(isl::checked::basic_set(bset2));
+}
+
 boolean basic_set::is_wrapping() const
 {
   auto res = isl_basic_set_is_wrapping(get());
   return manage(res);
 }
 
+boolean basic_set::isa_set() const
+{
+  return isl::checked::set(*this).isa_set();
+}
+
 isl::checked::set basic_set::lexmax() const
 {
   auto res = isl_basic_set_lexmax(copy());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff basic_set::lexmax_pw_multi_aff() const
+{
+  return isl::checked::set(*this).lexmax_pw_multi_aff();
+}
+
 isl::checked::set basic_set::lexmin() const
 {
   auto res = isl_basic_set_lexmin(copy());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff basic_set::lexmin_pw_multi_aff() const
+{
+  return isl::checked::set(*this).lexmin_pw_multi_aff();
+}
+
+isl::checked::set basic_set::lower_bound(const isl::checked::multi_pw_aff &lower) const
+{
+  return isl::checked::set(*this).lower_bound(lower);
+}
+
+isl::checked::set basic_set::lower_bound(const isl::checked::multi_val &lower) const
+{
+  return isl::checked::set(*this).lower_bound(lower);
+}
+
+isl::checked::multi_pw_aff basic_set::max_multi_pw_aff() const
+{
+  return isl::checked::set(*this).max_multi_pw_aff();
+}
+
+isl::checked::val basic_set::max_val(const isl::checked::aff &obj) const
+{
+  return isl::checked::set(*this).max_val(obj);
+}
+
+isl::checked::multi_pw_aff basic_set::min_multi_pw_aff() const
+{
+  return isl::checked::set(*this).min_multi_pw_aff();
+}
+
+isl::checked::val basic_set::min_val(const isl::checked::aff &obj) const
+{
+  return isl::checked::set(*this).min_val(obj);
+}
+
 isl::checked::basic_set basic_set::params() const
 {
   auto res = isl_basic_set_params(copy());
   return manage(res);
 }
 
+isl::checked::multi_val basic_set::plain_multi_val_if_fixed() const
+{
+  return isl::checked::set(*this).plain_multi_val_if_fixed();
+}
+
+isl::checked::basic_set basic_set::polyhedral_hull() const
+{
+  return isl::checked::set(*this).polyhedral_hull();
+}
+
+isl::checked::set basic_set::preimage(const isl::checked::multi_aff &ma) const
+{
+  return isl::checked::set(*this).preimage(ma);
+}
+
+isl::checked::set basic_set::preimage(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::set(*this).preimage(mpa);
+}
+
+isl::checked::set basic_set::preimage(const isl::checked::pw_multi_aff &pma) const
+{
+  return isl::checked::set(*this).preimage(pma);
+}
+
+isl::checked::union_set basic_set::preimage(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::set(*this).preimage(upma);
+}
+
+isl::checked::set basic_set::product(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).product(set2);
+}
+
+isl::checked::set basic_set::project_out_all_params() const
+{
+  return isl::checked::set(*this).project_out_all_params();
+}
+
+isl::checked::set basic_set::project_out_param(const isl::checked::id &id) const
+{
+  return isl::checked::set(*this).project_out_param(id);
+}
+
+isl::checked::set basic_set::project_out_param(const std::string &id) const
+{
+  return this->project_out_param(isl::checked::id(ctx(), id));
+}
+
+isl::checked::set basic_set::project_out_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::set(*this).project_out_param(list);
+}
+
+isl::checked::pw_multi_aff basic_set::pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::set(*this).pw_multi_aff_on_domain(mv);
+}
+
 isl::checked::basic_set basic_set::sample() const
 {
   auto res = isl_basic_set_sample(copy());
@@ -5782,12 +8324,108 @@
   return manage(res);
 }
 
+isl::checked::fixed_box basic_set::simple_fixed_box_hull() const
+{
+  return isl::checked::set(*this).simple_fixed_box_hull();
+}
+
+isl::checked::space basic_set::space() const
+{
+  return isl::checked::set(*this).space();
+}
+
+isl::checked::val basic_set::stride(int pos) const
+{
+  return isl::checked::set(*this).stride(pos);
+}
+
+isl::checked::set basic_set::subtract(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).subtract(set2);
+}
+
+isl::checked::union_set basic_set::subtract(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).subtract(uset2);
+}
+
+isl::checked::union_set_list basic_set::to_list() const
+{
+  return isl::checked::set(*this).to_list();
+}
+
+isl::checked::set basic_set::to_set() const
+{
+  auto res = isl_basic_set_to_set(copy());
+  return manage(res);
+}
+
+isl::checked::union_set basic_set::to_union_set() const
+{
+  return isl::checked::set(*this).to_union_set();
+}
+
+isl::checked::map basic_set::translation() const
+{
+  return isl::checked::set(*this).translation();
+}
+
+class size basic_set::tuple_dim() const
+{
+  return isl::checked::set(*this).tuple_dim();
+}
+
+isl::checked::set basic_set::unbind_params(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::set(*this).unbind_params(tuple);
+}
+
+isl::checked::map basic_set::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
+{
+  return isl::checked::set(*this).unbind_params_insert_domain(domain);
+}
+
 isl::checked::set basic_set::unite(isl::checked::basic_set bset2) const
 {
   auto res = isl_basic_set_union(copy(), bset2.release());
   return manage(res);
 }
 
+isl::checked::set basic_set::unite(const isl::checked::set &set2) const
+{
+  return isl::checked::set(*this).unite(set2);
+}
+
+isl::checked::union_set basic_set::unite(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::set(*this).unite(uset2);
+}
+
+isl::checked::set basic_set::unite(const isl::checked::point &bset2) const
+{
+  return this->unite(isl::checked::basic_set(bset2));
+}
+
+isl::checked::basic_set basic_set::unshifted_simple_hull() const
+{
+  return isl::checked::set(*this).unshifted_simple_hull();
+}
+
+isl::checked::map basic_set::unwrap() const
+{
+  return isl::checked::set(*this).unwrap();
+}
+
+isl::checked::set basic_set::upper_bound(const isl::checked::multi_pw_aff &upper) const
+{
+  return isl::checked::set(*this).upper_bound(upper);
+}
+
+isl::checked::set basic_set::upper_bound(const isl::checked::multi_val &upper) const
+{
+  return isl::checked::set(*this).upper_bound(upper);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const basic_set &obj)
 {
   char *str = isl_basic_set_to_str(obj.get());
@@ -5853,6 +8491,12 @@
   return isl::checked::ctx(isl_fixed_box_get_ctx(ptr));
 }
 
+boolean fixed_box::is_valid() const
+{
+  auto res = isl_fixed_box_is_valid(get());
+  return manage(res);
+}
+
 isl::checked::multi_aff fixed_box::offset() const
 {
   auto res = isl_fixed_box_get_offset(get());
@@ -5886,12 +8530,6 @@
   return space();
 }
 
-boolean fixed_box::is_valid() const
-{
-  auto res = isl_fixed_box_is_valid(get());
-  return manage(res);
-}
-
 inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj)
 {
   char *str = isl_fixed_box_to_str(obj.get());
@@ -5975,6 +8613,12 @@
   return name();
 }
 
+isl::checked::id_list id::to_list() const
+{
+  auto res = isl_id_to_list(copy());
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const id &obj)
 {
   char *str = isl_id_to_str(obj.get());
@@ -6020,6 +8664,12 @@
   ptr = res;
 }
 
+id_list::id_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_id_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 id_list &id_list::operator=(id_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -6063,6 +8713,17 @@
   return this->add(isl::checked::id(ctx(), el));
 }
 
+isl::checked::id id_list::at(int index) const
+{
+  auto res = isl_id_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::id id_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::id_list id_list::clear() const
 {
   auto res = isl_id_list_clear(copy());
@@ -6095,17 +8756,6 @@
   return manage(res);
 }
 
-isl::checked::id id_list::at(int index) const
-{
-  auto res = isl_id_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::id id_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::id_list id_list::insert(unsigned int pos, isl::checked::id el) const
 {
   auto res = isl_id_list_insert(copy(), pos, el.release());
@@ -6212,12 +8862,53 @@
   return manage(res);
 }
 
+isl::checked::union_map map::apply_domain(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).apply_domain(umap2);
+}
+
+isl::checked::map map::apply_domain(const isl::checked::basic_map &map2) const
+{
+  return this->apply_domain(isl::checked::map(map2));
+}
+
 isl::checked::map map::apply_range(isl::checked::map map2) const
 {
   auto res = isl_map_apply_range(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::apply_range(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).apply_range(umap2);
+}
+
+isl::checked::map map::apply_range(const isl::checked::basic_map &map2) const
+{
+  return this->apply_range(isl::checked::map(map2));
+}
+
+isl::checked::map map::as_map() const
+{
+  return isl::checked::union_map(*this).as_map();
+}
+
+isl::checked::multi_union_pw_aff map::as_multi_union_pw_aff() const
+{
+  return isl::checked::union_map(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff map::as_pw_multi_aff() const
+{
+  auto res = isl_map_as_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff map::as_union_pw_multi_aff() const
+{
+  return isl::checked::union_map(*this).as_union_pw_multi_aff();
+}
+
 isl::checked::set map::bind_domain(isl::checked::multi_id tuple) const
 {
   auto res = isl_map_bind_domain(copy(), tuple.release());
@@ -6242,6 +8933,11 @@
   return manage(res);
 }
 
+isl::checked::union_map map::compute_divs() const
+{
+  return isl::checked::union_map(*this).compute_divs();
+}
+
 isl::checked::map map::curry() const
 {
   auto res = isl_map_curry(copy());
@@ -6278,12 +8974,49 @@
   return manage(res);
 }
 
+isl::checked::union_map map::domain_map() const
+{
+  return isl::checked::union_map(*this).domain_map();
+}
+
+isl::checked::union_pw_multi_aff map::domain_map_union_pw_multi_aff() const
+{
+  return isl::checked::union_map(*this).domain_map_union_pw_multi_aff();
+}
+
 isl::checked::map map::domain_product(isl::checked::map map2) const
 {
   auto res = isl_map_domain_product(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::domain_product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).domain_product(umap2);
+}
+
+isl::checked::map map::domain_product(const isl::checked::basic_map &map2) const
+{
+  return this->domain_product(isl::checked::map(map2));
+}
+
+class size map::domain_tuple_dim() const
+{
+  auto res = isl_map_domain_tuple_dim(get());
+  return manage(res);
+}
+
+isl::checked::id map::domain_tuple_id() const
+{
+  auto res = isl_map_get_domain_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id map::get_domain_tuple_id() const
+{
+  return domain_tuple_id();
+}
+
 isl::checked::map map::empty(isl::checked::space space)
 {
   auto res = isl_map_empty(space.release());
@@ -6296,6 +9029,41 @@
   return manage(res);
 }
 
+isl::checked::union_map map::eq_at(const isl::checked::multi_union_pw_aff &mupa) const
+{
+  return isl::checked::union_map(*this).eq_at(mupa);
+}
+
+isl::checked::map map::eq_at(const isl::checked::aff &mpa) const
+{
+  return this->eq_at(isl::checked::multi_pw_aff(mpa));
+}
+
+isl::checked::map map::eq_at(const isl::checked::multi_aff &mpa) const
+{
+  return this->eq_at(isl::checked::multi_pw_aff(mpa));
+}
+
+isl::checked::map map::eq_at(const isl::checked::pw_aff &mpa) const
+{
+  return this->eq_at(isl::checked::multi_pw_aff(mpa));
+}
+
+isl::checked::map map::eq_at(const isl::checked::pw_multi_aff &mpa) const
+{
+  return this->eq_at(isl::checked::multi_pw_aff(mpa));
+}
+
+boolean map::every_map(const std::function<boolean(isl::checked::map)> &test) const
+{
+  return isl::checked::union_map(*this).every_map(test);
+}
+
+isl::checked::map map::extract_map(const isl::checked::space &space) const
+{
+  return isl::checked::union_map(*this).extract_map(space);
+}
+
 isl::checked::map map::factor_domain() const
 {
   auto res = isl_map_factor_domain(copy());
@@ -6308,6 +9076,16 @@
   return manage(res);
 }
 
+isl::checked::union_map map::fixed_power(const isl::checked::val &exp) const
+{
+  return isl::checked::union_map(*this).fixed_power(exp);
+}
+
+isl::checked::union_map map::fixed_power(long exp) const
+{
+  return this->fixed_power(isl::checked::val(ctx(), exp));
+}
+
 isl::checked::map map::flatten() const
 {
   auto res = isl_map_flatten(copy());
@@ -6340,26 +9118,9 @@
   return manage(res);
 }
 
-isl::checked::fixed_box map::range_simple_fixed_box_hull() const
+stat map::foreach_map(const std::function<stat(isl::checked::map)> &fn) const
 {
-  auto res = isl_map_get_range_simple_fixed_box_hull(get());
-  return manage(res);
-}
-
-isl::checked::fixed_box map::get_range_simple_fixed_box_hull() const
-{
-  return range_simple_fixed_box_hull();
-}
-
-isl::checked::space map::space() const
-{
-  auto res = isl_map_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space map::get_space() const
-{
-  return space();
+  return isl::checked::union_map(*this).foreach_map(fn);
 }
 
 isl::checked::map map::gist(isl::checked::map context) const
@@ -6368,36 +9129,133 @@
   return manage(res);
 }
 
+isl::checked::union_map map::gist(const isl::checked::union_map &context) const
+{
+  return isl::checked::union_map(*this).gist(context);
+}
+
+isl::checked::map map::gist(const isl::checked::basic_map &context) const
+{
+  return this->gist(isl::checked::map(context));
+}
+
 isl::checked::map map::gist_domain(isl::checked::set context) const
 {
   auto res = isl_map_gist_domain(copy(), context.release());
   return manage(res);
 }
 
+isl::checked::union_map map::gist_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_map(*this).gist_domain(uset);
+}
+
+isl::checked::map map::gist_domain(const isl::checked::basic_set &context) const
+{
+  return this->gist_domain(isl::checked::set(context));
+}
+
+isl::checked::map map::gist_domain(const isl::checked::point &context) const
+{
+  return this->gist_domain(isl::checked::set(context));
+}
+
+isl::checked::union_map map::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::union_map(*this).gist_params(set);
+}
+
+isl::checked::union_map map::gist_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_map(*this).gist_range(uset);
+}
+
+boolean map::has_domain_tuple_id() const
+{
+  auto res = isl_map_has_domain_tuple_id(get());
+  return manage(res);
+}
+
+boolean map::has_range_tuple_id() const
+{
+  auto res = isl_map_has_range_tuple_id(get());
+  return manage(res);
+}
+
 isl::checked::map map::intersect(isl::checked::map map2) const
 {
   auto res = isl_map_intersect(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).intersect(umap2);
+}
+
+isl::checked::map map::intersect(const isl::checked::basic_map &map2) const
+{
+  return this->intersect(isl::checked::map(map2));
+}
+
 isl::checked::map map::intersect_domain(isl::checked::set set) const
 {
   auto res = isl_map_intersect_domain(copy(), set.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::union_map(*this).intersect_domain(space);
+}
+
+isl::checked::union_map map::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_map(*this).intersect_domain(uset);
+}
+
+isl::checked::map map::intersect_domain(const isl::checked::basic_set &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
+isl::checked::map map::intersect_domain(const isl::checked::point &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
 isl::checked::map map::intersect_domain_factor_domain(isl::checked::map factor) const
 {
   auto res = isl_map_intersect_domain_factor_domain(copy(), factor.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_domain_factor_domain(const isl::checked::union_map &factor) const
+{
+  return isl::checked::union_map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::checked::map map::intersect_domain_factor_domain(const isl::checked::basic_map &factor) const
+{
+  return this->intersect_domain_factor_domain(isl::checked::map(factor));
+}
+
 isl::checked::map map::intersect_domain_factor_range(isl::checked::map factor) const
 {
   auto res = isl_map_intersect_domain_factor_range(copy(), factor.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_domain_factor_range(const isl::checked::union_map &factor) const
+{
+  return isl::checked::union_map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::checked::map map::intersect_domain_factor_range(const isl::checked::basic_map &factor) const
+{
+  return this->intersect_domain_factor_range(isl::checked::map(factor));
+}
+
 isl::checked::map map::intersect_params(isl::checked::set params) const
 {
   auto res = isl_map_intersect_params(copy(), params.release());
@@ -6410,18 +9268,58 @@
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_range(const isl::checked::space &space) const
+{
+  return isl::checked::union_map(*this).intersect_range(space);
+}
+
+isl::checked::union_map map::intersect_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_map(*this).intersect_range(uset);
+}
+
+isl::checked::map map::intersect_range(const isl::checked::basic_set &set) const
+{
+  return this->intersect_range(isl::checked::set(set));
+}
+
+isl::checked::map map::intersect_range(const isl::checked::point &set) const
+{
+  return this->intersect_range(isl::checked::set(set));
+}
+
 isl::checked::map map::intersect_range_factor_domain(isl::checked::map factor) const
 {
   auto res = isl_map_intersect_range_factor_domain(copy(), factor.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_range_factor_domain(const isl::checked::union_map &factor) const
+{
+  return isl::checked::union_map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::checked::map map::intersect_range_factor_domain(const isl::checked::basic_map &factor) const
+{
+  return this->intersect_range_factor_domain(isl::checked::map(factor));
+}
+
 isl::checked::map map::intersect_range_factor_range(isl::checked::map factor) const
 {
   auto res = isl_map_intersect_range_factor_range(copy(), factor.release());
   return manage(res);
 }
 
+isl::checked::union_map map::intersect_range_factor_range(const isl::checked::union_map &factor) const
+{
+  return isl::checked::union_map(*this).intersect_range_factor_range(factor);
+}
+
+isl::checked::map map::intersect_range_factor_range(const isl::checked::basic_map &factor) const
+{
+  return this->intersect_range_factor_range(isl::checked::map(factor));
+}
+
 boolean map::is_bijective() const
 {
   auto res = isl_map_is_bijective(get());
@@ -6434,6 +9332,16 @@
   return manage(res);
 }
 
+boolean map::is_disjoint(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).is_disjoint(umap2);
+}
+
+boolean map::is_disjoint(const isl::checked::basic_map &map2) const
+{
+  return this->is_disjoint(isl::checked::map(map2));
+}
+
 boolean map::is_empty() const
 {
   auto res = isl_map_is_empty(get());
@@ -6446,6 +9354,16 @@
   return manage(res);
 }
 
+boolean map::is_equal(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).is_equal(umap2);
+}
+
+boolean map::is_equal(const isl::checked::basic_map &map2) const
+{
+  return this->is_equal(isl::checked::map(map2));
+}
+
 boolean map::is_injective() const
 {
   auto res = isl_map_is_injective(get());
@@ -6464,12 +9382,37 @@
   return manage(res);
 }
 
+boolean map::is_strict_subset(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).is_strict_subset(umap2);
+}
+
+boolean map::is_strict_subset(const isl::checked::basic_map &map2) const
+{
+  return this->is_strict_subset(isl::checked::map(map2));
+}
+
 boolean map::is_subset(const isl::checked::map &map2) const
 {
   auto res = isl_map_is_subset(get(), map2.get());
   return manage(res);
 }
 
+boolean map::is_subset(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).is_subset(umap2);
+}
+
+boolean map::is_subset(const isl::checked::basic_map &map2) const
+{
+  return this->is_subset(isl::checked::map(map2));
+}
+
+boolean map::isa_map() const
+{
+  return isl::checked::union_map(*this).isa_map();
+}
+
 isl::checked::map map::lex_ge_at(isl::checked::multi_pw_aff mpa) const
 {
   auto res = isl_map_lex_ge_at_multi_pw_aff(copy(), mpa.release());
@@ -6524,6 +9467,11 @@
   return manage(res);
 }
 
+isl::checked::map_list map::map_list() const
+{
+  return isl::checked::union_map(*this).map_list();
+}
+
 isl::checked::multi_pw_aff map::max_multi_pw_aff() const
 {
   auto res = isl_map_max_multi_pw_aff(copy());
@@ -6560,6 +9508,11 @@
   return manage(res);
 }
 
+isl::checked::union_map map::preimage_domain(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::union_map(*this).preimage_domain(upma);
+}
+
 isl::checked::map map::preimage_range(isl::checked::multi_aff ma) const
 {
   auto res = isl_map_preimage_range_multi_aff(copy(), ma.release());
@@ -6572,12 +9525,27 @@
   return manage(res);
 }
 
+isl::checked::union_map map::preimage_range(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::union_map(*this).preimage_range(upma);
+}
+
 isl::checked::map map::product(isl::checked::map map2) const
 {
   auto res = isl_map_product(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).product(umap2);
+}
+
+isl::checked::map map::product(const isl::checked::basic_map &map2) const
+{
+  return this->product(isl::checked::map(map2));
+}
+
 isl::checked::map map::project_out_all_params() const
 {
   auto res = isl_map_project_out_all_params(copy());
@@ -6602,18 +9570,72 @@
   return manage(res);
 }
 
+isl::checked::fixed_box map::range_lattice_tile() const
+{
+  auto res = isl_map_get_range_lattice_tile(get());
+  return manage(res);
+}
+
+isl::checked::fixed_box map::get_range_lattice_tile() const
+{
+  return range_lattice_tile();
+}
+
+isl::checked::union_map map::range_map() const
+{
+  return isl::checked::union_map(*this).range_map();
+}
+
 isl::checked::map map::range_product(isl::checked::map map2) const
 {
   auto res = isl_map_range_product(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::range_product(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).range_product(umap2);
+}
+
+isl::checked::map map::range_product(const isl::checked::basic_map &map2) const
+{
+  return this->range_product(isl::checked::map(map2));
+}
+
 isl::checked::map map::range_reverse() const
 {
   auto res = isl_map_range_reverse(copy());
   return manage(res);
 }
 
+isl::checked::fixed_box map::range_simple_fixed_box_hull() const
+{
+  auto res = isl_map_get_range_simple_fixed_box_hull(get());
+  return manage(res);
+}
+
+isl::checked::fixed_box map::get_range_simple_fixed_box_hull() const
+{
+  return range_simple_fixed_box_hull();
+}
+
+class size map::range_tuple_dim() const
+{
+  auto res = isl_map_range_tuple_dim(get());
+  return manage(res);
+}
+
+isl::checked::id map::range_tuple_id() const
+{
+  auto res = isl_map_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id map::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
 isl::checked::map map::reverse() const
 {
   auto res = isl_map_reverse(copy());
@@ -6626,12 +9648,77 @@
   return manage(res);
 }
 
+isl::checked::map map::set_domain_tuple(isl::checked::id id) const
+{
+  auto res = isl_map_set_domain_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::map map::set_domain_tuple(const std::string &id) const
+{
+  return this->set_domain_tuple(isl::checked::id(ctx(), id));
+}
+
+isl::checked::map map::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_map_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::map map::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+isl::checked::space map::space() const
+{
+  auto res = isl_map_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space map::get_space() const
+{
+  return space();
+}
+
 isl::checked::map map::subtract(isl::checked::map map2) const
 {
   auto res = isl_map_subtract(copy(), map2.release());
   return manage(res);
 }
 
+isl::checked::union_map map::subtract(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).subtract(umap2);
+}
+
+isl::checked::map map::subtract(const isl::checked::basic_map &map2) const
+{
+  return this->subtract(isl::checked::map(map2));
+}
+
+isl::checked::union_map map::subtract_domain(const isl::checked::union_set &dom) const
+{
+  return isl::checked::union_map(*this).subtract_domain(dom);
+}
+
+isl::checked::union_map map::subtract_range(const isl::checked::union_set &dom) const
+{
+  return isl::checked::union_map(*this).subtract_range(dom);
+}
+
+isl::checked::map_list map::to_list() const
+{
+  auto res = isl_map_to_list(copy());
+  return manage(res);
+}
+
+isl::checked::union_map map::to_union_map() const
+{
+  auto res = isl_map_to_union_map(copy());
+  return manage(res);
+}
+
 isl::checked::map map::uncurry() const
 {
   auto res = isl_map_uncurry(copy());
@@ -6644,6 +9731,16 @@
   return manage(res);
 }
 
+isl::checked::union_map map::unite(const isl::checked::union_map &umap2) const
+{
+  return isl::checked::union_map(*this).unite(umap2);
+}
+
+isl::checked::map map::unite(const isl::checked::basic_map &map2) const
+{
+  return this->unite(isl::checked::map(map2));
+}
+
 isl::checked::map map::universe(isl::checked::space space)
 {
   auto res = isl_map_universe(space.release());
@@ -6686,6 +9783,150 @@
   return os;
 }
 
+// implementations for isl::map_list
+map_list manage(__isl_take isl_map_list *ptr) {
+  return map_list(ptr);
+}
+map_list manage_copy(__isl_keep isl_map_list *ptr) {
+  ptr = isl_map_list_copy(ptr);
+  return map_list(ptr);
+}
+
+map_list::map_list()
+    : ptr(nullptr) {}
+
+map_list::map_list(const map_list &obj)
+    : ptr(nullptr)
+{
+  ptr = obj.copy();
+}
+
+map_list::map_list(__isl_take isl_map_list *ptr)
+    : ptr(ptr) {}
+
+map_list::map_list(isl::checked::ctx ctx, int n)
+{
+  auto res = isl_map_list_alloc(ctx.release(), n);
+  ptr = res;
+}
+
+map_list::map_list(isl::checked::map el)
+{
+  auto res = isl_map_list_from_map(el.release());
+  ptr = res;
+}
+
+map_list::map_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_map_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
+map_list &map_list::operator=(map_list obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+map_list::~map_list() {
+  if (ptr)
+    isl_map_list_free(ptr);
+}
+
+__isl_give isl_map_list *map_list::copy() const & {
+  return isl_map_list_copy(ptr);
+}
+
+__isl_keep isl_map_list *map_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_map_list *map_list::release() {
+  isl_map_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool map_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::checked::ctx map_list::ctx() const {
+  return isl::checked::ctx(isl_map_list_get_ctx(ptr));
+}
+
+isl::checked::map_list map_list::add(isl::checked::map el) const
+{
+  auto res = isl_map_list_add(copy(), el.release());
+  return manage(res);
+}
+
+isl::checked::map map_list::at(int index) const
+{
+  auto res = isl_map_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::map map_list::get_at(int index) const
+{
+  return at(index);
+}
+
+isl::checked::map_list map_list::clear() const
+{
+  auto res = isl_map_list_clear(copy());
+  return manage(res);
+}
+
+isl::checked::map_list map_list::concat(isl::checked::map_list list2) const
+{
+  auto res = isl_map_list_concat(copy(), list2.release());
+  return manage(res);
+}
+
+isl::checked::map_list map_list::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl_map_list_drop(copy(), first, n);
+  return manage(res);
+}
+
+stat map_list::foreach(const std::function<stat(isl::checked::map)> &fn) const
+{
+  struct fn_data {
+    std::function<stat(isl::checked::map)> func;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    auto ret = (data->func)(manage(arg_0));
+    return ret.release();
+  };
+  auto res = isl_map_list_foreach(get(), fn_lambda, &fn_data);
+  return manage(res);
+}
+
+isl::checked::map_list map_list::insert(unsigned int pos, isl::checked::map el) const
+{
+  auto res = isl_map_list_insert(copy(), pos, el.release());
+  return manage(res);
+}
+
+class size map_list::size() const
+{
+  auto res = isl_map_list_size(get());
+  return manage(res);
+}
+
+inline std::ostream &operator<<(std::ostream &os, const map_list &obj)
+{
+  char *str = isl_map_list_to_str(obj.get());
+  if (!str) {
+    os.setstate(std::ios_base::badbit);
+    return os;
+  }
+  os << str;
+  free(str);
+  return os;
+}
+
 // implementations for isl::multi_aff
 multi_aff manage(__isl_take isl_multi_aff *ptr) {
   return multi_aff(ptr);
@@ -6763,6 +10004,31 @@
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::add(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(multi2);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(multi2);
+}
+
+isl::checked::pw_multi_aff multi_aff::add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(upma2);
+}
+
+isl::checked::multi_aff multi_aff::add(const isl::checked::aff &multi2) const
+{
+  return this->add(isl::checked::multi_aff(multi2));
+}
+
 isl::checked::multi_aff multi_aff::add_constant(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_aff_add_constant_multi_val(copy(), mv.release());
@@ -6780,6 +10046,54 @@
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
+isl::checked::union_pw_multi_aff multi_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).apply(upma2);
+}
+
+isl::checked::map multi_aff::as_map() const
+{
+  auto res = isl_multi_aff_as_map(copy());
+  return manage(res);
+}
+
+isl::checked::multi_aff multi_aff::as_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).as_multi_aff();
+}
+
+isl::checked::multi_union_pw_aff multi_aff::as_multi_union_pw_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff multi_aff::as_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::checked::set multi_aff::as_set() const
+{
+  auto res = isl_multi_aff_as_set(copy());
+  return manage(res);
+}
+
+isl::checked::union_map multi_aff::as_union_map() const
+{
+  return isl::checked::pw_multi_aff(*this).as_union_map();
+}
+
+isl::checked::aff multi_aff::at(int pos) const
+{
+  auto res = isl_multi_aff_get_at(get(), pos);
+  return manage(res);
+}
+
+isl::checked::aff multi_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::checked::basic_set multi_aff::bind(isl::checked::multi_id tuple) const
 {
   auto res = isl_multi_aff_bind(copy(), tuple.release());
@@ -6798,33 +10112,9 @@
   return manage(res);
 }
 
-isl::checked::multi_aff multi_aff::domain_map(isl::checked::space space)
+isl::checked::pw_multi_aff multi_aff::coalesce() const
 {
-  auto res = isl_multi_aff_domain_map(space.release());
-  return manage(res);
-}
-
-isl::checked::multi_aff multi_aff::flat_range_product(isl::checked::multi_aff multi2) const
-{
-  auto res = isl_multi_aff_flat_range_product(copy(), multi2.release());
-  return manage(res);
-}
-
-isl::checked::multi_aff multi_aff::floor() const
-{
-  auto res = isl_multi_aff_floor(copy());
-  return manage(res);
-}
-
-isl::checked::aff multi_aff::at(int pos) const
-{
-  auto res = isl_multi_aff_get_at(get(), pos);
-  return manage(res);
-}
-
-isl::checked::aff multi_aff::get_at(int pos) const
-{
-  return at(pos);
+  return isl::checked::pw_multi_aff(*this).coalesce();
 }
 
 isl::checked::multi_val multi_aff::constant_multi_val() const
@@ -6838,26 +10128,62 @@
   return constant_multi_val();
 }
 
-isl::checked::aff_list multi_aff::list() const
+isl::checked::set multi_aff::domain() const
 {
-  auto res = isl_multi_aff_get_list(get());
+  return isl::checked::pw_multi_aff(*this).domain();
+}
+
+isl::checked::multi_aff multi_aff::domain_map(isl::checked::space space)
+{
+  auto res = isl_multi_aff_domain_map(space.release());
   return manage(res);
 }
 
-isl::checked::aff_list multi_aff::get_list() const
+isl::checked::pw_multi_aff multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const
 {
-  return list();
+  return isl::checked::pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::checked::space multi_aff::space() const
+isl::checked::multi_aff multi_aff::flat_range_product(isl::checked::multi_aff multi2) const
 {
-  auto res = isl_multi_aff_get_space(get());
+  auto res = isl_multi_aff_flat_range_product(copy(), multi2.release());
   return manage(res);
 }
 
-isl::checked::space multi_aff::get_space() const
+isl::checked::multi_pw_aff multi_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
 {
-  return space();
+  return isl::checked::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::pw_multi_aff multi_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).flat_range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).flat_range_product(upma2);
+}
+
+isl::checked::multi_aff multi_aff::flat_range_product(const isl::checked::aff &multi2) const
+{
+  return this->flat_range_product(isl::checked::multi_aff(multi2));
+}
+
+isl::checked::multi_aff multi_aff::floor() const
+{
+  auto res = isl_multi_aff_floor(copy());
+  return manage(res);
+}
+
+stat multi_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
+{
+  return isl::checked::pw_multi_aff(*this).foreach_piece(fn);
 }
 
 isl::checked::multi_aff multi_aff::gist(isl::checked::set context) const
@@ -6866,6 +10192,27 @@
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff multi_aff::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::pw_multi_aff(*this).gist(context);
+}
+
+isl::checked::multi_aff multi_aff::gist(const isl::checked::basic_set &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+isl::checked::multi_aff multi_aff::gist(const isl::checked::point &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+boolean multi_aff::has_range_tuple_id() const
+{
+  auto res = isl_multi_aff_has_range_tuple_id(get());
+  return manage(res);
+}
+
 isl::checked::multi_aff multi_aff::identity() const
 {
   auto res = isl_multi_aff_identity_multi_aff(copy());
@@ -6884,6 +10231,36 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff multi_aff::intersect_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_domain(set);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_domain(space);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_domain(uset);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
+isl::checked::pw_multi_aff multi_aff::intersect_params(const isl::checked::set &set) const
+{
+  return isl::checked::pw_multi_aff(*this).intersect_params(set);
+}
+
 boolean multi_aff::involves_locals() const
 {
   auto res = isl_multi_aff_involves_locals(get());
@@ -6896,30 +10273,177 @@
   return manage(res);
 }
 
+boolean multi_aff::involves_param(const isl::checked::id &id) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(id);
+}
+
+boolean multi_aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
+}
+
+boolean multi_aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(list);
+}
+
+boolean multi_aff::isa_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).isa_multi_aff();
+}
+
+boolean multi_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::checked::aff_list multi_aff::list() const
+{
+  auto res = isl_multi_aff_get_list(get());
+  return manage(res);
+}
+
+isl::checked::aff_list multi_aff::get_list() const
+{
+  return list();
+}
+
+isl::checked::multi_pw_aff multi_aff::max(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).max(multi2);
+}
+
+isl::checked::multi_val multi_aff::max_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).max_multi_val();
+}
+
+isl::checked::multi_pw_aff multi_aff::min(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).min(multi2);
+}
+
+isl::checked::multi_val multi_aff::min_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).min_multi_val();
+}
+
+isl::checked::multi_aff multi_aff::multi_val_on_domain(isl::checked::space space, isl::checked::multi_val mv)
+{
+  auto res = isl_multi_aff_multi_val_on_domain_space(space.release(), mv.release());
+  return manage(res);
+}
+
+class size multi_aff::n_piece() const
+{
+  return isl::checked::pw_multi_aff(*this).n_piece();
+}
+
 isl::checked::multi_aff multi_aff::neg() const
 {
   auto res = isl_multi_aff_neg(copy());
   return manage(res);
 }
 
+boolean multi_aff::plain_is_empty() const
+{
+  return isl::checked::pw_multi_aff(*this).plain_is_empty();
+}
+
 boolean multi_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
 {
   auto res = isl_multi_aff_plain_is_equal(get(), multi2.get());
   return manage(res);
 }
 
+boolean multi_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+boolean multi_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+boolean multi_aff::plain_is_equal(const isl::checked::aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_aff(multi2));
+}
+
+isl::checked::pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
 isl::checked::multi_aff multi_aff::product(isl::checked::multi_aff multi2) const
 {
   auto res = isl_multi_aff_product(copy(), multi2.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).product(multi2);
+}
+
+isl::checked::pw_multi_aff multi_aff::product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).product(pma2);
+}
+
+isl::checked::multi_aff multi_aff::product(const isl::checked::aff &multi2) const
+{
+  return this->product(isl::checked::multi_aff(multi2));
+}
+
 isl::checked::multi_aff multi_aff::pullback(isl::checked::multi_aff ma2) const
 {
   auto res = isl_multi_aff_pullback_multi_aff(copy(), ma2.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::pullback(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::pw_multi_aff(*this).pullback(mpa2);
+}
+
+isl::checked::pw_multi_aff multi_aff::pullback(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).pullback(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::pullback(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).pullback(upma2);
+}
+
+isl::checked::multi_aff multi_aff::pullback(const isl::checked::aff &ma2) const
+{
+  return this->pullback(isl::checked::multi_aff(ma2));
+}
+
+isl::checked::pw_multi_aff_list multi_aff::pw_multi_aff_list() const
+{
+  return isl::checked::pw_multi_aff(*this).pw_multi_aff_list();
+}
+
+isl::checked::pw_multi_aff multi_aff::range_factor_domain() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::checked::pw_multi_aff multi_aff::range_factor_range() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_range();
+}
+
 isl::checked::multi_aff multi_aff::range_map(isl::checked::space space)
 {
   auto res = isl_multi_aff_range_map(space.release());
@@ -6932,6 +10456,48 @@
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::checked::pw_multi_aff multi_aff::range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::checked::multi_aff multi_aff::range_product(const isl::checked::aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_aff(multi2));
+}
+
+isl::checked::id multi_aff::range_tuple_id() const
+{
+  auto res = isl_multi_aff_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id multi_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::checked::multi_aff multi_aff::reset_range_tuple_id() const
+{
+  auto res = isl_multi_aff_reset_range_tuple_id(copy());
+  return manage(res);
+}
+
 isl::checked::multi_aff multi_aff::scale(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_aff_scale_multi_val(copy(), mv.release());
@@ -6972,24 +10538,144 @@
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::set_at(int pos, const isl::checked::pw_aff &el) const
+{
+  return isl::checked::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_aff multi_aff::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_multi_aff_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::multi_aff multi_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
 class size multi_aff::size() const
 {
   auto res = isl_multi_aff_size(get());
   return manage(res);
 }
 
+isl::checked::space multi_aff::space() const
+{
+  auto res = isl_multi_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space multi_aff::get_space() const
+{
+  return space();
+}
+
 isl::checked::multi_aff multi_aff::sub(isl::checked::multi_aff multi2) const
 {
   auto res = isl_multi_aff_sub(copy(), multi2.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::sub(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::checked::pw_multi_aff multi_aff::sub(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(upma2);
+}
+
+isl::checked::multi_aff multi_aff::sub(const isl::checked::aff &multi2) const
+{
+  return this->sub(isl::checked::multi_aff(multi2));
+}
+
+isl::checked::pw_multi_aff multi_aff::subtract_domain(const isl::checked::set &set) const
+{
+  return isl::checked::pw_multi_aff(*this).subtract_domain(set);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::subtract_domain(const isl::checked::space &space) const
+{
+  return isl::checked::pw_multi_aff(*this).subtract_domain(space);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::subtract_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::pw_multi_aff(*this).subtract_domain(uset);
+}
+
+isl::checked::pw_multi_aff_list multi_aff::to_list() const
+{
+  return isl::checked::pw_multi_aff(*this).to_list();
+}
+
+isl::checked::multi_pw_aff multi_aff::to_multi_pw_aff() const
+{
+  auto res = isl_multi_aff_to_multi_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::to_multi_union_pw_aff() const
+{
+  auto res = isl_multi_aff_to_multi_union_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff multi_aff::to_pw_multi_aff() const
+{
+  auto res = isl_multi_aff_to_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::to_union_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff();
+}
+
 isl::checked::multi_aff multi_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
 {
   auto res = isl_multi_aff_unbind_params_insert_domain(copy(), domain.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(mpa2);
+}
+
+isl::checked::multi_union_pw_aff multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(mupa2);
+}
+
+isl::checked::pw_multi_aff multi_aff::union_add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(pma2);
+}
+
+isl::checked::union_pw_multi_aff multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(upma2);
+}
+
 isl::checked::multi_aff multi_aff::zero(isl::checked::space space)
 {
   auto res = isl_multi_aff_zero(space.release());
@@ -7073,12 +10759,6 @@
   return isl::checked::ctx(isl_multi_id_get_ctx(ptr));
 }
 
-isl::checked::multi_id multi_id::flat_range_product(isl::checked::multi_id multi2) const
-{
-  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
-  return manage(res);
-}
-
 isl::checked::id multi_id::at(int pos) const
 {
   auto res = isl_multi_id_get_at(get(), pos);
@@ -7090,6 +10770,12 @@
   return at(pos);
 }
 
+isl::checked::multi_id multi_id::flat_range_product(isl::checked::multi_id multi2) const
+{
+  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
+  return manage(res);
+}
+
 isl::checked::id_list multi_id::list() const
 {
   auto res = isl_multi_id_get_list(get());
@@ -7101,17 +10787,6 @@
   return list();
 }
 
-isl::checked::space multi_id::space() const
-{
-  auto res = isl_multi_id_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space multi_id::get_space() const
-{
-  return space();
-}
-
 boolean multi_id::plain_is_equal(const isl::checked::multi_id &multi2) const
 {
   auto res = isl_multi_id_plain_is_equal(get(), multi2.get());
@@ -7141,6 +10816,17 @@
   return manage(res);
 }
 
+isl::checked::space multi_id::space() const
+{
+  auto res = isl_multi_id_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space multi_id::get_space() const
+{
+  return space();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
 {
   char *str = isl_multi_id_to_str(obj.get());
@@ -7248,6 +10934,31 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).add(multi2);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::aff &multi2) const
+{
+  return this->add(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::multi_aff &multi2) const
+{
+  return this->add(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_aff &multi2) const
+{
+  return this->add(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::add(const isl::checked::pw_multi_aff &multi2) const
+{
+  return this->add(isl::checked::multi_pw_aff(multi2));
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::add_constant(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_pw_aff_add_constant_multi_val(copy(), mv.release());
@@ -7265,6 +10976,35 @@
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
+isl::checked::map multi_pw_aff::as_map() const
+{
+  auto res = isl_multi_pw_aff_as_map(copy());
+  return manage(res);
+}
+
+isl::checked::multi_aff multi_pw_aff::as_multi_aff() const
+{
+  auto res = isl_multi_pw_aff_as_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::set multi_pw_aff::as_set() const
+{
+  auto res = isl_multi_pw_aff_as_set(copy());
+  return manage(res);
+}
+
+isl::checked::pw_aff multi_pw_aff::at(int pos) const
+{
+  auto res = isl_multi_pw_aff_get_at(get(), pos);
+  return manage(res);
+}
+
+isl::checked::pw_aff multi_pw_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::checked::set multi_pw_aff::bind(isl::checked::multi_id tuple) const
 {
   auto res = isl_multi_pw_aff_bind(copy(), tuple.release());
@@ -7301,37 +11041,29 @@
   return manage(res);
 }
 
-isl::checked::pw_aff multi_pw_aff::at(int pos) const
+isl::checked::multi_union_pw_aff multi_pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_get_at(get(), pos);
-  return manage(res);
+  return isl::checked::multi_union_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::checked::pw_aff multi_pw_aff::get_at(int pos) const
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::aff &multi2) const
 {
-  return at(pos);
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::pw_aff_list multi_pw_aff::list() const
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::multi_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_get_list(get());
-  return manage(res);
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::pw_aff_list multi_pw_aff::get_list() const
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_aff &multi2) const
 {
-  return list();
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
 }
 
-isl::checked::space multi_pw_aff::space() const
+isl::checked::multi_pw_aff multi_pw_aff::flat_range_product(const isl::checked::pw_multi_aff &multi2) const
 {
-  auto res = isl_multi_pw_aff_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space multi_pw_aff::get_space() const
-{
-  return space();
+  return this->flat_range_product(isl::checked::multi_pw_aff(multi2));
 }
 
 isl::checked::multi_pw_aff multi_pw_aff::gist(isl::checked::set set) const
@@ -7340,6 +11072,27 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::multi_union_pw_aff(*this).gist(context);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::basic_set &set) const
+{
+  return this->gist(isl::checked::set(set));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::gist(const isl::checked::point &set) const
+{
+  return this->gist(isl::checked::set(set));
+}
+
+boolean multi_pw_aff::has_range_tuple_id() const
+{
+  auto res = isl_multi_pw_aff_has_range_tuple_id(get());
+  return manage(res);
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::identity() const
 {
   auto res = isl_multi_pw_aff_identity_multi_pw_aff(copy());
@@ -7364,6 +11117,21 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::multi_union_pw_aff(*this).intersect_domain(uset);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(const isl::checked::basic_set &domain) const
+{
+  return this->intersect_domain(isl::checked::set(domain));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::intersect_domain(const isl::checked::point &domain) const
+{
+  return this->intersect_domain(isl::checked::set(domain));
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::intersect_params(isl::checked::set set) const
 {
   auto res = isl_multi_pw_aff_intersect_params(copy(), set.release());
@@ -7393,6 +11161,23 @@
   return manage(res);
 }
 
+boolean multi_pw_aff::isa_multi_aff() const
+{
+  auto res = isl_multi_pw_aff_isa_multi_aff(get());
+  return manage(res);
+}
+
+isl::checked::pw_aff_list multi_pw_aff::list() const
+{
+  auto res = isl_multi_pw_aff_get_list(get());
+  return manage(res);
+}
+
+isl::checked::pw_aff_list multi_pw_aff::get_list() const
+{
+  return list();
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::max(isl::checked::multi_pw_aff multi2) const
 {
   auto res = isl_multi_pw_aff_max(copy(), multi2.release());
@@ -7429,6 +11214,31 @@
   return manage(res);
 }
 
+boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+boolean multi_pw_aff::plain_is_equal(const isl::checked::aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
+}
+
+boolean multi_pw_aff::plain_is_equal(const isl::checked::multi_aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
+}
+
+boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
+}
+
+boolean multi_pw_aff::plain_is_equal(const isl::checked::pw_multi_aff &multi2) const
+{
+  return this->plain_is_equal(isl::checked::multi_pw_aff(multi2));
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::product(isl::checked::multi_pw_aff multi2) const
 {
   auto res = isl_multi_pw_aff_product(copy(), multi2.release());
@@ -7453,12 +11263,59 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::multi_union_pw_aff(*this).pullback(upma);
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::range_product(isl::checked::multi_pw_aff multi2) const
 {
   auto res = isl_multi_pw_aff_range_product(copy(), multi2.release());
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::multi_aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::pw_aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::range_product(const isl::checked::pw_multi_aff &multi2) const
+{
+  return this->range_product(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::id multi_pw_aff::range_tuple_id() const
+{
+  auto res = isl_multi_pw_aff_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id multi_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::reset_range_tuple_id() const
+{
+  auto res = isl_multi_pw_aff_reset_range_tuple_id(copy());
+  return manage(res);
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::scale(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_pw_aff_scale_multi_val(copy(), mv.release());
@@ -7499,18 +11356,70 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::multi_union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
 class size multi_pw_aff::size() const
 {
   auto res = isl_multi_pw_aff_size(get());
   return manage(res);
 }
 
+isl::checked::space multi_pw_aff::space() const
+{
+  auto res = isl_multi_pw_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space multi_pw_aff::get_space() const
+{
+  return space();
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::sub(isl::checked::multi_pw_aff multi2) const
 {
   auto res = isl_multi_pw_aff_sub(copy(), multi2.release());
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::aff &multi2) const
+{
+  return this->sub(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::multi_aff &multi2) const
+{
+  return this->sub(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::pw_aff &multi2) const
+{
+  return this->sub(isl::checked::multi_pw_aff(multi2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::sub(const isl::checked::pw_multi_aff &multi2) const
+{
+  return this->sub(isl::checked::multi_pw_aff(multi2));
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::checked::multi_id domain) const
 {
   auto res = isl_multi_pw_aff_unbind_params_insert_domain(copy(), domain.release());
@@ -7523,6 +11432,31 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).union_add(mupa2);
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::aff &mpa2) const
+{
+  return this->union_add(isl::checked::multi_pw_aff(mpa2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::multi_aff &mpa2) const
+{
+  return this->union_add(isl::checked::multi_pw_aff(mpa2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::pw_aff &mpa2) const
+{
+  return this->union_add(isl::checked::multi_pw_aff(mpa2));
+}
+
+isl::checked::multi_pw_aff multi_pw_aff::union_add(const isl::checked::pw_multi_aff &mpa2) const
+{
+  return this->union_add(isl::checked::multi_pw_aff(mpa2));
+}
+
 isl::checked::multi_pw_aff multi_pw_aff::zero(isl::checked::space space)
 {
   auto res = isl_multi_pw_aff_zero(space.release());
@@ -7624,6 +11558,17 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff multi_union_pw_aff::at(int pos) const
+{
+  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
+  return manage(res);
+}
+
+isl::checked::union_pw_aff multi_union_pw_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::checked::union_set multi_union_pw_aff::bind(isl::checked::multi_id tuple) const
 {
   auto res = isl_multi_union_pw_aff_bind(copy(), tuple.release());
@@ -7648,45 +11593,18 @@
   return manage(res);
 }
 
-isl::checked::union_pw_aff multi_union_pw_aff::at(int pos) const
-{
-  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
-  return manage(res);
-}
-
-isl::checked::union_pw_aff multi_union_pw_aff::get_at(int pos) const
-{
-  return at(pos);
-}
-
-isl::checked::union_pw_aff_list multi_union_pw_aff::list() const
-{
-  auto res = isl_multi_union_pw_aff_get_list(get());
-  return manage(res);
-}
-
-isl::checked::union_pw_aff_list multi_union_pw_aff::get_list() const
-{
-  return list();
-}
-
-isl::checked::space multi_union_pw_aff::space() const
-{
-  auto res = isl_multi_union_pw_aff_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space multi_union_pw_aff::get_space() const
-{
-  return space();
-}
-
 isl::checked::multi_union_pw_aff multi_union_pw_aff::gist(isl::checked::union_set context) const
 {
   auto res = isl_multi_union_pw_aff_gist(copy(), context.release());
   return manage(res);
 }
 
+boolean multi_union_pw_aff::has_range_tuple_id() const
+{
+  auto res = isl_multi_union_pw_aff_has_range_tuple_id(get());
+  return manage(res);
+}
+
 isl::checked::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::checked::union_set uset) const
 {
   auto res = isl_multi_union_pw_aff_intersect_domain(copy(), uset.release());
@@ -7705,6 +11623,17 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff_list multi_union_pw_aff::list() const
+{
+  auto res = isl_multi_union_pw_aff_get_list(get());
+  return manage(res);
+}
+
+isl::checked::union_pw_aff_list multi_union_pw_aff::get_list() const
+{
+  return list();
+}
+
 isl::checked::multi_union_pw_aff multi_union_pw_aff::neg() const
 {
   auto res = isl_multi_union_pw_aff_neg(copy());
@@ -7729,6 +11658,23 @@
   return manage(res);
 }
 
+isl::checked::id multi_union_pw_aff::range_tuple_id() const
+{
+  auto res = isl_multi_union_pw_aff_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id multi_union_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::checked::multi_union_pw_aff multi_union_pw_aff::reset_range_tuple_id() const
+{
+  auto res = isl_multi_union_pw_aff_reset_range_tuple_id(copy());
+  return manage(res);
+}
+
 isl::checked::multi_union_pw_aff multi_union_pw_aff::scale(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_union_pw_aff_scale_multi_val(copy(), mv.release());
@@ -7769,12 +11715,34 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
 class size multi_union_pw_aff::size() const
 {
   auto res = isl_multi_union_pw_aff_size(get());
   return manage(res);
 }
 
+isl::checked::space multi_union_pw_aff::space() const
+{
+  auto res = isl_multi_union_pw_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space multi_union_pw_aff::get_space() const
+{
+  return space();
+}
+
 isl::checked::multi_union_pw_aff multi_union_pw_aff::sub(isl::checked::multi_union_pw_aff multi2) const
 {
   auto res = isl_multi_union_pw_aff_sub(copy(), multi2.release());
@@ -7887,12 +11855,6 @@
   return this->add(isl::checked::val(ctx(), v));
 }
 
-isl::checked::multi_val multi_val::flat_range_product(isl::checked::multi_val multi2) const
-{
-  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
-  return manage(res);
-}
-
 isl::checked::val multi_val::at(int pos) const
 {
   auto res = isl_multi_val_get_at(get(), pos);
@@ -7904,6 +11866,24 @@
   return at(pos);
 }
 
+isl::checked::multi_val multi_val::flat_range_product(isl::checked::multi_val multi2) const
+{
+  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
+  return manage(res);
+}
+
+boolean multi_val::has_range_tuple_id() const
+{
+  auto res = isl_multi_val_has_range_tuple_id(get());
+  return manage(res);
+}
+
+boolean multi_val::involves_nan() const
+{
+  auto res = isl_multi_val_involves_nan(get());
+  return manage(res);
+}
+
 isl::checked::val_list multi_val::list() const
 {
   auto res = isl_multi_val_get_list(get());
@@ -7915,23 +11895,6 @@
   return list();
 }
 
-isl::checked::space multi_val::space() const
-{
-  auto res = isl_multi_val_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space multi_val::get_space() const
-{
-  return space();
-}
-
-boolean multi_val::involves_nan() const
-{
-  auto res = isl_multi_val_involves_nan(get());
-  return manage(res);
-}
-
 isl::checked::multi_val multi_val::max(isl::checked::multi_val multi2) const
 {
   auto res = isl_multi_val_max(copy(), multi2.release());
@@ -7968,6 +11931,23 @@
   return manage(res);
 }
 
+isl::checked::id multi_val::range_tuple_id() const
+{
+  auto res = isl_multi_val_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id multi_val::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::checked::multi_val multi_val::reset_range_tuple_id() const
+{
+  auto res = isl_multi_val_reset_range_tuple_id(copy());
+  return manage(res);
+}
+
 isl::checked::multi_val multi_val::scale(isl::checked::multi_val mv) const
 {
   auto res = isl_multi_val_scale_multi_val(copy(), mv.release());
@@ -8013,12 +11993,34 @@
   return this->set_at(pos, isl::checked::val(ctx(), el));
 }
 
+isl::checked::multi_val multi_val::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_multi_val_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::multi_val multi_val::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
 class size multi_val::size() const
 {
   auto res = isl_multi_val_size(get());
   return manage(res);
 }
 
+isl::checked::space multi_val::space() const
+{
+  auto res = isl_multi_val_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space multi_val::get_space() const
+{
+  return space();
+}
+
 isl::checked::multi_val multi_val::sub(isl::checked::multi_val multi2) const
 {
   auto res = isl_multi_val_sub(copy(), multi2.release());
@@ -8096,6 +12098,286 @@
   return isl::checked::ctx(isl_point_get_ctx(ptr));
 }
 
+isl::checked::basic_set point::affine_hull() const
+{
+  return isl::checked::basic_set(*this).affine_hull();
+}
+
+isl::checked::basic_set point::apply(const isl::checked::basic_map &bmap) const
+{
+  return isl::checked::basic_set(*this).apply(bmap);
+}
+
+isl::checked::set point::apply(const isl::checked::map &map) const
+{
+  return isl::checked::basic_set(*this).apply(map);
+}
+
+isl::checked::union_set point::apply(const isl::checked::union_map &umap) const
+{
+  return isl::checked::basic_set(*this).apply(umap);
+}
+
+isl::checked::pw_multi_aff point::as_pw_multi_aff() const
+{
+  return isl::checked::basic_set(*this).as_pw_multi_aff();
+}
+
+isl::checked::set point::as_set() const
+{
+  return isl::checked::basic_set(*this).as_set();
+}
+
+isl::checked::set point::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::basic_set(*this).bind(tuple);
+}
+
+isl::checked::set point::coalesce() const
+{
+  return isl::checked::basic_set(*this).coalesce();
+}
+
+isl::checked::set point::complement() const
+{
+  return isl::checked::basic_set(*this).complement();
+}
+
+isl::checked::union_set point::compute_divs() const
+{
+  return isl::checked::basic_set(*this).compute_divs();
+}
+
+isl::checked::basic_set point::detect_equalities() const
+{
+  return isl::checked::basic_set(*this).detect_equalities();
+}
+
+isl::checked::val point::dim_max_val(int pos) const
+{
+  return isl::checked::basic_set(*this).dim_max_val(pos);
+}
+
+isl::checked::val point::dim_min_val(int pos) const
+{
+  return isl::checked::basic_set(*this).dim_min_val(pos);
+}
+
+boolean point::every_set(const std::function<boolean(isl::checked::set)> &test) const
+{
+  return isl::checked::basic_set(*this).every_set(test);
+}
+
+isl::checked::set point::extract_set(const isl::checked::space &space) const
+{
+  return isl::checked::basic_set(*this).extract_set(space);
+}
+
+isl::checked::basic_set point::flatten() const
+{
+  return isl::checked::basic_set(*this).flatten();
+}
+
+stat point::foreach_basic_set(const std::function<stat(isl::checked::basic_set)> &fn) const
+{
+  return isl::checked::basic_set(*this).foreach_basic_set(fn);
+}
+
+stat point::foreach_point(const std::function<stat(isl::checked::point)> &fn) const
+{
+  return isl::checked::basic_set(*this).foreach_point(fn);
+}
+
+stat point::foreach_set(const std::function<stat(isl::checked::set)> &fn) const
+{
+  return isl::checked::basic_set(*this).foreach_set(fn);
+}
+
+isl::checked::basic_set point::gist(const isl::checked::basic_set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
+}
+
+isl::checked::set point::gist(const isl::checked::set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
+}
+
+isl::checked::union_set point::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::basic_set(*this).gist(context);
+}
+
+isl::checked::union_set point::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::basic_set(*this).gist_params(set);
+}
+
+isl::checked::map point::identity() const
+{
+  return isl::checked::basic_set(*this).identity();
+}
+
+isl::checked::pw_aff point::indicator_function() const
+{
+  return isl::checked::basic_set(*this).indicator_function();
+}
+
+isl::checked::map point::insert_domain(const isl::checked::space &domain) const
+{
+  return isl::checked::basic_set(*this).insert_domain(domain);
+}
+
+isl::checked::basic_set point::intersect(const isl::checked::basic_set &bset2) const
+{
+  return isl::checked::basic_set(*this).intersect(bset2);
+}
+
+isl::checked::set point::intersect(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).intersect(set2);
+}
+
+isl::checked::union_set point::intersect(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).intersect(uset2);
+}
+
+isl::checked::basic_set point::intersect_params(const isl::checked::basic_set &bset2) const
+{
+  return isl::checked::basic_set(*this).intersect_params(bset2);
+}
+
+isl::checked::set point::intersect_params(const isl::checked::set &params) const
+{
+  return isl::checked::basic_set(*this).intersect_params(params);
+}
+
+boolean point::involves_locals() const
+{
+  return isl::checked::basic_set(*this).involves_locals();
+}
+
+boolean point::is_disjoint(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).is_disjoint(set2);
+}
+
+boolean point::is_disjoint(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).is_disjoint(uset2);
+}
+
+boolean point::is_empty() const
+{
+  return isl::checked::basic_set(*this).is_empty();
+}
+
+boolean point::is_equal(const isl::checked::basic_set &bset2) const
+{
+  return isl::checked::basic_set(*this).is_equal(bset2);
+}
+
+boolean point::is_equal(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).is_equal(set2);
+}
+
+boolean point::is_equal(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).is_equal(uset2);
+}
+
+boolean point::is_singleton() const
+{
+  return isl::checked::basic_set(*this).is_singleton();
+}
+
+boolean point::is_strict_subset(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).is_strict_subset(set2);
+}
+
+boolean point::is_strict_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).is_strict_subset(uset2);
+}
+
+boolean point::is_subset(const isl::checked::basic_set &bset2) const
+{
+  return isl::checked::basic_set(*this).is_subset(bset2);
+}
+
+boolean point::is_subset(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).is_subset(set2);
+}
+
+boolean point::is_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).is_subset(uset2);
+}
+
+boolean point::is_wrapping() const
+{
+  return isl::checked::basic_set(*this).is_wrapping();
+}
+
+boolean point::isa_set() const
+{
+  return isl::checked::basic_set(*this).isa_set();
+}
+
+isl::checked::set point::lexmax() const
+{
+  return isl::checked::basic_set(*this).lexmax();
+}
+
+isl::checked::pw_multi_aff point::lexmax_pw_multi_aff() const
+{
+  return isl::checked::basic_set(*this).lexmax_pw_multi_aff();
+}
+
+isl::checked::set point::lexmin() const
+{
+  return isl::checked::basic_set(*this).lexmin();
+}
+
+isl::checked::pw_multi_aff point::lexmin_pw_multi_aff() const
+{
+  return isl::checked::basic_set(*this).lexmin_pw_multi_aff();
+}
+
+isl::checked::set point::lower_bound(const isl::checked::multi_pw_aff &lower) const
+{
+  return isl::checked::basic_set(*this).lower_bound(lower);
+}
+
+isl::checked::set point::lower_bound(const isl::checked::multi_val &lower) const
+{
+  return isl::checked::basic_set(*this).lower_bound(lower);
+}
+
+isl::checked::multi_pw_aff point::max_multi_pw_aff() const
+{
+  return isl::checked::basic_set(*this).max_multi_pw_aff();
+}
+
+isl::checked::val point::max_val(const isl::checked::aff &obj) const
+{
+  return isl::checked::basic_set(*this).max_val(obj);
+}
+
+isl::checked::multi_pw_aff point::min_multi_pw_aff() const
+{
+  return isl::checked::basic_set(*this).min_multi_pw_aff();
+}
+
+isl::checked::val point::min_val(const isl::checked::aff &obj) const
+{
+  return isl::checked::basic_set(*this).min_val(obj);
+}
+
 isl::checked::multi_val point::multi_val() const
 {
   auto res = isl_point_get_multi_val(get());
@@ -8107,6 +12389,177 @@
   return multi_val();
 }
 
+isl::checked::basic_set point::params() const
+{
+  return isl::checked::basic_set(*this).params();
+}
+
+isl::checked::multi_val point::plain_multi_val_if_fixed() const
+{
+  return isl::checked::basic_set(*this).plain_multi_val_if_fixed();
+}
+
+isl::checked::basic_set point::polyhedral_hull() const
+{
+  return isl::checked::basic_set(*this).polyhedral_hull();
+}
+
+isl::checked::set point::preimage(const isl::checked::multi_aff &ma) const
+{
+  return isl::checked::basic_set(*this).preimage(ma);
+}
+
+isl::checked::set point::preimage(const isl::checked::multi_pw_aff &mpa) const
+{
+  return isl::checked::basic_set(*this).preimage(mpa);
+}
+
+isl::checked::set point::preimage(const isl::checked::pw_multi_aff &pma) const
+{
+  return isl::checked::basic_set(*this).preimage(pma);
+}
+
+isl::checked::union_set point::preimage(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::basic_set(*this).preimage(upma);
+}
+
+isl::checked::set point::product(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).product(set2);
+}
+
+isl::checked::set point::project_out_all_params() const
+{
+  return isl::checked::basic_set(*this).project_out_all_params();
+}
+
+isl::checked::set point::project_out_param(const isl::checked::id &id) const
+{
+  return isl::checked::basic_set(*this).project_out_param(id);
+}
+
+isl::checked::set point::project_out_param(const std::string &id) const
+{
+  return this->project_out_param(isl::checked::id(ctx(), id));
+}
+
+isl::checked::set point::project_out_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::basic_set(*this).project_out_param(list);
+}
+
+isl::checked::pw_multi_aff point::pw_multi_aff_on_domain(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::basic_set(*this).pw_multi_aff_on_domain(mv);
+}
+
+isl::checked::basic_set point::sample() const
+{
+  return isl::checked::basic_set(*this).sample();
+}
+
+isl::checked::point point::sample_point() const
+{
+  return isl::checked::basic_set(*this).sample_point();
+}
+
+isl::checked::fixed_box point::simple_fixed_box_hull() const
+{
+  return isl::checked::basic_set(*this).simple_fixed_box_hull();
+}
+
+isl::checked::space point::space() const
+{
+  return isl::checked::basic_set(*this).space();
+}
+
+isl::checked::val point::stride(int pos) const
+{
+  return isl::checked::basic_set(*this).stride(pos);
+}
+
+isl::checked::set point::subtract(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).subtract(set2);
+}
+
+isl::checked::union_set point::subtract(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).subtract(uset2);
+}
+
+isl::checked::union_set_list point::to_list() const
+{
+  return isl::checked::basic_set(*this).to_list();
+}
+
+isl::checked::set point::to_set() const
+{
+  auto res = isl_point_to_set(copy());
+  return manage(res);
+}
+
+isl::checked::union_set point::to_union_set() const
+{
+  return isl::checked::basic_set(*this).to_union_set();
+}
+
+isl::checked::map point::translation() const
+{
+  return isl::checked::basic_set(*this).translation();
+}
+
+class size point::tuple_dim() const
+{
+  return isl::checked::basic_set(*this).tuple_dim();
+}
+
+isl::checked::set point::unbind_params(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::basic_set(*this).unbind_params(tuple);
+}
+
+isl::checked::map point::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
+{
+  return isl::checked::basic_set(*this).unbind_params_insert_domain(domain);
+}
+
+isl::checked::set point::unite(const isl::checked::basic_set &bset2) const
+{
+  return isl::checked::basic_set(*this).unite(bset2);
+}
+
+isl::checked::set point::unite(const isl::checked::set &set2) const
+{
+  return isl::checked::basic_set(*this).unite(set2);
+}
+
+isl::checked::union_set point::unite(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::basic_set(*this).unite(uset2);
+}
+
+isl::checked::basic_set point::unshifted_simple_hull() const
+{
+  return isl::checked::basic_set(*this).unshifted_simple_hull();
+}
+
+isl::checked::map point::unwrap() const
+{
+  return isl::checked::basic_set(*this).unwrap();
+}
+
+isl::checked::set point::upper_bound(const isl::checked::multi_pw_aff &upper) const
+{
+  return isl::checked::basic_set(*this).upper_bound(upper);
+}
+
+isl::checked::set point::upper_bound(const isl::checked::multi_val &upper) const
+{
+  return isl::checked::basic_set(*this).upper_bound(upper);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const point &obj)
 {
   char *str = isl_point_to_str(obj.get());
@@ -8184,12 +12637,42 @@
   return isl::checked::ctx(isl_pw_aff_get_ctx(ptr));
 }
 
+isl::checked::multi_pw_aff pw_aff::add(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::union_pw_aff(*this).add(multi2);
+}
+
 isl::checked::pw_aff pw_aff::add(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_add(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_aff::add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).add(pma2);
+}
+
+isl::checked::union_pw_aff pw_aff::add(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::union_pw_aff(*this).add(upa2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).add(upma2);
+}
+
+isl::checked::pw_aff pw_aff::add(const isl::checked::aff &pwaff2) const
+{
+  return this->add(isl::checked::pw_aff(pwaff2));
+}
+
 isl::checked::pw_aff pw_aff::add_constant(isl::checked::val v) const
 {
   auto res = isl_pw_aff_add_constant_val(copy(), v.release());
@@ -8201,12 +12684,63 @@
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
+isl::checked::pw_multi_aff pw_aff::add_constant(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::pw_multi_aff(*this).add_constant(mv);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).apply(upma2);
+}
+
 isl::checked::aff pw_aff::as_aff() const
 {
   auto res = isl_pw_aff_as_aff(copy());
   return manage(res);
 }
 
+isl::checked::map pw_aff::as_map() const
+{
+  auto res = isl_pw_aff_as_map(copy());
+  return manage(res);
+}
+
+isl::checked::multi_aff pw_aff::as_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).as_multi_aff();
+}
+
+isl::checked::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const
+{
+  return isl::checked::union_pw_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff pw_aff::as_pw_multi_aff() const
+{
+  return isl::checked::union_pw_aff(*this).as_pw_multi_aff();
+}
+
+isl::checked::set pw_aff::as_set() const
+{
+  return isl::checked::pw_multi_aff(*this).as_set();
+}
+
+isl::checked::union_map pw_aff::as_union_map() const
+{
+  return isl::checked::union_pw_aff(*this).as_union_map();
+}
+
+isl::checked::pw_aff pw_aff::at(int pos) const
+{
+  return isl::checked::pw_multi_aff(*this).at(pos);
+}
+
+isl::checked::set pw_aff::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::multi_pw_aff(*this).bind(tuple);
+}
+
 isl::checked::set pw_aff::bind(isl::checked::id id) const
 {
   auto res = isl_pw_aff_bind_id(copy(), id.release());
@@ -8272,12 +12806,42 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_aff::extract_pw_multi_aff(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::checked::multi_pw_aff pw_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::union_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::pw_multi_aff pw_aff::flat_range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).flat_range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).flat_range_product(upma2);
+}
+
 isl::checked::pw_aff pw_aff::floor() const
 {
   auto res = isl_pw_aff_floor(copy());
   return manage(res);
 }
 
+stat pw_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
+{
+  return isl::checked::pw_multi_aff(*this).foreach_piece(fn);
+}
+
 isl::checked::set pw_aff::ge_set(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_ge_set(copy(), pwaff2.release());
@@ -8290,12 +12854,37 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff pw_aff::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::union_pw_aff(*this).gist(context);
+}
+
+isl::checked::pw_aff pw_aff::gist(const isl::checked::basic_set &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+isl::checked::pw_aff pw_aff::gist(const isl::checked::point &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
 isl::checked::set pw_aff::gt_set(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_gt_set(copy(), pwaff2.release());
   return manage(res);
 }
 
+boolean pw_aff::has_range_tuple_id() const
+{
+  return isl::checked::pw_multi_aff(*this).has_range_tuple_id();
+}
+
+isl::checked::multi_pw_aff pw_aff::identity() const
+{
+  return isl::checked::pw_multi_aff(*this).identity();
+}
+
 isl::checked::pw_aff pw_aff::insert_domain(isl::checked::space domain) const
 {
   auto res = isl_pw_aff_insert_domain(copy(), domain.release());
@@ -8308,42 +12897,142 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_aff(*this).intersect_domain(space);
+}
+
+isl::checked::union_pw_aff pw_aff::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_aff(*this).intersect_domain(uset);
+}
+
+isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::basic_set &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
+isl::checked::pw_aff pw_aff::intersect_domain(const isl::checked::point &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
+isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::checked::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
 isl::checked::pw_aff pw_aff::intersect_params(isl::checked::set set) const
 {
   auto res = isl_pw_aff_intersect_params(copy(), set.release());
   return manage(res);
 }
 
+boolean pw_aff::involves_locals() const
+{
+  return isl::checked::pw_multi_aff(*this).involves_locals();
+}
+
+boolean pw_aff::involves_nan() const
+{
+  return isl::checked::multi_pw_aff(*this).involves_nan();
+}
+
+boolean pw_aff::involves_param(const isl::checked::id &id) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(id);
+}
+
+boolean pw_aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
+}
+
+boolean pw_aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::pw_multi_aff(*this).involves_param(list);
+}
+
 boolean pw_aff::isa_aff() const
 {
   auto res = isl_pw_aff_isa_aff(get());
   return manage(res);
 }
 
+boolean pw_aff::isa_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).isa_multi_aff();
+}
+
+boolean pw_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::union_pw_aff(*this).isa_pw_multi_aff();
+}
+
 isl::checked::set pw_aff::le_set(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_le_set(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_aff_list pw_aff::list() const
+{
+  return isl::checked::multi_pw_aff(*this).list();
+}
+
 isl::checked::set pw_aff::lt_set(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_lt_set(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff pw_aff::max(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).max(multi2);
+}
+
 isl::checked::pw_aff pw_aff::max(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_max(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_aff pw_aff::max(const isl::checked::aff &pwaff2) const
+{
+  return this->max(isl::checked::pw_aff(pwaff2));
+}
+
+isl::checked::multi_val pw_aff::max_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).max_multi_val();
+}
+
+isl::checked::multi_pw_aff pw_aff::min(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).min(multi2);
+}
+
 isl::checked::pw_aff pw_aff::min(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_min(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_aff pw_aff::min(const isl::checked::aff &pwaff2) const
+{
+  return this->min(isl::checked::pw_aff(pwaff2));
+}
+
+isl::checked::multi_val pw_aff::min_multi_val() const
+{
+  return isl::checked::pw_multi_aff(*this).min_multi_val();
+}
+
 isl::checked::pw_aff pw_aff::mod(isl::checked::val mod) const
 {
   auto res = isl_pw_aff_mod_val(copy(), mod.release());
@@ -8361,6 +13050,11 @@
   return manage(res);
 }
 
+class size pw_aff::n_piece() const
+{
+  return isl::checked::pw_multi_aff(*this).n_piece();
+}
+
 isl::checked::set pw_aff::ne_set(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_ne_set(copy(), pwaff2.release());
@@ -8379,6 +13073,41 @@
   return manage(res);
 }
 
+boolean pw_aff::plain_is_empty() const
+{
+  return isl::checked::union_pw_aff(*this).plain_is_empty();
+}
+
+boolean pw_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+boolean pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::checked::pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::checked::multi_pw_aff pw_aff::product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).product(multi2);
+}
+
+isl::checked::pw_multi_aff pw_aff::product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).product(pma2);
+}
+
 isl::checked::pw_aff pw_aff::pullback(isl::checked::multi_aff ma) const
 {
   auto res = isl_pw_aff_pullback_multi_aff(copy(), ma.release());
@@ -8397,6 +13126,61 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff pw_aff::pullback(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::union_pw_aff(*this).pullback(upma);
+}
+
+isl::checked::pw_multi_aff_list pw_aff::pw_multi_aff_list() const
+{
+  return isl::checked::union_pw_aff(*this).pw_multi_aff_list();
+}
+
+isl::checked::pw_multi_aff pw_aff::range_factor_domain() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::checked::pw_multi_aff pw_aff::range_factor_range() const
+{
+  return isl::checked::pw_multi_aff(*this).range_factor_range();
+}
+
+isl::checked::multi_pw_aff pw_aff::range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::union_pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::pw_multi_aff pw_aff::range_product(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).range_product(pma2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).range_product(upma2);
+}
+
+isl::checked::id pw_aff::range_tuple_id() const
+{
+  return isl::checked::pw_multi_aff(*this).range_tuple_id();
+}
+
+isl::checked::multi_pw_aff pw_aff::reset_range_tuple_id() const
+{
+  return isl::checked::multi_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::checked::multi_pw_aff pw_aff::scale(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_pw_aff(*this).scale(mv);
+}
+
 isl::checked::pw_aff pw_aff::scale(isl::checked::val v) const
 {
   auto res = isl_pw_aff_scale_val(copy(), v.release());
@@ -8408,6 +13192,11 @@
   return this->scale(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_pw_aff pw_aff::scale_down(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_pw_aff(*this).scale_down(mv);
+}
+
 isl::checked::pw_aff pw_aff::scale_down(isl::checked::val f) const
 {
   auto res = isl_pw_aff_scale_down_val(copy(), f.release());
@@ -8419,18 +13208,98 @@
   return this->scale_down(isl::checked::val(ctx(), f));
 }
 
+isl::checked::multi_pw_aff pw_aff::set_at(int pos, const isl::checked::pw_aff &el) const
+{
+  return isl::checked::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::pw_multi_aff pw_aff::set_range_tuple(const isl::checked::id &id) const
+{
+  return isl::checked::pw_multi_aff(*this).set_range_tuple(id);
+}
+
+isl::checked::pw_multi_aff pw_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+class size pw_aff::size() const
+{
+  return isl::checked::multi_pw_aff(*this).size();
+}
+
+isl::checked::space pw_aff::space() const
+{
+  return isl::checked::union_pw_aff(*this).space();
+}
+
+isl::checked::multi_pw_aff pw_aff::sub(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::union_pw_aff(*this).sub(multi2);
+}
+
 isl::checked::pw_aff pw_aff::sub(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_sub(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_aff::sub(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).sub(pma2);
+}
+
+isl::checked::union_pw_aff pw_aff::sub(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::union_pw_aff(*this).sub(upa2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).sub(upma2);
+}
+
+isl::checked::pw_aff pw_aff::sub(const isl::checked::aff &pwaff2) const
+{
+  return this->sub(isl::checked::pw_aff(pwaff2));
+}
+
 isl::checked::pw_aff pw_aff::subtract_domain(isl::checked::set set) const
 {
   auto res = isl_pw_aff_subtract_domain(copy(), set.release());
   return manage(res);
 }
 
+isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_aff(*this).subtract_domain(space);
+}
+
+isl::checked::union_pw_aff pw_aff::subtract_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_aff(*this).subtract_domain(uset);
+}
+
+isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::basic_set &set) const
+{
+  return this->subtract_domain(isl::checked::set(set));
+}
+
+isl::checked::pw_aff pw_aff::subtract_domain(const isl::checked::point &set) const
+{
+  return this->subtract_domain(isl::checked::set(set));
+}
+
 isl::checked::pw_aff pw_aff::tdiv_q(isl::checked::pw_aff pa2) const
 {
   auto res = isl_pw_aff_tdiv_q(copy(), pa2.release());
@@ -8443,12 +13312,69 @@
   return manage(res);
 }
 
+isl::checked::pw_aff_list pw_aff::to_list() const
+{
+  auto res = isl_pw_aff_to_list(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff pw_aff::to_multi_pw_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).to_multi_pw_aff();
+}
+
+isl::checked::union_pw_aff pw_aff::to_union_pw_aff() const
+{
+  auto res = isl_pw_aff_to_union_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const
+{
+  return isl::checked::pw_multi_aff(*this).to_union_pw_multi_aff();
+}
+
+isl::checked::multi_pw_aff pw_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
+{
+  return isl::checked::pw_multi_aff(*this).unbind_params_insert_domain(domain);
+}
+
+isl::checked::multi_pw_aff pw_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(mpa2);
+}
+
+isl::checked::multi_union_pw_aff pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::union_pw_aff(*this).union_add(mupa2);
+}
+
 isl::checked::pw_aff pw_aff::union_add(isl::checked::pw_aff pwaff2) const
 {
   auto res = isl_pw_aff_union_add(copy(), pwaff2.release());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_aff::union_add(const isl::checked::pw_multi_aff &pma2) const
+{
+  return isl::checked::pw_multi_aff(*this).union_add(pma2);
+}
+
+isl::checked::union_pw_aff pw_aff::union_add(const isl::checked::union_pw_aff &upa2) const
+{
+  return isl::checked::union_pw_aff(*this).union_add(upa2);
+}
+
+isl::checked::union_pw_multi_aff pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_aff(*this).union_add(upma2);
+}
+
+isl::checked::pw_aff pw_aff::union_add(const isl::checked::aff &pwaff2) const
+{
+  return this->union_add(isl::checked::pw_aff(pwaff2));
+}
+
 inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
 {
   char *str = isl_pw_aff_to_str(obj.get());
@@ -8494,6 +13420,12 @@
   ptr = res;
 }
 
+pw_aff_list::pw_aff_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_pw_aff_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -8532,6 +13464,17 @@
   return manage(res);
 }
 
+isl::checked::pw_aff pw_aff_list::at(int index) const
+{
+  auto res = isl_pw_aff_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::pw_aff pw_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::pw_aff_list pw_aff_list::clear() const
 {
   auto res = isl_pw_aff_list_clear(copy());
@@ -8564,17 +13507,6 @@
   return manage(res);
 }
 
-isl::checked::pw_aff pw_aff_list::at(int index) const
-{
-  auto res = isl_pw_aff_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::pw_aff pw_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::checked::pw_aff el) const
 {
   auto res = isl_pw_aff_list_insert(copy(), pos, el.release());
@@ -8670,12 +13602,37 @@
   return isl::checked::ctx(isl_pw_multi_aff_get_ctx(ptr));
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::add(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).add(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).add(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::add(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_add(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).add(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::multi_aff &pma2) const
+{
+  return this->add(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::add(const isl::checked::pw_aff &pma2) const
+{
+  return this->add(isl::checked::pw_multi_aff(pma2));
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::add_constant(isl::checked::multi_val mv) const
 {
   auto res = isl_pw_multi_aff_add_constant_multi_val(copy(), mv.release());
@@ -8693,12 +13650,60 @@
   return this->add_constant(isl::checked::val(ctx(), v));
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).apply(upma2);
+}
+
+isl::checked::map pw_multi_aff::as_map() const
+{
+  auto res = isl_pw_multi_aff_as_map(copy());
+  return manage(res);
+}
+
 isl::checked::multi_aff pw_multi_aff::as_multi_aff() const
 {
   auto res = isl_pw_multi_aff_as_multi_aff(copy());
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff pw_multi_aff::as_multi_union_pw_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::as_pw_multi_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::checked::set pw_multi_aff::as_set() const
+{
+  auto res = isl_pw_multi_aff_as_set(copy());
+  return manage(res);
+}
+
+isl::checked::union_map pw_multi_aff::as_union_map() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_union_map();
+}
+
+isl::checked::pw_aff pw_multi_aff::at(int pos) const
+{
+  auto res = isl_pw_multi_aff_get_at(get(), pos);
+  return manage(res);
+}
+
+isl::checked::pw_aff pw_multi_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
+isl::checked::set pw_multi_aff::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::multi_pw_aff(*this).bind(tuple);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::bind_domain(isl::checked::multi_id tuple) const
 {
   auto res = isl_pw_multi_aff_bind_domain(copy(), tuple.release());
@@ -8729,12 +13734,42 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).flat_range_product(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_flat_range_product(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).flat_range_product(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::multi_aff &pma2) const
+{
+  return this->flat_range_product(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::flat_range_product(const isl::checked::pw_aff &pma2) const
+{
+  return this->flat_range_product(isl::checked::pw_multi_aff(pma2));
+}
+
 stat pw_multi_aff::foreach_piece(const std::function<stat(isl::checked::set, isl::checked::multi_aff)> &fn) const
 {
   struct fn_data {
@@ -8749,23 +13784,38 @@
   return manage(res);
 }
 
-isl::checked::space pw_multi_aff::space() const
-{
-  auto res = isl_pw_multi_aff_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space pw_multi_aff::get_space() const
-{
-  return space();
-}
-
 isl::checked::pw_multi_aff pw_multi_aff::gist(isl::checked::set set) const
 {
   auto res = isl_pw_multi_aff_gist(copy(), set.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::union_pw_multi_aff(*this).gist(context);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::basic_set &set) const
+{
+  return this->gist(isl::checked::set(set));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::gist(const isl::checked::point &set) const
+{
+  return this->gist(isl::checked::set(set));
+}
+
+boolean pw_multi_aff::has_range_tuple_id() const
+{
+  auto res = isl_pw_multi_aff_has_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::identity() const
+{
+  return isl::checked::multi_pw_aff(*this).identity();
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::identity_on_domain(isl::checked::space space)
 {
   auto res = isl_pw_multi_aff_identity_on_domain_space(space.release());
@@ -8784,6 +13834,36 @@
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain(space);
+}
+
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain(uset);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::basic_set &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::intersect_domain(const isl::checked::point &set) const
+{
+  return this->intersect_domain(isl::checked::set(set));
+}
+
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::checked::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_range(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_multi_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::intersect_params(isl::checked::set set) const
 {
   auto res = isl_pw_multi_aff_intersect_params(copy(), set.release());
@@ -8796,42 +13876,143 @@
   return manage(res);
 }
 
+boolean pw_multi_aff::involves_nan() const
+{
+  return isl::checked::multi_pw_aff(*this).involves_nan();
+}
+
+boolean pw_multi_aff::involves_param(const isl::checked::id &id) const
+{
+  return isl::checked::multi_pw_aff(*this).involves_param(id);
+}
+
+boolean pw_multi_aff::involves_param(const std::string &id) const
+{
+  return this->involves_param(isl::checked::id(ctx(), id));
+}
+
+boolean pw_multi_aff::involves_param(const isl::checked::id_list &list) const
+{
+  return isl::checked::multi_pw_aff(*this).involves_param(list);
+}
+
 boolean pw_multi_aff::isa_multi_aff() const
 {
   auto res = isl_pw_multi_aff_isa_multi_aff(get());
   return manage(res);
 }
 
+boolean pw_multi_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::checked::pw_aff_list pw_multi_aff::list() const
+{
+  return isl::checked::multi_pw_aff(*this).list();
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::max(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).max(multi2);
+}
+
 isl::checked::multi_val pw_multi_aff::max_multi_val() const
 {
   auto res = isl_pw_multi_aff_max_multi_val(copy());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::min(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).min(multi2);
+}
+
 isl::checked::multi_val pw_multi_aff::min_multi_val() const
 {
   auto res = isl_pw_multi_aff_min_multi_val(copy());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff::multi_val_on_domain(isl::checked::set domain, isl::checked::multi_val mv)
+{
+  auto res = isl_pw_multi_aff_multi_val_on_domain(domain.release(), mv.release());
+  return manage(res);
+}
+
 class size pw_multi_aff::n_piece() const
 {
   auto res = isl_pw_multi_aff_n_piece(get());
   return manage(res);
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::neg() const
+{
+  return isl::checked::multi_pw_aff(*this).neg();
+}
+
+boolean pw_multi_aff::plain_is_empty() const
+{
+  return isl::checked::union_pw_multi_aff(*this).plain_is_empty();
+}
+
+boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2);
+}
+
+boolean pw_multi_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).plain_is_equal(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::multi_aff &pma2) const
+{
+  return this->preimage_domain_wrapped_domain(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::checked::pw_aff &pma2) const
+{
+  return this->preimage_domain_wrapped_domain(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).product(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::product(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_product(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff::product(const isl::checked::multi_aff &pma2) const
+{
+  return this->product(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::product(const isl::checked::pw_aff &pma2) const
+{
+  return this->product(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::pullback(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::multi_pw_aff(*this).pullback(mpa2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::pullback(isl::checked::multi_aff ma) const
 {
   auto res = isl_pw_multi_aff_pullback_multi_aff(copy(), ma.release());
@@ -8844,6 +14025,16 @@
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::pullback(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).pullback(upma2);
+}
+
+isl::checked::pw_multi_aff_list pw_multi_aff::pw_multi_aff_list() const
+{
+  return isl::checked::union_pw_multi_aff(*this).pw_multi_aff_list();
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::range_factor_domain() const
 {
   auto res = isl_pw_multi_aff_range_factor_domain(copy());
@@ -8862,12 +14053,58 @@
   return manage(res);
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::range_product(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).range_product(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::range_product(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_range_product(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::multi_aff &pma2) const
+{
+  return this->range_product(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::range_product(const isl::checked::pw_aff &pma2) const
+{
+  return this->range_product(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::id pw_multi_aff::range_tuple_id() const
+{
+  auto res = isl_pw_multi_aff_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id pw_multi_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::reset_range_tuple_id() const
+{
+  return isl::checked::multi_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::scale(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_pw_aff(*this).scale(mv);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::scale(isl::checked::val v) const
 {
   auto res = isl_pw_multi_aff_scale_val(copy(), v.release());
@@ -8879,6 +14116,11 @@
   return this->scale(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::scale_down(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_pw_aff(*this).scale_down(mv);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::scale_down(isl::checked::val v) const
 {
   auto res = isl_pw_multi_aff_scale_down_val(copy(), v.release());
@@ -8890,24 +14132,154 @@
   return this->scale_down(isl::checked::val(ctx(), v));
 }
 
+isl::checked::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::pw_aff &el) const
+{
+  return isl::checked::multi_pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::multi_pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_pw_multi_aff_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+class size pw_multi_aff::size() const
+{
+  return isl::checked::multi_pw_aff(*this).size();
+}
+
+isl::checked::space pw_multi_aff::space() const
+{
+  auto res = isl_pw_multi_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space pw_multi_aff::get_space() const
+{
+  return space();
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::sub(const isl::checked::multi_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).sub(multi2);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_pw_aff(*this).sub(multi2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::sub(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_sub(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).sub(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::multi_aff &pma2) const
+{
+  return this->sub(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::sub(const isl::checked::pw_aff &pma2) const
+{
+  return this->sub(isl::checked::pw_multi_aff(pma2));
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(isl::checked::set set) const
 {
   auto res = isl_pw_multi_aff_subtract_domain(copy(), set.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::space &space) const
+{
+  return isl::checked::union_pw_multi_aff(*this).subtract_domain(space);
+}
+
+isl::checked::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::union_set &uset) const
+{
+  return isl::checked::union_pw_multi_aff(*this).subtract_domain(uset);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::basic_set &set) const
+{
+  return this->subtract_domain(isl::checked::set(set));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::subtract_domain(const isl::checked::point &set) const
+{
+  return this->subtract_domain(isl::checked::set(set));
+}
+
+isl::checked::pw_multi_aff_list pw_multi_aff::to_list() const
+{
+  auto res = isl_pw_multi_aff_to_list(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const
+{
+  auto res = isl_pw_multi_aff_to_multi_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const
+{
+  auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::unbind_params_insert_domain(const isl::checked::multi_id &domain) const
+{
+  return isl::checked::multi_pw_aff(*this).unbind_params_insert_domain(domain);
+}
+
+isl::checked::multi_pw_aff pw_multi_aff::union_add(const isl::checked::multi_pw_aff &mpa2) const
+{
+  return isl::checked::multi_pw_aff(*this).union_add(mpa2);
+}
+
+isl::checked::multi_union_pw_aff pw_multi_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::multi_pw_aff(*this).union_add(mupa2);
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::union_add(isl::checked::pw_multi_aff pma2) const
 {
   auto res = isl_pw_multi_aff_union_add(copy(), pma2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff pw_multi_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).union_add(upma2);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::multi_aff &pma2) const
+{
+  return this->union_add(isl::checked::pw_multi_aff(pma2));
+}
+
+isl::checked::pw_multi_aff pw_multi_aff::union_add(const isl::checked::pw_aff &pma2) const
+{
+  return this->union_add(isl::checked::pw_multi_aff(pma2));
+}
+
 isl::checked::pw_multi_aff pw_multi_aff::zero(isl::checked::space space)
 {
   auto res = isl_pw_multi_aff_zero(space.release());
@@ -8959,6 +14331,12 @@
   ptr = res;
 }
 
+pw_multi_aff_list::pw_multi_aff_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_pw_multi_aff_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 pw_multi_aff_list &pw_multi_aff_list::operator=(pw_multi_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -8997,6 +14375,17 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff pw_multi_aff_list::at(int index) const
+{
+  auto res = isl_pw_multi_aff_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff pw_multi_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::pw_multi_aff_list pw_multi_aff_list::clear() const
 {
   auto res = isl_pw_multi_aff_list_clear(copy());
@@ -9029,17 +14418,6 @@
   return manage(res);
 }
 
-isl::checked::pw_multi_aff pw_multi_aff_list::at(int index) const
-{
-  auto res = isl_pw_multi_aff_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::pw_multi_aff pw_multi_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::checked::pw_multi_aff el) const
 {
   auto res = isl_pw_multi_aff_list_insert(copy(), pos, el.release());
@@ -9123,12 +14501,6 @@
   return isl::checked::ctx(isl_schedule_get_ctx(ptr));
 }
 
-isl::checked::schedule schedule::from_domain(isl::checked::union_set domain)
-{
-  auto res = isl_schedule_from_domain(domain.release());
-  return manage(res);
-}
-
 isl::checked::union_set schedule::domain() const
 {
   auto res = isl_schedule_get_domain(get());
@@ -9140,6 +14512,12 @@
   return domain();
 }
 
+isl::checked::schedule schedule::from_domain(isl::checked::union_set domain)
+{
+  auto res = isl_schedule_from_domain(domain.release());
+  return manage(res);
+}
+
 isl::checked::union_map schedule::map() const
 {
   auto res = isl_schedule_get_map(get());
@@ -9151,6 +14529,12 @@
   return map();
 }
 
+isl::checked::schedule schedule::pullback(isl::checked::union_pw_multi_aff upma) const
+{
+  auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
+  return manage(res);
+}
+
 isl::checked::schedule_node schedule::root() const
 {
   auto res = isl_schedule_get_root(get());
@@ -9162,12 +14546,6 @@
   return root();
 }
 
-isl::checked::schedule schedule::pullback(isl::checked::union_pw_multi_aff upma) const
-{
-  auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
-  return manage(res);
-}
-
 inline std::ostream &operator<<(std::ostream &os, const schedule &obj)
 {
   char *str = isl_schedule_to_str(obj.get());
@@ -9239,12 +14617,6 @@
   return isl::checked::ctx(isl_schedule_constraints_get_ctx(ptr));
 }
 
-isl::checked::schedule schedule_constraints::compute_schedule() const
-{
-  auto res = isl_schedule_constraints_compute_schedule(copy());
-  return manage(res);
-}
-
 isl::checked::union_map schedule_constraints::coincidence() const
 {
   auto res = isl_schedule_constraints_get_coincidence(get());
@@ -9256,6 +14628,12 @@
   return coincidence();
 }
 
+isl::checked::schedule schedule_constraints::compute_schedule() const
+{
+  auto res = isl_schedule_constraints_compute_schedule(copy());
+  return manage(res);
+}
+
 isl::checked::union_map schedule_constraints::conditional_validity() const
 {
   auto res = isl_schedule_constraints_get_conditional_validity(get());
@@ -9300,6 +14678,12 @@
   return domain();
 }
 
+isl::checked::schedule_constraints schedule_constraints::on_domain(isl::checked::union_set domain)
+{
+  auto res = isl_schedule_constraints_on_domain(domain.release());
+  return manage(res);
+}
+
 isl::checked::union_map schedule_constraints::proximity() const
 {
   auto res = isl_schedule_constraints_get_proximity(get());
@@ -9311,23 +14695,6 @@
   return proximity();
 }
 
-isl::checked::union_map schedule_constraints::validity() const
-{
-  auto res = isl_schedule_constraints_get_validity(get());
-  return manage(res);
-}
-
-isl::checked::union_map schedule_constraints::get_validity() const
-{
-  return validity();
-}
-
-isl::checked::schedule_constraints schedule_constraints::on_domain(isl::checked::union_set domain)
-{
-  auto res = isl_schedule_constraints_on_domain(domain.release());
-  return manage(res);
-}
-
 isl::checked::schedule_constraints schedule_constraints::set_coincidence(isl::checked::union_map coincidence) const
 {
   auto res = isl_schedule_constraints_set_coincidence(copy(), coincidence.release());
@@ -9358,6 +14725,17 @@
   return manage(res);
 }
 
+isl::checked::union_map schedule_constraints::validity() const
+{
+  auto res = isl_schedule_constraints_get_validity(get());
+  return manage(res);
+}
+
+isl::checked::union_map schedule_constraints::get_validity() const
+{
+  return validity();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj)
 {
   char *str = isl_schedule_constraints_to_str(obj.get());
@@ -9449,12 +14827,34 @@
   return manage(res);
 }
 
+class size schedule_node::ancestor_child_position(const isl::checked::schedule_node &ancestor) const
+{
+  auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get());
+  return manage(res);
+}
+
+class size schedule_node::get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const
+{
+  return ancestor_child_position(ancestor);
+}
+
 isl::checked::schedule_node schedule_node::child(int pos) const
 {
   auto res = isl_schedule_node_child(copy(), pos);
   return manage(res);
 }
 
+class size schedule_node::child_position() const
+{
+  auto res = isl_schedule_node_get_child_position(get());
+  return manage(res);
+}
+
+class size schedule_node::get_child_position() const
+{
+  return child_position();
+}
+
 boolean schedule_node::every_descendant(const std::function<boolean(isl::checked::schedule_node)> &test) const
 {
   struct test_data {
@@ -9515,94 +14915,6 @@
   return manage(res);
 }
 
-class size schedule_node::ancestor_child_position(const isl::checked::schedule_node &ancestor) const
-{
-  auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get());
-  return manage(res);
-}
-
-class size schedule_node::get_ancestor_child_position(const isl::checked::schedule_node &ancestor) const
-{
-  return ancestor_child_position(ancestor);
-}
-
-class size schedule_node::child_position() const
-{
-  auto res = isl_schedule_node_get_child_position(get());
-  return manage(res);
-}
-
-class size schedule_node::get_child_position() const
-{
-  return child_position();
-}
-
-isl::checked::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
-{
-  auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get());
-  return manage(res);
-}
-
-isl::checked::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const
-{
-  return prefix_schedule_multi_union_pw_aff();
-}
-
-isl::checked::union_map schedule_node::prefix_schedule_union_map() const
-{
-  auto res = isl_schedule_node_get_prefix_schedule_union_map(get());
-  return manage(res);
-}
-
-isl::checked::union_map schedule_node::get_prefix_schedule_union_map() const
-{
-  return prefix_schedule_union_map();
-}
-
-isl::checked::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
-{
-  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
-  return manage(res);
-}
-
-isl::checked::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
-{
-  return prefix_schedule_union_pw_multi_aff();
-}
-
-isl::checked::schedule schedule_node::schedule() const
-{
-  auto res = isl_schedule_node_get_schedule(get());
-  return manage(res);
-}
-
-isl::checked::schedule schedule_node::get_schedule() const
-{
-  return schedule();
-}
-
-isl::checked::schedule_node schedule_node::shared_ancestor(const isl::checked::schedule_node &node2) const
-{
-  auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get());
-  return manage(res);
-}
-
-isl::checked::schedule_node schedule_node::get_shared_ancestor(const isl::checked::schedule_node &node2) const
-{
-  return shared_ancestor(node2);
-}
-
-class size schedule_node::tree_depth() const
-{
-  auto res = isl_schedule_node_get_tree_depth(get());
-  return manage(res);
-}
-
-class size schedule_node::get_tree_depth() const
-{
-  return tree_depth();
-}
-
 isl::checked::schedule_node schedule_node::graft_after(isl::checked::schedule_node graft) const
 {
   auto res = isl_schedule_node_graft_after(copy(), graft.release());
@@ -9742,6 +15054,39 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
+{
+  auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const
+{
+  return prefix_schedule_multi_union_pw_aff();
+}
+
+isl::checked::union_map schedule_node::prefix_schedule_union_map() const
+{
+  auto res = isl_schedule_node_get_prefix_schedule_union_map(get());
+  return manage(res);
+}
+
+isl::checked::union_map schedule_node::get_prefix_schedule_union_map() const
+{
+  return prefix_schedule_union_map();
+}
+
+isl::checked::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
+{
+  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
+{
+  return prefix_schedule_union_pw_multi_aff();
+}
+
 isl::checked::schedule_node schedule_node::previous_sibling() const
 {
   auto res = isl_schedule_node_previous_sibling(copy());
@@ -9754,6 +15099,39 @@
   return manage(res);
 }
 
+isl::checked::schedule schedule_node::schedule() const
+{
+  auto res = isl_schedule_node_get_schedule(get());
+  return manage(res);
+}
+
+isl::checked::schedule schedule_node::get_schedule() const
+{
+  return schedule();
+}
+
+isl::checked::schedule_node schedule_node::shared_ancestor(const isl::checked::schedule_node &node2) const
+{
+  auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get());
+  return manage(res);
+}
+
+isl::checked::schedule_node schedule_node::get_shared_ancestor(const isl::checked::schedule_node &node2) const
+{
+  return shared_ancestor(node2);
+}
+
+class size schedule_node::tree_depth() const
+{
+  auto res = isl_schedule_node_get_tree_depth(get());
+  return manage(res);
+}
+
+class size schedule_node::get_tree_depth() const
+{
+  return tree_depth();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj)
 {
   char *str = isl_schedule_node_to_str(obj.get());
@@ -9809,28 +15187,6 @@
   return ast_isolate_option();
 }
 
-isl::checked::multi_union_pw_aff schedule_node_band::partial_schedule() const
-{
-  auto res = isl_schedule_node_band_get_partial_schedule(get());
-  return manage(res);
-}
-
-isl::checked::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
-{
-  return partial_schedule();
-}
-
-boolean schedule_node_band::permutable() const
-{
-  auto res = isl_schedule_node_band_get_permutable(get());
-  return manage(res);
-}
-
-boolean schedule_node_band::get_permutable() const
-{
-  return permutable();
-}
-
 boolean schedule_node_band::member_get_coincident(int pos) const
 {
   auto res = isl_schedule_node_band_member_get_coincident(get(), pos);
@@ -9855,6 +15211,28 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff schedule_node_band::partial_schedule() const
+{
+  auto res = isl_schedule_node_band_get_partial_schedule(get());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
+{
+  return partial_schedule();
+}
+
+boolean schedule_node_band::permutable() const
+{
+  auto res = isl_schedule_node_band_get_permutable(get());
+  return manage(res);
+}
+
+boolean schedule_node_band::get_permutable() const
+{
+  return permutable();
+}
+
 schedule_node_band schedule_node_band::scale(isl::checked::multi_val mv) const
 {
   auto res = isl_schedule_node_band_scale(copy(), mv.release());
@@ -10423,6 +15801,27 @@
   return manage(res);
 }
 
+isl::checked::union_set set::apply(const isl::checked::union_map &umap) const
+{
+  return isl::checked::union_set(*this).apply(umap);
+}
+
+isl::checked::set set::apply(const isl::checked::basic_map &map) const
+{
+  return this->apply(isl::checked::map(map));
+}
+
+isl::checked::pw_multi_aff set::as_pw_multi_aff() const
+{
+  auto res = isl_set_as_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::set set::as_set() const
+{
+  return isl::checked::union_set(*this).as_set();
+}
+
 isl::checked::set set::bind(isl::checked::multi_id tuple) const
 {
   auto res = isl_set_bind(copy(), tuple.release());
@@ -10441,6 +15840,11 @@
   return manage(res);
 }
 
+isl::checked::union_set set::compute_divs() const
+{
+  return isl::checked::union_set(*this).compute_divs();
+}
+
 isl::checked::set set::detect_equalities() const
 {
   auto res = isl_set_detect_equalities(copy());
@@ -10465,6 +15869,16 @@
   return manage(res);
 }
 
+boolean set::every_set(const std::function<boolean(isl::checked::set)> &test) const
+{
+  return isl::checked::union_set(*this).every_set(test);
+}
+
+isl::checked::set set::extract_set(const isl::checked::space &space) const
+{
+  return isl::checked::union_set(*this).extract_set(space);
+}
+
 isl::checked::set set::flatten() const
 {
   auto res = isl_set_flatten(copy());
@@ -10499,48 +15913,9 @@
   return manage(res);
 }
 
-isl::checked::multi_val set::plain_multi_val_if_fixed() const
+stat set::foreach_set(const std::function<stat(isl::checked::set)> &fn) const
 {
-  auto res = isl_set_get_plain_multi_val_if_fixed(get());
-  return manage(res);
-}
-
-isl::checked::multi_val set::get_plain_multi_val_if_fixed() const
-{
-  return plain_multi_val_if_fixed();
-}
-
-isl::checked::fixed_box set::simple_fixed_box_hull() const
-{
-  auto res = isl_set_get_simple_fixed_box_hull(get());
-  return manage(res);
-}
-
-isl::checked::fixed_box set::get_simple_fixed_box_hull() const
-{
-  return simple_fixed_box_hull();
-}
-
-isl::checked::space set::space() const
-{
-  auto res = isl_set_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space set::get_space() const
-{
-  return space();
-}
-
-isl::checked::val set::stride(int pos) const
-{
-  auto res = isl_set_get_stride(get(), pos);
-  return manage(res);
-}
-
-isl::checked::val set::get_stride(int pos) const
-{
-  return stride(pos);
+  return isl::checked::union_set(*this).foreach_set(fn);
 }
 
 isl::checked::set set::gist(isl::checked::set context) const
@@ -10549,6 +15924,26 @@
   return manage(res);
 }
 
+isl::checked::union_set set::gist(const isl::checked::union_set &context) const
+{
+  return isl::checked::union_set(*this).gist(context);
+}
+
+isl::checked::set set::gist(const isl::checked::basic_set &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+isl::checked::set set::gist(const isl::checked::point &context) const
+{
+  return this->gist(isl::checked::set(context));
+}
+
+isl::checked::union_set set::gist_params(const isl::checked::set &set) const
+{
+  return isl::checked::union_set(*this).gist_params(set);
+}
+
 isl::checked::map set::identity() const
 {
   auto res = isl_set_identity(copy());
@@ -10573,6 +15968,21 @@
   return manage(res);
 }
 
+isl::checked::union_set set::intersect(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).intersect(uset2);
+}
+
+isl::checked::set set::intersect(const isl::checked::basic_set &set2) const
+{
+  return this->intersect(isl::checked::set(set2));
+}
+
+isl::checked::set set::intersect(const isl::checked::point &set2) const
+{
+  return this->intersect(isl::checked::set(set2));
+}
+
 isl::checked::set set::intersect_params(isl::checked::set params) const
 {
   auto res = isl_set_intersect_params(copy(), params.release());
@@ -10591,6 +16001,21 @@
   return manage(res);
 }
 
+boolean set::is_disjoint(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).is_disjoint(uset2);
+}
+
+boolean set::is_disjoint(const isl::checked::basic_set &set2) const
+{
+  return this->is_disjoint(isl::checked::set(set2));
+}
+
+boolean set::is_disjoint(const isl::checked::point &set2) const
+{
+  return this->is_disjoint(isl::checked::set(set2));
+}
+
 boolean set::is_empty() const
 {
   auto res = isl_set_is_empty(get());
@@ -10603,6 +16028,21 @@
   return manage(res);
 }
 
+boolean set::is_equal(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).is_equal(uset2);
+}
+
+boolean set::is_equal(const isl::checked::basic_set &set2) const
+{
+  return this->is_equal(isl::checked::set(set2));
+}
+
+boolean set::is_equal(const isl::checked::point &set2) const
+{
+  return this->is_equal(isl::checked::set(set2));
+}
+
 boolean set::is_singleton() const
 {
   auto res = isl_set_is_singleton(get());
@@ -10615,18 +16055,53 @@
   return manage(res);
 }
 
+boolean set::is_strict_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).is_strict_subset(uset2);
+}
+
+boolean set::is_strict_subset(const isl::checked::basic_set &set2) const
+{
+  return this->is_strict_subset(isl::checked::set(set2));
+}
+
+boolean set::is_strict_subset(const isl::checked::point &set2) const
+{
+  return this->is_strict_subset(isl::checked::set(set2));
+}
+
 boolean set::is_subset(const isl::checked::set &set2) const
 {
   auto res = isl_set_is_subset(get(), set2.get());
   return manage(res);
 }
 
+boolean set::is_subset(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).is_subset(uset2);
+}
+
+boolean set::is_subset(const isl::checked::basic_set &set2) const
+{
+  return this->is_subset(isl::checked::set(set2));
+}
+
+boolean set::is_subset(const isl::checked::point &set2) const
+{
+  return this->is_subset(isl::checked::set(set2));
+}
+
 boolean set::is_wrapping() const
 {
   auto res = isl_set_is_wrapping(get());
   return manage(res);
 }
 
+boolean set::isa_set() const
+{
+  return isl::checked::union_set(*this).isa_set();
+}
+
 isl::checked::set set::lexmax() const
 {
   auto res = isl_set_lexmax(copy());
@@ -10693,6 +16168,17 @@
   return manage(res);
 }
 
+isl::checked::multi_val set::plain_multi_val_if_fixed() const
+{
+  auto res = isl_set_get_plain_multi_val_if_fixed(get());
+  return manage(res);
+}
+
+isl::checked::multi_val set::get_plain_multi_val_if_fixed() const
+{
+  return plain_multi_val_if_fixed();
+}
+
 isl::checked::basic_set set::polyhedral_hull() const
 {
   auto res = isl_set_polyhedral_hull(copy());
@@ -10717,6 +16203,11 @@
   return manage(res);
 }
 
+isl::checked::union_set set::preimage(const isl::checked::union_pw_multi_aff &upma) const
+{
+  return isl::checked::union_set(*this).preimage(upma);
+}
+
 isl::checked::set set::product(isl::checked::set set2) const
 {
   auto res = isl_set_product(copy(), set2.release());
@@ -10746,6 +16237,12 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff set::pw_multi_aff_on_domain(isl::checked::multi_val mv) const
+{
+  auto res = isl_set_pw_multi_aff_on_domain_multi_val(copy(), mv.release());
+  return manage(res);
+}
+
 isl::checked::basic_set set::sample() const
 {
   auto res = isl_set_sample(copy());
@@ -10758,18 +16255,83 @@
   return manage(res);
 }
 
+isl::checked::fixed_box set::simple_fixed_box_hull() const
+{
+  auto res = isl_set_get_simple_fixed_box_hull(get());
+  return manage(res);
+}
+
+isl::checked::fixed_box set::get_simple_fixed_box_hull() const
+{
+  return simple_fixed_box_hull();
+}
+
+isl::checked::space set::space() const
+{
+  auto res = isl_set_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space set::get_space() const
+{
+  return space();
+}
+
+isl::checked::val set::stride(int pos) const
+{
+  auto res = isl_set_get_stride(get(), pos);
+  return manage(res);
+}
+
+isl::checked::val set::get_stride(int pos) const
+{
+  return stride(pos);
+}
+
 isl::checked::set set::subtract(isl::checked::set set2) const
 {
   auto res = isl_set_subtract(copy(), set2.release());
   return manage(res);
 }
 
+isl::checked::union_set set::subtract(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).subtract(uset2);
+}
+
+isl::checked::set set::subtract(const isl::checked::basic_set &set2) const
+{
+  return this->subtract(isl::checked::set(set2));
+}
+
+isl::checked::set set::subtract(const isl::checked::point &set2) const
+{
+  return this->subtract(isl::checked::set(set2));
+}
+
+isl::checked::union_set_list set::to_list() const
+{
+  return isl::checked::union_set(*this).to_list();
+}
+
+isl::checked::union_set set::to_union_set() const
+{
+  auto res = isl_set_to_union_set(copy());
+  return manage(res);
+}
+
 isl::checked::map set::translation() const
 {
   auto res = isl_set_translation(copy());
   return manage(res);
 }
 
+class size set::tuple_dim() const
+{
+  auto res = isl_set_tuple_dim(get());
+  return manage(res);
+}
+
 isl::checked::set set::unbind_params(isl::checked::multi_id tuple) const
 {
   auto res = isl_set_unbind_params(copy(), tuple.release());
@@ -10788,6 +16350,21 @@
   return manage(res);
 }
 
+isl::checked::union_set set::unite(const isl::checked::union_set &uset2) const
+{
+  return isl::checked::union_set(*this).unite(uset2);
+}
+
+isl::checked::set set::unite(const isl::checked::basic_set &set2) const
+{
+  return this->unite(isl::checked::set(set2));
+}
+
+isl::checked::set set::unite(const isl::checked::point &set2) const
+{
+  return this->unite(isl::checked::set(set2));
+}
+
 isl::checked::set set::universe(isl::checked::space space)
 {
   auto res = isl_set_universe(space.release());
@@ -10894,6 +16471,17 @@
   return this->add_named_tuple(isl::checked::id(ctx(), tuple_id), dim);
 }
 
+isl::checked::space space::add_param(isl::checked::id id) const
+{
+  auto res = isl_space_add_param_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::space space::add_param(const std::string &id) const
+{
+  return this->add_param(isl::checked::id(ctx(), id));
+}
+
 isl::checked::space space::add_unnamed_tuple(unsigned int dim) const
 {
   auto res = isl_space_add_unnamed_tuple_ui(copy(), dim);
@@ -10912,6 +16500,29 @@
   return manage(res);
 }
 
+isl::checked::multi_aff space::domain_map_multi_aff() const
+{
+  auto res = isl_space_domain_map_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff space::domain_map_pw_multi_aff() const
+{
+  auto res = isl_space_domain_map_pw_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::id space::domain_tuple_id() const
+{
+  auto res = isl_space_get_domain_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id space::get_domain_tuple_id() const
+{
+  return domain_tuple_id();
+}
+
 isl::checked::space space::flatten_domain() const
 {
   auto res = isl_space_flatten_domain(copy());
@@ -10924,6 +16535,36 @@
   return manage(res);
 }
 
+boolean space::has_domain_tuple_id() const
+{
+  auto res = isl_space_has_domain_tuple_id(get());
+  return manage(res);
+}
+
+boolean space::has_range_tuple_id() const
+{
+  auto res = isl_space_has_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::multi_aff space::identity_multi_aff_on_domain() const
+{
+  auto res = isl_space_identity_multi_aff_on_domain(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff space::identity_multi_pw_aff_on_domain() const
+{
+  auto res = isl_space_identity_multi_pw_aff_on_domain(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff space::identity_pw_multi_aff_on_domain() const
+{
+  auto res = isl_space_identity_pw_multi_aff_on_domain(copy());
+  return manage(res);
+}
+
 boolean space::is_equal(const isl::checked::space &space2) const
 {
   auto res = isl_space_is_equal(get(), space2.get());
@@ -10942,6 +16583,53 @@
   return manage(res);
 }
 
+isl::checked::multi_aff space::multi_aff(isl::checked::aff_list list) const
+{
+  auto res = isl_space_multi_aff(copy(), list.release());
+  return manage(res);
+}
+
+isl::checked::multi_aff space::multi_aff_on_domain(isl::checked::multi_val mv) const
+{
+  auto res = isl_space_multi_aff_on_domain_multi_val(copy(), mv.release());
+  return manage(res);
+}
+
+isl::checked::multi_id space::multi_id(isl::checked::id_list list) const
+{
+  auto res = isl_space_multi_id(copy(), list.release());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff space::multi_pw_aff(isl::checked::pw_aff_list list) const
+{
+  auto res = isl_space_multi_pw_aff(copy(), list.release());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff space::multi_union_pw_aff(isl::checked::union_pw_aff_list list) const
+{
+  auto res = isl_space_multi_union_pw_aff(copy(), list.release());
+  return manage(res);
+}
+
+isl::checked::multi_val space::multi_val(isl::checked::val_list list) const
+{
+  auto res = isl_space_multi_val(copy(), list.release());
+  return manage(res);
+}
+
+isl::checked::aff space::param_aff_on_domain(isl::checked::id id) const
+{
+  auto res = isl_space_param_aff_on_domain_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::aff space::param_aff_on_domain(const std::string &id) const
+{
+  return this->param_aff_on_domain(isl::checked::id(ctx(), id));
+}
+
 isl::checked::space space::params() const
 {
   auto res = isl_space_params(copy());
@@ -10960,18 +16648,63 @@
   return manage(res);
 }
 
+isl::checked::multi_aff space::range_map_multi_aff() const
+{
+  auto res = isl_space_range_map_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff space::range_map_pw_multi_aff() const
+{
+  auto res = isl_space_range_map_pw_multi_aff(copy());
+  return manage(res);
+}
+
 isl::checked::space space::range_reverse() const
 {
   auto res = isl_space_range_reverse(copy());
   return manage(res);
 }
 
+isl::checked::id space::range_tuple_id() const
+{
+  auto res = isl_space_get_range_tuple_id(get());
+  return manage(res);
+}
+
+isl::checked::id space::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
 isl::checked::space space::reverse() const
 {
   auto res = isl_space_reverse(copy());
   return manage(res);
 }
 
+isl::checked::space space::set_domain_tuple(isl::checked::id id) const
+{
+  auto res = isl_space_set_domain_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::space space::set_domain_tuple(const std::string &id) const
+{
+  return this->set_domain_tuple(isl::checked::id(ctx(), id));
+}
+
+isl::checked::space space::set_range_tuple(isl::checked::id id) const
+{
+  auto res = isl_space_set_range_tuple_id(copy(), id.release());
+  return manage(res);
+}
+
+isl::checked::space space::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
 isl::checked::space space::uncurry() const
 {
   auto res = isl_space_uncurry(copy());
@@ -10984,6 +16717,18 @@
   return manage(res);
 }
 
+isl::checked::map space::universe_map() const
+{
+  auto res = isl_space_universe_map(copy());
+  return manage(res);
+}
+
+isl::checked::set space::universe_set() const
+{
+  auto res = isl_space_universe_set(copy());
+  return manage(res);
+}
+
 isl::checked::space space::unwrap() const
 {
   auto res = isl_space_unwrap(copy());
@@ -10996,6 +16741,36 @@
   return manage(res);
 }
 
+isl::checked::aff space::zero_aff_on_domain() const
+{
+  auto res = isl_space_zero_aff_on_domain(copy());
+  return manage(res);
+}
+
+isl::checked::multi_aff space::zero_multi_aff() const
+{
+  auto res = isl_space_zero_multi_aff(copy());
+  return manage(res);
+}
+
+isl::checked::multi_pw_aff space::zero_multi_pw_aff() const
+{
+  auto res = isl_space_zero_multi_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff space::zero_multi_union_pw_aff() const
+{
+  auto res = isl_space_zero_multi_union_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::multi_val space::zero_multi_val() const
+{
+  auto res = isl_space_zero_multi_val(copy());
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const space &obj)
 {
   char *str = isl_space_to_str(obj.get());
@@ -11335,6 +17110,24 @@
   return manage(res);
 }
 
+isl::checked::map union_map::as_map() const
+{
+  auto res = isl_union_map_as_map(copy());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff union_map::as_multi_union_pw_aff() const
+{
+  auto res = isl_union_map_as_multi_union_pw_aff(copy());
+  return manage(res);
+}
+
+isl::checked::union_pw_multi_aff union_map::as_union_pw_multi_aff() const
+{
+  auto res = isl_union_map_as_union_pw_multi_aff(copy());
+  return manage(res);
+}
+
 isl::checked::union_set union_map::bind_range(isl::checked::multi_id tuple) const
 {
   auto res = isl_union_map_bind_range(copy(), tuple.release());
@@ -11506,17 +17299,6 @@
   return manage(res);
 }
 
-isl::checked::space union_map::space() const
-{
-  auto res = isl_union_map_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space union_map::get_space() const
-{
-  return space();
-}
-
 isl::checked::union_map union_map::gist(isl::checked::union_map context) const
 {
   auto res = isl_union_map_gist(copy(), context.release());
@@ -11667,6 +17449,17 @@
   return manage(res);
 }
 
+isl::checked::map_list union_map::map_list() const
+{
+  auto res = isl_union_map_get_map_list(get());
+  return manage(res);
+}
+
+isl::checked::map_list union_map::get_map_list() const
+{
+  return map_list();
+}
+
 isl::checked::union_map union_map::polyhedral_hull() const
 {
   auto res = isl_union_map_polyhedral_hull(copy());
@@ -11769,6 +17562,17 @@
   return manage(res);
 }
 
+isl::checked::space union_map::space() const
+{
+  auto res = isl_union_map_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space union_map::get_space() const
+{
+  return space();
+}
+
 isl::checked::union_map union_map::subtract(isl::checked::union_map umap2) const
 {
   auto res = isl_union_map_subtract(copy(), umap2.release());
@@ -11900,12 +17704,62 @@
   return isl::checked::ctx(isl_union_pw_aff_get_ctx(ptr));
 }
 
+isl::checked::multi_union_pw_aff union_pw_aff::add(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).add(multi2);
+}
+
 isl::checked::union_pw_aff union_pw_aff::add(isl::checked::union_pw_aff upa2) const
 {
   auto res = isl_union_pw_aff_add(copy(), upa2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff union_pw_aff::add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).add(upma2);
+}
+
+isl::checked::union_pw_aff union_pw_aff::add(const isl::checked::aff &upa2) const
+{
+  return this->add(isl::checked::union_pw_aff(upa2));
+}
+
+isl::checked::union_pw_aff union_pw_aff::add(const isl::checked::pw_aff &upa2) const
+{
+  return this->add(isl::checked::union_pw_aff(upa2));
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::apply(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).apply(upma2);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::as_multi_union_pw_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::checked::pw_multi_aff union_pw_aff::as_pw_multi_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::checked::union_map union_pw_aff::as_union_map() const
+{
+  return isl::checked::union_pw_multi_aff(*this).as_union_map();
+}
+
+isl::checked::union_pw_aff union_pw_aff::at(int pos) const
+{
+  return isl::checked::multi_union_pw_aff(*this).at(pos);
+}
+
+isl::checked::union_set union_pw_aff::bind(const isl::checked::multi_id &tuple) const
+{
+  return isl::checked::multi_union_pw_aff(*this).bind(tuple);
+}
+
 isl::checked::union_set union_pw_aff::bind(isl::checked::id id) const
 {
   auto res = isl_union_pw_aff_bind_id(copy(), id.release());
@@ -11929,15 +17783,19 @@
   return manage(res);
 }
 
-isl::checked::space union_pw_aff::space() const
+isl::checked::pw_multi_aff union_pw_aff::extract_pw_multi_aff(const isl::checked::space &space) const
 {
-  auto res = isl_union_pw_aff_get_space(get());
-  return manage(res);
+  return isl::checked::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::checked::space union_pw_aff::get_space() const
+isl::checked::multi_union_pw_aff union_pw_aff::flat_range_product(const isl::checked::multi_union_pw_aff &multi2) const
 {
-  return space();
+  return isl::checked::multi_union_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::flat_range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).flat_range_product(upma2);
 }
 
 isl::checked::union_pw_aff union_pw_aff::gist(isl::checked::union_set context) const
@@ -11946,6 +17804,11 @@
   return manage(res);
 }
 
+boolean union_pw_aff::has_range_tuple_id() const
+{
+  return isl::checked::multi_union_pw_aff(*this).has_range_tuple_id();
+}
+
 isl::checked::union_pw_aff union_pw_aff::intersect_domain(isl::checked::space space) const
 {
   auto res = isl_union_pw_aff_intersect_domain_space(copy(), space.release());
@@ -11976,18 +17839,174 @@
   return manage(res);
 }
 
+boolean union_pw_aff::involves_locals() const
+{
+  return isl::checked::union_pw_multi_aff(*this).involves_locals();
+}
+
+boolean union_pw_aff::involves_nan() const
+{
+  return isl::checked::multi_union_pw_aff(*this).involves_nan();
+}
+
+boolean union_pw_aff::isa_pw_multi_aff() const
+{
+  return isl::checked::union_pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::checked::union_pw_aff_list union_pw_aff::list() const
+{
+  return isl::checked::multi_union_pw_aff(*this).list();
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::neg() const
+{
+  return isl::checked::multi_union_pw_aff(*this).neg();
+}
+
+boolean union_pw_aff::plain_is_empty() const
+{
+  return isl::checked::union_pw_multi_aff(*this).plain_is_empty();
+}
+
+boolean union_pw_aff::plain_is_equal(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::preimage_domain_wrapped_domain(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
 isl::checked::union_pw_aff union_pw_aff::pullback(isl::checked::union_pw_multi_aff upma) const
 {
   auto res = isl_union_pw_aff_pullback_union_pw_multi_aff(copy(), upma.release());
   return manage(res);
 }
 
+isl::checked::pw_multi_aff_list union_pw_aff::pw_multi_aff_list() const
+{
+  return isl::checked::union_pw_multi_aff(*this).pw_multi_aff_list();
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::range_factor_domain() const
+{
+  return isl::checked::union_pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::range_factor_range() const
+{
+  return isl::checked::union_pw_multi_aff(*this).range_factor_range();
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::range_product(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).range_product(multi2);
+}
+
+isl::checked::union_pw_multi_aff union_pw_aff::range_product(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::checked::id union_pw_aff::range_tuple_id() const
+{
+  return isl::checked::multi_union_pw_aff(*this).range_tuple_id();
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::reset_range_tuple_id() const
+{
+  return isl::checked::multi_union_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_union_pw_aff(*this).scale(mv);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale(const isl::checked::val &v) const
+{
+  return isl::checked::multi_union_pw_aff(*this).scale(v);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale(long v) const
+{
+  return this->scale(isl::checked::val(ctx(), v));
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale_down(const isl::checked::multi_val &mv) const
+{
+  return isl::checked::multi_union_pw_aff(*this).scale_down(mv);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale_down(const isl::checked::val &v) const
+{
+  return isl::checked::multi_union_pw_aff(*this).scale_down(v);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::scale_down(long v) const
+{
+  return this->scale_down(isl::checked::val(ctx(), v));
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::checked::union_pw_aff &el) const
+{
+  return isl::checked::multi_union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const isl::checked::id &id) const
+{
+  return isl::checked::multi_union_pw_aff(*this).set_range_tuple(id);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::set_range_tuple(const std::string &id) const
+{
+  return this->set_range_tuple(isl::checked::id(ctx(), id));
+}
+
+class size union_pw_aff::size() const
+{
+  return isl::checked::multi_union_pw_aff(*this).size();
+}
+
+isl::checked::space union_pw_aff::space() const
+{
+  auto res = isl_union_pw_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space union_pw_aff::get_space() const
+{
+  return space();
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::sub(const isl::checked::multi_union_pw_aff &multi2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).sub(multi2);
+}
+
 isl::checked::union_pw_aff union_pw_aff::sub(isl::checked::union_pw_aff upa2) const
 {
   auto res = isl_union_pw_aff_sub(copy(), upa2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff union_pw_aff::sub(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).sub(upma2);
+}
+
+isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::aff &upa2) const
+{
+  return this->sub(isl::checked::union_pw_aff(upa2));
+}
+
+isl::checked::union_pw_aff union_pw_aff::sub(const isl::checked::pw_aff &upa2) const
+{
+  return this->sub(isl::checked::union_pw_aff(upa2));
+}
+
 isl::checked::union_pw_aff union_pw_aff::subtract_domain(isl::checked::space space) const
 {
   auto res = isl_union_pw_aff_subtract_domain_space(copy(), space.release());
@@ -12000,12 +18019,38 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff_list union_pw_aff::to_list() const
+{
+  auto res = isl_union_pw_aff_to_list(copy());
+  return manage(res);
+}
+
+isl::checked::multi_union_pw_aff union_pw_aff::union_add(const isl::checked::multi_union_pw_aff &mupa2) const
+{
+  return isl::checked::multi_union_pw_aff(*this).union_add(mupa2);
+}
+
 isl::checked::union_pw_aff union_pw_aff::union_add(isl::checked::union_pw_aff upa2) const
 {
   auto res = isl_union_pw_aff_union_add(copy(), upa2.release());
   return manage(res);
 }
 
+isl::checked::union_pw_multi_aff union_pw_aff::union_add(const isl::checked::union_pw_multi_aff &upma2) const
+{
+  return isl::checked::union_pw_multi_aff(*this).union_add(upma2);
+}
+
+isl::checked::union_pw_aff union_pw_aff::union_add(const isl::checked::aff &upa2) const
+{
+  return this->union_add(isl::checked::union_pw_aff(upa2));
+}
+
+isl::checked::union_pw_aff union_pw_aff::union_add(const isl::checked::pw_aff &upa2) const
+{
+  return this->union_add(isl::checked::union_pw_aff(upa2));
+}
+
 inline std::ostream &operator<<(std::ostream &os, const union_pw_aff &obj)
 {
   char *str = isl_union_pw_aff_to_str(obj.get());
@@ -12051,6 +18096,12 @@
   ptr = res;
 }
 
+union_pw_aff_list::union_pw_aff_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_union_pw_aff_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 union_pw_aff_list &union_pw_aff_list::operator=(union_pw_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -12089,6 +18140,17 @@
   return manage(res);
 }
 
+isl::checked::union_pw_aff union_pw_aff_list::at(int index) const
+{
+  auto res = isl_union_pw_aff_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::union_pw_aff union_pw_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::union_pw_aff_list union_pw_aff_list::clear() const
 {
   auto res = isl_union_pw_aff_list_clear(copy());
@@ -12121,17 +18183,6 @@
   return manage(res);
 }
 
-isl::checked::union_pw_aff union_pw_aff_list::at(int index) const
-{
-  auto res = isl_union_pw_aff_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::union_pw_aff union_pw_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::union_pw_aff_list union_pw_aff_list::insert(unsigned int pos, isl::checked::union_pw_aff el) const
 {
   auto res = isl_union_pw_aff_list_insert(copy(), pos, el.release());
@@ -12245,12 +18296,24 @@
   return manage(res);
 }
 
+isl::checked::multi_union_pw_aff union_pw_multi_aff::as_multi_union_pw_aff() const
+{
+  auto res = isl_union_pw_multi_aff_as_multi_union_pw_aff(copy());
+  return manage(res);
+}
+
 isl::checked::pw_multi_aff union_pw_multi_aff::as_pw_multi_aff() const
 {
   auto res = isl_union_pw_multi_aff_as_pw_multi_aff(copy());
   return manage(res);
 }
 
+isl::checked::union_map union_pw_multi_aff::as_union_map() const
+{
+  auto res = isl_union_pw_multi_aff_as_union_map(copy());
+  return manage(res);
+}
+
 isl::checked::union_pw_multi_aff union_pw_multi_aff::coalesce() const
 {
   auto res = isl_union_pw_multi_aff_coalesce(copy());
@@ -12281,17 +18344,6 @@
   return manage(res);
 }
 
-isl::checked::space union_pw_multi_aff::space() const
-{
-  auto res = isl_union_pw_multi_aff_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space union_pw_multi_aff::get_space() const
-{
-  return space();
-}
-
 isl::checked::union_pw_multi_aff union_pw_multi_aff::gist(isl::checked::union_set context) const
 {
   auto res = isl_union_pw_multi_aff_gist(copy(), context.release());
@@ -12358,6 +18410,17 @@
   return manage(res);
 }
 
+isl::checked::pw_multi_aff_list union_pw_multi_aff::pw_multi_aff_list() const
+{
+  auto res = isl_union_pw_multi_aff_get_pw_multi_aff_list(get());
+  return manage(res);
+}
+
+isl::checked::pw_multi_aff_list union_pw_multi_aff::get_pw_multi_aff_list() const
+{
+  return pw_multi_aff_list();
+}
+
 isl::checked::union_pw_multi_aff union_pw_multi_aff::range_factor_domain() const
 {
   auto res = isl_union_pw_multi_aff_range_factor_domain(copy());
@@ -12376,6 +18439,17 @@
   return manage(res);
 }
 
+isl::checked::space union_pw_multi_aff::space() const
+{
+  auto res = isl_union_pw_multi_aff_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space union_pw_multi_aff::get_space() const
+{
+  return space();
+}
+
 isl::checked::union_pw_multi_aff union_pw_multi_aff::sub(isl::checked::union_pw_multi_aff upma2) const
 {
   auto res = isl_union_pw_multi_aff_sub(copy(), upma2.release());
@@ -12501,6 +18575,12 @@
   return manage(res);
 }
 
+isl::checked::set union_set::as_set() const
+{
+  auto res = isl_union_set_as_set(copy());
+  return manage(res);
+}
+
 isl::checked::union_set union_set::coalesce() const
 {
   auto res = isl_union_set_coalesce(copy());
@@ -12573,17 +18653,6 @@
   return manage(res);
 }
 
-isl::checked::space union_set::space() const
-{
-  auto res = isl_union_set_get_space(get());
-  return manage(res);
-}
-
-isl::checked::space union_set::get_space() const
-{
-  return space();
-}
-
 isl::checked::union_set union_set::gist(isl::checked::union_set context) const
 {
   auto res = isl_union_set_gist(copy(), context.release());
@@ -12692,12 +18761,29 @@
   return manage(res);
 }
 
+isl::checked::space union_set::space() const
+{
+  auto res = isl_union_set_get_space(get());
+  return manage(res);
+}
+
+isl::checked::space union_set::get_space() const
+{
+  return space();
+}
+
 isl::checked::union_set union_set::subtract(isl::checked::union_set uset2) const
 {
   auto res = isl_union_set_subtract(copy(), uset2.release());
   return manage(res);
 }
 
+isl::checked::union_set_list union_set::to_list() const
+{
+  auto res = isl_union_set_to_list(copy());
+  return manage(res);
+}
+
 isl::checked::union_set union_set::unite(isl::checked::union_set uset2) const
 {
   auto res = isl_union_set_union(copy(), uset2.release());
@@ -12761,6 +18847,12 @@
   ptr = res;
 }
 
+union_set_list::union_set_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_union_set_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 union_set_list &union_set_list::operator=(union_set_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -12799,6 +18891,17 @@
   return manage(res);
 }
 
+isl::checked::union_set union_set_list::at(int index) const
+{
+  auto res = isl_union_set_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::union_set union_set_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::union_set_list union_set_list::clear() const
 {
   auto res = isl_union_set_list_clear(copy());
@@ -12831,17 +18934,6 @@
   return manage(res);
 }
 
-isl::checked::union_set union_set_list::at(int index) const
-{
-  auto res = isl_union_set_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::union_set union_set_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::union_set_list union_set_list::insert(unsigned int pos, isl::checked::union_set el) const
 {
   auto res = isl_union_set_list_insert(copy(), pos, el.release());
@@ -12971,6 +19063,17 @@
   return res;
 }
 
+long val::den_si() const
+{
+  auto res = isl_val_get_den_si(get());
+  return res;
+}
+
+long val::get_den_si() const
+{
+  return den_si();
+}
+
 isl::checked::val val::div(isl::checked::val v2) const
 {
   auto res = isl_val_div(copy(), v2.release());
@@ -13021,28 +19124,6 @@
   return this->ge(isl::checked::val(ctx(), v2));
 }
 
-long val::den_si() const
-{
-  auto res = isl_val_get_den_si(get());
-  return res;
-}
-
-long val::get_den_si() const
-{
-  return den_si();
-}
-
-long val::num_si() const
-{
-  auto res = isl_val_get_num_si(get());
-  return res;
-}
-
-long val::get_num_si() const
-{
-  return num_si();
-}
-
 boolean val::gt(const isl::checked::val &v2) const
 {
   auto res = isl_val_gt(get(), v2.get());
@@ -13250,6 +19331,17 @@
   return manage(res);
 }
 
+long val::num_si() const
+{
+  auto res = isl_val_get_num_si(get());
+  return res;
+}
+
+long val::get_num_si() const
+{
+  return num_si();
+}
+
 isl::checked::val val::one(isl::checked::ctx ctx)
 {
   auto res = isl_val_one(ctx.release());
@@ -13279,6 +19371,12 @@
   return this->sub(isl::checked::val(ctx(), v2));
 }
 
+isl::checked::val_list val::to_list() const
+{
+  auto res = isl_val_to_list(copy());
+  return manage(res);
+}
+
 isl::checked::val val::trunc() const
 {
   auto res = isl_val_trunc(copy());
@@ -13336,6 +19434,12 @@
   ptr = res;
 }
 
+val_list::val_list(isl::checked::ctx ctx, const std::string &str)
+{
+  auto res = isl_val_list_read_from_str(ctx.release(), str.c_str());
+  ptr = res;
+}
+
 val_list &val_list::operator=(val_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -13379,6 +19483,17 @@
   return this->add(isl::checked::val(ctx(), el));
 }
 
+isl::checked::val val_list::at(int index) const
+{
+  auto res = isl_val_list_get_at(get(), index);
+  return manage(res);
+}
+
+isl::checked::val val_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::checked::val_list val_list::clear() const
 {
   auto res = isl_val_list_clear(copy());
@@ -13411,17 +19526,6 @@
   return manage(res);
 }
 
-isl::checked::val val_list::at(int index) const
-{
-  auto res = isl_val_list_get_at(get(), index);
-  return manage(res);
-}
-
-isl::checked::val val_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::checked::val_list val_list::insert(unsigned int pos, isl::checked::val el) const
 {
   auto res = isl_val_list_insert(copy(), pos, el.release());
diff --git a/lib/External/isl/include/isl/cpp.h b/lib/External/isl/include/isl/cpp.h
index 147cc05..f47b12a 100644
--- a/lib/External/isl/include/isl/cpp.h
+++ b/lib/External/isl/include/isl/cpp.h
@@ -8,21 +8,6 @@
 #ifndef ISL_CPP
 #define ISL_CPP
 
-#include <isl/id.h>
-#include <isl/space.h>
-#include <isl/val.h>
-#include <isl/aff.h>
-#include <isl/set.h>
-#include <isl/map.h>
-#include <isl/ilp.h>
-#include <isl/union_set.h>
-#include <isl/union_map.h>
-#include <isl/flow.h>
-#include <isl/schedule.h>
-#include <isl/schedule_node.h>
-#include <isl/ast_build.h>
-#include <isl/fixed_box.h>
-
 #include <isl/ctx.h>
 #include <isl/options.h>
 
@@ -269,6 +254,21 @@
 
 } // namespace isl
 
+#include <isl/id.h>
+#include <isl/space.h>
+#include <isl/val.h>
+#include <isl/aff.h>
+#include <isl/set.h>
+#include <isl/map.h>
+#include <isl/ilp.h>
+#include <isl/union_set.h>
+#include <isl/union_map.h>
+#include <isl/flow.h>
+#include <isl/schedule.h>
+#include <isl/schedule_node.h>
+#include <isl/ast_build.h>
+#include <isl/fixed_box.h>
+
 namespace isl {
 
 // forward declarations
@@ -318,6 +318,7 @@
 class id;
 class id_list;
 class map;
+class map_list;
 class multi_aff;
 class multi_id;
 class multi_pw_aff;
@@ -382,35 +383,158 @@
   inline isl::ctx ctx() const;
 
   inline isl::aff add(isl::aff aff2) const;
+  inline isl::multi_aff add(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_aff add(const isl::pw_aff &pwaff2) const;
+  inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff add(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const;
   inline isl::aff add_constant(isl::val v) const;
   inline isl::aff add_constant(long v) const;
+  inline isl::multi_aff add_constant(const isl::multi_val &mv) const;
+  inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::aff as_aff() const;
+  inline isl::map as_map() const;
+  inline isl::multi_aff as_multi_aff() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::union_map as_union_map() const;
+  inline isl::aff at(int pos) const;
   inline isl::basic_set bind(isl::id id) const;
   inline isl::basic_set bind(const std::string &id) const;
+  inline isl::basic_set bind(const isl::multi_id &tuple) const;
+  inline isl::pw_aff bind_domain(const isl::multi_id &tuple) const;
+  inline isl::pw_aff bind_domain_wrapped_domain(const isl::multi_id &tuple) const;
   inline isl::aff ceil() const;
-  inline isl::aff div(isl::aff aff2) const;
-  inline isl::set eq_set(isl::aff aff2) const;
-  inline isl::val eval(isl::point pnt) const;
-  inline isl::aff floor() const;
-  inline isl::set ge_set(isl::aff aff2) const;
+  inline isl::pw_aff coalesce() const;
+  inline isl::pw_aff cond(const isl::pw_aff &pwaff_true, const isl::pw_aff &pwaff_false) const;
+  inline isl::multi_val constant_multi_val() const;
   inline isl::val constant_val() const;
   inline isl::val get_constant_val() const;
+  inline isl::aff div(isl::aff aff2) const;
+  inline isl::pw_aff div(const isl::pw_aff &pa2) const;
+  inline isl::set domain() const;
+  inline isl::set eq_set(isl::aff aff2) const;
+  inline isl::set eq_set(const isl::pw_aff &pwaff2) const;
+  inline isl::val eval(isl::point pnt) const;
+  inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const;
+  inline isl::multi_aff flat_range_product(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::aff floor() const;
+  inline void foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const;
+  inline isl::set ge_set(isl::aff aff2) const;
+  inline isl::set ge_set(const isl::pw_aff &pwaff2) const;
   inline isl::aff gist(isl::set context) const;
+  inline isl::union_pw_aff gist(const isl::union_set &context) const;
+  inline isl::aff gist(const isl::basic_set &context) const;
+  inline isl::aff gist(const isl::point &context) const;
   inline isl::set gt_set(isl::aff aff2) const;
+  inline isl::set gt_set(const isl::pw_aff &pwaff2) const;
+  inline bool has_range_tuple_id() const;
+  inline isl::multi_aff identity() const;
+  inline isl::pw_aff insert_domain(const isl::space &domain) const;
+  inline isl::pw_aff intersect_domain(const isl::set &set) const;
+  inline isl::union_pw_aff intersect_domain(const isl::space &space) const;
+  inline isl::union_pw_aff intersect_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_aff intersect_domain_wrapped_range(const isl::union_set &uset) const;
+  inline isl::pw_aff intersect_params(const isl::set &set) const;
+  inline bool involves_locals() const;
+  inline bool involves_nan() const;
+  inline bool involves_param(const isl::id &id) const;
+  inline bool involves_param(const std::string &id) const;
+  inline bool involves_param(const isl::id_list &list) const;
   inline bool is_cst() const;
+  inline bool isa_aff() const;
+  inline bool isa_multi_aff() const;
+  inline bool isa_pw_multi_aff() const;
   inline isl::set le_set(isl::aff aff2) const;
+  inline isl::set le_set(const isl::pw_aff &pwaff2) const;
+  inline isl::aff_list list() const;
   inline isl::set lt_set(isl::aff aff2) const;
+  inline isl::set lt_set(const isl::pw_aff &pwaff2) const;
+  inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const;
+  inline isl::pw_aff max(const isl::pw_aff &pwaff2) const;
+  inline isl::multi_val max_multi_val() const;
+  inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const;
+  inline isl::pw_aff min(const isl::pw_aff &pwaff2) const;
+  inline isl::multi_val min_multi_val() const;
   inline isl::aff mod(isl::val mod) const;
   inline isl::aff mod(long mod) const;
   inline isl::aff mul(isl::aff aff2) const;
+  inline isl::pw_aff mul(const isl::pw_aff &pwaff2) const;
+  inline unsigned n_piece() const;
   inline isl::set ne_set(isl::aff aff2) const;
+  inline isl::set ne_set(const isl::pw_aff &pwaff2) const;
   inline isl::aff neg() const;
+  inline bool plain_is_empty() const;
+  inline bool plain_is_equal(const isl::multi_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff product(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const;
+  inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const;
   inline isl::aff pullback(isl::multi_aff ma) const;
+  inline isl::pw_aff pullback(const isl::multi_pw_aff &mpa) const;
+  inline isl::pw_aff pullback(const isl::pw_multi_aff &pma) const;
+  inline isl::union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const;
+  inline isl::aff pullback(const isl::aff &ma) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::pw_multi_aff range_factor_domain() const;
+  inline isl::pw_multi_aff range_factor_range() const;
+  inline isl::multi_aff range_product(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::multi_aff reset_range_tuple_id() const;
   inline isl::aff scale(isl::val v) const;
   inline isl::aff scale(long v) const;
+  inline isl::multi_aff scale(const isl::multi_val &mv) const;
   inline isl::aff scale_down(isl::val v) const;
   inline isl::aff scale_down(long v) const;
+  inline isl::multi_aff scale_down(const isl::multi_val &mv) const;
+  inline isl::multi_aff set_at(int pos, const isl::aff &el) const;
+  inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::multi_aff set_range_tuple(const isl::id &id) const;
+  inline isl::multi_aff set_range_tuple(const std::string &id) const;
+  inline unsigned size() const;
+  inline isl::space space() const;
   inline isl::aff sub(isl::aff aff2) const;
+  inline isl::multi_aff sub(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_aff sub(const isl::pw_aff &pwaff2) const;
+  inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff sub(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_aff subtract_domain(const isl::set &set) const;
+  inline isl::union_pw_aff subtract_domain(const isl::space &space) const;
+  inline isl::union_pw_aff subtract_domain(const isl::union_set &uset) const;
+  inline isl::pw_aff tdiv_q(const isl::pw_aff &pa2) const;
+  inline isl::pw_aff tdiv_r(const isl::pw_aff &pa2) const;
+  inline isl::aff_list to_list() const;
+  inline isl::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::multi_union_pw_aff to_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff to_pw_multi_aff() const;
+  inline isl::union_pw_aff to_union_pw_aff() const;
+  inline isl::union_pw_multi_aff to_union_pw_multi_aff() const;
   inline isl::aff unbind_params_insert_domain(isl::multi_id domain) const;
+  inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
+  inline isl::pw_aff union_add(const isl::pw_aff &pwaff2) const;
+  inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff union_add(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const;
   static inline isl::aff zero_on_domain(isl::space space);
 };
 
@@ -432,6 +556,7 @@
   inline /* implicit */ aff_list(const aff_list &obj);
   inline explicit aff_list(isl::ctx ctx, int n);
   inline explicit aff_list(isl::aff el);
+  inline explicit aff_list(isl::ctx ctx, const std::string &str);
   inline aff_list &operator=(aff_list obj);
   inline ~aff_list();
   inline __isl_give isl_aff_list *copy() const &;
@@ -442,12 +567,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::aff_list add(isl::aff el) const;
+  inline isl::aff at(int index) const;
+  inline isl::aff get_at(int index) const;
   inline isl::aff_list clear() const;
   inline isl::aff_list concat(isl::aff_list list2) const;
   inline isl::aff_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::aff)> &fn) const;
-  inline isl::aff at(int index) const;
-  inline isl::aff get_at(int index) const;
   inline isl::aff_list insert(unsigned int pos, isl::aff el) const;
   inline unsigned size() const;
 };
@@ -496,10 +621,10 @@
   inline isl::ast_expr expr_from(isl::pw_aff pa) const;
   inline isl::ast_expr expr_from(isl::set set) const;
   static inline isl::ast_build from_context(isl::set set);
-  inline isl::union_map schedule() const;
-  inline isl::union_map get_schedule() const;
   inline isl::ast_node node_from(isl::schedule schedule) const;
   inline isl::ast_node node_from_schedule_map(isl::union_map schedule) const;
+  inline isl::union_map schedule() const;
+  inline isl::union_map get_schedule() const;
 };
 
 // declarations for isl::ast_expr
@@ -1142,6 +1267,7 @@
   inline isl::ctx ctx() const;
 
   inline std::string to_C_str() const;
+  inline isl::ast_node_list to_list() const;
 };
 
 // declarations for isl::ast_node_block
@@ -1190,9 +1316,9 @@
   inline isl::ast_expr get_inc() const;
   inline isl::ast_expr init() const;
   inline isl::ast_expr get_init() const;
+  inline bool is_degenerate() const;
   inline isl::ast_expr iterator() const;
   inline isl::ast_expr get_iterator() const;
-  inline bool is_degenerate() const;
 };
 
 // declarations for isl::ast_node_if
@@ -1216,9 +1342,9 @@
   inline isl::ast_expr get_cond() const;
   inline isl::ast_node else_node() const;
   inline isl::ast_node get_else_node() const;
+  inline bool has_else_node() const;
   inline isl::ast_node then_node() const;
   inline isl::ast_node get_then_node() const;
-  inline bool has_else_node() const;
 };
 
 // declarations for isl::ast_node_list
@@ -1249,12 +1375,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::ast_node_list add(isl::ast_node el) const;
+  inline isl::ast_node at(int index) const;
+  inline isl::ast_node get_at(int index) const;
   inline isl::ast_node_list clear() const;
   inline isl::ast_node_list concat(isl::ast_node_list list2) const;
   inline isl::ast_node_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::ast_node)> &fn) const;
-  inline isl::ast_node at(int index) const;
-  inline isl::ast_node get_at(int index) const;
   inline isl::ast_node_list insert(unsigned int pos, isl::ast_node el) const;
   inline unsigned size() const;
 };
@@ -1331,24 +1457,146 @@
 
   inline isl::basic_map affine_hull() const;
   inline isl::basic_map apply_domain(isl::basic_map bmap2) const;
+  inline isl::map apply_domain(const isl::map &map2) const;
+  inline isl::union_map apply_domain(const isl::union_map &umap2) const;
   inline isl::basic_map apply_range(isl::basic_map bmap2) const;
+  inline isl::map apply_range(const isl::map &map2) const;
+  inline isl::union_map apply_range(const isl::union_map &umap2) const;
+  inline isl::map as_map() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::union_pw_multi_aff as_union_pw_multi_aff() const;
+  inline isl::set bind_domain(const isl::multi_id &tuple) const;
+  inline isl::set bind_range(const isl::multi_id &tuple) const;
+  inline isl::map coalesce() const;
+  inline isl::map complement() const;
+  inline isl::union_map compute_divs() const;
+  inline isl::map curry() const;
   inline isl::basic_set deltas() const;
   inline isl::basic_map detect_equalities() const;
+  inline isl::set domain() const;
+  inline isl::map domain_factor_domain() const;
+  inline isl::map domain_factor_range() const;
+  inline isl::union_map domain_map() const;
+  inline isl::union_pw_multi_aff domain_map_union_pw_multi_aff() const;
+  inline isl::map domain_product(const isl::map &map2) const;
+  inline isl::union_map domain_product(const isl::union_map &umap2) const;
+  inline unsigned domain_tuple_dim() const;
+  inline isl::id domain_tuple_id() const;
+  inline isl::map eq_at(const isl::multi_pw_aff &mpa) const;
+  inline isl::union_map eq_at(const isl::multi_union_pw_aff &mupa) const;
+  inline bool every_map(const std::function<bool(isl::map)> &test) const;
+  inline isl::map extract_map(const isl::space &space) const;
+  inline isl::map factor_domain() const;
+  inline isl::map factor_range() const;
+  inline isl::union_map fixed_power(const isl::val &exp) const;
+  inline isl::union_map fixed_power(long exp) const;
   inline isl::basic_map flatten() const;
   inline isl::basic_map flatten_domain() const;
   inline isl::basic_map flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(isl::basic_map)> &fn) const;
+  inline void foreach_map(const std::function<void(isl::map)> &fn) const;
   inline isl::basic_map gist(isl::basic_map context) const;
+  inline isl::map gist(const isl::map &context) const;
+  inline isl::union_map gist(const isl::union_map &context) const;
+  inline isl::map gist_domain(const isl::set &context) const;
+  inline isl::union_map gist_domain(const isl::union_set &uset) const;
+  inline isl::union_map gist_params(const isl::set &set) const;
+  inline isl::union_map gist_range(const isl::union_set &uset) const;
+  inline bool has_domain_tuple_id() const;
+  inline bool has_range_tuple_id() const;
   inline isl::basic_map intersect(isl::basic_map bmap2) const;
+  inline isl::map intersect(const isl::map &map2) const;
+  inline isl::union_map intersect(const isl::union_map &umap2) const;
   inline isl::basic_map intersect_domain(isl::basic_set bset) const;
+  inline isl::map intersect_domain(const isl::set &set) const;
+  inline isl::union_map intersect_domain(const isl::space &space) const;
+  inline isl::union_map intersect_domain(const isl::union_set &uset) const;
+  inline isl::basic_map intersect_domain(const isl::point &bset) const;
+  inline isl::map intersect_domain_factor_domain(const isl::map &factor) const;
+  inline isl::union_map intersect_domain_factor_domain(const isl::union_map &factor) const;
+  inline isl::map intersect_domain_factor_range(const isl::map &factor) const;
+  inline isl::union_map intersect_domain_factor_range(const isl::union_map &factor) const;
+  inline isl::map intersect_params(const isl::set &params) const;
   inline isl::basic_map intersect_range(isl::basic_set bset) const;
+  inline isl::map intersect_range(const isl::set &set) const;
+  inline isl::union_map intersect_range(const isl::space &space) const;
+  inline isl::union_map intersect_range(const isl::union_set &uset) const;
+  inline isl::basic_map intersect_range(const isl::point &bset) const;
+  inline isl::map intersect_range_factor_domain(const isl::map &factor) const;
+  inline isl::union_map intersect_range_factor_domain(const isl::union_map &factor) const;
+  inline isl::map intersect_range_factor_range(const isl::map &factor) const;
+  inline isl::union_map intersect_range_factor_range(const isl::union_map &factor) const;
+  inline bool is_bijective() const;
+  inline bool is_disjoint(const isl::map &map2) const;
+  inline bool is_disjoint(const isl::union_map &umap2) const;
   inline bool is_empty() const;
   inline bool is_equal(const isl::basic_map &bmap2) const;
+  inline bool is_equal(const isl::map &map2) const;
+  inline bool is_equal(const isl::union_map &umap2) const;
+  inline bool is_injective() const;
+  inline bool is_single_valued() const;
+  inline bool is_strict_subset(const isl::map &map2) const;
+  inline bool is_strict_subset(const isl::union_map &umap2) const;
   inline bool is_subset(const isl::basic_map &bmap2) const;
+  inline bool is_subset(const isl::map &map2) const;
+  inline bool is_subset(const isl::union_map &umap2) const;
+  inline bool isa_map() const;
+  inline isl::map lex_ge_at(const isl::multi_pw_aff &mpa) const;
+  inline isl::map lex_gt_at(const isl::multi_pw_aff &mpa) const;
+  inline isl::map lex_le_at(const isl::multi_pw_aff &mpa) const;
+  inline isl::map lex_lt_at(const isl::multi_pw_aff &mpa) const;
   inline isl::map lexmax() const;
+  inline isl::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::map lexmin() const;
+  inline isl::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::map lower_bound(const isl::multi_pw_aff &lower) const;
+  inline isl::map_list map_list() const;
+  inline isl::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::basic_map polyhedral_hull() const;
+  inline isl::map preimage_domain(const isl::multi_aff &ma) const;
+  inline isl::map preimage_domain(const isl::multi_pw_aff &mpa) const;
+  inline isl::map preimage_domain(const isl::pw_multi_aff &pma) const;
+  inline isl::union_map preimage_domain(const isl::union_pw_multi_aff &upma) const;
+  inline isl::map preimage_range(const isl::multi_aff &ma) const;
+  inline isl::map preimage_range(const isl::pw_multi_aff &pma) const;
+  inline isl::union_map preimage_range(const isl::union_pw_multi_aff &upma) const;
+  inline isl::map product(const isl::map &map2) const;
+  inline isl::union_map product(const isl::union_map &umap2) const;
+  inline isl::map project_out_all_params() const;
+  inline isl::set range() const;
+  inline isl::map range_factor_domain() const;
+  inline isl::map range_factor_range() const;
+  inline isl::fixed_box range_lattice_tile() const;
+  inline isl::union_map range_map() const;
+  inline isl::map range_product(const isl::map &map2) const;
+  inline isl::union_map range_product(const isl::union_map &umap2) const;
+  inline isl::map range_reverse() const;
+  inline isl::fixed_box range_simple_fixed_box_hull() const;
+  inline unsigned range_tuple_dim() const;
+  inline isl::id range_tuple_id() const;
   inline isl::basic_map reverse() const;
   inline isl::basic_map sample() const;
+  inline isl::map set_domain_tuple(const isl::id &id) const;
+  inline isl::map set_domain_tuple(const std::string &id) const;
+  inline isl::map set_range_tuple(const isl::id &id) const;
+  inline isl::map set_range_tuple(const std::string &id) const;
+  inline isl::space space() const;
+  inline isl::map subtract(const isl::map &map2) const;
+  inline isl::union_map subtract(const isl::union_map &umap2) const;
+  inline isl::union_map subtract_domain(const isl::union_set &dom) const;
+  inline isl::union_map subtract_range(const isl::union_set &dom) const;
+  inline isl::map_list to_list() const;
+  inline isl::union_map to_union_map() const;
+  inline isl::map uncurry() const;
   inline isl::map unite(isl::basic_map bmap2) const;
+  inline isl::map unite(const isl::map &map2) const;
+  inline isl::union_map unite(const isl::union_map &umap2) const;
+  inline isl::basic_map unshifted_simple_hull() const;
+  inline isl::map upper_bound(const isl::multi_pw_aff &upper) const;
+  inline isl::set wrap() const;
+  inline isl::map zip() const;
 };
 
 // declarations for isl::basic_set
@@ -1380,22 +1628,100 @@
 
   inline isl::basic_set affine_hull() const;
   inline isl::basic_set apply(isl::basic_map bmap) const;
+  inline isl::set apply(const isl::map &map) const;
+  inline isl::union_set apply(const isl::union_map &umap) const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::set bind(const isl::multi_id &tuple) const;
+  inline isl::set coalesce() const;
+  inline isl::set complement() const;
+  inline isl::union_set compute_divs() const;
   inline isl::basic_set detect_equalities() const;
   inline isl::val dim_max_val(int pos) const;
+  inline isl::val dim_min_val(int pos) const;
+  inline bool every_set(const std::function<bool(isl::set)> &test) const;
+  inline isl::set extract_set(const isl::space &space) const;
   inline isl::basic_set flatten() const;
+  inline void foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const;
+  inline void foreach_point(const std::function<void(isl::point)> &fn) const;
+  inline void foreach_set(const std::function<void(isl::set)> &fn) const;
   inline isl::basic_set gist(isl::basic_set context) const;
+  inline isl::set gist(const isl::set &context) const;
+  inline isl::union_set gist(const isl::union_set &context) const;
+  inline isl::basic_set gist(const isl::point &context) const;
+  inline isl::union_set gist_params(const isl::set &set) const;
+  inline isl::map identity() const;
+  inline isl::pw_aff indicator_function() const;
+  inline isl::map insert_domain(const isl::space &domain) const;
   inline isl::basic_set intersect(isl::basic_set bset2) const;
+  inline isl::set intersect(const isl::set &set2) const;
+  inline isl::union_set intersect(const isl::union_set &uset2) const;
+  inline isl::basic_set intersect(const isl::point &bset2) const;
   inline isl::basic_set intersect_params(isl::basic_set bset2) const;
+  inline isl::set intersect_params(const isl::set &params) const;
+  inline isl::basic_set intersect_params(const isl::point &bset2) const;
+  inline bool involves_locals() const;
+  inline bool is_disjoint(const isl::set &set2) const;
+  inline bool is_disjoint(const isl::union_set &uset2) const;
   inline bool is_empty() const;
   inline bool is_equal(const isl::basic_set &bset2) const;
+  inline bool is_equal(const isl::set &set2) const;
+  inline bool is_equal(const isl::union_set &uset2) const;
+  inline bool is_equal(const isl::point &bset2) const;
+  inline bool is_singleton() const;
+  inline bool is_strict_subset(const isl::set &set2) const;
+  inline bool is_strict_subset(const isl::union_set &uset2) const;
   inline bool is_subset(const isl::basic_set &bset2) const;
+  inline bool is_subset(const isl::set &set2) const;
+  inline bool is_subset(const isl::union_set &uset2) const;
+  inline bool is_subset(const isl::point &bset2) const;
   inline bool is_wrapping() const;
+  inline bool isa_set() const;
   inline isl::set lexmax() const;
+  inline isl::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::set lexmin() const;
+  inline isl::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::set lower_bound(const isl::multi_pw_aff &lower) const;
+  inline isl::set lower_bound(const isl::multi_val &lower) const;
+  inline isl::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::val max_val(const isl::aff &obj) const;
+  inline isl::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::val min_val(const isl::aff &obj) const;
   inline isl::basic_set params() const;
+  inline isl::multi_val plain_multi_val_if_fixed() const;
+  inline isl::basic_set polyhedral_hull() const;
+  inline isl::set preimage(const isl::multi_aff &ma) const;
+  inline isl::set preimage(const isl::multi_pw_aff &mpa) const;
+  inline isl::set preimage(const isl::pw_multi_aff &pma) const;
+  inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const;
+  inline isl::set product(const isl::set &set2) const;
+  inline isl::set project_out_all_params() const;
+  inline isl::set project_out_param(const isl::id &id) const;
+  inline isl::set project_out_param(const std::string &id) const;
+  inline isl::set project_out_param(const isl::id_list &list) const;
+  inline isl::pw_multi_aff pw_multi_aff_on_domain(const isl::multi_val &mv) const;
   inline isl::basic_set sample() const;
   inline isl::point sample_point() const;
+  inline isl::fixed_box simple_fixed_box_hull() const;
+  inline isl::space space() const;
+  inline isl::val stride(int pos) const;
+  inline isl::set subtract(const isl::set &set2) const;
+  inline isl::union_set subtract(const isl::union_set &uset2) const;
+  inline isl::union_set_list to_list() const;
+  inline isl::set to_set() const;
+  inline isl::union_set to_union_set() const;
+  inline isl::map translation() const;
+  inline unsigned tuple_dim() const;
+  inline isl::set unbind_params(const isl::multi_id &tuple) const;
+  inline isl::map unbind_params_insert_domain(const isl::multi_id &domain) const;
   inline isl::set unite(isl::basic_set bset2) const;
+  inline isl::set unite(const isl::set &set2) const;
+  inline isl::union_set unite(const isl::union_set &uset2) const;
+  inline isl::set unite(const isl::point &bset2) const;
+  inline isl::basic_set unshifted_simple_hull() const;
+  inline isl::map unwrap() const;
+  inline isl::set upper_bound(const isl::multi_pw_aff &upper) const;
+  inline isl::set upper_bound(const isl::multi_val &upper) const;
 };
 
 // declarations for isl::fixed_box
@@ -1423,13 +1749,13 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
+  inline bool is_valid() const;
   inline isl::multi_aff offset() const;
   inline isl::multi_aff get_offset() const;
   inline isl::multi_val size() const;
   inline isl::multi_val get_size() const;
   inline isl::space space() const;
   inline isl::space get_space() const;
-  inline bool is_valid() const;
 };
 
 // declarations for isl::id
@@ -1460,6 +1786,7 @@
 
   inline std::string name() const;
   inline std::string get_name() const;
+  inline isl::id_list to_list() const;
 };
 
 // declarations for isl::id_list
@@ -1480,6 +1807,7 @@
   inline /* implicit */ id_list(const id_list &obj);
   inline explicit id_list(isl::ctx ctx, int n);
   inline explicit id_list(isl::id el);
+  inline explicit id_list(isl::ctx ctx, const std::string &str);
   inline id_list &operator=(id_list obj);
   inline ~id_list();
   inline __isl_give isl_id_list *copy() const &;
@@ -1491,12 +1819,12 @@
 
   inline isl::id_list add(isl::id el) const;
   inline isl::id_list add(const std::string &el) const;
+  inline isl::id at(int index) const;
+  inline isl::id get_at(int index) const;
   inline isl::id_list clear() const;
   inline isl::id_list concat(isl::id_list list2) const;
   inline isl::id_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::id)> &fn) const;
-  inline isl::id at(int index) const;
-  inline isl::id get_at(int index) const;
   inline isl::id_list insert(unsigned int pos, isl::id el) const;
   inline isl::id_list insert(unsigned int pos, const std::string &el) const;
   inline unsigned size() const;
@@ -1531,48 +1859,106 @@
 
   inline isl::basic_map affine_hull() const;
   inline isl::map apply_domain(isl::map map2) const;
+  inline isl::union_map apply_domain(const isl::union_map &umap2) const;
+  inline isl::map apply_domain(const isl::basic_map &map2) const;
   inline isl::map apply_range(isl::map map2) const;
+  inline isl::union_map apply_range(const isl::union_map &umap2) const;
+  inline isl::map apply_range(const isl::basic_map &map2) const;
+  inline isl::map as_map() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::union_pw_multi_aff as_union_pw_multi_aff() const;
   inline isl::set bind_domain(isl::multi_id tuple) const;
   inline isl::set bind_range(isl::multi_id tuple) const;
   inline isl::map coalesce() const;
   inline isl::map complement() const;
+  inline isl::union_map compute_divs() const;
   inline isl::map curry() const;
   inline isl::set deltas() const;
   inline isl::map detect_equalities() const;
   inline isl::set domain() const;
   inline isl::map domain_factor_domain() const;
   inline isl::map domain_factor_range() const;
+  inline isl::union_map domain_map() const;
+  inline isl::union_pw_multi_aff domain_map_union_pw_multi_aff() const;
   inline isl::map domain_product(isl::map map2) const;
+  inline isl::union_map domain_product(const isl::union_map &umap2) const;
+  inline isl::map domain_product(const isl::basic_map &map2) const;
+  inline unsigned domain_tuple_dim() const;
+  inline isl::id domain_tuple_id() const;
+  inline isl::id get_domain_tuple_id() const;
   static inline isl::map empty(isl::space space);
   inline isl::map eq_at(isl::multi_pw_aff mpa) const;
+  inline isl::union_map eq_at(const isl::multi_union_pw_aff &mupa) const;
+  inline isl::map eq_at(const isl::aff &mpa) const;
+  inline isl::map eq_at(const isl::multi_aff &mpa) const;
+  inline isl::map eq_at(const isl::pw_aff &mpa) const;
+  inline isl::map eq_at(const isl::pw_multi_aff &mpa) const;
+  inline bool every_map(const std::function<bool(isl::map)> &test) const;
+  inline isl::map extract_map(const isl::space &space) const;
   inline isl::map factor_domain() const;
   inline isl::map factor_range() const;
+  inline isl::union_map fixed_power(const isl::val &exp) const;
+  inline isl::union_map fixed_power(long exp) const;
   inline isl::map flatten() const;
   inline isl::map flatten_domain() const;
   inline isl::map flatten_range() const;
   inline void foreach_basic_map(const std::function<void(isl::basic_map)> &fn) const;
-  inline isl::fixed_box range_simple_fixed_box_hull() const;
-  inline isl::fixed_box get_range_simple_fixed_box_hull() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
+  inline void foreach_map(const std::function<void(isl::map)> &fn) const;
   inline isl::map gist(isl::map context) const;
+  inline isl::union_map gist(const isl::union_map &context) const;
+  inline isl::map gist(const isl::basic_map &context) const;
   inline isl::map gist_domain(isl::set context) const;
+  inline isl::union_map gist_domain(const isl::union_set &uset) const;
+  inline isl::map gist_domain(const isl::basic_set &context) const;
+  inline isl::map gist_domain(const isl::point &context) const;
+  inline isl::union_map gist_params(const isl::set &set) const;
+  inline isl::union_map gist_range(const isl::union_set &uset) const;
+  inline bool has_domain_tuple_id() const;
+  inline bool has_range_tuple_id() const;
   inline isl::map intersect(isl::map map2) const;
+  inline isl::union_map intersect(const isl::union_map &umap2) const;
+  inline isl::map intersect(const isl::basic_map &map2) const;
   inline isl::map intersect_domain(isl::set set) const;
+  inline isl::union_map intersect_domain(const isl::space &space) const;
+  inline isl::union_map intersect_domain(const isl::union_set &uset) const;
+  inline isl::map intersect_domain(const isl::basic_set &set) const;
+  inline isl::map intersect_domain(const isl::point &set) const;
   inline isl::map intersect_domain_factor_domain(isl::map factor) const;
+  inline isl::union_map intersect_domain_factor_domain(const isl::union_map &factor) const;
+  inline isl::map intersect_domain_factor_domain(const isl::basic_map &factor) const;
   inline isl::map intersect_domain_factor_range(isl::map factor) const;
+  inline isl::union_map intersect_domain_factor_range(const isl::union_map &factor) const;
+  inline isl::map intersect_domain_factor_range(const isl::basic_map &factor) const;
   inline isl::map intersect_params(isl::set params) const;
   inline isl::map intersect_range(isl::set set) const;
+  inline isl::union_map intersect_range(const isl::space &space) const;
+  inline isl::union_map intersect_range(const isl::union_set &uset) const;
+  inline isl::map intersect_range(const isl::basic_set &set) const;
+  inline isl::map intersect_range(const isl::point &set) const;
   inline isl::map intersect_range_factor_domain(isl::map factor) const;
+  inline isl::union_map intersect_range_factor_domain(const isl::union_map &factor) const;
+  inline isl::map intersect_range_factor_domain(const isl::basic_map &factor) const;
   inline isl::map intersect_range_factor_range(isl::map factor) const;
+  inline isl::union_map intersect_range_factor_range(const isl::union_map &factor) const;
+  inline isl::map intersect_range_factor_range(const isl::basic_map &factor) const;
   inline bool is_bijective() const;
   inline bool is_disjoint(const isl::map &map2) const;
+  inline bool is_disjoint(const isl::union_map &umap2) const;
+  inline bool is_disjoint(const isl::basic_map &map2) const;
   inline bool is_empty() const;
   inline bool is_equal(const isl::map &map2) const;
+  inline bool is_equal(const isl::union_map &umap2) const;
+  inline bool is_equal(const isl::basic_map &map2) const;
   inline bool is_injective() const;
   inline bool is_single_valued() const;
   inline bool is_strict_subset(const isl::map &map2) const;
+  inline bool is_strict_subset(const isl::union_map &umap2) const;
+  inline bool is_strict_subset(const isl::basic_map &map2) const;
   inline bool is_subset(const isl::map &map2) const;
+  inline bool is_subset(const isl::union_map &umap2) const;
+  inline bool is_subset(const isl::basic_map &map2) const;
+  inline bool isa_map() const;
   inline isl::map lex_ge_at(isl::multi_pw_aff mpa) const;
   inline isl::map lex_gt_at(isl::multi_pw_aff mpa) const;
   inline isl::map lex_le_at(isl::multi_pw_aff mpa) const;
@@ -1582,26 +1968,55 @@
   inline isl::map lexmin() const;
   inline isl::pw_multi_aff lexmin_pw_multi_aff() const;
   inline isl::map lower_bound(isl::multi_pw_aff lower) const;
+  inline isl::map_list map_list() const;
   inline isl::multi_pw_aff max_multi_pw_aff() const;
   inline isl::multi_pw_aff min_multi_pw_aff() const;
   inline isl::basic_map polyhedral_hull() const;
   inline isl::map preimage_domain(isl::multi_aff ma) const;
   inline isl::map preimage_domain(isl::multi_pw_aff mpa) const;
   inline isl::map preimage_domain(isl::pw_multi_aff pma) const;
+  inline isl::union_map preimage_domain(const isl::union_pw_multi_aff &upma) const;
   inline isl::map preimage_range(isl::multi_aff ma) const;
   inline isl::map preimage_range(isl::pw_multi_aff pma) const;
+  inline isl::union_map preimage_range(const isl::union_pw_multi_aff &upma) const;
   inline isl::map product(isl::map map2) const;
+  inline isl::union_map product(const isl::union_map &umap2) const;
+  inline isl::map product(const isl::basic_map &map2) const;
   inline isl::map project_out_all_params() const;
   inline isl::set range() const;
   inline isl::map range_factor_domain() const;
   inline isl::map range_factor_range() const;
+  inline isl::fixed_box range_lattice_tile() const;
+  inline isl::fixed_box get_range_lattice_tile() const;
+  inline isl::union_map range_map() const;
   inline isl::map range_product(isl::map map2) const;
+  inline isl::union_map range_product(const isl::union_map &umap2) const;
+  inline isl::map range_product(const isl::basic_map &map2) const;
   inline isl::map range_reverse() const;
+  inline isl::fixed_box range_simple_fixed_box_hull() const;
+  inline isl::fixed_box get_range_simple_fixed_box_hull() const;
+  inline unsigned range_tuple_dim() const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
   inline isl::map reverse() const;
   inline isl::basic_map sample() const;
+  inline isl::map set_domain_tuple(isl::id id) const;
+  inline isl::map set_domain_tuple(const std::string &id) const;
+  inline isl::map set_range_tuple(isl::id id) const;
+  inline isl::map set_range_tuple(const std::string &id) const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::map subtract(isl::map map2) const;
+  inline isl::union_map subtract(const isl::union_map &umap2) const;
+  inline isl::map subtract(const isl::basic_map &map2) const;
+  inline isl::union_map subtract_domain(const isl::union_set &dom) const;
+  inline isl::union_map subtract_range(const isl::union_set &dom) const;
+  inline isl::map_list to_list() const;
+  inline isl::union_map to_union_map() const;
   inline isl::map uncurry() const;
   inline isl::map unite(isl::map map2) const;
+  inline isl::union_map unite(const isl::union_map &umap2) const;
+  inline isl::map unite(const isl::basic_map &map2) const;
   static inline isl::map universe(isl::space space);
   inline isl::basic_map unshifted_simple_hull() const;
   inline isl::map upper_bound(isl::multi_pw_aff upper) const;
@@ -1609,6 +2024,45 @@
   inline isl::map zip() const;
 };
 
+// declarations for isl::map_list
+inline map_list manage(__isl_take isl_map_list *ptr);
+inline map_list manage_copy(__isl_keep isl_map_list *ptr);
+
+class map_list {
+  friend inline map_list manage(__isl_take isl_map_list *ptr);
+  friend inline map_list manage_copy(__isl_keep isl_map_list *ptr);
+
+protected:
+  isl_map_list *ptr = nullptr;
+
+  inline explicit map_list(__isl_take isl_map_list *ptr);
+
+public:
+  inline /* implicit */ map_list();
+  inline /* implicit */ map_list(const map_list &obj);
+  inline explicit map_list(isl::ctx ctx, int n);
+  inline explicit map_list(isl::map el);
+  inline explicit map_list(isl::ctx ctx, const std::string &str);
+  inline map_list &operator=(map_list obj);
+  inline ~map_list();
+  inline __isl_give isl_map_list *copy() const &;
+  inline __isl_give isl_map_list *copy() && = delete;
+  inline __isl_keep isl_map_list *get() const;
+  inline __isl_give isl_map_list *release();
+  inline bool is_null() const;
+  inline isl::ctx ctx() const;
+
+  inline isl::map_list add(isl::map el) const;
+  inline isl::map at(int index) const;
+  inline isl::map get_at(int index) const;
+  inline isl::map_list clear() const;
+  inline isl::map_list concat(isl::map_list list2) const;
+  inline isl::map_list drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(isl::map)> &fn) const;
+  inline isl::map_list insert(unsigned int pos, isl::map el) const;
+  inline unsigned size() const;
+};
+
 // declarations for isl::multi_aff
 inline multi_aff manage(__isl_take isl_multi_aff *ptr);
 inline multi_aff manage_copy(__isl_keep isl_multi_aff *ptr);
@@ -1638,35 +2092,99 @@
   inline isl::ctx ctx() const;
 
   inline isl::multi_aff add(isl::multi_aff multi2) const;
+  inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff add(const isl::aff &multi2) const;
   inline isl::multi_aff add_constant(isl::multi_val mv) const;
   inline isl::multi_aff add_constant(isl::val v) const;
   inline isl::multi_aff add_constant(long v) const;
+  inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::map as_map() const;
+  inline isl::multi_aff as_multi_aff() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::union_map as_union_map() const;
+  inline isl::aff at(int pos) const;
+  inline isl::aff get_at(int pos) const;
   inline isl::basic_set bind(isl::multi_id tuple) const;
   inline isl::multi_aff bind_domain(isl::multi_id tuple) const;
   inline isl::multi_aff bind_domain_wrapped_domain(isl::multi_id tuple) const;
-  static inline isl::multi_aff domain_map(isl::space space);
-  inline isl::multi_aff flat_range_product(isl::multi_aff multi2) const;
-  inline isl::multi_aff floor() const;
-  inline isl::aff at(int pos) const;
-  inline isl::aff get_at(int pos) const;
+  inline isl::pw_multi_aff coalesce() const;
   inline isl::multi_val constant_multi_val() const;
   inline isl::multi_val get_constant_multi_val() const;
-  inline isl::aff_list list() const;
-  inline isl::aff_list get_list() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
+  inline isl::set domain() const;
+  static inline isl::multi_aff domain_map(isl::space space);
+  inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const;
+  inline isl::multi_aff flat_range_product(isl::multi_aff multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff flat_range_product(const isl::aff &multi2) const;
+  inline isl::multi_aff floor() const;
+  inline void foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const;
   inline isl::multi_aff gist(isl::set context) const;
+  inline isl::union_pw_multi_aff gist(const isl::union_set &context) const;
+  inline isl::multi_aff gist(const isl::basic_set &context) const;
+  inline isl::multi_aff gist(const isl::point &context) const;
+  inline bool has_range_tuple_id() const;
   inline isl::multi_aff identity() const;
   static inline isl::multi_aff identity_on_domain(isl::space space);
   inline isl::multi_aff insert_domain(isl::space domain) const;
+  inline isl::pw_multi_aff intersect_domain(const isl::set &set) const;
+  inline isl::union_pw_multi_aff intersect_domain(const isl::space &space) const;
+  inline isl::union_pw_multi_aff intersect_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_multi_aff intersect_domain_wrapped_range(const isl::union_set &uset) const;
+  inline isl::pw_multi_aff intersect_params(const isl::set &set) const;
   inline bool involves_locals() const;
   inline bool involves_nan() const;
+  inline bool involves_param(const isl::id &id) const;
+  inline bool involves_param(const std::string &id) const;
+  inline bool involves_param(const isl::id_list &list) const;
+  inline bool isa_multi_aff() const;
+  inline bool isa_pw_multi_aff() const;
+  inline isl::aff_list list() const;
+  inline isl::aff_list get_list() const;
+  inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_val max_multi_val() const;
+  inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_val min_multi_val() const;
+  static inline isl::multi_aff multi_val_on_domain(isl::space space, isl::multi_val mv);
+  inline unsigned n_piece() const;
   inline isl::multi_aff neg() const;
+  inline bool plain_is_empty() const;
   inline bool plain_is_equal(const isl::multi_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::aff &multi2) const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const;
   inline isl::multi_aff product(isl::multi_aff multi2) const;
+  inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const;
+  inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const;
+  inline isl::multi_aff product(const isl::aff &multi2) const;
   inline isl::multi_aff pullback(isl::multi_aff ma2) const;
+  inline isl::multi_pw_aff pullback(const isl::multi_pw_aff &mpa2) const;
+  inline isl::pw_multi_aff pullback(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff pullback(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff pullback(const isl::aff &ma2) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::pw_multi_aff range_factor_domain() const;
+  inline isl::pw_multi_aff range_factor_range() const;
   static inline isl::multi_aff range_map(isl::space space);
   inline isl::multi_aff range_product(isl::multi_aff multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff range_product(const isl::aff &multi2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
+  inline isl::multi_aff reset_range_tuple_id() const;
   inline isl::multi_aff scale(isl::multi_val mv) const;
   inline isl::multi_aff scale(isl::val v) const;
   inline isl::multi_aff scale(long v) const;
@@ -1674,9 +2192,32 @@
   inline isl::multi_aff scale_down(isl::val v) const;
   inline isl::multi_aff scale_down(long v) const;
   inline isl::multi_aff set_at(int pos, isl::aff el) const;
+  inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::multi_aff set_range_tuple(isl::id id) const;
+  inline isl::multi_aff set_range_tuple(const std::string &id) const;
   inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::multi_aff sub(isl::multi_aff multi2) const;
+  inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_aff sub(const isl::aff &multi2) const;
+  inline isl::pw_multi_aff subtract_domain(const isl::set &set) const;
+  inline isl::union_pw_multi_aff subtract_domain(const isl::space &space) const;
+  inline isl::union_pw_multi_aff subtract_domain(const isl::union_set &uset) const;
+  inline isl::pw_multi_aff_list to_list() const;
+  inline isl::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::multi_union_pw_aff to_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff to_pw_multi_aff() const;
+  inline isl::union_pw_multi_aff to_union_pw_multi_aff() const;
   inline isl::multi_aff unbind_params_insert_domain(isl::multi_id domain) const;
+  inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
+  inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const;
   static inline isl::multi_aff zero(isl::space space);
 };
 
@@ -1707,18 +2248,18 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
-  inline isl::multi_id flat_range_product(isl::multi_id multi2) const;
   inline isl::id at(int pos) const;
   inline isl::id get_at(int pos) const;
+  inline isl::multi_id flat_range_product(isl::multi_id multi2) const;
   inline isl::id_list list() const;
   inline isl::id_list get_list() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline bool plain_is_equal(const isl::multi_id &multi2) const;
   inline isl::multi_id range_product(isl::multi_id multi2) const;
   inline isl::multi_id set_at(int pos, isl::id el) const;
   inline isl::multi_id set_at(int pos, const std::string &el) const;
   inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
 };
 
 // declarations for isl::multi_pw_aff
@@ -1753,42 +2294,75 @@
   inline isl::ctx ctx() const;
 
   inline isl::multi_pw_aff add(isl::multi_pw_aff multi2) const;
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::multi_pw_aff add(const isl::aff &multi2) const;
+  inline isl::multi_pw_aff add(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff add(const isl::pw_aff &multi2) const;
+  inline isl::multi_pw_aff add(const isl::pw_multi_aff &multi2) const;
   inline isl::multi_pw_aff add_constant(isl::multi_val mv) const;
   inline isl::multi_pw_aff add_constant(isl::val v) const;
   inline isl::multi_pw_aff add_constant(long v) const;
+  inline isl::map as_map() const;
+  inline isl::multi_aff as_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::pw_aff at(int pos) const;
+  inline isl::pw_aff get_at(int pos) const;
   inline isl::set bind(isl::multi_id tuple) const;
   inline isl::multi_pw_aff bind_domain(isl::multi_id tuple) const;
   inline isl::multi_pw_aff bind_domain_wrapped_domain(isl::multi_id tuple) const;
   inline isl::multi_pw_aff coalesce() const;
   inline isl::set domain() const;
   inline isl::multi_pw_aff flat_range_product(isl::multi_pw_aff multi2) const;
-  inline isl::pw_aff at(int pos) const;
-  inline isl::pw_aff get_at(int pos) const;
-  inline isl::pw_aff_list list() const;
-  inline isl::pw_aff_list get_list() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::aff &multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::pw_aff &multi2) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::pw_multi_aff &multi2) const;
   inline isl::multi_pw_aff gist(isl::set set) const;
+  inline isl::multi_union_pw_aff gist(const isl::union_set &context) const;
+  inline isl::multi_pw_aff gist(const isl::basic_set &set) const;
+  inline isl::multi_pw_aff gist(const isl::point &set) const;
+  inline bool has_range_tuple_id() const;
   inline isl::multi_pw_aff identity() const;
   static inline isl::multi_pw_aff identity_on_domain(isl::space space);
   inline isl::multi_pw_aff insert_domain(isl::space domain) const;
   inline isl::multi_pw_aff intersect_domain(isl::set domain) const;
+  inline isl::multi_union_pw_aff intersect_domain(const isl::union_set &uset) const;
+  inline isl::multi_pw_aff intersect_domain(const isl::basic_set &domain) const;
+  inline isl::multi_pw_aff intersect_domain(const isl::point &domain) const;
   inline isl::multi_pw_aff intersect_params(isl::set set) const;
   inline bool involves_nan() const;
   inline bool involves_param(const isl::id &id) const;
   inline bool involves_param(const std::string &id) const;
   inline bool involves_param(const isl::id_list &list) const;
+  inline bool isa_multi_aff() const;
+  inline isl::pw_aff_list list() const;
+  inline isl::pw_aff_list get_list() const;
   inline isl::multi_pw_aff max(isl::multi_pw_aff multi2) const;
   inline isl::multi_val max_multi_val() const;
   inline isl::multi_pw_aff min(isl::multi_pw_aff multi2) const;
   inline isl::multi_val min_multi_val() const;
   inline isl::multi_pw_aff neg() const;
   inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_aff &multi2) const;
+  inline bool plain_is_equal(const isl::pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::pw_multi_aff &multi2) const;
   inline isl::multi_pw_aff product(isl::multi_pw_aff multi2) const;
   inline isl::multi_pw_aff pullback(isl::multi_aff ma) const;
   inline isl::multi_pw_aff pullback(isl::multi_pw_aff mpa2) const;
   inline isl::multi_pw_aff pullback(isl::pw_multi_aff pma) const;
+  inline isl::multi_union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const;
   inline isl::multi_pw_aff range_product(isl::multi_pw_aff multi2) const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::aff &multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::pw_aff &multi2) const;
+  inline isl::multi_pw_aff range_product(const isl::pw_multi_aff &multi2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
+  inline isl::multi_pw_aff reset_range_tuple_id() const;
   inline isl::multi_pw_aff scale(isl::multi_val mv) const;
   inline isl::multi_pw_aff scale(isl::val v) const;
   inline isl::multi_pw_aff scale(long v) const;
@@ -1796,10 +2370,25 @@
   inline isl::multi_pw_aff scale_down(isl::val v) const;
   inline isl::multi_pw_aff scale_down(long v) const;
   inline isl::multi_pw_aff set_at(int pos, isl::pw_aff el) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::multi_pw_aff set_range_tuple(isl::id id) const;
+  inline isl::multi_pw_aff set_range_tuple(const std::string &id) const;
   inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::multi_pw_aff sub(isl::multi_pw_aff multi2) const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::multi_pw_aff sub(const isl::aff &multi2) const;
+  inline isl::multi_pw_aff sub(const isl::multi_aff &multi2) const;
+  inline isl::multi_pw_aff sub(const isl::pw_aff &multi2) const;
+  inline isl::multi_pw_aff sub(const isl::pw_multi_aff &multi2) const;
   inline isl::multi_pw_aff unbind_params_insert_domain(isl::multi_id domain) const;
   inline isl::multi_pw_aff union_add(isl::multi_pw_aff mpa2) const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
+  inline isl::multi_pw_aff union_add(const isl::aff &mpa2) const;
+  inline isl::multi_pw_aff union_add(const isl::multi_aff &mpa2) const;
+  inline isl::multi_pw_aff union_add(const isl::pw_aff &mpa2) const;
+  inline isl::multi_pw_aff union_add(const isl::pw_multi_aff &mpa2) const;
   static inline isl::multi_pw_aff zero(isl::space space);
 };
 
@@ -1833,24 +2422,26 @@
   inline isl::ctx ctx() const;
 
   inline isl::multi_union_pw_aff add(isl::multi_union_pw_aff multi2) const;
+  inline isl::union_pw_aff at(int pos) const;
+  inline isl::union_pw_aff get_at(int pos) const;
   inline isl::union_set bind(isl::multi_id tuple) const;
   inline isl::multi_union_pw_aff coalesce() const;
   inline isl::union_set domain() const;
   inline isl::multi_union_pw_aff flat_range_product(isl::multi_union_pw_aff multi2) const;
-  inline isl::union_pw_aff at(int pos) const;
-  inline isl::union_pw_aff get_at(int pos) const;
-  inline isl::union_pw_aff_list list() const;
-  inline isl::union_pw_aff_list get_list() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline isl::multi_union_pw_aff gist(isl::union_set context) const;
+  inline bool has_range_tuple_id() const;
   inline isl::multi_union_pw_aff intersect_domain(isl::union_set uset) const;
   inline isl::multi_union_pw_aff intersect_params(isl::set params) const;
   inline bool involves_nan() const;
+  inline isl::union_pw_aff_list list() const;
+  inline isl::union_pw_aff_list get_list() const;
   inline isl::multi_union_pw_aff neg() const;
   inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
   inline isl::multi_union_pw_aff pullback(isl::union_pw_multi_aff upma) const;
   inline isl::multi_union_pw_aff range_product(isl::multi_union_pw_aff multi2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
+  inline isl::multi_union_pw_aff reset_range_tuple_id() const;
   inline isl::multi_union_pw_aff scale(isl::multi_val mv) const;
   inline isl::multi_union_pw_aff scale(isl::val v) const;
   inline isl::multi_union_pw_aff scale(long v) const;
@@ -1858,7 +2449,11 @@
   inline isl::multi_union_pw_aff scale_down(isl::val v) const;
   inline isl::multi_union_pw_aff scale_down(long v) const;
   inline isl::multi_union_pw_aff set_at(int pos, isl::union_pw_aff el) const;
+  inline isl::multi_union_pw_aff set_range_tuple(isl::id id) const;
+  inline isl::multi_union_pw_aff set_range_tuple(const std::string &id) const;
   inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::multi_union_pw_aff sub(isl::multi_union_pw_aff multi2) const;
   inline isl::multi_union_pw_aff union_add(isl::multi_union_pw_aff mupa2) const;
   static inline isl::multi_union_pw_aff zero(isl::space space);
@@ -1894,20 +2489,22 @@
   inline isl::multi_val add(isl::multi_val multi2) const;
   inline isl::multi_val add(isl::val v) const;
   inline isl::multi_val add(long v) const;
-  inline isl::multi_val flat_range_product(isl::multi_val multi2) const;
   inline isl::val at(int pos) const;
   inline isl::val get_at(int pos) const;
+  inline isl::multi_val flat_range_product(isl::multi_val multi2) const;
+  inline bool has_range_tuple_id() const;
+  inline bool involves_nan() const;
   inline isl::val_list list() const;
   inline isl::val_list get_list() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
-  inline bool involves_nan() const;
   inline isl::multi_val max(isl::multi_val multi2) const;
   inline isl::multi_val min(isl::multi_val multi2) const;
   inline isl::multi_val neg() const;
   inline bool plain_is_equal(const isl::multi_val &multi2) const;
   inline isl::multi_val product(isl::multi_val multi2) const;
   inline isl::multi_val range_product(isl::multi_val multi2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
+  inline isl::multi_val reset_range_tuple_id() const;
   inline isl::multi_val scale(isl::multi_val mv) const;
   inline isl::multi_val scale(isl::val v) const;
   inline isl::multi_val scale(long v) const;
@@ -1916,7 +2513,11 @@
   inline isl::multi_val scale_down(long v) const;
   inline isl::multi_val set_at(int pos, isl::val el) const;
   inline isl::multi_val set_at(int pos, long el) const;
+  inline isl::multi_val set_range_tuple(isl::id id) const;
+  inline isl::multi_val set_range_tuple(const std::string &id) const;
   inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::multi_val sub(isl::multi_val multi2) const;
   static inline isl::multi_val zero(isl::space space);
 };
@@ -1946,8 +2547,98 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
+  inline isl::basic_set affine_hull() const;
+  inline isl::basic_set apply(const isl::basic_map &bmap) const;
+  inline isl::set apply(const isl::map &map) const;
+  inline isl::union_set apply(const isl::union_map &umap) const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::set bind(const isl::multi_id &tuple) const;
+  inline isl::set coalesce() const;
+  inline isl::set complement() const;
+  inline isl::union_set compute_divs() const;
+  inline isl::basic_set detect_equalities() const;
+  inline isl::val dim_max_val(int pos) const;
+  inline isl::val dim_min_val(int pos) const;
+  inline bool every_set(const std::function<bool(isl::set)> &test) const;
+  inline isl::set extract_set(const isl::space &space) const;
+  inline isl::basic_set flatten() const;
+  inline void foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const;
+  inline void foreach_point(const std::function<void(isl::point)> &fn) const;
+  inline void foreach_set(const std::function<void(isl::set)> &fn) const;
+  inline isl::basic_set gist(const isl::basic_set &context) const;
+  inline isl::set gist(const isl::set &context) const;
+  inline isl::union_set gist(const isl::union_set &context) const;
+  inline isl::union_set gist_params(const isl::set &set) const;
+  inline isl::map identity() const;
+  inline isl::pw_aff indicator_function() const;
+  inline isl::map insert_domain(const isl::space &domain) const;
+  inline isl::basic_set intersect(const isl::basic_set &bset2) const;
+  inline isl::set intersect(const isl::set &set2) const;
+  inline isl::union_set intersect(const isl::union_set &uset2) const;
+  inline isl::basic_set intersect_params(const isl::basic_set &bset2) const;
+  inline isl::set intersect_params(const isl::set &params) const;
+  inline bool involves_locals() const;
+  inline bool is_disjoint(const isl::set &set2) const;
+  inline bool is_disjoint(const isl::union_set &uset2) const;
+  inline bool is_empty() const;
+  inline bool is_equal(const isl::basic_set &bset2) const;
+  inline bool is_equal(const isl::set &set2) const;
+  inline bool is_equal(const isl::union_set &uset2) const;
+  inline bool is_singleton() const;
+  inline bool is_strict_subset(const isl::set &set2) const;
+  inline bool is_strict_subset(const isl::union_set &uset2) const;
+  inline bool is_subset(const isl::basic_set &bset2) const;
+  inline bool is_subset(const isl::set &set2) const;
+  inline bool is_subset(const isl::union_set &uset2) const;
+  inline bool is_wrapping() const;
+  inline bool isa_set() const;
+  inline isl::set lexmax() const;
+  inline isl::pw_multi_aff lexmax_pw_multi_aff() const;
+  inline isl::set lexmin() const;
+  inline isl::pw_multi_aff lexmin_pw_multi_aff() const;
+  inline isl::set lower_bound(const isl::multi_pw_aff &lower) const;
+  inline isl::set lower_bound(const isl::multi_val &lower) const;
+  inline isl::multi_pw_aff max_multi_pw_aff() const;
+  inline isl::val max_val(const isl::aff &obj) const;
+  inline isl::multi_pw_aff min_multi_pw_aff() const;
+  inline isl::val min_val(const isl::aff &obj) const;
   inline isl::multi_val multi_val() const;
   inline isl::multi_val get_multi_val() const;
+  inline isl::basic_set params() const;
+  inline isl::multi_val plain_multi_val_if_fixed() const;
+  inline isl::basic_set polyhedral_hull() const;
+  inline isl::set preimage(const isl::multi_aff &ma) const;
+  inline isl::set preimage(const isl::multi_pw_aff &mpa) const;
+  inline isl::set preimage(const isl::pw_multi_aff &pma) const;
+  inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const;
+  inline isl::set product(const isl::set &set2) const;
+  inline isl::set project_out_all_params() const;
+  inline isl::set project_out_param(const isl::id &id) const;
+  inline isl::set project_out_param(const std::string &id) const;
+  inline isl::set project_out_param(const isl::id_list &list) const;
+  inline isl::pw_multi_aff pw_multi_aff_on_domain(const isl::multi_val &mv) const;
+  inline isl::basic_set sample() const;
+  inline isl::point sample_point() const;
+  inline isl::fixed_box simple_fixed_box_hull() const;
+  inline isl::space space() const;
+  inline isl::val stride(int pos) const;
+  inline isl::set subtract(const isl::set &set2) const;
+  inline isl::union_set subtract(const isl::union_set &uset2) const;
+  inline isl::union_set_list to_list() const;
+  inline isl::set to_set() const;
+  inline isl::union_set to_union_set() const;
+  inline isl::map translation() const;
+  inline unsigned tuple_dim() const;
+  inline isl::set unbind_params(const isl::multi_id &tuple) const;
+  inline isl::map unbind_params_insert_domain(const isl::multi_id &domain) const;
+  inline isl::set unite(const isl::basic_set &bset2) const;
+  inline isl::set unite(const isl::set &set2) const;
+  inline isl::union_set unite(const isl::union_set &uset2) const;
+  inline isl::basic_set unshifted_simple_hull() const;
+  inline isl::map unwrap() const;
+  inline isl::set upper_bound(const isl::multi_pw_aff &upper) const;
+  inline isl::set upper_bound(const isl::multi_val &upper) const;
 };
 
 // declarations for isl::pw_aff
@@ -1977,10 +2668,26 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
+  inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_aff add(isl::pw_aff pwaff2) const;
+  inline isl::pw_multi_aff add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff add(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_aff add(const isl::aff &pwaff2) const;
   inline isl::pw_aff add_constant(isl::val v) const;
   inline isl::pw_aff add_constant(long v) const;
+  inline isl::pw_multi_aff add_constant(const isl::multi_val &mv) const;
+  inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const;
   inline isl::aff as_aff() const;
+  inline isl::map as_map() const;
+  inline isl::multi_aff as_multi_aff() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::union_map as_union_map() const;
+  inline isl::pw_aff at(int pos) const;
+  inline isl::set bind(const isl::multi_id &tuple) const;
   inline isl::set bind(isl::id id) const;
   inline isl::set bind(const std::string &id) const;
   inline isl::pw_aff bind_domain(isl::multi_id tuple) const;
@@ -1992,36 +2699,114 @@
   inline isl::set domain() const;
   inline isl::set eq_set(isl::pw_aff pwaff2) const;
   inline isl::val eval(isl::point pnt) const;
+  inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff flat_range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const;
   inline isl::pw_aff floor() const;
+  inline void foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const;
   inline isl::set ge_set(isl::pw_aff pwaff2) const;
   inline isl::pw_aff gist(isl::set context) const;
+  inline isl::union_pw_aff gist(const isl::union_set &context) const;
+  inline isl::pw_aff gist(const isl::basic_set &context) const;
+  inline isl::pw_aff gist(const isl::point &context) const;
   inline isl::set gt_set(isl::pw_aff pwaff2) const;
+  inline bool has_range_tuple_id() const;
+  inline isl::multi_pw_aff identity() const;
   inline isl::pw_aff insert_domain(isl::space domain) const;
   inline isl::pw_aff intersect_domain(isl::set set) const;
+  inline isl::union_pw_aff intersect_domain(const isl::space &space) const;
+  inline isl::union_pw_aff intersect_domain(const isl::union_set &uset) const;
+  inline isl::pw_aff intersect_domain(const isl::basic_set &set) const;
+  inline isl::pw_aff intersect_domain(const isl::point &set) const;
+  inline isl::union_pw_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_aff intersect_domain_wrapped_range(const isl::union_set &uset) const;
   inline isl::pw_aff intersect_params(isl::set set) const;
+  inline bool involves_locals() const;
+  inline bool involves_nan() const;
+  inline bool involves_param(const isl::id &id) const;
+  inline bool involves_param(const std::string &id) const;
+  inline bool involves_param(const isl::id_list &list) const;
   inline bool isa_aff() const;
+  inline bool isa_multi_aff() const;
+  inline bool isa_pw_multi_aff() const;
   inline isl::set le_set(isl::pw_aff pwaff2) const;
+  inline isl::pw_aff_list list() const;
   inline isl::set lt_set(isl::pw_aff pwaff2) const;
+  inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const;
   inline isl::pw_aff max(isl::pw_aff pwaff2) const;
+  inline isl::pw_aff max(const isl::aff &pwaff2) const;
+  inline isl::multi_val max_multi_val() const;
+  inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const;
   inline isl::pw_aff min(isl::pw_aff pwaff2) const;
+  inline isl::pw_aff min(const isl::aff &pwaff2) const;
+  inline isl::multi_val min_multi_val() const;
   inline isl::pw_aff mod(isl::val mod) const;
   inline isl::pw_aff mod(long mod) const;
   inline isl::pw_aff mul(isl::pw_aff pwaff2) const;
+  inline unsigned n_piece() const;
   inline isl::set ne_set(isl::pw_aff pwaff2) const;
   inline isl::pw_aff neg() const;
   static inline isl::pw_aff param_on_domain(isl::set domain, isl::id id);
+  inline bool plain_is_empty() const;
+  inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const;
+  inline isl::pw_multi_aff product(const isl::pw_multi_aff &pma2) const;
   inline isl::pw_aff pullback(isl::multi_aff ma) const;
   inline isl::pw_aff pullback(isl::multi_pw_aff mpa) const;
   inline isl::pw_aff pullback(isl::pw_multi_aff pma) const;
+  inline isl::union_pw_aff pullback(const isl::union_pw_multi_aff &upma) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::pw_multi_aff range_factor_domain() const;
+  inline isl::pw_multi_aff range_factor_range() const;
+  inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::pw_multi_aff range_product(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::multi_pw_aff reset_range_tuple_id() const;
+  inline isl::multi_pw_aff scale(const isl::multi_val &mv) const;
   inline isl::pw_aff scale(isl::val v) const;
   inline isl::pw_aff scale(long v) const;
+  inline isl::multi_pw_aff scale_down(const isl::multi_val &mv) const;
   inline isl::pw_aff scale_down(isl::val f) const;
   inline isl::pw_aff scale_down(long f) const;
+  inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::pw_multi_aff set_range_tuple(const isl::id &id) const;
+  inline isl::pw_multi_aff set_range_tuple(const std::string &id) const;
+  inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_aff sub(isl::pw_aff pwaff2) const;
+  inline isl::pw_multi_aff sub(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff sub(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_aff sub(const isl::aff &pwaff2) const;
   inline isl::pw_aff subtract_domain(isl::set set) const;
+  inline isl::union_pw_aff subtract_domain(const isl::space &space) const;
+  inline isl::union_pw_aff subtract_domain(const isl::union_set &uset) const;
+  inline isl::pw_aff subtract_domain(const isl::basic_set &set) const;
+  inline isl::pw_aff subtract_domain(const isl::point &set) const;
   inline isl::pw_aff tdiv_q(isl::pw_aff pa2) const;
   inline isl::pw_aff tdiv_r(isl::pw_aff pa2) const;
+  inline isl::pw_aff_list to_list() const;
+  inline isl::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::union_pw_aff to_union_pw_aff() const;
+  inline isl::union_pw_multi_aff to_union_pw_multi_aff() const;
+  inline isl::multi_pw_aff unbind_params_insert_domain(const isl::multi_id &domain) const;
+  inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
   inline isl::pw_aff union_add(isl::pw_aff pwaff2) const;
+  inline isl::pw_multi_aff union_add(const isl::pw_multi_aff &pma2) const;
+  inline isl::union_pw_aff union_add(const isl::union_pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_aff union_add(const isl::aff &pwaff2) const;
 };
 
 // declarations for isl::pw_aff_list
@@ -2042,6 +2827,7 @@
   inline /* implicit */ pw_aff_list(const pw_aff_list &obj);
   inline explicit pw_aff_list(isl::ctx ctx, int n);
   inline explicit pw_aff_list(isl::pw_aff el);
+  inline explicit pw_aff_list(isl::ctx ctx, const std::string &str);
   inline pw_aff_list &operator=(pw_aff_list obj);
   inline ~pw_aff_list();
   inline __isl_give isl_pw_aff_list *copy() const &;
@@ -2052,12 +2838,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::pw_aff_list add(isl::pw_aff el) const;
+  inline isl::pw_aff at(int index) const;
+  inline isl::pw_aff get_at(int index) const;
   inline isl::pw_aff_list clear() const;
   inline isl::pw_aff_list concat(isl::pw_aff_list list2) const;
   inline isl::pw_aff_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::pw_aff)> &fn) const;
-  inline isl::pw_aff at(int index) const;
-  inline isl::pw_aff get_at(int index) const;
   inline isl::pw_aff_list insert(unsigned int pos, isl::pw_aff el) const;
   inline unsigned size() const;
 };
@@ -2090,45 +2876,131 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
+  inline isl::multi_pw_aff add(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_multi_aff add(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff add(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff add(const isl::pw_aff &pma2) const;
   inline isl::pw_multi_aff add_constant(isl::multi_val mv) const;
   inline isl::pw_multi_aff add_constant(isl::val v) const;
   inline isl::pw_multi_aff add_constant(long v) const;
+  inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::map as_map() const;
   inline isl::multi_aff as_multi_aff() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
+  inline isl::union_map as_union_map() const;
+  inline isl::pw_aff at(int pos) const;
+  inline isl::pw_aff get_at(int pos) const;
+  inline isl::set bind(const isl::multi_id &tuple) const;
   inline isl::pw_multi_aff bind_domain(isl::multi_id tuple) const;
   inline isl::pw_multi_aff bind_domain_wrapped_domain(isl::multi_id tuple) const;
   inline isl::pw_multi_aff coalesce() const;
   inline isl::set domain() const;
   static inline isl::pw_multi_aff domain_map(isl::space space);
+  inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const;
+  inline isl::multi_pw_aff flat_range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_multi_aff flat_range_product(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff flat_range_product(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff flat_range_product(const isl::pw_aff &pma2) const;
   inline void foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline isl::pw_multi_aff gist(isl::set set) const;
+  inline isl::union_pw_multi_aff gist(const isl::union_set &context) const;
+  inline isl::pw_multi_aff gist(const isl::basic_set &set) const;
+  inline isl::pw_multi_aff gist(const isl::point &set) const;
+  inline bool has_range_tuple_id() const;
+  inline isl::multi_pw_aff identity() const;
   static inline isl::pw_multi_aff identity_on_domain(isl::space space);
   inline isl::pw_multi_aff insert_domain(isl::space domain) const;
   inline isl::pw_multi_aff intersect_domain(isl::set set) const;
+  inline isl::union_pw_multi_aff intersect_domain(const isl::space &space) const;
+  inline isl::union_pw_multi_aff intersect_domain(const isl::union_set &uset) const;
+  inline isl::pw_multi_aff intersect_domain(const isl::basic_set &set) const;
+  inline isl::pw_multi_aff intersect_domain(const isl::point &set) const;
+  inline isl::union_pw_multi_aff intersect_domain_wrapped_domain(const isl::union_set &uset) const;
+  inline isl::union_pw_multi_aff intersect_domain_wrapped_range(const isl::union_set &uset) const;
   inline isl::pw_multi_aff intersect_params(isl::set set) const;
   inline bool involves_locals() const;
+  inline bool involves_nan() const;
+  inline bool involves_param(const isl::id &id) const;
+  inline bool involves_param(const std::string &id) const;
+  inline bool involves_param(const isl::id_list &list) const;
   inline bool isa_multi_aff() const;
+  inline bool isa_pw_multi_aff() const;
+  inline isl::pw_aff_list list() const;
+  inline isl::multi_pw_aff max(const isl::multi_pw_aff &multi2) const;
   inline isl::multi_val max_multi_val() const;
+  inline isl::multi_pw_aff min(const isl::multi_pw_aff &multi2) const;
   inline isl::multi_val min_multi_val() const;
+  static inline isl::pw_multi_aff multi_val_on_domain(isl::set domain, isl::multi_val mv);
   inline unsigned n_piece() const;
+  inline isl::multi_pw_aff neg() const;
+  inline bool plain_is_empty() const;
+  inline bool plain_is_equal(const isl::multi_pw_aff &multi2) const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_multi_aff preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff preimage_domain_wrapped_domain(const isl::pw_aff &pma2) const;
+  inline isl::multi_pw_aff product(const isl::multi_pw_aff &multi2) const;
   inline isl::pw_multi_aff product(isl::pw_multi_aff pma2) const;
+  inline isl::pw_multi_aff product(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff product(const isl::pw_aff &pma2) const;
+  inline isl::multi_pw_aff pullback(const isl::multi_pw_aff &mpa2) const;
   inline isl::pw_multi_aff pullback(isl::multi_aff ma) const;
   inline isl::pw_multi_aff pullback(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff pullback(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
   inline isl::pw_multi_aff range_factor_domain() const;
   inline isl::pw_multi_aff range_factor_range() const;
   static inline isl::pw_multi_aff range_map(isl::space space);
+  inline isl::multi_pw_aff range_product(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_multi_aff range_product(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff range_product(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff range_product(const isl::pw_aff &pma2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
+  inline isl::multi_pw_aff reset_range_tuple_id() const;
+  inline isl::multi_pw_aff scale(const isl::multi_val &mv) const;
   inline isl::pw_multi_aff scale(isl::val v) const;
   inline isl::pw_multi_aff scale(long v) const;
+  inline isl::multi_pw_aff scale_down(const isl::multi_val &mv) const;
   inline isl::pw_multi_aff scale_down(isl::val v) const;
   inline isl::pw_multi_aff scale_down(long v) const;
+  inline isl::multi_pw_aff set_at(int pos, const isl::pw_aff &el) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::pw_multi_aff set_range_tuple(isl::id id) const;
+  inline isl::pw_multi_aff set_range_tuple(const std::string &id) const;
+  inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
+  inline isl::multi_pw_aff sub(const isl::multi_pw_aff &multi2) const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
   inline isl::pw_multi_aff sub(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff sub(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff sub(const isl::pw_aff &pma2) const;
   inline isl::pw_multi_aff subtract_domain(isl::set set) const;
+  inline isl::union_pw_multi_aff subtract_domain(const isl::space &space) const;
+  inline isl::union_pw_multi_aff subtract_domain(const isl::union_set &uset) const;
+  inline isl::pw_multi_aff subtract_domain(const isl::basic_set &set) const;
+  inline isl::pw_multi_aff subtract_domain(const isl::point &set) const;
+  inline isl::pw_multi_aff_list to_list() const;
+  inline isl::multi_pw_aff to_multi_pw_aff() const;
+  inline isl::union_pw_multi_aff to_union_pw_multi_aff() const;
+  inline isl::multi_pw_aff unbind_params_insert_domain(const isl::multi_id &domain) const;
+  inline isl::multi_pw_aff union_add(const isl::multi_pw_aff &mpa2) const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
   inline isl::pw_multi_aff union_add(isl::pw_multi_aff pma2) const;
+  inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::pw_multi_aff union_add(const isl::multi_aff &pma2) const;
+  inline isl::pw_multi_aff union_add(const isl::pw_aff &pma2) const;
   static inline isl::pw_multi_aff zero(isl::space space);
 };
 
@@ -2150,6 +3022,7 @@
   inline /* implicit */ pw_multi_aff_list(const pw_multi_aff_list &obj);
   inline explicit pw_multi_aff_list(isl::ctx ctx, int n);
   inline explicit pw_multi_aff_list(isl::pw_multi_aff el);
+  inline explicit pw_multi_aff_list(isl::ctx ctx, const std::string &str);
   inline pw_multi_aff_list &operator=(pw_multi_aff_list obj);
   inline ~pw_multi_aff_list();
   inline __isl_give isl_pw_multi_aff_list *copy() const &;
@@ -2160,12 +3033,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::pw_multi_aff_list add(isl::pw_multi_aff el) const;
+  inline isl::pw_multi_aff at(int index) const;
+  inline isl::pw_multi_aff get_at(int index) const;
   inline isl::pw_multi_aff_list clear() const;
   inline isl::pw_multi_aff_list concat(isl::pw_multi_aff_list list2) const;
   inline isl::pw_multi_aff_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::pw_multi_aff)> &fn) const;
-  inline isl::pw_multi_aff at(int index) const;
-  inline isl::pw_multi_aff get_at(int index) const;
   inline isl::pw_multi_aff_list insert(unsigned int pos, isl::pw_multi_aff el) const;
   inline unsigned size() const;
 };
@@ -2196,14 +3069,14 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
-  static inline isl::schedule from_domain(isl::union_set domain);
   inline isl::union_set domain() const;
   inline isl::union_set get_domain() const;
+  static inline isl::schedule from_domain(isl::union_set domain);
   inline isl::union_map map() const;
   inline isl::union_map get_map() const;
+  inline isl::schedule pullback(isl::union_pw_multi_aff upma) const;
   inline isl::schedule_node root() const;
   inline isl::schedule_node get_root() const;
-  inline isl::schedule pullback(isl::union_pw_multi_aff upma) const;
 };
 
 // declarations for isl::schedule_constraints
@@ -2232,9 +3105,9 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
-  inline isl::schedule compute_schedule() const;
   inline isl::union_map coincidence() const;
   inline isl::union_map get_coincidence() const;
+  inline isl::schedule compute_schedule() const;
   inline isl::union_map conditional_validity() const;
   inline isl::union_map get_conditional_validity() const;
   inline isl::union_map conditional_validity_condition() const;
@@ -2243,16 +3116,16 @@
   inline isl::set get_context() const;
   inline isl::union_set domain() const;
   inline isl::union_set get_domain() const;
+  static inline isl::schedule_constraints on_domain(isl::union_set domain);
   inline isl::union_map proximity() const;
   inline isl::union_map get_proximity() const;
-  inline isl::union_map validity() const;
-  inline isl::union_map get_validity() const;
-  static inline isl::schedule_constraints on_domain(isl::union_set domain);
   inline isl::schedule_constraints set_coincidence(isl::union_map coincidence) const;
   inline isl::schedule_constraints set_conditional_validity(isl::union_map condition, isl::union_map validity) const;
   inline isl::schedule_constraints set_context(isl::set context) const;
   inline isl::schedule_constraints set_proximity(isl::union_map proximity) const;
   inline isl::schedule_constraints set_validity(isl::union_map validity) const;
+  inline isl::union_map validity() const;
+  inline isl::union_map get_validity() const;
 };
 
 // declarations for isl::schedule_node
@@ -2290,29 +3163,17 @@
   inline isl::ctx ctx() const;
 
   inline isl::schedule_node ancestor(int generation) const;
+  inline unsigned ancestor_child_position(const isl::schedule_node &ancestor) const;
+  inline unsigned get_ancestor_child_position(const isl::schedule_node &ancestor) const;
   inline isl::schedule_node child(int pos) const;
+  inline unsigned child_position() const;
+  inline unsigned get_child_position() const;
   inline bool every_descendant(const std::function<bool(isl::schedule_node)> &test) const;
   inline isl::schedule_node first_child() const;
   inline void foreach_ancestor_top_down(const std::function<void(isl::schedule_node)> &fn) const;
   inline void foreach_descendant_top_down(const std::function<bool(isl::schedule_node)> &fn) const;
   static inline isl::schedule_node from_domain(isl::union_set domain);
   static inline isl::schedule_node from_extension(isl::union_map extension);
-  inline unsigned ancestor_child_position(const isl::schedule_node &ancestor) const;
-  inline unsigned get_ancestor_child_position(const isl::schedule_node &ancestor) const;
-  inline unsigned child_position() const;
-  inline unsigned get_child_position() const;
-  inline isl::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const;
-  inline isl::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const;
-  inline isl::union_map prefix_schedule_union_map() const;
-  inline isl::union_map get_prefix_schedule_union_map() const;
-  inline isl::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const;
-  inline isl::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const;
-  inline isl::schedule schedule() const;
-  inline isl::schedule get_schedule() const;
-  inline isl::schedule_node shared_ancestor(const isl::schedule_node &node2) const;
-  inline isl::schedule_node get_shared_ancestor(const isl::schedule_node &node2) const;
-  inline unsigned tree_depth() const;
-  inline unsigned get_tree_depth() const;
   inline isl::schedule_node graft_after(isl::schedule_node graft) const;
   inline isl::schedule_node graft_before(isl::schedule_node graft) const;
   inline bool has_children() const;
@@ -2335,8 +3196,20 @@
   inline isl::schedule_node order_after(isl::union_set filter) const;
   inline isl::schedule_node order_before(isl::union_set filter) const;
   inline isl::schedule_node parent() const;
+  inline isl::multi_union_pw_aff prefix_schedule_multi_union_pw_aff() const;
+  inline isl::multi_union_pw_aff get_prefix_schedule_multi_union_pw_aff() const;
+  inline isl::union_map prefix_schedule_union_map() const;
+  inline isl::union_map get_prefix_schedule_union_map() const;
+  inline isl::union_pw_multi_aff prefix_schedule_union_pw_multi_aff() const;
+  inline isl::union_pw_multi_aff get_prefix_schedule_union_pw_multi_aff() const;
   inline isl::schedule_node previous_sibling() const;
   inline isl::schedule_node root() const;
+  inline isl::schedule schedule() const;
+  inline isl::schedule get_schedule() const;
+  inline isl::schedule_node shared_ancestor(const isl::schedule_node &node2) const;
+  inline isl::schedule_node get_shared_ancestor(const isl::schedule_node &node2) const;
+  inline unsigned tree_depth() const;
+  inline unsigned get_tree_depth() const;
 };
 
 // declarations for isl::schedule_node_band
@@ -2360,14 +3233,14 @@
   inline isl::union_set get_ast_build_options() const;
   inline isl::set ast_isolate_option() const;
   inline isl::set get_ast_isolate_option() const;
-  inline isl::multi_union_pw_aff partial_schedule() const;
-  inline isl::multi_union_pw_aff get_partial_schedule() const;
-  inline bool permutable() const;
-  inline bool get_permutable() const;
   inline bool member_get_coincident(int pos) const;
   inline schedule_node_band member_set_coincident(int pos, int coincident) const;
   inline schedule_node_band mod(isl::multi_val mv) const;
   inline unsigned n_member() const;
+  inline isl::multi_union_pw_aff partial_schedule() const;
+  inline isl::multi_union_pw_aff get_partial_schedule() const;
+  inline bool permutable() const;
+  inline bool get_permutable() const;
   inline schedule_node_band scale(isl::multi_val mv) const;
   inline schedule_node_band scale_down(isl::multi_val mv) const;
   inline schedule_node_band set_ast_build_options(isl::union_set options) const;
@@ -2615,38 +3488,58 @@
 
   inline isl::basic_set affine_hull() const;
   inline isl::set apply(isl::map map) const;
+  inline isl::union_set apply(const isl::union_map &umap) const;
+  inline isl::set apply(const isl::basic_map &map) const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::set as_set() const;
   inline isl::set bind(isl::multi_id tuple) const;
   inline isl::set coalesce() const;
   inline isl::set complement() const;
+  inline isl::union_set compute_divs() const;
   inline isl::set detect_equalities() const;
   inline isl::val dim_max_val(int pos) const;
   inline isl::val dim_min_val(int pos) const;
   static inline isl::set empty(isl::space space);
+  inline bool every_set(const std::function<bool(isl::set)> &test) const;
+  inline isl::set extract_set(const isl::space &space) const;
   inline isl::set flatten() const;
   inline void foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const;
   inline void foreach_point(const std::function<void(isl::point)> &fn) const;
-  inline isl::multi_val plain_multi_val_if_fixed() const;
-  inline isl::multi_val get_plain_multi_val_if_fixed() const;
-  inline isl::fixed_box simple_fixed_box_hull() const;
-  inline isl::fixed_box get_simple_fixed_box_hull() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
-  inline isl::val stride(int pos) const;
-  inline isl::val get_stride(int pos) const;
+  inline void foreach_set(const std::function<void(isl::set)> &fn) const;
   inline isl::set gist(isl::set context) const;
+  inline isl::union_set gist(const isl::union_set &context) const;
+  inline isl::set gist(const isl::basic_set &context) const;
+  inline isl::set gist(const isl::point &context) const;
+  inline isl::union_set gist_params(const isl::set &set) const;
   inline isl::map identity() const;
   inline isl::pw_aff indicator_function() const;
   inline isl::map insert_domain(isl::space domain) const;
   inline isl::set intersect(isl::set set2) const;
+  inline isl::union_set intersect(const isl::union_set &uset2) const;
+  inline isl::set intersect(const isl::basic_set &set2) const;
+  inline isl::set intersect(const isl::point &set2) const;
   inline isl::set intersect_params(isl::set params) const;
   inline bool involves_locals() const;
   inline bool is_disjoint(const isl::set &set2) const;
+  inline bool is_disjoint(const isl::union_set &uset2) const;
+  inline bool is_disjoint(const isl::basic_set &set2) const;
+  inline bool is_disjoint(const isl::point &set2) const;
   inline bool is_empty() const;
   inline bool is_equal(const isl::set &set2) const;
+  inline bool is_equal(const isl::union_set &uset2) const;
+  inline bool is_equal(const isl::basic_set &set2) const;
+  inline bool is_equal(const isl::point &set2) const;
   inline bool is_singleton() const;
   inline bool is_strict_subset(const isl::set &set2) const;
+  inline bool is_strict_subset(const isl::union_set &uset2) const;
+  inline bool is_strict_subset(const isl::basic_set &set2) const;
+  inline bool is_strict_subset(const isl::point &set2) const;
   inline bool is_subset(const isl::set &set2) const;
+  inline bool is_subset(const isl::union_set &uset2) const;
+  inline bool is_subset(const isl::basic_set &set2) const;
+  inline bool is_subset(const isl::point &set2) const;
   inline bool is_wrapping() const;
+  inline bool isa_set() const;
   inline isl::set lexmax() const;
   inline isl::pw_multi_aff lexmax_pw_multi_aff() const;
   inline isl::set lexmin() const;
@@ -2658,22 +3551,41 @@
   inline isl::multi_pw_aff min_multi_pw_aff() const;
   inline isl::val min_val(const isl::aff &obj) const;
   inline isl::set params() const;
+  inline isl::multi_val plain_multi_val_if_fixed() const;
+  inline isl::multi_val get_plain_multi_val_if_fixed() const;
   inline isl::basic_set polyhedral_hull() const;
   inline isl::set preimage(isl::multi_aff ma) const;
   inline isl::set preimage(isl::multi_pw_aff mpa) const;
   inline isl::set preimage(isl::pw_multi_aff pma) const;
+  inline isl::union_set preimage(const isl::union_pw_multi_aff &upma) const;
   inline isl::set product(isl::set set2) const;
   inline isl::set project_out_all_params() const;
   inline isl::set project_out_param(isl::id id) const;
   inline isl::set project_out_param(const std::string &id) const;
   inline isl::set project_out_param(isl::id_list list) const;
+  inline isl::pw_multi_aff pw_multi_aff_on_domain(isl::multi_val mv) const;
   inline isl::basic_set sample() const;
   inline isl::point sample_point() const;
+  inline isl::fixed_box simple_fixed_box_hull() const;
+  inline isl::fixed_box get_simple_fixed_box_hull() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
+  inline isl::val stride(int pos) const;
+  inline isl::val get_stride(int pos) const;
   inline isl::set subtract(isl::set set2) const;
+  inline isl::union_set subtract(const isl::union_set &uset2) const;
+  inline isl::set subtract(const isl::basic_set &set2) const;
+  inline isl::set subtract(const isl::point &set2) const;
+  inline isl::union_set_list to_list() const;
+  inline isl::union_set to_union_set() const;
   inline isl::map translation() const;
+  inline unsigned tuple_dim() const;
   inline isl::set unbind_params(isl::multi_id tuple) const;
   inline isl::map unbind_params_insert_domain(isl::multi_id domain) const;
   inline isl::set unite(isl::set set2) const;
+  inline isl::union_set unite(const isl::union_set &uset2) const;
+  inline isl::set unite(const isl::basic_set &set2) const;
+  inline isl::set unite(const isl::point &set2) const;
   static inline isl::set universe(isl::space space);
   inline isl::basic_set unshifted_simple_hull() const;
   inline isl::map unwrap() const;
@@ -2708,23 +3620,57 @@
 
   inline isl::space add_named_tuple(isl::id tuple_id, unsigned int dim) const;
   inline isl::space add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
+  inline isl::space add_param(isl::id id) const;
+  inline isl::space add_param(const std::string &id) const;
   inline isl::space add_unnamed_tuple(unsigned int dim) const;
   inline isl::space curry() const;
   inline isl::space domain() const;
+  inline isl::multi_aff domain_map_multi_aff() const;
+  inline isl::pw_multi_aff domain_map_pw_multi_aff() const;
+  inline isl::id domain_tuple_id() const;
+  inline isl::id get_domain_tuple_id() const;
   inline isl::space flatten_domain() const;
   inline isl::space flatten_range() const;
+  inline bool has_domain_tuple_id() const;
+  inline bool has_range_tuple_id() const;
+  inline isl::multi_aff identity_multi_aff_on_domain() const;
+  inline isl::multi_pw_aff identity_multi_pw_aff_on_domain() const;
+  inline isl::pw_multi_aff identity_pw_multi_aff_on_domain() const;
   inline bool is_equal(const isl::space &space2) const;
   inline bool is_wrapping() const;
   inline isl::space map_from_set() const;
+  inline isl::multi_aff multi_aff(isl::aff_list list) const;
+  inline isl::multi_aff multi_aff_on_domain(isl::multi_val mv) const;
+  inline isl::multi_id multi_id(isl::id_list list) const;
+  inline isl::multi_pw_aff multi_pw_aff(isl::pw_aff_list list) const;
+  inline isl::multi_union_pw_aff multi_union_pw_aff(isl::union_pw_aff_list list) const;
+  inline isl::multi_val multi_val(isl::val_list list) const;
+  inline isl::aff param_aff_on_domain(isl::id id) const;
+  inline isl::aff param_aff_on_domain(const std::string &id) const;
   inline isl::space params() const;
   inline isl::space product(isl::space right) const;
   inline isl::space range() const;
+  inline isl::multi_aff range_map_multi_aff() const;
+  inline isl::pw_multi_aff range_map_pw_multi_aff() const;
   inline isl::space range_reverse() const;
+  inline isl::id range_tuple_id() const;
+  inline isl::id get_range_tuple_id() const;
   inline isl::space reverse() const;
+  inline isl::space set_domain_tuple(isl::id id) const;
+  inline isl::space set_domain_tuple(const std::string &id) const;
+  inline isl::space set_range_tuple(isl::id id) const;
+  inline isl::space set_range_tuple(const std::string &id) const;
   inline isl::space uncurry() const;
   static inline isl::space unit(isl::ctx ctx);
+  inline isl::map universe_map() const;
+  inline isl::set universe_set() const;
   inline isl::space unwrap() const;
   inline isl::space wrap() const;
+  inline isl::aff zero_aff_on_domain() const;
+  inline isl::multi_aff zero_multi_aff() const;
+  inline isl::multi_pw_aff zero_multi_pw_aff() const;
+  inline isl::multi_union_pw_aff zero_multi_union_pw_aff() const;
+  inline isl::multi_val zero_multi_val() const;
 };
 
 // declarations for isl::union_access_info
@@ -2831,6 +3777,9 @@
   inline isl::union_map affine_hull() const;
   inline isl::union_map apply_domain(isl::union_map umap2) const;
   inline isl::union_map apply_range(isl::union_map umap2) const;
+  inline isl::map as_map() const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::union_pw_multi_aff as_union_pw_multi_aff() const;
   inline isl::union_set bind_range(isl::multi_id tuple) const;
   inline isl::union_map coalesce() const;
   inline isl::union_map compute_divs() const;
@@ -2857,8 +3806,6 @@
   static inline isl::union_map from_domain(isl::union_set uset);
   static inline isl::union_map from_domain_and_range(isl::union_set domain, isl::union_set range);
   static inline isl::union_map from_range(isl::union_set uset);
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline isl::union_map gist(isl::union_map context) const;
   inline isl::union_map gist_domain(isl::union_set uset) const;
   inline isl::union_map gist_params(isl::set set) const;
@@ -2884,6 +3831,8 @@
   inline bool isa_map() const;
   inline isl::union_map lexmax() const;
   inline isl::union_map lexmin() const;
+  inline isl::map_list map_list() const;
+  inline isl::map_list get_map_list() const;
   inline isl::union_map polyhedral_hull() const;
   inline isl::union_map preimage_domain(isl::multi_aff ma) const;
   inline isl::union_map preimage_domain(isl::multi_pw_aff mpa) const;
@@ -2901,6 +3850,8 @@
   inline isl::union_map range_product(isl::union_map umap2) const;
   inline isl::union_map range_reverse() const;
   inline isl::union_map reverse() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::union_map subtract(isl::union_map umap2) const;
   inline isl::union_map subtract_domain(isl::union_set dom) const;
   inline isl::union_map subtract_range(isl::union_set dom) const;
@@ -2939,24 +3890,72 @@
   inline bool is_null() const;
   inline isl::ctx ctx() const;
 
+  inline isl::multi_union_pw_aff add(const isl::multi_union_pw_aff &multi2) const;
   inline isl::union_pw_aff add(isl::union_pw_aff upa2) const;
+  inline isl::union_pw_multi_aff add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::union_pw_aff add(const isl::aff &upa2) const;
+  inline isl::union_pw_aff add(const isl::pw_aff &upa2) const;
+  inline isl::union_pw_multi_aff apply(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
+  inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::union_map as_union_map() const;
+  inline isl::union_pw_aff at(int pos) const;
+  inline isl::union_set bind(const isl::multi_id &tuple) const;
   inline isl::union_set bind(isl::id id) const;
   inline isl::union_set bind(const std::string &id) const;
   inline isl::union_pw_aff coalesce() const;
   inline isl::union_set domain() const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
+  inline isl::pw_multi_aff extract_pw_multi_aff(const isl::space &space) const;
+  inline isl::multi_union_pw_aff flat_range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::union_pw_multi_aff flat_range_product(const isl::union_pw_multi_aff &upma2) const;
   inline isl::union_pw_aff gist(isl::union_set context) const;
+  inline bool has_range_tuple_id() const;
   inline isl::union_pw_aff intersect_domain(isl::space space) const;
   inline isl::union_pw_aff intersect_domain(isl::union_set uset) const;
   inline isl::union_pw_aff intersect_domain_wrapped_domain(isl::union_set uset) const;
   inline isl::union_pw_aff intersect_domain_wrapped_range(isl::union_set uset) const;
   inline isl::union_pw_aff intersect_params(isl::set set) const;
+  inline bool involves_locals() const;
+  inline bool involves_nan() const;
+  inline bool isa_pw_multi_aff() const;
+  inline isl::union_pw_aff_list list() const;
+  inline isl::multi_union_pw_aff neg() const;
+  inline bool plain_is_empty() const;
+  inline bool plain_is_equal(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const;
   inline isl::union_pw_aff pullback(isl::union_pw_multi_aff upma) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::union_pw_multi_aff range_factor_domain() const;
+  inline isl::union_pw_multi_aff range_factor_range() const;
+  inline isl::multi_union_pw_aff range_product(const isl::multi_union_pw_aff &multi2) const;
+  inline isl::union_pw_multi_aff range_product(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::id range_tuple_id() const;
+  inline isl::multi_union_pw_aff reset_range_tuple_id() const;
+  inline isl::multi_union_pw_aff scale(const isl::multi_val &mv) const;
+  inline isl::multi_union_pw_aff scale(const isl::val &v) const;
+  inline isl::multi_union_pw_aff scale(long v) const;
+  inline isl::multi_union_pw_aff scale_down(const isl::multi_val &mv) const;
+  inline isl::multi_union_pw_aff scale_down(const isl::val &v) const;
+  inline isl::multi_union_pw_aff scale_down(long v) const;
+  inline isl::multi_union_pw_aff set_at(int pos, const isl::union_pw_aff &el) const;
+  inline isl::multi_union_pw_aff set_range_tuple(const isl::id &id) const;
+  inline isl::multi_union_pw_aff set_range_tuple(const std::string &id) const;
+  inline unsigned size() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
+  inline isl::multi_union_pw_aff sub(const isl::multi_union_pw_aff &multi2) const;
   inline isl::union_pw_aff sub(isl::union_pw_aff upa2) const;
+  inline isl::union_pw_multi_aff sub(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::union_pw_aff sub(const isl::aff &upa2) const;
+  inline isl::union_pw_aff sub(const isl::pw_aff &upa2) const;
   inline isl::union_pw_aff subtract_domain(isl::space space) const;
   inline isl::union_pw_aff subtract_domain(isl::union_set uset) const;
+  inline isl::union_pw_aff_list to_list() const;
+  inline isl::multi_union_pw_aff union_add(const isl::multi_union_pw_aff &mupa2) const;
   inline isl::union_pw_aff union_add(isl::union_pw_aff upa2) const;
+  inline isl::union_pw_multi_aff union_add(const isl::union_pw_multi_aff &upma2) const;
+  inline isl::union_pw_aff union_add(const isl::aff &upa2) const;
+  inline isl::union_pw_aff union_add(const isl::pw_aff &upa2) const;
 };
 
 // declarations for isl::union_pw_aff_list
@@ -2977,6 +3976,7 @@
   inline /* implicit */ union_pw_aff_list(const union_pw_aff_list &obj);
   inline explicit union_pw_aff_list(isl::ctx ctx, int n);
   inline explicit union_pw_aff_list(isl::union_pw_aff el);
+  inline explicit union_pw_aff_list(isl::ctx ctx, const std::string &str);
   inline union_pw_aff_list &operator=(union_pw_aff_list obj);
   inline ~union_pw_aff_list();
   inline __isl_give isl_union_pw_aff_list *copy() const &;
@@ -2987,12 +3987,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::union_pw_aff_list add(isl::union_pw_aff el) const;
+  inline isl::union_pw_aff at(int index) const;
+  inline isl::union_pw_aff get_at(int index) const;
   inline isl::union_pw_aff_list clear() const;
   inline isl::union_pw_aff_list concat(isl::union_pw_aff_list list2) const;
   inline isl::union_pw_aff_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::union_pw_aff)> &fn) const;
-  inline isl::union_pw_aff at(int index) const;
-  inline isl::union_pw_aff get_at(int index) const;
   inline isl::union_pw_aff_list insert(unsigned int pos, isl::union_pw_aff el) const;
   inline unsigned size() const;
 };
@@ -3028,14 +4028,14 @@
 
   inline isl::union_pw_multi_aff add(isl::union_pw_multi_aff upma2) const;
   inline isl::union_pw_multi_aff apply(isl::union_pw_multi_aff upma2) const;
+  inline isl::multi_union_pw_aff as_multi_union_pw_aff() const;
   inline isl::pw_multi_aff as_pw_multi_aff() const;
+  inline isl::union_map as_union_map() const;
   inline isl::union_pw_multi_aff coalesce() const;
   inline isl::union_set domain() const;
   static inline isl::union_pw_multi_aff empty(isl::ctx ctx);
   inline isl::pw_multi_aff extract_pw_multi_aff(isl::space space) const;
   inline isl::union_pw_multi_aff flat_range_product(isl::union_pw_multi_aff upma2) const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline isl::union_pw_multi_aff gist(isl::union_set context) const;
   inline isl::union_pw_multi_aff intersect_domain(isl::space space) const;
   inline isl::union_pw_multi_aff intersect_domain(isl::union_set uset) const;
@@ -3047,9 +4047,13 @@
   inline bool plain_is_empty() const;
   inline isl::union_pw_multi_aff preimage_domain_wrapped_domain(isl::union_pw_multi_aff upma2) const;
   inline isl::union_pw_multi_aff pullback(isl::union_pw_multi_aff upma2) const;
+  inline isl::pw_multi_aff_list pw_multi_aff_list() const;
+  inline isl::pw_multi_aff_list get_pw_multi_aff_list() const;
   inline isl::union_pw_multi_aff range_factor_domain() const;
   inline isl::union_pw_multi_aff range_factor_range() const;
   inline isl::union_pw_multi_aff range_product(isl::union_pw_multi_aff upma2) const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::union_pw_multi_aff sub(isl::union_pw_multi_aff upma2) const;
   inline isl::union_pw_multi_aff subtract_domain(isl::space space) const;
   inline isl::union_pw_multi_aff subtract_domain(isl::union_set uset) const;
@@ -3087,6 +4091,7 @@
 
   inline isl::union_set affine_hull() const;
   inline isl::union_set apply(isl::union_map umap) const;
+  inline isl::set as_set() const;
   inline isl::union_set coalesce() const;
   inline isl::union_set compute_divs() const;
   inline isl::union_set detect_equalities() const;
@@ -3095,8 +4100,6 @@
   inline isl::set extract_set(isl::space space) const;
   inline void foreach_point(const std::function<void(isl::point)> &fn) const;
   inline void foreach_set(const std::function<void(isl::set)> &fn) const;
-  inline isl::space space() const;
-  inline isl::space get_space() const;
   inline isl::union_set gist(isl::union_set context) const;
   inline isl::union_set gist_params(isl::set set) const;
   inline isl::union_map identity() const;
@@ -3115,7 +4118,10 @@
   inline isl::union_set preimage(isl::pw_multi_aff pma) const;
   inline isl::union_set preimage(isl::union_pw_multi_aff upma) const;
   inline isl::point sample_point() const;
+  inline isl::space space() const;
+  inline isl::space get_space() const;
   inline isl::union_set subtract(isl::union_set uset2) const;
+  inline isl::union_set_list to_list() const;
   inline isl::union_set unite(isl::union_set uset2) const;
   inline isl::union_set universe() const;
   inline isl::union_map unwrap() const;
@@ -3139,6 +4145,7 @@
   inline /* implicit */ union_set_list(const union_set_list &obj);
   inline explicit union_set_list(isl::ctx ctx, int n);
   inline explicit union_set_list(isl::union_set el);
+  inline explicit union_set_list(isl::ctx ctx, const std::string &str);
   inline union_set_list &operator=(union_set_list obj);
   inline ~union_set_list();
   inline __isl_give isl_union_set_list *copy() const &;
@@ -3149,12 +4156,12 @@
   inline isl::ctx ctx() const;
 
   inline isl::union_set_list add(isl::union_set el) const;
+  inline isl::union_set at(int index) const;
+  inline isl::union_set get_at(int index) const;
   inline isl::union_set_list clear() const;
   inline isl::union_set_list concat(isl::union_set_list list2) const;
   inline isl::union_set_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::union_set)> &fn) const;
-  inline isl::union_set at(int index) const;
-  inline isl::union_set get_at(int index) const;
   inline isl::union_set_list insert(unsigned int pos, isl::union_set el) const;
   inline unsigned size() const;
 };
@@ -3193,6 +4200,8 @@
   inline isl::val add(long v2) const;
   inline isl::val ceil() const;
   inline int cmp_si(long i) const;
+  inline long den_si() const;
+  inline long get_den_si() const;
   inline isl::val div(isl::val v2) const;
   inline isl::val div(long v2) const;
   inline bool eq(const isl::val &v2) const;
@@ -3202,10 +4211,6 @@
   inline isl::val gcd(long v2) const;
   inline bool ge(const isl::val &v2) const;
   inline bool ge(long v2) const;
-  inline long den_si() const;
-  inline long get_den_si() const;
-  inline long num_si() const;
-  inline long get_num_si() const;
   inline bool gt(const isl::val &v2) const;
   inline bool gt(long v2) const;
   static inline isl::val infty(isl::ctx ctx);
@@ -3242,11 +4247,14 @@
   inline isl::val neg() const;
   static inline isl::val neginfty(isl::ctx ctx);
   static inline isl::val negone(isl::ctx ctx);
+  inline long num_si() const;
+  inline long get_num_si() const;
   static inline isl::val one(isl::ctx ctx);
   inline isl::val pow2() const;
   inline int sgn() const;
   inline isl::val sub(isl::val v2) const;
   inline isl::val sub(long v2) const;
+  inline isl::val_list to_list() const;
   inline isl::val trunc() const;
   static inline isl::val zero(isl::ctx ctx);
 };
@@ -3269,6 +4277,7 @@
   inline /* implicit */ val_list(const val_list &obj);
   inline explicit val_list(isl::ctx ctx, int n);
   inline explicit val_list(isl::val el);
+  inline explicit val_list(isl::ctx ctx, const std::string &str);
   inline val_list &operator=(val_list obj);
   inline ~val_list();
   inline __isl_give isl_val_list *copy() const &;
@@ -3280,12 +4289,12 @@
 
   inline isl::val_list add(isl::val el) const;
   inline isl::val_list add(long el) const;
+  inline isl::val at(int index) const;
+  inline isl::val get_at(int index) const;
   inline isl::val_list clear() const;
   inline isl::val_list concat(isl::val_list list2) const;
   inline isl::val_list drop(unsigned int first, unsigned int n) const;
   inline void foreach(const std::function<void(isl::val)> &fn) const;
-  inline isl::val at(int index) const;
-  inline isl::val get_at(int index) const;
   inline isl::val_list insert(unsigned int pos, isl::val el) const;
   inline isl::val_list insert(unsigned int pos, long el) const;
   inline unsigned size() const;
@@ -3380,6 +4389,55 @@
   return manage(res);
 }
 
+isl::multi_aff aff::add(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).add(multi2);
+}
+
+isl::multi_pw_aff aff::add(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(multi2);
+}
+
+isl::multi_union_pw_aff aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(multi2);
+}
+
+isl::pw_aff aff::add(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(pwaff2);
+}
+
+isl::pw_multi_aff aff::add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(pma2);
+}
+
+isl::union_pw_aff aff::add(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(upa2);
+}
+
+isl::union_pw_multi_aff aff::add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).add(upma2);
+}
+
 isl::aff aff::add_constant(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -3399,6 +4457,76 @@
   return this->add_constant(isl::val(ctx(), v));
 }
 
+isl::multi_aff aff::add_constant(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).add_constant(mv);
+}
+
+isl::union_pw_multi_aff aff::apply(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).apply(upma2);
+}
+
+isl::aff aff::as_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_aff();
+}
+
+isl::map aff::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_map();
+}
+
+isl::multi_aff aff::as_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_multi_aff();
+}
+
+isl::multi_union_pw_aff aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff aff::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_pw_multi_aff();
+}
+
+isl::set aff::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).as_set();
+}
+
+isl::union_map aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).as_union_map();
+}
+
+isl::aff aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).at(pos);
+}
+
 isl::basic_set aff::bind(isl::id id) const
 {
   if (!ptr || id.is_null())
@@ -3418,6 +4546,27 @@
   return this->bind(isl::id(ctx(), id));
 }
 
+isl::basic_set aff::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).bind(tuple);
+}
+
+isl::pw_aff aff::bind_domain(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).bind_domain(tuple);
+}
+
+isl::pw_aff aff::bind_domain_wrapped_domain(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).bind_domain_wrapped_domain(tuple);
+}
+
 isl::aff aff::ceil() const
 {
   if (!ptr)
@@ -3430,64 +4579,25 @@
   return manage(res);
 }
 
-isl::aff aff::div(isl::aff aff2) const
-{
-  if (!ptr || aff2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_div(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::set aff::eq_set(isl::aff aff2) const
-{
-  if (!ptr || aff2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_eq_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::val aff::eval(isl::point pnt) const
-{
-  if (!ptr || pnt.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_eval(copy(), pnt.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::aff aff::floor() const
+isl::pw_aff aff::coalesce() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_floor(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).coalesce();
 }
 
-isl::set aff::ge_set(isl::aff aff2) const
+isl::pw_aff aff::cond(const isl::pw_aff &pwaff_true, const isl::pw_aff &pwaff_false) const
 {
-  if (!ptr || aff2.is_null())
+  if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_ge_set(copy(), aff2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::pw_aff(*this).cond(pwaff_true, pwaff_false);
+}
+
+isl::multi_val aff::constant_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).constant_multi_val();
 }
 
 isl::val aff::constant_val() const
@@ -3507,6 +4617,143 @@
   return constant_val();
 }
 
+isl::aff aff::div(isl::aff aff2) const
+{
+  if (!ptr || aff2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_div(copy(), aff2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff aff::div(const isl::pw_aff &pa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).div(pa2);
+}
+
+isl::set aff::domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).domain();
+}
+
+isl::set aff::eq_set(isl::aff aff2) const
+{
+  if (!ptr || aff2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_eq_set(copy(), aff2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set aff::eq_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).eq_set(pwaff2);
+}
+
+isl::val aff::eval(isl::point pnt) const
+{
+  if (!ptr || pnt.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_eval(copy(), pnt.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff aff::extract_pw_multi_aff(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::multi_aff aff::flat_range_product(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::multi_pw_aff aff::flat_range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::multi_union_pw_aff aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::pw_multi_aff aff::flat_range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).flat_range_product(pma2);
+}
+
+isl::union_pw_multi_aff aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).flat_range_product(upma2);
+}
+
+isl::aff aff::floor() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_floor(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).foreach_piece(fn);
+}
+
+isl::set aff::ge_set(isl::aff aff2) const
+{
+  if (!ptr || aff2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_ge_set(copy(), aff2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set aff::ge_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).ge_set(pwaff2);
+}
+
 isl::aff aff::gist(isl::set context) const
 {
   if (!ptr || context.is_null())
@@ -3519,6 +4766,27 @@
   return manage(res);
 }
 
+isl::union_pw_aff aff::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).gist(context);
+}
+
+isl::aff aff::gist(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+isl::aff aff::gist(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
 isl::set aff::gt_set(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -3531,6 +4799,111 @@
   return manage(res);
 }
 
+isl::set aff::gt_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).gt_set(pwaff2);
+}
+
+bool aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).has_range_tuple_id();
+}
+
+isl::multi_aff aff::identity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).identity();
+}
+
+isl::pw_aff aff::insert_domain(const isl::space &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).insert_domain(domain);
+}
+
+isl::pw_aff aff::intersect_domain(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain(set);
+}
+
+isl::union_pw_aff aff::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain(space);
+}
+
+isl::union_pw_aff aff::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain(uset);
+}
+
+isl::union_pw_aff aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::union_pw_aff aff::intersect_domain_wrapped_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
+isl::pw_aff aff::intersect_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).intersect_params(set);
+}
+
+bool aff::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).involves_locals();
+}
+
+bool aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).involves_nan();
+}
+
+bool aff::involves_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).involves_param(id);
+}
+
+bool aff::involves_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->involves_param(isl::id(ctx(), id));
+}
+
+bool aff::involves_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).involves_param(list);
+}
+
 bool aff::is_cst() const
 {
   if (!ptr)
@@ -3543,6 +4916,27 @@
   return res;
 }
 
+bool aff::isa_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).isa_aff();
+}
+
+bool aff::isa_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).isa_multi_aff();
+}
+
+bool aff::isa_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).isa_pw_multi_aff();
+}
+
 isl::set aff::le_set(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -3555,6 +4949,20 @@
   return manage(res);
 }
 
+isl::set aff::le_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).le_set(pwaff2);
+}
+
+isl::aff_list aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).list();
+}
+
 isl::set aff::lt_set(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -3567,6 +4975,55 @@
   return manage(res);
 }
 
+isl::set aff::lt_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).lt_set(pwaff2);
+}
+
+isl::multi_pw_aff aff::max(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).max(multi2);
+}
+
+isl::pw_aff aff::max(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).max(pwaff2);
+}
+
+isl::multi_val aff::max_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).max_multi_val();
+}
+
+isl::multi_pw_aff aff::min(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).min(multi2);
+}
+
+isl::pw_aff aff::min(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).min(pwaff2);
+}
+
+isl::multi_val aff::min_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).min_multi_val();
+}
+
 isl::aff aff::mod(isl::val mod) const
 {
   if (!ptr || mod.is_null())
@@ -3598,6 +5055,20 @@
   return manage(res);
 }
 
+isl::pw_aff aff::mul(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).mul(pwaff2);
+}
+
+unsigned aff::n_piece() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).n_piece();
+}
+
 isl::set aff::ne_set(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -3610,6 +5081,13 @@
   return manage(res);
 }
 
+isl::set aff::ne_set(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).ne_set(pwaff2);
+}
+
 isl::aff aff::neg() const
 {
   if (!ptr)
@@ -3622,6 +5100,69 @@
   return manage(res);
 }
 
+bool aff::plain_is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).plain_is_empty();
+}
+
+bool aff::plain_is_equal(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).plain_is_equal(multi2);
+}
+
+bool aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).plain_is_equal(multi2);
+}
+
+bool aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::union_pw_multi_aff aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::multi_aff aff::product(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).product(multi2);
+}
+
+isl::multi_pw_aff aff::product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).product(multi2);
+}
+
+isl::pw_multi_aff aff::product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).product(pma2);
+}
+
 isl::aff aff::pullback(isl::multi_aff ma) const
 {
   if (!ptr || ma.is_null())
@@ -3634,6 +5175,104 @@
   return manage(res);
 }
 
+isl::pw_aff aff::pullback(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).pullback(mpa);
+}
+
+isl::pw_aff aff::pullback(const isl::pw_multi_aff &pma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).pullback(pma);
+}
+
+isl::union_pw_aff aff::pullback(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).pullback(upma);
+}
+
+isl::aff aff::pullback(const isl::aff &ma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->pullback(isl::multi_aff(ma));
+}
+
+isl::pw_multi_aff_list aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).pw_multi_aff_list();
+}
+
+isl::pw_multi_aff aff::range_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_factor_domain();
+}
+
+isl::pw_multi_aff aff::range_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_factor_range();
+}
+
+isl::multi_aff aff::range_product(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).range_product(multi2);
+}
+
+isl::multi_pw_aff aff::range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(multi2);
+}
+
+isl::multi_union_pw_aff aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(multi2);
+}
+
+isl::pw_multi_aff aff::range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(pma2);
+}
+
+isl::union_pw_multi_aff aff::range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).range_product(upma2);
+}
+
+isl::id aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).range_tuple_id();
+}
+
+isl::multi_aff aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).reset_range_tuple_id();
+}
+
 isl::aff aff::scale(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -3653,6 +5292,13 @@
   return this->scale(isl::val(ctx(), v));
 }
 
+isl::multi_aff aff::scale(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).scale(mv);
+}
+
 isl::aff aff::scale_down(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -3672,6 +5318,62 @@
   return this->scale_down(isl::val(ctx(), v));
 }
 
+isl::multi_aff aff::scale_down(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).scale_down(mv);
+}
+
+isl::multi_aff aff::set_at(int pos, const isl::aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).set_at(pos, el);
+}
+
+isl::multi_pw_aff aff::set_at(int pos, const isl::pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).set_at(pos, el);
+}
+
+isl::multi_union_pw_aff aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).set_at(pos, el);
+}
+
+isl::multi_aff aff::set_range_tuple(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).set_range_tuple(id);
+}
+
+isl::multi_aff aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+unsigned aff::size() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).size();
+}
+
+isl::space aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).space();
+}
+
 isl::aff aff::sub(isl::aff aff2) const
 {
   if (!ptr || aff2.is_null())
@@ -3684,6 +5386,137 @@
   return manage(res);
 }
 
+isl::multi_aff aff::sub(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).sub(multi2);
+}
+
+isl::multi_pw_aff aff::sub(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(multi2);
+}
+
+isl::multi_union_pw_aff aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(multi2);
+}
+
+isl::pw_aff aff::sub(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(pwaff2);
+}
+
+isl::pw_multi_aff aff::sub(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(pma2);
+}
+
+isl::union_pw_aff aff::sub(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(upa2);
+}
+
+isl::union_pw_multi_aff aff::sub(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).sub(upma2);
+}
+
+isl::pw_aff aff::subtract_domain(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).subtract_domain(set);
+}
+
+isl::union_pw_aff aff::subtract_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).subtract_domain(space);
+}
+
+isl::union_pw_aff aff::subtract_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).subtract_domain(uset);
+}
+
+isl::pw_aff aff::tdiv_q(const isl::pw_aff &pa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).tdiv_q(pa2);
+}
+
+isl::pw_aff aff::tdiv_r(const isl::pw_aff &pa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).tdiv_r(pa2);
+}
+
+isl::aff_list aff::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff aff::to_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).to_multi_pw_aff();
+}
+
+isl::multi_union_pw_aff aff::to_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).to_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff aff::to_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_aff(*this).to_pw_multi_aff();
+}
+
+isl::union_pw_aff aff::to_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).to_union_pw_aff();
+}
+
+isl::union_pw_multi_aff aff::to_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).to_union_pw_multi_aff();
+}
+
 isl::aff aff::unbind_params_insert_domain(isl::multi_id domain) const
 {
   if (!ptr || domain.is_null())
@@ -3696,6 +5529,48 @@
   return manage(res);
 }
 
+isl::multi_pw_aff aff::union_add(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(mpa2);
+}
+
+isl::multi_union_pw_aff aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(mupa2);
+}
+
+isl::pw_aff aff::union_add(const isl::pw_aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(pwaff2);
+}
+
+isl::pw_multi_aff aff::union_add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(pma2);
+}
+
+isl::union_pw_aff aff::union_add(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(upa2);
+}
+
+isl::union_pw_multi_aff aff::union_add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_aff(*this).union_add(upma2);
+}
+
 isl::aff aff::zero_on_domain(isl::space space)
 {
   if (space.is_null())
@@ -3779,6 +5654,16 @@
   ptr = res;
 }
 
+aff_list::aff_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 aff_list &aff_list::operator=(aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -3823,6 +5708,23 @@
   return manage(res);
 }
 
+isl::aff aff_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_aff_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::aff aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::aff_list aff_list::clear() const
 {
   if (!ptr)
@@ -3887,23 +5789,6 @@
   return;
 }
 
-isl::aff aff_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_aff_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::aff aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::aff_list aff_list::insert(unsigned int pos, isl::aff el) const
 {
   if (!ptr || el.is_null())
@@ -4175,28 +6060,6 @@
   return manage(res);
 }
 
-isl::union_map ast_build::schedule() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_build_get_schedule(get());
-  if (at_each_domain_data && at_each_domain_data->eptr) {
-    std::exception_ptr eptr = at_each_domain_data->eptr;
-    at_each_domain_data->eptr = nullptr;
-    std::rethrow_exception(eptr);
-  }
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_map ast_build::get_schedule() const
-{
-  return schedule();
-}
-
 isl::ast_node ast_build::node_from(isl::schedule schedule) const
 {
   if (!ptr || schedule.is_null())
@@ -4231,6 +6094,28 @@
   return manage(res);
 }
 
+isl::union_map ast_build::schedule() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_build_get_schedule(get());
+  if (at_each_domain_data && at_each_domain_data->eptr) {
+    std::exception_ptr eptr = at_each_domain_data->eptr;
+    at_each_domain_data->eptr = nullptr;
+    std::rethrow_exception(eptr);
+  }
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map ast_build::get_schedule() const
+{
+  return schedule();
+}
+
 // implementations for isl::ast_expr
 ast_expr manage(__isl_take isl_ast_expr *ptr) {
   if (!ptr)
@@ -5546,6 +7431,18 @@
   return tmp;
 }
 
+isl::ast_node_list ast_node::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_node_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const ast_node &obj)
 {
   if (!obj.get())
@@ -5701,6 +7598,18 @@
   return init();
 }
 
+bool ast_node_for::is_degenerate() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_node_for_is_degenerate(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::ast_expr ast_node_for::iterator() const
 {
   if (!ptr)
@@ -5718,18 +7627,6 @@
   return iterator();
 }
 
-bool ast_node_for::is_degenerate() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_for_is_degenerate(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
 inline std::ostream &operator<<(std::ostream &os, const ast_node_for &obj)
 {
   if (!obj.get())
@@ -5799,6 +7696,18 @@
   return else_node();
 }
 
+bool ast_node_if::has_else_node() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_node_if_has_else_node(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::ast_node ast_node_if::then_node() const
 {
   if (!ptr)
@@ -5816,18 +7725,6 @@
   return then_node();
 }
 
-bool ast_node_if::has_else_node() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_if_has_else_node(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
 inline std::ostream &operator<<(std::ostream &os, const ast_node_if &obj)
 {
   if (!obj.get())
@@ -5943,6 +7840,23 @@
   return manage(res);
 }
 
+isl::ast_node ast_node_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_ast_node_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::ast_node ast_node_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::ast_node_list ast_node_list::clear() const
 {
   if (!ptr)
@@ -6007,23 +7921,6 @@
   return;
 }
 
-isl::ast_node ast_node_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_ast_node_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::ast_node ast_node_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::ast_node_list ast_node_list::insert(unsigned int pos, isl::ast_node el) const
 {
   if (!ptr || el.is_null())
@@ -6284,6 +8181,20 @@
   return manage(res);
 }
 
+isl::map basic_map::apply_domain(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).apply_domain(map2);
+}
+
+isl::union_map basic_map::apply_domain(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).apply_domain(umap2);
+}
+
 isl::basic_map basic_map::apply_range(isl::basic_map bmap2) const
 {
   if (!ptr || bmap2.is_null())
@@ -6296,6 +8207,90 @@
   return manage(res);
 }
 
+isl::map basic_map::apply_range(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).apply_range(map2);
+}
+
+isl::union_map basic_map::apply_range(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).apply_range(umap2);
+}
+
+isl::map basic_map::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).as_map();
+}
+
+isl::multi_union_pw_aff basic_map::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff basic_map::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).as_pw_multi_aff();
+}
+
+isl::union_pw_multi_aff basic_map::as_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).as_union_pw_multi_aff();
+}
+
+isl::set basic_map::bind_domain(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).bind_domain(tuple);
+}
+
+isl::set basic_map::bind_range(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).bind_range(tuple);
+}
+
+isl::map basic_map::coalesce() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).coalesce();
+}
+
+isl::map basic_map::complement() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).complement();
+}
+
+isl::union_map basic_map::compute_divs() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).compute_divs();
+}
+
+isl::map basic_map::curry() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).curry();
+}
+
 isl::basic_set basic_map::deltas() const
 {
   if (!ptr)
@@ -6320,6 +8315,125 @@
   return manage(res);
 }
 
+isl::set basic_map::domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain();
+}
+
+isl::map basic_map::domain_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_factor_domain();
+}
+
+isl::map basic_map::domain_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_factor_range();
+}
+
+isl::union_map basic_map::domain_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_map();
+}
+
+isl::union_pw_multi_aff basic_map::domain_map_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_map_union_pw_multi_aff();
+}
+
+isl::map basic_map::domain_product(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_product(map2);
+}
+
+isl::union_map basic_map::domain_product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_product(umap2);
+}
+
+unsigned basic_map::domain_tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_tuple_dim();
+}
+
+isl::id basic_map::domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).domain_tuple_id();
+}
+
+isl::map basic_map::eq_at(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).eq_at(mpa);
+}
+
+isl::union_map basic_map::eq_at(const isl::multi_union_pw_aff &mupa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).eq_at(mupa);
+}
+
+bool basic_map::every_map(const std::function<bool(isl::map)> &test) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).every_map(test);
+}
+
+isl::map basic_map::extract_map(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).extract_map(space);
+}
+
+isl::map basic_map::factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).factor_domain();
+}
+
+isl::map basic_map::factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).factor_range();
+}
+
+isl::union_map basic_map::fixed_power(const isl::val &exp) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).fixed_power(exp);
+}
+
+isl::union_map basic_map::fixed_power(long exp) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->fixed_power(isl::val(ctx(), exp));
+}
+
 isl::basic_map basic_map::flatten() const
 {
   if (!ptr)
@@ -6356,6 +8470,20 @@
   return manage(res);
 }
 
+void basic_map::foreach_basic_map(const std::function<void(isl::basic_map)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).foreach_basic_map(fn);
+}
+
+void basic_map::foreach_map(const std::function<void(isl::map)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).foreach_map(fn);
+}
+
 isl::basic_map basic_map::gist(isl::basic_map context) const
 {
   if (!ptr || context.is_null())
@@ -6368,6 +8496,62 @@
   return manage(res);
 }
 
+isl::map basic_map::gist(const isl::map &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist(context);
+}
+
+isl::union_map basic_map::gist(const isl::union_map &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist(context);
+}
+
+isl::map basic_map::gist_domain(const isl::set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist_domain(context);
+}
+
+isl::union_map basic_map::gist_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist_domain(uset);
+}
+
+isl::union_map basic_map::gist_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist_params(set);
+}
+
+isl::union_map basic_map::gist_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).gist_range(uset);
+}
+
+bool basic_map::has_domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).has_domain_tuple_id();
+}
+
+bool basic_map::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).has_range_tuple_id();
+}
+
 isl::basic_map basic_map::intersect(isl::basic_map bmap2) const
 {
   if (!ptr || bmap2.is_null())
@@ -6380,6 +8564,20 @@
   return manage(res);
 }
 
+isl::map basic_map::intersect(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect(map2);
+}
+
+isl::union_map basic_map::intersect(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect(umap2);
+}
+
 isl::basic_map basic_map::intersect_domain(isl::basic_set bset) const
 {
   if (!ptr || bset.is_null())
@@ -6392,6 +8590,69 @@
   return manage(res);
 }
 
+isl::map basic_map::intersect_domain(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain(set);
+}
+
+isl::union_map basic_map::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain(space);
+}
+
+isl::union_map basic_map::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain(uset);
+}
+
+isl::basic_map basic_map::intersect_domain(const isl::point &bset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::basic_set(bset));
+}
+
+isl::map basic_map::intersect_domain_factor_domain(const isl::map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::union_map basic_map::intersect_domain_factor_domain(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::map basic_map::intersect_domain_factor_range(const isl::map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::union_map basic_map::intersect_domain_factor_range(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::map basic_map::intersect_params(const isl::set &params) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_params(params);
+}
+
 isl::basic_map basic_map::intersect_range(isl::basic_set bset) const
 {
   if (!ptr || bset.is_null())
@@ -6404,6 +8665,83 @@
   return manage(res);
 }
 
+isl::map basic_map::intersect_range(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range(set);
+}
+
+isl::union_map basic_map::intersect_range(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range(space);
+}
+
+isl::union_map basic_map::intersect_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range(uset);
+}
+
+isl::basic_map basic_map::intersect_range(const isl::point &bset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_range(isl::basic_set(bset));
+}
+
+isl::map basic_map::intersect_range_factor_domain(const isl::map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::union_map basic_map::intersect_range_factor_domain(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::map basic_map::intersect_range_factor_range(const isl::map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range_factor_range(factor);
+}
+
+isl::union_map basic_map::intersect_range_factor_range(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).intersect_range_factor_range(factor);
+}
+
+bool basic_map::is_bijective() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_bijective();
+}
+
+bool basic_map::is_disjoint(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_disjoint(map2);
+}
+
+bool basic_map::is_disjoint(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_disjoint(umap2);
+}
+
 bool basic_map::is_empty() const
 {
   if (!ptr)
@@ -6428,6 +8766,48 @@
   return res;
 }
 
+bool basic_map::is_equal(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_equal(map2);
+}
+
+bool basic_map::is_equal(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_equal(umap2);
+}
+
+bool basic_map::is_injective() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_injective();
+}
+
+bool basic_map::is_single_valued() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_single_valued();
+}
+
+bool basic_map::is_strict_subset(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_strict_subset(map2);
+}
+
+bool basic_map::is_strict_subset(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_strict_subset(umap2);
+}
+
 bool basic_map::is_subset(const isl::basic_map &bmap2) const
 {
   if (!ptr || bmap2.is_null())
@@ -6440,6 +8820,55 @@
   return res;
 }
 
+bool basic_map::is_subset(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_subset(map2);
+}
+
+bool basic_map::is_subset(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).is_subset(umap2);
+}
+
+bool basic_map::isa_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).isa_map();
+}
+
+isl::map basic_map::lex_ge_at(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lex_ge_at(mpa);
+}
+
+isl::map basic_map::lex_gt_at(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lex_gt_at(mpa);
+}
+
+isl::map basic_map::lex_le_at(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lex_le_at(mpa);
+}
+
+isl::map basic_map::lex_lt_at(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lex_lt_at(mpa);
+}
+
 isl::map basic_map::lexmax() const
 {
   if (!ptr)
@@ -6452,6 +8881,13 @@
   return manage(res);
 }
 
+isl::pw_multi_aff basic_map::lexmax_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lexmax_pw_multi_aff();
+}
+
 isl::map basic_map::lexmin() const
 {
   if (!ptr)
@@ -6464,6 +8900,195 @@
   return manage(res);
 }
 
+isl::pw_multi_aff basic_map::lexmin_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lexmin_pw_multi_aff();
+}
+
+isl::map basic_map::lower_bound(const isl::multi_pw_aff &lower) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).lower_bound(lower);
+}
+
+isl::map_list basic_map::map_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).map_list();
+}
+
+isl::multi_pw_aff basic_map::max_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).max_multi_pw_aff();
+}
+
+isl::multi_pw_aff basic_map::min_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).min_multi_pw_aff();
+}
+
+isl::basic_map basic_map::polyhedral_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).polyhedral_hull();
+}
+
+isl::map basic_map::preimage_domain(const isl::multi_aff &ma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_domain(ma);
+}
+
+isl::map basic_map::preimage_domain(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_domain(mpa);
+}
+
+isl::map basic_map::preimage_domain(const isl::pw_multi_aff &pma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_domain(pma);
+}
+
+isl::union_map basic_map::preimage_domain(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_domain(upma);
+}
+
+isl::map basic_map::preimage_range(const isl::multi_aff &ma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_range(ma);
+}
+
+isl::map basic_map::preimage_range(const isl::pw_multi_aff &pma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_range(pma);
+}
+
+isl::union_map basic_map::preimage_range(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).preimage_range(upma);
+}
+
+isl::map basic_map::product(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).product(map2);
+}
+
+isl::union_map basic_map::product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).product(umap2);
+}
+
+isl::map basic_map::project_out_all_params() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).project_out_all_params();
+}
+
+isl::set basic_map::range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range();
+}
+
+isl::map basic_map::range_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_factor_domain();
+}
+
+isl::map basic_map::range_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_factor_range();
+}
+
+isl::fixed_box basic_map::range_lattice_tile() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_lattice_tile();
+}
+
+isl::union_map basic_map::range_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_map();
+}
+
+isl::map basic_map::range_product(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_product(map2);
+}
+
+isl::union_map basic_map::range_product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_product(umap2);
+}
+
+isl::map basic_map::range_reverse() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_reverse();
+}
+
+isl::fixed_box basic_map::range_simple_fixed_box_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_simple_fixed_box_hull();
+}
+
+unsigned basic_map::range_tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_tuple_dim();
+}
+
+isl::id basic_map::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).range_tuple_id();
+}
+
 isl::basic_map basic_map::reverse() const
 {
   if (!ptr)
@@ -6488,6 +9113,90 @@
   return manage(res);
 }
 
+isl::map basic_map::set_domain_tuple(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).set_domain_tuple(id);
+}
+
+isl::map basic_map::set_domain_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_domain_tuple(isl::id(ctx(), id));
+}
+
+isl::map basic_map::set_range_tuple(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).set_range_tuple(id);
+}
+
+isl::map basic_map::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+isl::space basic_map::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).space();
+}
+
+isl::map basic_map::subtract(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).subtract(map2);
+}
+
+isl::union_map basic_map::subtract(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).subtract(umap2);
+}
+
+isl::union_map basic_map::subtract_domain(const isl::union_set &dom) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).subtract_domain(dom);
+}
+
+isl::union_map basic_map::subtract_range(const isl::union_set &dom) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).subtract_range(dom);
+}
+
+isl::map_list basic_map::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).to_list();
+}
+
+isl::union_map basic_map::to_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).to_union_map();
+}
+
+isl::map basic_map::uncurry() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).uncurry();
+}
+
 isl::map basic_map::unite(isl::basic_map bmap2) const
 {
   if (!ptr || bmap2.is_null())
@@ -6500,6 +9209,48 @@
   return manage(res);
 }
 
+isl::map basic_map::unite(const isl::map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).unite(map2);
+}
+
+isl::union_map basic_map::unite(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).unite(umap2);
+}
+
+isl::basic_map basic_map::unshifted_simple_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).unshifted_simple_hull();
+}
+
+isl::map basic_map::upper_bound(const isl::multi_pw_aff &upper) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).upper_bound(upper);
+}
+
+isl::set basic_map::wrap() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).wrap();
+}
+
+isl::map basic_map::zip() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::map(*this).zip();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const basic_map &obj)
 {
   if (!obj.get())
@@ -6627,6 +9378,62 @@
   return manage(res);
 }
 
+isl::set basic_set::apply(const isl::map &map) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).apply(map);
+}
+
+isl::union_set basic_set::apply(const isl::union_map &umap) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).apply(umap);
+}
+
+isl::pw_multi_aff basic_set::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).as_pw_multi_aff();
+}
+
+isl::set basic_set::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).as_set();
+}
+
+isl::set basic_set::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).bind(tuple);
+}
+
+isl::set basic_set::coalesce() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).coalesce();
+}
+
+isl::set basic_set::complement() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).complement();
+}
+
+isl::union_set basic_set::compute_divs() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).compute_divs();
+}
+
 isl::basic_set basic_set::detect_equalities() const
 {
   if (!ptr)
@@ -6651,6 +9458,27 @@
   return manage(res);
 }
 
+isl::val basic_set::dim_min_val(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).dim_min_val(pos);
+}
+
+bool basic_set::every_set(const std::function<bool(isl::set)> &test) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).every_set(test);
+}
+
+isl::set basic_set::extract_set(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).extract_set(space);
+}
+
 isl::basic_set basic_set::flatten() const
 {
   if (!ptr)
@@ -6663,6 +9491,27 @@
   return manage(res);
 }
 
+void basic_set::foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).foreach_basic_set(fn);
+}
+
+void basic_set::foreach_point(const std::function<void(isl::point)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).foreach_point(fn);
+}
+
+void basic_set::foreach_set(const std::function<void(isl::set)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).foreach_set(fn);
+}
+
 isl::basic_set basic_set::gist(isl::basic_set context) const
 {
   if (!ptr || context.is_null())
@@ -6675,6 +9524,55 @@
   return manage(res);
 }
 
+isl::set basic_set::gist(const isl::set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).gist(context);
+}
+
+isl::union_set basic_set::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).gist(context);
+}
+
+isl::basic_set basic_set::gist(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::basic_set(context));
+}
+
+isl::union_set basic_set::gist_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).gist_params(set);
+}
+
+isl::map basic_set::identity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).identity();
+}
+
+isl::pw_aff basic_set::indicator_function() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).indicator_function();
+}
+
+isl::map basic_set::insert_domain(const isl::space &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).insert_domain(domain);
+}
+
 isl::basic_set basic_set::intersect(isl::basic_set bset2) const
 {
   if (!ptr || bset2.is_null())
@@ -6687,6 +9585,27 @@
   return manage(res);
 }
 
+isl::set basic_set::intersect(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).intersect(set2);
+}
+
+isl::union_set basic_set::intersect(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).intersect(uset2);
+}
+
+isl::basic_set basic_set::intersect(const isl::point &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect(isl::basic_set(bset2));
+}
+
 isl::basic_set basic_set::intersect_params(isl::basic_set bset2) const
 {
   if (!ptr || bset2.is_null())
@@ -6699,6 +9618,41 @@
   return manage(res);
 }
 
+isl::set basic_set::intersect_params(const isl::set &params) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).intersect_params(params);
+}
+
+isl::basic_set basic_set::intersect_params(const isl::point &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_params(isl::basic_set(bset2));
+}
+
+bool basic_set::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).involves_locals();
+}
+
+bool basic_set::is_disjoint(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_disjoint(set2);
+}
+
+bool basic_set::is_disjoint(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_disjoint(uset2);
+}
+
 bool basic_set::is_empty() const
 {
   if (!ptr)
@@ -6723,6 +9677,48 @@
   return res;
 }
 
+bool basic_set::is_equal(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_equal(set2);
+}
+
+bool basic_set::is_equal(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_equal(uset2);
+}
+
+bool basic_set::is_equal(const isl::point &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_equal(isl::basic_set(bset2));
+}
+
+bool basic_set::is_singleton() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_singleton();
+}
+
+bool basic_set::is_strict_subset(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_strict_subset(set2);
+}
+
+bool basic_set::is_strict_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_strict_subset(uset2);
+}
+
 bool basic_set::is_subset(const isl::basic_set &bset2) const
 {
   if (!ptr || bset2.is_null())
@@ -6735,6 +9731,27 @@
   return res;
 }
 
+bool basic_set::is_subset(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_subset(set2);
+}
+
+bool basic_set::is_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).is_subset(uset2);
+}
+
+bool basic_set::is_subset(const isl::point &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_subset(isl::basic_set(bset2));
+}
+
 bool basic_set::is_wrapping() const
 {
   if (!ptr)
@@ -6747,6 +9764,13 @@
   return res;
 }
 
+bool basic_set::isa_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).isa_set();
+}
+
 isl::set basic_set::lexmax() const
 {
   if (!ptr)
@@ -6759,6 +9783,13 @@
   return manage(res);
 }
 
+isl::pw_multi_aff basic_set::lexmax_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).lexmax_pw_multi_aff();
+}
+
 isl::set basic_set::lexmin() const
 {
   if (!ptr)
@@ -6771,6 +9802,55 @@
   return manage(res);
 }
 
+isl::pw_multi_aff basic_set::lexmin_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).lexmin_pw_multi_aff();
+}
+
+isl::set basic_set::lower_bound(const isl::multi_pw_aff &lower) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).lower_bound(lower);
+}
+
+isl::set basic_set::lower_bound(const isl::multi_val &lower) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).lower_bound(lower);
+}
+
+isl::multi_pw_aff basic_set::max_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).max_multi_pw_aff();
+}
+
+isl::val basic_set::max_val(const isl::aff &obj) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).max_val(obj);
+}
+
+isl::multi_pw_aff basic_set::min_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).min_multi_pw_aff();
+}
+
+isl::val basic_set::min_val(const isl::aff &obj) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).min_val(obj);
+}
+
 isl::basic_set basic_set::params() const
 {
   if (!ptr)
@@ -6783,6 +9863,90 @@
   return manage(res);
 }
 
+isl::multi_val basic_set::plain_multi_val_if_fixed() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).plain_multi_val_if_fixed();
+}
+
+isl::basic_set basic_set::polyhedral_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).polyhedral_hull();
+}
+
+isl::set basic_set::preimage(const isl::multi_aff &ma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).preimage(ma);
+}
+
+isl::set basic_set::preimage(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).preimage(mpa);
+}
+
+isl::set basic_set::preimage(const isl::pw_multi_aff &pma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).preimage(pma);
+}
+
+isl::union_set basic_set::preimage(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).preimage(upma);
+}
+
+isl::set basic_set::product(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).product(set2);
+}
+
+isl::set basic_set::project_out_all_params() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).project_out_all_params();
+}
+
+isl::set basic_set::project_out_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).project_out_param(id);
+}
+
+isl::set basic_set::project_out_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->project_out_param(isl::id(ctx(), id));
+}
+
+isl::set basic_set::project_out_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).project_out_param(list);
+}
+
+isl::pw_multi_aff basic_set::pw_multi_aff_on_domain(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).pw_multi_aff_on_domain(mv);
+}
+
 isl::basic_set basic_set::sample() const
 {
   if (!ptr)
@@ -6807,6 +9971,95 @@
   return manage(res);
 }
 
+isl::fixed_box basic_set::simple_fixed_box_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).simple_fixed_box_hull();
+}
+
+isl::space basic_set::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).space();
+}
+
+isl::val basic_set::stride(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).stride(pos);
+}
+
+isl::set basic_set::subtract(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).subtract(set2);
+}
+
+isl::union_set basic_set::subtract(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).subtract(uset2);
+}
+
+isl::union_set_list basic_set::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).to_list();
+}
+
+isl::set basic_set::to_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_basic_set_to_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_set basic_set::to_union_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).to_union_set();
+}
+
+isl::map basic_set::translation() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).translation();
+}
+
+unsigned basic_set::tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).tuple_dim();
+}
+
+isl::set basic_set::unbind_params(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unbind_params(tuple);
+}
+
+isl::map basic_set::unbind_params_insert_domain(const isl::multi_id &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unbind_params_insert_domain(domain);
+}
+
 isl::set basic_set::unite(isl::basic_set bset2) const
 {
   if (!ptr || bset2.is_null())
@@ -6819,6 +10072,55 @@
   return manage(res);
 }
 
+isl::set basic_set::unite(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unite(set2);
+}
+
+isl::union_set basic_set::unite(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unite(uset2);
+}
+
+isl::set basic_set::unite(const isl::point &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->unite(isl::basic_set(bset2));
+}
+
+isl::basic_set basic_set::unshifted_simple_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unshifted_simple_hull();
+}
+
+isl::map basic_set::unwrap() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).unwrap();
+}
+
+isl::set basic_set::upper_bound(const isl::multi_pw_aff &upper) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).upper_bound(upper);
+}
+
+isl::set basic_set::upper_bound(const isl::multi_val &upper) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::set(*this).upper_bound(upper);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const basic_set &obj)
 {
   if (!obj.get())
@@ -6900,6 +10202,18 @@
   return isl::ctx(isl_fixed_box_get_ctx(ptr));
 }
 
+bool fixed_box::is_valid() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_fixed_box_is_valid(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_aff fixed_box::offset() const
 {
   if (!ptr)
@@ -6951,18 +10265,6 @@
   return space();
 }
 
-bool fixed_box::is_valid() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_fixed_box_is_valid(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
 inline std::ostream &operator<<(std::ostream &os, const fixed_box &obj)
 {
   if (!obj.get())
@@ -7070,6 +10372,18 @@
   return name();
 }
 
+isl::id_list id::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_id_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const id &obj)
 {
   if (!obj.get())
@@ -7141,6 +10455,16 @@
   ptr = res;
 }
 
+id_list::id_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_id_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 id_list &id_list::operator=(id_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -7192,6 +10516,23 @@
   return this->add(isl::id(ctx(), el));
 }
 
+isl::id id_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_id_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id id_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::id_list id_list::clear() const
 {
   if (!ptr)
@@ -7256,23 +10597,6 @@
   return;
 }
 
-isl::id id_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_id_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::id id_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::id_list id_list::insert(unsigned int pos, isl::id el) const
 {
   if (!ptr || el.is_null())
@@ -7431,6 +10755,20 @@
   return manage(res);
 }
 
+isl::union_map map::apply_domain(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).apply_domain(umap2);
+}
+
+isl::map map::apply_domain(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->apply_domain(isl::map(map2));
+}
+
 isl::map map::apply_range(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -7443,6 +10781,53 @@
   return manage(res);
 }
 
+isl::union_map map::apply_range(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).apply_range(umap2);
+}
+
+isl::map map::apply_range(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->apply_range(isl::map(map2));
+}
+
+isl::map map::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).as_map();
+}
+
+isl::multi_union_pw_aff map::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff map::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_as_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff map::as_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).as_union_pw_multi_aff();
+}
+
 isl::set map::bind_domain(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -7491,6 +10876,13 @@
   return manage(res);
 }
 
+isl::union_map map::compute_divs() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).compute_divs();
+}
+
 isl::map map::curry() const
 {
   if (!ptr)
@@ -7563,6 +10955,20 @@
   return manage(res);
 }
 
+isl::union_map map::domain_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).domain_map();
+}
+
+isl::union_pw_multi_aff map::domain_map_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).domain_map_union_pw_multi_aff();
+}
+
 isl::map map::domain_product(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -7575,6 +10981,49 @@
   return manage(res);
 }
 
+isl::union_map map::domain_product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).domain_product(umap2);
+}
+
+isl::map map::domain_product(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->domain_product(isl::map(map2));
+}
+
+unsigned map::domain_tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_domain_tuple_dim(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+isl::id map::domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_get_domain_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id map::get_domain_tuple_id() const
+{
+  return domain_tuple_id();
+}
+
 isl::map map::empty(isl::space space)
 {
   if (space.is_null())
@@ -7599,6 +11048,55 @@
   return manage(res);
 }
 
+isl::union_map map::eq_at(const isl::multi_union_pw_aff &mupa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).eq_at(mupa);
+}
+
+isl::map map::eq_at(const isl::aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->eq_at(isl::multi_pw_aff(mpa));
+}
+
+isl::map map::eq_at(const isl::multi_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->eq_at(isl::multi_pw_aff(mpa));
+}
+
+isl::map map::eq_at(const isl::pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->eq_at(isl::multi_pw_aff(mpa));
+}
+
+isl::map map::eq_at(const isl::pw_multi_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->eq_at(isl::multi_pw_aff(mpa));
+}
+
+bool map::every_map(const std::function<bool(isl::map)> &test) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).every_map(test);
+}
+
+isl::map map::extract_map(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).extract_map(space);
+}
+
 isl::map map::factor_domain() const
 {
   if (!ptr)
@@ -7623,6 +11121,20 @@
   return manage(res);
 }
 
+isl::union_map map::fixed_power(const isl::val &exp) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).fixed_power(exp);
+}
+
+isl::union_map map::fixed_power(long exp) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->fixed_power(isl::val(ctx(), exp));
+}
+
 isl::map map::flatten() const
 {
   if (!ptr)
@@ -7687,38 +11199,11 @@
   return;
 }
 
-isl::fixed_box map::range_simple_fixed_box_hull() const
+void map::foreach_map(const std::function<void(isl::map)> &fn) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_map_get_range_simple_fixed_box_hull(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::fixed_box map::get_range_simple_fixed_box_hull() const
-{
-  return range_simple_fixed_box_hull();
-}
-
-isl::space map::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_map_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space map::get_space() const
-{
-  return space();
+  return isl::union_map(*this).foreach_map(fn);
 }
 
 isl::map map::gist(isl::map context) const
@@ -7733,6 +11218,20 @@
   return manage(res);
 }
 
+isl::union_map map::gist(const isl::union_map &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).gist(context);
+}
+
+isl::map map::gist(const isl::basic_map &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::map(context));
+}
+
 isl::map map::gist_domain(isl::set context) const
 {
   if (!ptr || context.is_null())
@@ -7745,6 +11244,65 @@
   return manage(res);
 }
 
+isl::union_map map::gist_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).gist_domain(uset);
+}
+
+isl::map map::gist_domain(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist_domain(isl::set(context));
+}
+
+isl::map map::gist_domain(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist_domain(isl::set(context));
+}
+
+isl::union_map map::gist_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).gist_params(set);
+}
+
+isl::union_map map::gist_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).gist_range(uset);
+}
+
+bool map::has_domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_has_domain_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool map::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::map map::intersect(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -7757,6 +11315,20 @@
   return manage(res);
 }
 
+isl::union_map map::intersect(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect(umap2);
+}
+
+isl::map map::intersect(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect(isl::map(map2));
+}
+
 isl::map map::intersect_domain(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -7769,6 +11341,34 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_domain(space);
+}
+
+isl::union_map map::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_domain(uset);
+}
+
+isl::map map::intersect_domain(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
+isl::map map::intersect_domain(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
 isl::map map::intersect_domain_factor_domain(isl::map factor) const
 {
   if (!ptr || factor.is_null())
@@ -7781,6 +11381,20 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_domain_factor_domain(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_domain_factor_domain(factor);
+}
+
+isl::map map::intersect_domain_factor_domain(const isl::basic_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain_factor_domain(isl::map(factor));
+}
+
 isl::map map::intersect_domain_factor_range(isl::map factor) const
 {
   if (!ptr || factor.is_null())
@@ -7793,6 +11407,20 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_domain_factor_range(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_domain_factor_range(factor);
+}
+
+isl::map map::intersect_domain_factor_range(const isl::basic_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain_factor_range(isl::map(factor));
+}
+
 isl::map map::intersect_params(isl::set params) const
 {
   if (!ptr || params.is_null())
@@ -7817,6 +11445,34 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_range(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_range(space);
+}
+
+isl::union_map map::intersect_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_range(uset);
+}
+
+isl::map map::intersect_range(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_range(isl::set(set));
+}
+
+isl::map map::intersect_range(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_range(isl::set(set));
+}
+
 isl::map map::intersect_range_factor_domain(isl::map factor) const
 {
   if (!ptr || factor.is_null())
@@ -7829,6 +11485,20 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_range_factor_domain(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_range_factor_domain(factor);
+}
+
+isl::map map::intersect_range_factor_domain(const isl::basic_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_range_factor_domain(isl::map(factor));
+}
+
 isl::map map::intersect_range_factor_range(isl::map factor) const
 {
   if (!ptr || factor.is_null())
@@ -7841,6 +11511,20 @@
   return manage(res);
 }
 
+isl::union_map map::intersect_range_factor_range(const isl::union_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).intersect_range_factor_range(factor);
+}
+
+isl::map map::intersect_range_factor_range(const isl::basic_map &factor) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_range_factor_range(isl::map(factor));
+}
+
 bool map::is_bijective() const
 {
   if (!ptr)
@@ -7865,6 +11549,20 @@
   return res;
 }
 
+bool map::is_disjoint(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).is_disjoint(umap2);
+}
+
+bool map::is_disjoint(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_disjoint(isl::map(map2));
+}
+
 bool map::is_empty() const
 {
   if (!ptr)
@@ -7889,6 +11587,20 @@
   return res;
 }
 
+bool map::is_equal(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).is_equal(umap2);
+}
+
+bool map::is_equal(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_equal(isl::map(map2));
+}
+
 bool map::is_injective() const
 {
   if (!ptr)
@@ -7925,6 +11637,20 @@
   return res;
 }
 
+bool map::is_strict_subset(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).is_strict_subset(umap2);
+}
+
+bool map::is_strict_subset(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_strict_subset(isl::map(map2));
+}
+
 bool map::is_subset(const isl::map &map2) const
 {
   if (!ptr || map2.is_null())
@@ -7937,6 +11663,27 @@
   return res;
 }
 
+bool map::is_subset(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).is_subset(umap2);
+}
+
+bool map::is_subset(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_subset(isl::map(map2));
+}
+
+bool map::isa_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).isa_map();
+}
+
 isl::map map::lex_ge_at(isl::multi_pw_aff mpa) const
 {
   if (!ptr || mpa.is_null())
@@ -8045,6 +11792,13 @@
   return manage(res);
 }
 
+isl::map_list map::map_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).map_list();
+}
+
 isl::multi_pw_aff map::max_multi_pw_aff() const
 {
   if (!ptr)
@@ -8117,6 +11871,13 @@
   return manage(res);
 }
 
+isl::union_map map::preimage_domain(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).preimage_domain(upma);
+}
+
 isl::map map::preimage_range(isl::multi_aff ma) const
 {
   if (!ptr || ma.is_null())
@@ -8141,6 +11902,13 @@
   return manage(res);
 }
 
+isl::union_map map::preimage_range(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).preimage_range(upma);
+}
+
 isl::map map::product(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -8153,6 +11921,20 @@
   return manage(res);
 }
 
+isl::union_map map::product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).product(umap2);
+}
+
+isl::map map::product(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->product(isl::map(map2));
+}
+
 isl::map map::project_out_all_params() const
 {
   if (!ptr)
@@ -8201,6 +11983,30 @@
   return manage(res);
 }
 
+isl::fixed_box map::range_lattice_tile() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_get_range_lattice_tile(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::fixed_box map::get_range_lattice_tile() const
+{
+  return range_lattice_tile();
+}
+
+isl::union_map map::range_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).range_map();
+}
+
 isl::map map::range_product(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -8213,6 +12019,20 @@
   return manage(res);
 }
 
+isl::union_map map::range_product(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).range_product(umap2);
+}
+
+isl::map map::range_product(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::map(map2));
+}
+
 isl::map map::range_reverse() const
 {
   if (!ptr)
@@ -8225,6 +12045,52 @@
   return manage(res);
 }
 
+isl::fixed_box map::range_simple_fixed_box_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_get_range_simple_fixed_box_hull(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::fixed_box map::get_range_simple_fixed_box_hull() const
+{
+  return range_simple_fixed_box_hull();
+}
+
+unsigned map::range_tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_range_tuple_dim(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+isl::id map::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id map::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
 isl::map map::reverse() const
 {
   if (!ptr)
@@ -8249,6 +12115,61 @@
   return manage(res);
 }
 
+isl::map map::set_domain_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_set_domain_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::set_domain_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_domain_tuple(isl::id(ctx(), id));
+}
+
+isl::map map::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+isl::space map::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space map::get_space() const
+{
+  return space();
+}
+
 isl::map map::subtract(isl::map map2) const
 {
   if (!ptr || map2.is_null())
@@ -8261,6 +12182,58 @@
   return manage(res);
 }
 
+isl::union_map map::subtract(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).subtract(umap2);
+}
+
+isl::map map::subtract(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract(isl::map(map2));
+}
+
+isl::union_map map::subtract_domain(const isl::union_set &dom) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).subtract_domain(dom);
+}
+
+isl::union_map map::subtract_range(const isl::union_set &dom) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).subtract_range(dom);
+}
+
+isl::map_list map::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map map::to_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_to_union_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::map map::uncurry() const
 {
   if (!ptr)
@@ -8285,6 +12258,20 @@
   return manage(res);
 }
 
+isl::union_map map::unite(const isl::union_map &umap2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_map(*this).unite(umap2);
+}
+
+isl::map map::unite(const isl::basic_map &map2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->unite(isl::map(map2));
+}
+
 isl::map map::universe(isl::space space)
 {
   if (space.is_null())
@@ -8359,6 +12346,236 @@
   return os;
 }
 
+// implementations for isl::map_list
+map_list manage(__isl_take isl_map_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return map_list(ptr);
+}
+map_list manage_copy(__isl_keep isl_map_list *ptr) {
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_list_get_ctx(ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = isl_map_list_copy(ptr);
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+  return map_list(ptr);
+}
+
+map_list::map_list()
+    : ptr(nullptr) {}
+
+map_list::map_list(const map_list &obj)
+    : ptr(nullptr)
+{
+  if (!obj.ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_list_get_ctx(obj.ptr);
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  ptr = obj.copy();
+  if (!ptr)
+    exception::throw_last_error(saved_ctx);
+}
+
+map_list::map_list(__isl_take isl_map_list *ptr)
+    : ptr(ptr) {}
+
+map_list::map_list(isl::ctx ctx, int n)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_alloc(ctx.release(), n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+map_list::map_list(isl::map el)
+{
+  if (el.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = el.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_from_map(el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+map_list::map_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
+map_list &map_list::operator=(map_list obj) {
+  std::swap(this->ptr, obj.ptr);
+  return *this;
+}
+
+map_list::~map_list() {
+  if (ptr)
+    isl_map_list_free(ptr);
+}
+
+__isl_give isl_map_list *map_list::copy() const & {
+  return isl_map_list_copy(ptr);
+}
+
+__isl_keep isl_map_list *map_list::get() const {
+  return ptr;
+}
+
+__isl_give isl_map_list *map_list::release() {
+  isl_map_list *tmp = ptr;
+  ptr = nullptr;
+  return tmp;
+}
+
+bool map_list::is_null() const {
+  return ptr == nullptr;
+}
+
+isl::ctx map_list::ctx() const {
+  return isl::ctx(isl_map_list_get_ctx(ptr));
+}
+
+isl::map_list map_list::add(isl::map el) const
+{
+  if (!ptr || el.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_add(copy(), el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map map_list::get_at(int index) const
+{
+  return at(index);
+}
+
+isl::map_list map_list::clear() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_clear(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map_list map_list::concat(isl::map_list list2) const
+{
+  if (!ptr || list2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_concat(copy(), list2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map_list map_list::drop(unsigned int first, unsigned int n) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_drop(copy(), first, n);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void map_list::foreach(const std::function<void(isl::map)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  struct fn_data {
+    std::function<void(isl::map)> func;
+    std::exception_ptr eptr;
+  } fn_data = { fn };
+  auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat {
+    auto *data = static_cast<struct fn_data *>(arg_1);
+    ISL_CPP_TRY {
+      (data->func)(manage(arg_0));
+      return isl_stat_ok;
+    } ISL_CPP_CATCH_ALL {
+      data->eptr = std::current_exception();
+      return isl_stat_error;
+    }
+  };
+  auto res = isl_map_list_foreach(get(), fn_lambda, &fn_data);
+  if (fn_data.eptr)
+    std::rethrow_exception(fn_data.eptr);
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return;
+}
+
+isl::map_list map_list::insert(unsigned int pos, isl::map el) const
+{
+  if (!ptr || el.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_insert(copy(), pos, el.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+unsigned map_list::size() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_map_list_size(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+inline std::ostream &operator<<(std::ostream &os, const map_list &obj)
+{
+  if (!obj.get())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = isl_map_list_get_ctx(obj.get());
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  char *str = isl_map_list_to_str(obj.get());
+  if (!str)
+    exception::throw_last_error(saved_ctx);
+  os << str;
+  free(str);
+  return os;
+}
+
 // implementations for isl::multi_aff
 multi_aff manage(__isl_take isl_multi_aff *ptr) {
   if (!ptr)
@@ -8472,6 +12689,41 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::add(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(multi2);
+}
+
+isl::multi_union_pw_aff multi_aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(multi2);
+}
+
+isl::pw_multi_aff multi_aff::add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(upma2);
+}
+
+isl::multi_aff multi_aff::add(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::multi_aff(multi2));
+}
+
 isl::multi_aff multi_aff::add_constant(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -8503,6 +12755,82 @@
   return this->add_constant(isl::val(ctx(), v));
 }
 
+isl::union_pw_multi_aff multi_aff::apply(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).apply(upma2);
+}
+
+isl::map multi_aff::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_as_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::as_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_multi_aff();
+}
+
+isl::multi_union_pw_aff multi_aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff multi_aff::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::set multi_aff::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_as_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map multi_aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_union_map();
+}
+
+isl::aff multi_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_get_at(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::aff multi_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::basic_set multi_aff::bind(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -8539,57 +12867,11 @@
   return manage(res);
 }
 
-isl::multi_aff multi_aff::domain_map(isl::space space)
-{
-  if (space.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = space.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_domain_map(space.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_aff multi_aff::flat_range_product(isl::multi_aff multi2) const
-{
-  if (!ptr || multi2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_flat_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_aff multi_aff::floor() const
+isl::pw_multi_aff multi_aff::coalesce() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_floor(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::aff multi_aff::at(int pos) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_get_at(get(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::aff multi_aff::get_at(int pos) const
-{
-  return at(pos);
+  return isl::pw_multi_aff(*this).coalesce();
 }
 
 isl::multi_val multi_aff::constant_multi_val() const
@@ -8609,38 +12891,96 @@
   return constant_multi_val();
 }
 
-isl::aff_list multi_aff::list() const
+isl::set multi_aff::domain() const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
+  return isl::pw_multi_aff(*this).domain();
+}
+
+isl::multi_aff multi_aff::domain_map(isl::space space)
+{
+  if (space.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = space.ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_get_list(get());
+  auto res = isl_multi_aff_domain_map(space.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::aff_list multi_aff::get_list() const
-{
-  return list();
-}
-
-isl::space multi_aff::space() const
+isl::pw_multi_aff multi_aff::extract_pw_multi_aff(const isl::space &space) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::multi_aff multi_aff::flat_range_product(isl::multi_aff multi2) const
+{
+  if (!ptr || multi2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
   auto saved_ctx = ctx();
   options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_aff_get_space(get());
+  auto res = isl_multi_aff_flat_range_product(copy(), multi2.release());
   if (!res)
     exception::throw_last_error(saved_ctx);
   return manage(res);
 }
 
-isl::space multi_aff::get_space() const
+isl::multi_pw_aff multi_aff::flat_range_product(const isl::multi_pw_aff &multi2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::multi_union_pw_aff multi_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::pw_multi_aff multi_aff::flat_range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(upma2);
+}
+
+isl::multi_aff multi_aff::flat_range_product(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::multi_aff(multi2));
+}
+
+isl::multi_aff multi_aff::floor() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_floor(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+void multi_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).foreach_piece(fn);
 }
 
 isl::multi_aff multi_aff::gist(isl::set context) const
@@ -8655,6 +12995,39 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff multi_aff::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).gist(context);
+}
+
+isl::multi_aff multi_aff::gist(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+isl::multi_aff multi_aff::gist(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+bool multi_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_aff multi_aff::identity() const
 {
   if (!ptr)
@@ -8691,6 +13064,48 @@
   return manage(res);
 }
 
+isl::pw_multi_aff multi_aff::intersect_domain(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_domain(set);
+}
+
+isl::union_pw_multi_aff multi_aff::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_domain(space);
+}
+
+isl::union_pw_multi_aff multi_aff::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_domain(uset);
+}
+
+isl::union_pw_multi_aff multi_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::union_pw_multi_aff multi_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
+isl::pw_multi_aff multi_aff::intersect_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).intersect_params(set);
+}
+
 bool multi_aff::involves_locals() const
 {
   if (!ptr)
@@ -8715,6 +13130,105 @@
   return res;
 }
 
+bool multi_aff::involves_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).involves_param(id);
+}
+
+bool multi_aff::involves_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->involves_param(isl::id(ctx(), id));
+}
+
+bool multi_aff::involves_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).involves_param(list);
+}
+
+bool multi_aff::isa_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).isa_multi_aff();
+}
+
+bool multi_aff::isa_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::aff_list multi_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_get_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::aff_list multi_aff::get_list() const
+{
+  return list();
+}
+
+isl::multi_pw_aff multi_aff::max(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).max(multi2);
+}
+
+isl::multi_val multi_aff::max_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).max_multi_val();
+}
+
+isl::multi_pw_aff multi_aff::min(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).min(multi2);
+}
+
+isl::multi_val multi_aff::min_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).min_multi_val();
+}
+
+isl::multi_aff multi_aff::multi_val_on_domain(isl::space space, isl::multi_val mv)
+{
+  if (space.is_null() || mv.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = space.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_multi_val_on_domain_space(space.release(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+unsigned multi_aff::n_piece() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).n_piece();
+}
+
 isl::multi_aff multi_aff::neg() const
 {
   if (!ptr)
@@ -8727,6 +13241,13 @@
   return manage(res);
 }
 
+bool multi_aff::plain_is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).plain_is_empty();
+}
+
 bool multi_aff::plain_is_equal(const isl::multi_aff &multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -8739,6 +13260,41 @@
   return res;
 }
 
+bool multi_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+bool multi_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+bool multi_aff::plain_is_equal(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->plain_is_equal(isl::multi_aff(multi2));
+}
+
+isl::pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
 isl::multi_aff multi_aff::product(isl::multi_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -8751,6 +13307,27 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).product(multi2);
+}
+
+isl::pw_multi_aff multi_aff::product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).product(pma2);
+}
+
+isl::multi_aff multi_aff::product(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->product(isl::multi_aff(multi2));
+}
+
 isl::multi_aff multi_aff::pullback(isl::multi_aff ma2) const
 {
   if (!ptr || ma2.is_null())
@@ -8763,6 +13340,55 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::pullback(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).pullback(mpa2);
+}
+
+isl::pw_multi_aff multi_aff::pullback(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).pullback(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::pullback(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).pullback(upma2);
+}
+
+isl::multi_aff multi_aff::pullback(const isl::aff &ma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->pullback(isl::multi_aff(ma2));
+}
+
+isl::pw_multi_aff_list multi_aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).pw_multi_aff_list();
+}
+
+isl::pw_multi_aff multi_aff::range_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::pw_multi_aff multi_aff::range_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_factor_range();
+}
+
 isl::multi_aff multi_aff::range_map(isl::space space)
 {
   if (space.is_null())
@@ -8787,6 +13413,70 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::multi_union_pw_aff multi_aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::pw_multi_aff multi_aff::range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::multi_aff multi_aff::range_product(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_aff(multi2));
+}
+
+isl::id multi_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id multi_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::multi_aff multi_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_reset_range_tuple_id(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::multi_aff multi_aff::scale(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -8861,6 +13551,39 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::set_at(int pos, const isl::pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::multi_union_pw_aff multi_aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::multi_aff multi_aff::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
 unsigned multi_aff::size() const
 {
   if (!ptr)
@@ -8873,6 +13596,23 @@
   return res;
 }
 
+isl::space multi_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space multi_aff::get_space() const
+{
+  return space();
+}
+
 isl::multi_aff multi_aff::sub(isl::multi_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -8885,6 +13625,112 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::sub(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::multi_union_pw_aff multi_aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::pw_multi_aff multi_aff::sub(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::sub(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(upma2);
+}
+
+isl::multi_aff multi_aff::sub(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::multi_aff(multi2));
+}
+
+isl::pw_multi_aff multi_aff::subtract_domain(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).subtract_domain(set);
+}
+
+isl::union_pw_multi_aff multi_aff::subtract_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).subtract_domain(space);
+}
+
+isl::union_pw_multi_aff multi_aff::subtract_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).subtract_domain(uset);
+}
+
+isl::pw_multi_aff_list multi_aff::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).to_list();
+}
+
+isl::multi_pw_aff multi_aff::to_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_to_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff multi_aff::to_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_to_multi_union_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff multi_aff::to_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_aff_to_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff multi_aff::to_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).to_union_pw_multi_aff();
+}
+
 isl::multi_aff multi_aff::unbind_params_insert_domain(isl::multi_id domain) const
 {
   if (!ptr || domain.is_null())
@@ -8897,6 +13743,34 @@
   return manage(res);
 }
 
+isl::multi_pw_aff multi_aff::union_add(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(mpa2);
+}
+
+isl::multi_union_pw_aff multi_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(mupa2);
+}
+
+isl::pw_multi_aff multi_aff::union_add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(pma2);
+}
+
+isl::union_pw_multi_aff multi_aff::union_add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(upma2);
+}
+
 isl::multi_aff multi_aff::zero(isl::space space)
 {
   if (space.is_null())
@@ -9012,18 +13886,6 @@
   return isl::ctx(isl_multi_id_get_ctx(ptr));
 }
 
-isl::multi_id multi_id::flat_range_product(isl::multi_id multi2) const
-{
-  if (!ptr || multi2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::id multi_id::at(int pos) const
 {
   if (!ptr)
@@ -9041,6 +13903,18 @@
   return at(pos);
 }
 
+isl::multi_id multi_id::flat_range_product(isl::multi_id multi2) const
+{
+  if (!ptr || multi2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_id_flat_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::id_list multi_id::list() const
 {
   if (!ptr)
@@ -9058,23 +13932,6 @@
   return list();
 }
 
-isl::space multi_id::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_id_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space multi_id::get_space() const
-{
-  return space();
-}
-
 bool multi_id::plain_is_equal(const isl::multi_id &multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -9130,6 +13987,23 @@
   return res;
 }
 
+isl::space multi_id::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_id_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space multi_id::get_space() const
+{
+  return space();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const multi_id &obj)
 {
   if (!obj.get())
@@ -9293,6 +14167,41 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).add(multi2);
+}
+
+isl::multi_pw_aff multi_pw_aff::add(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::add(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::add(const isl::pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::add(const isl::pw_multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::multi_pw_aff(multi2));
+}
+
 isl::multi_pw_aff multi_pw_aff::add_constant(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -9324,6 +14233,59 @@
   return this->add_constant(isl::val(ctx(), v));
 }
 
+isl::map multi_pw_aff::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_as_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff multi_pw_aff::as_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_as_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set multi_pw_aff::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_as_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff multi_pw_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_get_at(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff multi_pw_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::set multi_pw_aff::bind(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -9396,55 +14358,39 @@
   return manage(res);
 }
 
-isl::pw_aff multi_pw_aff::at(int pos) const
+isl::multi_union_pw_aff multi_pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_get_at(get(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::multi_union_pw_aff(*this).flat_range_product(multi2);
 }
 
-isl::pw_aff multi_pw_aff::get_at(int pos) const
-{
-  return at(pos);
-}
-
-isl::pw_aff_list multi_pw_aff::list() const
+isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::aff &multi2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_get_list(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
 }
 
-isl::pw_aff_list multi_pw_aff::get_list() const
-{
-  return list();
-}
-
-isl::space multi_pw_aff::space() const
+isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::multi_aff &multi2) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_pw_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
 }
 
-isl::space multi_pw_aff::get_space() const
+isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::pw_aff &multi2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::flat_range_product(const isl::pw_multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::multi_pw_aff(multi2));
 }
 
 isl::multi_pw_aff multi_pw_aff::gist(isl::set set) const
@@ -9459,6 +14405,39 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).gist(context);
+}
+
+isl::multi_pw_aff multi_pw_aff::gist(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
+}
+
+isl::multi_pw_aff multi_pw_aff::gist(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
+}
+
+bool multi_pw_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_pw_aff multi_pw_aff::identity() const
 {
   if (!ptr)
@@ -9507,6 +14486,27 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).intersect_domain(uset);
+}
+
+isl::multi_pw_aff multi_pw_aff::intersect_domain(const isl::basic_set &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(domain));
+}
+
+isl::multi_pw_aff multi_pw_aff::intersect_domain(const isl::point &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(domain));
+}
+
 isl::multi_pw_aff multi_pw_aff::intersect_params(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -9562,6 +14562,35 @@
   return res;
 }
 
+bool multi_pw_aff::isa_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_isa_multi_aff(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+isl::pw_aff_list multi_pw_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_get_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff_list multi_pw_aff::get_list() const
+{
+  return list();
+}
+
 isl::multi_pw_aff multi_pw_aff::max(isl::multi_pw_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -9634,6 +14663,41 @@
   return res;
 }
 
+bool multi_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+bool multi_pw_aff::plain_is_equal(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->plain_is_equal(isl::multi_pw_aff(multi2));
+}
+
+bool multi_pw_aff::plain_is_equal(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->plain_is_equal(isl::multi_pw_aff(multi2));
+}
+
+bool multi_pw_aff::plain_is_equal(const isl::pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->plain_is_equal(isl::multi_pw_aff(multi2));
+}
+
+bool multi_pw_aff::plain_is_equal(const isl::pw_multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->plain_is_equal(isl::multi_pw_aff(multi2));
+}
+
 isl::multi_pw_aff multi_pw_aff::product(isl::multi_pw_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -9682,6 +14746,13 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::pullback(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).pullback(upma);
+}
+
 isl::multi_pw_aff multi_pw_aff::range_product(isl::multi_pw_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -9694,6 +14765,70 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).range_product(multi2);
+}
+
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::range_product(const isl::pw_multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::multi_pw_aff(multi2));
+}
+
+isl::id multi_pw_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id multi_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::multi_pw_aff multi_pw_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_reset_range_tuple_id(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::multi_pw_aff multi_pw_aff::scale(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -9768,6 +14903,32 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::multi_pw_aff multi_pw_aff::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff multi_pw_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
 unsigned multi_pw_aff::size() const
 {
   if (!ptr)
@@ -9780,6 +14941,23 @@
   return res;
 }
 
+isl::space multi_pw_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_pw_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space multi_pw_aff::get_space() const
+{
+  return space();
+}
+
 isl::multi_pw_aff multi_pw_aff::sub(isl::multi_pw_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -9792,6 +14970,41 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).sub(multi2);
+}
+
+isl::multi_pw_aff multi_pw_aff::sub(const isl::aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::sub(const isl::multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::sub(const isl::pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::multi_pw_aff(multi2));
+}
+
+isl::multi_pw_aff multi_pw_aff::sub(const isl::pw_multi_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::multi_pw_aff(multi2));
+}
+
 isl::multi_pw_aff multi_pw_aff::unbind_params_insert_domain(isl::multi_id domain) const
 {
   if (!ptr || domain.is_null())
@@ -9816,6 +15029,41 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).union_add(mupa2);
+}
+
+isl::multi_pw_aff multi_pw_aff::union_add(const isl::aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::multi_pw_aff(mpa2));
+}
+
+isl::multi_pw_aff multi_pw_aff::union_add(const isl::multi_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::multi_pw_aff(mpa2));
+}
+
+isl::multi_pw_aff multi_pw_aff::union_add(const isl::pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::multi_pw_aff(mpa2));
+}
+
+isl::multi_pw_aff multi_pw_aff::union_add(const isl::pw_multi_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::multi_pw_aff(mpa2));
+}
+
 isl::multi_pw_aff multi_pw_aff::zero(isl::space space)
 {
   if (space.is_null())
@@ -9967,6 +15215,23 @@
   return manage(res);
 }
 
+isl::union_pw_aff multi_union_pw_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_aff multi_union_pw_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
 isl::union_set multi_union_pw_aff::bind(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -10015,57 +15280,6 @@
   return manage(res);
 }
 
-isl::union_pw_aff multi_union_pw_aff::at(int pos) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_get_at(get(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_pw_aff multi_union_pw_aff::get_at(int pos) const
-{
-  return at(pos);
-}
-
-isl::union_pw_aff_list multi_union_pw_aff::list() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_get_list(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_pw_aff_list multi_union_pw_aff::get_list() const
-{
-  return list();
-}
-
-isl::space multi_union_pw_aff::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_union_pw_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space multi_union_pw_aff::get_space() const
-{
-  return space();
-}
-
 isl::multi_union_pw_aff multi_union_pw_aff::gist(isl::union_set context) const
 {
   if (!ptr || context.is_null())
@@ -10078,6 +15292,18 @@
   return manage(res);
 }
 
+bool multi_union_pw_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::multi_union_pw_aff multi_union_pw_aff::intersect_domain(isl::union_set uset) const
 {
   if (!ptr || uset.is_null())
@@ -10114,6 +15340,23 @@
   return res;
 }
 
+isl::union_pw_aff_list multi_union_pw_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_get_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_aff_list multi_union_pw_aff::get_list() const
+{
+  return list();
+}
+
 isl::multi_union_pw_aff multi_union_pw_aff::neg() const
 {
   if (!ptr)
@@ -10162,6 +15405,35 @@
   return manage(res);
 }
 
+isl::id multi_union_pw_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id multi_union_pw_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::multi_union_pw_aff multi_union_pw_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_reset_range_tuple_id(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::multi_union_pw_aff multi_union_pw_aff::scale(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -10236,6 +15508,25 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff multi_union_pw_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
 unsigned multi_union_pw_aff::size() const
 {
   if (!ptr)
@@ -10248,6 +15539,23 @@
   return res;
 }
 
+isl::space multi_union_pw_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_union_pw_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space multi_union_pw_aff::get_space() const
+{
+  return space();
+}
+
 isl::multi_union_pw_aff multi_union_pw_aff::sub(isl::multi_union_pw_aff multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -10418,18 +15726,6 @@
   return this->add(isl::val(ctx(), v));
 }
 
-isl::multi_val multi_val::flat_range_product(isl::multi_val multi2) const
-{
-  if (!ptr || multi2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::val multi_val::at(int pos) const
 {
   if (!ptr)
@@ -10447,6 +15743,42 @@
   return at(pos);
 }
 
+isl::multi_val multi_val::flat_range_product(isl::multi_val multi2) const
+{
+  if (!ptr || multi2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_flat_range_product(copy(), multi2.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+bool multi_val::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool multi_val::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_involves_nan(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::val_list multi_val::list() const
 {
   if (!ptr)
@@ -10464,35 +15796,6 @@
   return list();
 }
 
-isl::space multi_val::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space multi_val::get_space() const
-{
-  return space();
-}
-
-bool multi_val::involves_nan() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_multi_val_involves_nan(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
 isl::multi_val multi_val::max(isl::multi_val multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -10565,6 +15868,35 @@
   return manage(res);
 }
 
+isl::id multi_val::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id multi_val::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::multi_val multi_val::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_reset_range_tuple_id(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::multi_val multi_val::scale(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -10646,6 +15978,25 @@
   return this->set_at(pos, isl::val(ctx(), el));
 }
 
+isl::multi_val multi_val::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val multi_val::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
 unsigned multi_val::size() const
 {
   if (!ptr)
@@ -10658,6 +16009,23 @@
   return res;
 }
 
+isl::space multi_val::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_multi_val_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space multi_val::get_space() const
+{
+  return space();
+}
+
 isl::multi_val multi_val::sub(isl::multi_val multi2) const
 {
   if (!ptr || multi2.is_null())
@@ -10763,6 +16131,398 @@
   return isl::ctx(isl_point_get_ctx(ptr));
 }
 
+isl::basic_set point::affine_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).affine_hull();
+}
+
+isl::basic_set point::apply(const isl::basic_map &bmap) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).apply(bmap);
+}
+
+isl::set point::apply(const isl::map &map) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).apply(map);
+}
+
+isl::union_set point::apply(const isl::union_map &umap) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).apply(umap);
+}
+
+isl::pw_multi_aff point::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).as_pw_multi_aff();
+}
+
+isl::set point::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).as_set();
+}
+
+isl::set point::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).bind(tuple);
+}
+
+isl::set point::coalesce() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).coalesce();
+}
+
+isl::set point::complement() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).complement();
+}
+
+isl::union_set point::compute_divs() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).compute_divs();
+}
+
+isl::basic_set point::detect_equalities() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).detect_equalities();
+}
+
+isl::val point::dim_max_val(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).dim_max_val(pos);
+}
+
+isl::val point::dim_min_val(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).dim_min_val(pos);
+}
+
+bool point::every_set(const std::function<bool(isl::set)> &test) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).every_set(test);
+}
+
+isl::set point::extract_set(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).extract_set(space);
+}
+
+isl::basic_set point::flatten() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).flatten();
+}
+
+void point::foreach_basic_set(const std::function<void(isl::basic_set)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).foreach_basic_set(fn);
+}
+
+void point::foreach_point(const std::function<void(isl::point)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).foreach_point(fn);
+}
+
+void point::foreach_set(const std::function<void(isl::set)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).foreach_set(fn);
+}
+
+isl::basic_set point::gist(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).gist(context);
+}
+
+isl::set point::gist(const isl::set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).gist(context);
+}
+
+isl::union_set point::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).gist(context);
+}
+
+isl::union_set point::gist_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).gist_params(set);
+}
+
+isl::map point::identity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).identity();
+}
+
+isl::pw_aff point::indicator_function() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).indicator_function();
+}
+
+isl::map point::insert_domain(const isl::space &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).insert_domain(domain);
+}
+
+isl::basic_set point::intersect(const isl::basic_set &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).intersect(bset2);
+}
+
+isl::set point::intersect(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).intersect(set2);
+}
+
+isl::union_set point::intersect(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).intersect(uset2);
+}
+
+isl::basic_set point::intersect_params(const isl::basic_set &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).intersect_params(bset2);
+}
+
+isl::set point::intersect_params(const isl::set &params) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).intersect_params(params);
+}
+
+bool point::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).involves_locals();
+}
+
+bool point::is_disjoint(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_disjoint(set2);
+}
+
+bool point::is_disjoint(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_disjoint(uset2);
+}
+
+bool point::is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_empty();
+}
+
+bool point::is_equal(const isl::basic_set &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_equal(bset2);
+}
+
+bool point::is_equal(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_equal(set2);
+}
+
+bool point::is_equal(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_equal(uset2);
+}
+
+bool point::is_singleton() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_singleton();
+}
+
+bool point::is_strict_subset(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_strict_subset(set2);
+}
+
+bool point::is_strict_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_strict_subset(uset2);
+}
+
+bool point::is_subset(const isl::basic_set &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_subset(bset2);
+}
+
+bool point::is_subset(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_subset(set2);
+}
+
+bool point::is_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_subset(uset2);
+}
+
+bool point::is_wrapping() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).is_wrapping();
+}
+
+bool point::isa_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).isa_set();
+}
+
+isl::set point::lexmax() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lexmax();
+}
+
+isl::pw_multi_aff point::lexmax_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lexmax_pw_multi_aff();
+}
+
+isl::set point::lexmin() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lexmin();
+}
+
+isl::pw_multi_aff point::lexmin_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lexmin_pw_multi_aff();
+}
+
+isl::set point::lower_bound(const isl::multi_pw_aff &lower) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lower_bound(lower);
+}
+
+isl::set point::lower_bound(const isl::multi_val &lower) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).lower_bound(lower);
+}
+
+isl::multi_pw_aff point::max_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).max_multi_pw_aff();
+}
+
+isl::val point::max_val(const isl::aff &obj) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).max_val(obj);
+}
+
+isl::multi_pw_aff point::min_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).min_multi_pw_aff();
+}
+
+isl::val point::min_val(const isl::aff &obj) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).min_val(obj);
+}
+
 isl::multi_val point::multi_val() const
 {
   if (!ptr)
@@ -10780,6 +16540,249 @@
   return multi_val();
 }
 
+isl::basic_set point::params() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).params();
+}
+
+isl::multi_val point::plain_multi_val_if_fixed() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).plain_multi_val_if_fixed();
+}
+
+isl::basic_set point::polyhedral_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).polyhedral_hull();
+}
+
+isl::set point::preimage(const isl::multi_aff &ma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).preimage(ma);
+}
+
+isl::set point::preimage(const isl::multi_pw_aff &mpa) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).preimage(mpa);
+}
+
+isl::set point::preimage(const isl::pw_multi_aff &pma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).preimage(pma);
+}
+
+isl::union_set point::preimage(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).preimage(upma);
+}
+
+isl::set point::product(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).product(set2);
+}
+
+isl::set point::project_out_all_params() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).project_out_all_params();
+}
+
+isl::set point::project_out_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).project_out_param(id);
+}
+
+isl::set point::project_out_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->project_out_param(isl::id(ctx(), id));
+}
+
+isl::set point::project_out_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).project_out_param(list);
+}
+
+isl::pw_multi_aff point::pw_multi_aff_on_domain(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).pw_multi_aff_on_domain(mv);
+}
+
+isl::basic_set point::sample() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).sample();
+}
+
+isl::point point::sample_point() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).sample_point();
+}
+
+isl::fixed_box point::simple_fixed_box_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).simple_fixed_box_hull();
+}
+
+isl::space point::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).space();
+}
+
+isl::val point::stride(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).stride(pos);
+}
+
+isl::set point::subtract(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).subtract(set2);
+}
+
+isl::union_set point::subtract(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).subtract(uset2);
+}
+
+isl::union_set_list point::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).to_list();
+}
+
+isl::set point::to_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_point_to_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_set point::to_union_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).to_union_set();
+}
+
+isl::map point::translation() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).translation();
+}
+
+unsigned point::tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).tuple_dim();
+}
+
+isl::set point::unbind_params(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unbind_params(tuple);
+}
+
+isl::map point::unbind_params_insert_domain(const isl::multi_id &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unbind_params_insert_domain(domain);
+}
+
+isl::set point::unite(const isl::basic_set &bset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unite(bset2);
+}
+
+isl::set point::unite(const isl::set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unite(set2);
+}
+
+isl::union_set point::unite(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unite(uset2);
+}
+
+isl::basic_set point::unshifted_simple_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unshifted_simple_hull();
+}
+
+isl::map point::unwrap() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).unwrap();
+}
+
+isl::set point::upper_bound(const isl::multi_pw_aff &upper) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).upper_bound(upper);
+}
+
+isl::set point::upper_bound(const isl::multi_val &upper) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::basic_set(*this).upper_bound(upper);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const point &obj)
 {
   if (!obj.get())
@@ -10883,6 +16886,20 @@
   return isl::ctx(isl_pw_aff_get_ctx(ptr));
 }
 
+isl::multi_pw_aff pw_aff::add(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(multi2);
+}
+
+isl::multi_union_pw_aff pw_aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).add(multi2);
+}
+
 isl::pw_aff pw_aff::add(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -10895,6 +16912,34 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_aff::add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add(pma2);
+}
+
+isl::union_pw_aff pw_aff::add(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).add(upa2);
+}
+
+isl::union_pw_multi_aff pw_aff::add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).add(upma2);
+}
+
+isl::pw_aff pw_aff::add(const isl::aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::pw_aff(pwaff2));
+}
+
 isl::pw_aff pw_aff::add_constant(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -10914,6 +16959,20 @@
   return this->add_constant(isl::val(ctx(), v));
 }
 
+isl::pw_multi_aff pw_aff::add_constant(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).add_constant(mv);
+}
+
+isl::union_pw_multi_aff pw_aff::apply(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).apply(upma2);
+}
+
 isl::aff pw_aff::as_aff() const
 {
   if (!ptr)
@@ -10926,6 +16985,67 @@
   return manage(res);
 }
 
+isl::map pw_aff::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_aff_as_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff pw_aff::as_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_multi_aff();
+}
+
+isl::multi_union_pw_aff pw_aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff pw_aff::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).as_pw_multi_aff();
+}
+
+isl::set pw_aff::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).as_set();
+}
+
+isl::union_map pw_aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).as_union_map();
+}
+
+isl::pw_aff pw_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).at(pos);
+}
+
+isl::set pw_aff::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).bind(tuple);
+}
+
 isl::set pw_aff::bind(isl::id id) const
 {
   if (!ptr || id.is_null())
@@ -11053,6 +17173,41 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_aff::extract_pw_multi_aff(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::multi_pw_aff pw_aff::flat_range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(multi2);
+}
+
+isl::multi_union_pw_aff pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::pw_multi_aff pw_aff::flat_range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).flat_range_product(pma2);
+}
+
+isl::union_pw_multi_aff pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).flat_range_product(upma2);
+}
+
 isl::pw_aff pw_aff::floor() const
 {
   if (!ptr)
@@ -11065,6 +17220,13 @@
   return manage(res);
 }
 
+void pw_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).foreach_piece(fn);
+}
+
 isl::set pw_aff::ge_set(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11089,6 +17251,27 @@
   return manage(res);
 }
 
+isl::union_pw_aff pw_aff::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).gist(context);
+}
+
+isl::pw_aff pw_aff::gist(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+isl::pw_aff pw_aff::gist(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
 isl::set pw_aff::gt_set(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11101,6 +17284,20 @@
   return manage(res);
 }
 
+bool pw_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).has_range_tuple_id();
+}
+
+isl::multi_pw_aff pw_aff::identity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).identity();
+}
+
 isl::pw_aff pw_aff::insert_domain(isl::space domain) const
 {
   if (!ptr || domain.is_null())
@@ -11125,6 +17322,48 @@
   return manage(res);
 }
 
+isl::union_pw_aff pw_aff::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).intersect_domain(space);
+}
+
+isl::union_pw_aff pw_aff::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).intersect_domain(uset);
+}
+
+isl::pw_aff pw_aff::intersect_domain(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
+isl::pw_aff pw_aff::intersect_domain(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
+isl::union_pw_aff pw_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::union_pw_aff pw_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
 isl::pw_aff pw_aff::intersect_params(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -11137,6 +17376,41 @@
   return manage(res);
 }
 
+bool pw_aff::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).involves_locals();
+}
+
+bool pw_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).involves_nan();
+}
+
+bool pw_aff::involves_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).involves_param(id);
+}
+
+bool pw_aff::involves_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->involves_param(isl::id(ctx(), id));
+}
+
+bool pw_aff::involves_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).involves_param(list);
+}
+
 bool pw_aff::isa_aff() const
 {
   if (!ptr)
@@ -11149,6 +17423,20 @@
   return res;
 }
 
+bool pw_aff::isa_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).isa_multi_aff();
+}
+
+bool pw_aff::isa_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).isa_pw_multi_aff();
+}
+
 isl::set pw_aff::le_set(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11161,6 +17449,13 @@
   return manage(res);
 }
 
+isl::pw_aff_list pw_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).list();
+}
+
 isl::set pw_aff::lt_set(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11173,6 +17468,13 @@
   return manage(res);
 }
 
+isl::multi_pw_aff pw_aff::max(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).max(multi2);
+}
+
 isl::pw_aff pw_aff::max(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11185,6 +17487,27 @@
   return manage(res);
 }
 
+isl::pw_aff pw_aff::max(const isl::aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->max(isl::pw_aff(pwaff2));
+}
+
+isl::multi_val pw_aff::max_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).max_multi_val();
+}
+
+isl::multi_pw_aff pw_aff::min(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).min(multi2);
+}
+
 isl::pw_aff pw_aff::min(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11197,6 +17520,20 @@
   return manage(res);
 }
 
+isl::pw_aff pw_aff::min(const isl::aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->min(isl::pw_aff(pwaff2));
+}
+
+isl::multi_val pw_aff::min_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).min_multi_val();
+}
+
 isl::pw_aff pw_aff::mod(isl::val mod) const
 {
   if (!ptr || mod.is_null())
@@ -11228,6 +17565,13 @@
   return manage(res);
 }
 
+unsigned pw_aff::n_piece() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).n_piece();
+}
+
 isl::set pw_aff::ne_set(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11264,6 +17608,55 @@
   return manage(res);
 }
 
+bool pw_aff::plain_is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).plain_is_empty();
+}
+
+bool pw_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).plain_is_equal(multi2);
+}
+
+bool pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).preimage_domain_wrapped_domain(pma2);
+}
+
+isl::union_pw_multi_aff pw_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::multi_pw_aff pw_aff::product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).product(multi2);
+}
+
+isl::pw_multi_aff pw_aff::product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).product(pma2);
+}
+
 isl::pw_aff pw_aff::pullback(isl::multi_aff ma) const
 {
   if (!ptr || ma.is_null())
@@ -11300,6 +17693,83 @@
   return manage(res);
 }
 
+isl::union_pw_aff pw_aff::pullback(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).pullback(upma);
+}
+
+isl::pw_multi_aff_list pw_aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).pw_multi_aff_list();
+}
+
+isl::pw_multi_aff pw_aff::range_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::pw_multi_aff pw_aff::range_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_factor_range();
+}
+
+isl::multi_pw_aff pw_aff::range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(multi2);
+}
+
+isl::multi_union_pw_aff pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).range_product(multi2);
+}
+
+isl::pw_multi_aff pw_aff::range_product(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_product(pma2);
+}
+
+isl::union_pw_multi_aff pw_aff::range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).range_product(upma2);
+}
+
+isl::id pw_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).range_tuple_id();
+}
+
+isl::multi_pw_aff pw_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::multi_pw_aff pw_aff::scale(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).scale(mv);
+}
+
 isl::pw_aff pw_aff::scale(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -11319,6 +17789,13 @@
   return this->scale(isl::val(ctx(), v));
 }
 
+isl::multi_pw_aff pw_aff::scale_down(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).scale_down(mv);
+}
+
 isl::pw_aff pw_aff::scale_down(isl::val f) const
 {
   if (!ptr || f.is_null())
@@ -11338,6 +17815,62 @@
   return this->scale_down(isl::val(ctx(), f));
 }
 
+isl::multi_pw_aff pw_aff::set_at(int pos, const isl::pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).set_at(pos, el);
+}
+
+isl::multi_union_pw_aff pw_aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::pw_multi_aff pw_aff::set_range_tuple(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).set_range_tuple(id);
+}
+
+isl::pw_multi_aff pw_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+unsigned pw_aff::size() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).size();
+}
+
+isl::space pw_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).space();
+}
+
+isl::multi_pw_aff pw_aff::sub(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(multi2);
+}
+
+isl::multi_union_pw_aff pw_aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).sub(multi2);
+}
+
 isl::pw_aff pw_aff::sub(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11350,6 +17883,34 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_aff::sub(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).sub(pma2);
+}
+
+isl::union_pw_aff pw_aff::sub(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).sub(upa2);
+}
+
+isl::union_pw_multi_aff pw_aff::sub(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).sub(upma2);
+}
+
+isl::pw_aff pw_aff::sub(const isl::aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::pw_aff(pwaff2));
+}
+
 isl::pw_aff pw_aff::subtract_domain(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -11362,6 +17923,34 @@
   return manage(res);
 }
 
+isl::union_pw_aff pw_aff::subtract_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).subtract_domain(space);
+}
+
+isl::union_pw_aff pw_aff::subtract_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).subtract_domain(uset);
+}
+
+isl::pw_aff pw_aff::subtract_domain(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract_domain(isl::set(set));
+}
+
+isl::pw_aff pw_aff::subtract_domain(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract_domain(isl::set(set));
+}
+
 isl::pw_aff pw_aff::tdiv_q(isl::pw_aff pa2) const
 {
   if (!ptr || pa2.is_null())
@@ -11386,6 +17975,65 @@
   return manage(res);
 }
 
+isl::pw_aff_list pw_aff::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_aff_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff pw_aff::to_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).to_multi_pw_aff();
+}
+
+isl::union_pw_aff pw_aff::to_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_aff_to_union_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff pw_aff::to_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).to_union_pw_multi_aff();
+}
+
+isl::multi_pw_aff pw_aff::unbind_params_insert_domain(const isl::multi_id &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).unbind_params_insert_domain(domain);
+}
+
+isl::multi_pw_aff pw_aff::union_add(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(mpa2);
+}
+
+isl::multi_union_pw_aff pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).union_add(mupa2);
+}
+
 isl::pw_aff pw_aff::union_add(isl::pw_aff pwaff2) const
 {
   if (!ptr || pwaff2.is_null())
@@ -11398,6 +18046,34 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_aff::union_add(const isl::pw_multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::pw_multi_aff(*this).union_add(pma2);
+}
+
+isl::union_pw_aff pw_aff::union_add(const isl::union_pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).union_add(upa2);
+}
+
+isl::union_pw_multi_aff pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_aff(*this).union_add(upma2);
+}
+
+isl::pw_aff pw_aff::union_add(const isl::aff &pwaff2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::pw_aff(pwaff2));
+}
+
 inline std::ostream &operator<<(std::ostream &os, const pw_aff &obj)
 {
   if (!obj.get())
@@ -11469,6 +18145,16 @@
   ptr = res;
 }
 
+pw_aff_list::pw_aff_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_aff_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 pw_aff_list &pw_aff_list::operator=(pw_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -11513,6 +18199,23 @@
   return manage(res);
 }
 
+isl::pw_aff pw_aff_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_aff_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff pw_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::pw_aff_list pw_aff_list::clear() const
 {
   if (!ptr)
@@ -11577,23 +18280,6 @@
   return;
 }
 
-isl::pw_aff pw_aff_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_aff_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::pw_aff pw_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::pw_aff_list pw_aff_list::insert(unsigned int pos, isl::pw_aff el) const
 {
   if (!ptr || el.is_null())
@@ -11733,6 +18419,20 @@
   return isl::ctx(isl_pw_multi_aff_get_ctx(ptr));
 }
 
+isl::multi_pw_aff pw_multi_aff::add(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).add(multi2);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).add(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::add(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -11745,6 +18445,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).add(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::add(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::add(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::pw_multi_aff(pma2));
+}
+
 isl::pw_multi_aff pw_multi_aff::add_constant(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -11776,6 +18497,25 @@
   return this->add_constant(isl::val(ctx(), v));
 }
 
+isl::union_pw_multi_aff pw_multi_aff::apply(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).apply(upma2);
+}
+
+isl::map pw_multi_aff::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_as_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::multi_aff pw_multi_aff::as_multi_aff() const
 {
   if (!ptr)
@@ -11788,6 +18528,63 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff pw_multi_aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff pw_multi_aff::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::set pw_multi_aff::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_as_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map pw_multi_aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_union_map();
+}
+
+isl::pw_aff pw_multi_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_get_at(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_aff pw_multi_aff::get_at(int pos) const
+{
+  return at(pos);
+}
+
+isl::set pw_multi_aff::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).bind(tuple);
+}
+
 isl::pw_multi_aff pw_multi_aff::bind_domain(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -11848,6 +18645,27 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_multi_aff::extract_pw_multi_aff(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
+}
+
+isl::multi_pw_aff pw_multi_aff::flat_range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).flat_range_product(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::flat_range_product(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -11860,6 +18678,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).flat_range_product(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::flat_range_product(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::flat_range_product(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->flat_range_product(isl::pw_multi_aff(pma2));
+}
+
 void pw_multi_aff::foreach_piece(const std::function<void(isl::set, isl::multi_aff)> &fn) const
 {
   if (!ptr)
@@ -11888,23 +18727,6 @@
   return;
 }
 
-isl::space pw_multi_aff::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space pw_multi_aff::get_space() const
-{
-  return space();
-}
-
 isl::pw_multi_aff pw_multi_aff::gist(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -11917,6 +18739,46 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).gist(context);
+}
+
+isl::pw_multi_aff pw_multi_aff::gist(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
+}
+
+isl::pw_multi_aff pw_multi_aff::gist(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(set));
+}
+
+bool pw_multi_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+isl::multi_pw_aff pw_multi_aff::identity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).identity();
+}
+
 isl::pw_multi_aff pw_multi_aff::identity_on_domain(isl::space space)
 {
   if (space.is_null())
@@ -11953,6 +18815,48 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).intersect_domain(space);
+}
+
+isl::union_pw_multi_aff pw_multi_aff::intersect_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).intersect_domain(uset);
+}
+
+isl::pw_multi_aff pw_multi_aff::intersect_domain(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
+isl::pw_multi_aff pw_multi_aff::intersect_domain(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect_domain(isl::set(set));
+}
+
+isl::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).intersect_domain_wrapped_domain(uset);
+}
+
+isl::union_pw_multi_aff pw_multi_aff::intersect_domain_wrapped_range(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).intersect_domain_wrapped_range(uset);
+}
+
 isl::pw_multi_aff pw_multi_aff::intersect_params(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -11977,6 +18881,34 @@
   return res;
 }
 
+bool pw_multi_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).involves_nan();
+}
+
+bool pw_multi_aff::involves_param(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).involves_param(id);
+}
+
+bool pw_multi_aff::involves_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->involves_param(isl::id(ctx(), id));
+}
+
+bool pw_multi_aff::involves_param(const isl::id_list &list) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).involves_param(list);
+}
+
 bool pw_multi_aff::isa_multi_aff() const
 {
   if (!ptr)
@@ -11989,6 +18921,27 @@
   return res;
 }
 
+bool pw_multi_aff::isa_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::pw_aff_list pw_multi_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).list();
+}
+
+isl::multi_pw_aff pw_multi_aff::max(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).max(multi2);
+}
+
 isl::multi_val pw_multi_aff::max_multi_val() const
 {
   if (!ptr)
@@ -12001,6 +18954,13 @@
   return manage(res);
 }
 
+isl::multi_pw_aff pw_multi_aff::min(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).min(multi2);
+}
+
 isl::multi_val pw_multi_aff::min_multi_val() const
 {
   if (!ptr)
@@ -12013,6 +18973,18 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_multi_aff::multi_val_on_domain(isl::set domain, isl::multi_val mv)
+{
+  if (domain.is_null() || mv.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = domain.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_multi_val_on_domain(domain.release(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 unsigned pw_multi_aff::n_piece() const
 {
   if (!ptr)
@@ -12025,6 +18997,34 @@
   return res;
 }
 
+isl::multi_pw_aff pw_multi_aff::neg() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).neg();
+}
+
+bool pw_multi_aff::plain_is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).plain_is_empty();
+}
+
+bool pw_multi_aff::plain_is_equal(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).plain_is_equal(multi2);
+}
+
+bool pw_multi_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).plain_is_equal(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12037,6 +19037,34 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::preimage_domain_wrapped_domain(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->preimage_domain_wrapped_domain(isl::pw_multi_aff(pma2));
+}
+
+isl::multi_pw_aff pw_multi_aff::product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).product(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::product(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12049,6 +19077,27 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_multi_aff::product(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->product(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::product(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->product(isl::pw_multi_aff(pma2));
+}
+
+isl::multi_pw_aff pw_multi_aff::pullback(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).pullback(mpa2);
+}
+
 isl::pw_multi_aff pw_multi_aff::pullback(isl::multi_aff ma) const
 {
   if (!ptr || ma.is_null())
@@ -12073,6 +19122,20 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::pullback(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).pullback(upma2);
+}
+
+isl::pw_multi_aff_list pw_multi_aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).pw_multi_aff_list();
+}
+
 isl::pw_multi_aff pw_multi_aff::range_factor_domain() const
 {
   if (!ptr)
@@ -12109,6 +19172,20 @@
   return manage(res);
 }
 
+isl::multi_pw_aff pw_multi_aff::range_product(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).range_product(multi2);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).range_product(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::range_product(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12121,6 +19198,58 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::range_product(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::range_product(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->range_product(isl::pw_multi_aff(pma2));
+}
+
+isl::id pw_multi_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id pw_multi_aff::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
+isl::multi_pw_aff pw_multi_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::multi_pw_aff pw_multi_aff::scale(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).scale(mv);
+}
+
 isl::pw_multi_aff pw_multi_aff::scale(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -12140,6 +19269,13 @@
   return this->scale(isl::val(ctx(), v));
 }
 
+isl::multi_pw_aff pw_multi_aff::scale_down(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).scale_down(mv);
+}
+
 isl::pw_multi_aff pw_multi_aff::scale_down(isl::val v) const
 {
   if (!ptr || v.is_null())
@@ -12159,6 +19295,77 @@
   return this->scale_down(isl::val(ctx(), v));
 }
 
+isl::multi_pw_aff pw_multi_aff::set_at(int pos, const isl::pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).set_at(pos, el);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).set_at(pos, el);
+}
+
+isl::pw_multi_aff pw_multi_aff::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff pw_multi_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+unsigned pw_multi_aff::size() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).size();
+}
+
+isl::space pw_multi_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space pw_multi_aff::get_space() const
+{
+  return space();
+}
+
+isl::multi_pw_aff pw_multi_aff::sub(const isl::multi_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).sub(multi2);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).sub(multi2);
+}
+
 isl::pw_multi_aff pw_multi_aff::sub(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12171,6 +19378,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::sub(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).sub(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::sub(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::sub(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::pw_multi_aff(pma2));
+}
+
 isl::pw_multi_aff pw_multi_aff::subtract_domain(isl::set set) const
 {
   if (!ptr || set.is_null())
@@ -12183,6 +19411,91 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).subtract_domain(space);
+}
+
+isl::union_pw_multi_aff pw_multi_aff::subtract_domain(const isl::union_set &uset) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).subtract_domain(uset);
+}
+
+isl::pw_multi_aff pw_multi_aff::subtract_domain(const isl::basic_set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract_domain(isl::set(set));
+}
+
+isl::pw_multi_aff pw_multi_aff::subtract_domain(const isl::point &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract_domain(isl::set(set));
+}
+
+isl::pw_multi_aff_list pw_multi_aff::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff pw_multi_aff::to_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_to_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff pw_multi_aff::to_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_to_union_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff pw_multi_aff::unbind_params_insert_domain(const isl::multi_id &domain) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).unbind_params_insert_domain(domain);
+}
+
+isl::multi_pw_aff pw_multi_aff::union_add(const isl::multi_pw_aff &mpa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).union_add(mpa2);
+}
+
+isl::multi_union_pw_aff pw_multi_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_pw_aff(*this).union_add(mupa2);
+}
+
 isl::pw_multi_aff pw_multi_aff::union_add(isl::pw_multi_aff pma2) const
 {
   if (!ptr || pma2.is_null())
@@ -12195,6 +19508,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff pw_multi_aff::union_add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).union_add(upma2);
+}
+
+isl::pw_multi_aff pw_multi_aff::union_add(const isl::multi_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::pw_multi_aff(pma2));
+}
+
+isl::pw_multi_aff pw_multi_aff::union_add(const isl::pw_aff &pma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::pw_multi_aff(pma2));
+}
+
 isl::pw_multi_aff pw_multi_aff::zero(isl::space space)
 {
   if (space.is_null())
@@ -12278,6 +19612,16 @@
   ptr = res;
 }
 
+pw_multi_aff_list::pw_multi_aff_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 pw_multi_aff_list &pw_multi_aff_list::operator=(pw_multi_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -12322,6 +19666,23 @@
   return manage(res);
 }
 
+isl::pw_multi_aff pw_multi_aff_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_pw_multi_aff_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff pw_multi_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::pw_multi_aff_list pw_multi_aff_list::clear() const
 {
   if (!ptr)
@@ -12386,23 +19747,6 @@
   return;
 }
 
-isl::pw_multi_aff pw_multi_aff_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_pw_multi_aff_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::pw_multi_aff pw_multi_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::pw_multi_aff_list pw_multi_aff_list::insert(unsigned int pos, isl::pw_multi_aff el) const
 {
   if (!ptr || el.is_null())
@@ -12518,18 +19862,6 @@
   return isl::ctx(isl_schedule_get_ctx(ptr));
 }
 
-isl::schedule schedule::from_domain(isl::union_set domain)
-{
-  if (domain.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_from_domain(domain.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::union_set schedule::domain() const
 {
   if (!ptr)
@@ -12547,6 +19879,18 @@
   return domain();
 }
 
+isl::schedule schedule::from_domain(isl::union_set domain)
+{
+  if (domain.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = domain.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_from_domain(domain.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_map schedule::map() const
 {
   if (!ptr)
@@ -12564,6 +19908,18 @@
   return map();
 }
 
+isl::schedule schedule::pullback(isl::union_pw_multi_aff upma) const
+{
+  if (!ptr || upma.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::schedule_node schedule::root() const
 {
   if (!ptr)
@@ -12581,18 +19937,6 @@
   return root();
 }
 
-isl::schedule schedule::pullback(isl::union_pw_multi_aff upma) const
-{
-  if (!ptr || upma.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_pullback_union_pw_multi_aff(copy(), upma.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 inline std::ostream &operator<<(std::ostream &os, const schedule &obj)
 {
   if (!obj.get())
@@ -12684,18 +20028,6 @@
   return isl::ctx(isl_schedule_constraints_get_ctx(ptr));
 }
 
-isl::schedule schedule_constraints::compute_schedule() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_constraints_compute_schedule(copy());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::union_map schedule_constraints::coincidence() const
 {
   if (!ptr)
@@ -12713,6 +20045,18 @@
   return coincidence();
 }
 
+isl::schedule schedule_constraints::compute_schedule() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_constraints_compute_schedule(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_map schedule_constraints::conditional_validity() const
 {
   if (!ptr)
@@ -12781,6 +20125,18 @@
   return domain();
 }
 
+isl::schedule_constraints schedule_constraints::on_domain(isl::union_set domain)
+{
+  if (domain.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = domain.ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_constraints_on_domain(domain.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_map schedule_constraints::proximity() const
 {
   if (!ptr)
@@ -12798,35 +20154,6 @@
   return proximity();
 }
 
-isl::union_map schedule_constraints::validity() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_constraints_get_validity(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_map schedule_constraints::get_validity() const
-{
-  return validity();
-}
-
-isl::schedule_constraints schedule_constraints::on_domain(isl::union_set domain)
-{
-  if (domain.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = domain.ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_constraints_on_domain(domain.release());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
 isl::schedule_constraints schedule_constraints::set_coincidence(isl::union_map coincidence) const
 {
   if (!ptr || coincidence.is_null())
@@ -12887,6 +20214,23 @@
   return manage(res);
 }
 
+isl::union_map schedule_constraints::validity() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_constraints_get_validity(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map schedule_constraints::get_validity() const
+{
+  return validity();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const schedule_constraints &obj)
 {
   if (!obj.get())
@@ -13000,6 +20344,23 @@
   return manage(res);
 }
 
+unsigned schedule_node::ancestor_child_position(const isl::schedule_node &ancestor) const
+{
+  if (!ptr || ancestor.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+unsigned schedule_node::get_ancestor_child_position(const isl::schedule_node &ancestor) const
+{
+  return ancestor_child_position(ancestor);
+}
+
 isl::schedule_node schedule_node::child(int pos) const
 {
   if (!ptr)
@@ -13012,6 +20373,23 @@
   return manage(res);
 }
 
+unsigned schedule_node::child_position() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_child_position(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+unsigned schedule_node::get_child_position() const
+{
+  return child_position();
+}
+
 bool schedule_node::every_descendant(const std::function<bool(isl::schedule_node)> &test) const
 {
   if (!ptr)
@@ -13132,142 +20510,6 @@
   return manage(res);
 }
 
-unsigned schedule_node::ancestor_child_position(const isl::schedule_node &ancestor) const
-{
-  if (!ptr || ancestor.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_ancestor_child_position(get(), ancestor.get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
-unsigned schedule_node::get_ancestor_child_position(const isl::schedule_node &ancestor) const
-{
-  return ancestor_child_position(ancestor);
-}
-
-unsigned schedule_node::child_position() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_child_position(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
-unsigned schedule_node::get_child_position() const
-{
-  return child_position();
-}
-
-isl::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const
-{
-  return prefix_schedule_multi_union_pw_aff();
-}
-
-isl::union_map schedule_node::prefix_schedule_union_map() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_prefix_schedule_union_map(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_map schedule_node::get_prefix_schedule_union_map() const
-{
-  return prefix_schedule_union_map();
-}
-
-isl::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
-{
-  return prefix_schedule_union_pw_multi_aff();
-}
-
-isl::schedule schedule_node::schedule() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_schedule(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::schedule schedule_node::get_schedule() const
-{
-  return schedule();
-}
-
-isl::schedule_node schedule_node::shared_ancestor(const isl::schedule_node &node2) const
-{
-  if (!ptr || node2.is_null())
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::schedule_node schedule_node::get_shared_ancestor(const isl::schedule_node &node2) const
-{
-  return shared_ancestor(node2);
-}
-
-unsigned schedule_node::tree_depth() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_get_tree_depth(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
-unsigned schedule_node::get_tree_depth() const
-{
-  return tree_depth();
-}
-
 isl::schedule_node schedule_node::graft_after(isl::schedule_node graft) const
 {
   if (!ptr || graft.is_null())
@@ -13543,6 +20785,57 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff schedule_node::prefix_schedule_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff schedule_node::get_prefix_schedule_multi_union_pw_aff() const
+{
+  return prefix_schedule_multi_union_pw_aff();
+}
+
+isl::union_map schedule_node::prefix_schedule_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_prefix_schedule_union_map(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_map schedule_node::get_prefix_schedule_union_map() const
+{
+  return prefix_schedule_union_map();
+}
+
+isl::union_pw_multi_aff schedule_node::prefix_schedule_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff schedule_node::get_prefix_schedule_union_pw_multi_aff() const
+{
+  return prefix_schedule_union_pw_multi_aff();
+}
+
 isl::schedule_node schedule_node::previous_sibling() const
 {
   if (!ptr)
@@ -13567,6 +20860,57 @@
   return manage(res);
 }
 
+isl::schedule schedule_node::schedule() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_schedule(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::schedule schedule_node::get_schedule() const
+{
+  return schedule();
+}
+
+isl::schedule_node schedule_node::shared_ancestor(const isl::schedule_node &node2) const
+{
+  if (!ptr || node2.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_shared_ancestor(get(), node2.get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::schedule_node schedule_node::get_shared_ancestor(const isl::schedule_node &node2) const
+{
+  return shared_ancestor(node2);
+}
+
+unsigned schedule_node::tree_depth() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_get_tree_depth(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+unsigned schedule_node::get_tree_depth() const
+{
+  return tree_depth();
+}
+
 inline std::ostream &operator<<(std::ostream &os, const schedule_node &obj)
 {
   if (!obj.get())
@@ -13636,40 +20980,6 @@
   return ast_isolate_option();
 }
 
-isl::multi_union_pw_aff schedule_node_band::partial_schedule() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_band_get_partial_schedule(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
-{
-  return partial_schedule();
-}
-
-bool schedule_node_band::permutable() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_schedule_node_band_get_permutable(get());
-  if (res < 0)
-    exception::throw_last_error(saved_ctx);
-  return res;
-}
-
-bool schedule_node_band::get_permutable() const
-{
-  return permutable();
-}
-
 bool schedule_node_band::member_get_coincident(int pos) const
 {
   if (!ptr)
@@ -13718,6 +21028,40 @@
   return res;
 }
 
+isl::multi_union_pw_aff schedule_node_band::partial_schedule() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_band_get_partial_schedule(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff schedule_node_band::get_partial_schedule() const
+{
+  return partial_schedule();
+}
+
+bool schedule_node_band::permutable() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_schedule_node_band_get_permutable(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool schedule_node_band::get_permutable() const
+{
+  return permutable();
+}
+
 schedule_node_band schedule_node_band::scale(isl::multi_val mv) const
 {
   if (!ptr || mv.is_null())
@@ -14458,6 +21802,39 @@
   return manage(res);
 }
 
+isl::union_set set::apply(const isl::union_map &umap) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).apply(umap);
+}
+
+isl::set set::apply(const isl::basic_map &map) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->apply(isl::map(map));
+}
+
+isl::pw_multi_aff set::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_as_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set set::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).as_set();
+}
+
 isl::set set::bind(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -14494,6 +21871,13 @@
   return manage(res);
 }
 
+isl::union_set set::compute_divs() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).compute_divs();
+}
+
 isl::set set::detect_equalities() const
 {
   if (!ptr)
@@ -14542,6 +21926,20 @@
   return manage(res);
 }
 
+bool set::every_set(const std::function<bool(isl::set)> &test) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).every_set(test);
+}
+
+isl::set set::extract_set(const isl::space &space) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).extract_set(space);
+}
+
 isl::set set::flatten() const
 {
   if (!ptr)
@@ -14610,72 +22008,11 @@
   return;
 }
 
-isl::multi_val set::plain_multi_val_if_fixed() const
+void set::foreach_set(const std::function<void(isl::set)> &fn) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_get_plain_multi_val_if_fixed(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::multi_val set::get_plain_multi_val_if_fixed() const
-{
-  return plain_multi_val_if_fixed();
-}
-
-isl::fixed_box set::simple_fixed_box_hull() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_get_simple_fixed_box_hull(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::fixed_box set::get_simple_fixed_box_hull() const
-{
-  return simple_fixed_box_hull();
-}
-
-isl::space set::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space set::get_space() const
-{
-  return space();
-}
-
-isl::val set::stride(int pos) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_set_get_stride(get(), pos);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::val set::get_stride(int pos) const
-{
-  return stride(pos);
+  return isl::union_set(*this).foreach_set(fn);
 }
 
 isl::set set::gist(isl::set context) const
@@ -14690,6 +22027,34 @@
   return manage(res);
 }
 
+isl::union_set set::gist(const isl::union_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).gist(context);
+}
+
+isl::set set::gist(const isl::basic_set &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+isl::set set::gist(const isl::point &context) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->gist(isl::set(context));
+}
+
+isl::union_set set::gist_params(const isl::set &set) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).gist_params(set);
+}
+
 isl::map set::identity() const
 {
   if (!ptr)
@@ -14738,6 +22103,27 @@
   return manage(res);
 }
 
+isl::union_set set::intersect(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).intersect(uset2);
+}
+
+isl::set set::intersect(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect(isl::set(set2));
+}
+
+isl::set set::intersect(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->intersect(isl::set(set2));
+}
+
 isl::set set::intersect_params(isl::set params) const
 {
   if (!ptr || params.is_null())
@@ -14774,6 +22160,27 @@
   return res;
 }
 
+bool set::is_disjoint(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).is_disjoint(uset2);
+}
+
+bool set::is_disjoint(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_disjoint(isl::set(set2));
+}
+
+bool set::is_disjoint(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_disjoint(isl::set(set2));
+}
+
 bool set::is_empty() const
 {
   if (!ptr)
@@ -14798,6 +22205,27 @@
   return res;
 }
 
+bool set::is_equal(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).is_equal(uset2);
+}
+
+bool set::is_equal(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_equal(isl::set(set2));
+}
+
+bool set::is_equal(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_equal(isl::set(set2));
+}
+
 bool set::is_singleton() const
 {
   if (!ptr)
@@ -14822,6 +22250,27 @@
   return res;
 }
 
+bool set::is_strict_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).is_strict_subset(uset2);
+}
+
+bool set::is_strict_subset(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_strict_subset(isl::set(set2));
+}
+
+bool set::is_strict_subset(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_strict_subset(isl::set(set2));
+}
+
 bool set::is_subset(const isl::set &set2) const
 {
   if (!ptr || set2.is_null())
@@ -14834,6 +22283,27 @@
   return res;
 }
 
+bool set::is_subset(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).is_subset(uset2);
+}
+
+bool set::is_subset(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_subset(isl::set(set2));
+}
+
+bool set::is_subset(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->is_subset(isl::set(set2));
+}
+
 bool set::is_wrapping() const
 {
   if (!ptr)
@@ -14846,6 +22316,13 @@
   return res;
 }
 
+bool set::isa_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).isa_set();
+}
+
 isl::set set::lexmax() const
 {
   if (!ptr)
@@ -14978,6 +22455,23 @@
   return manage(res);
 }
 
+isl::multi_val set::plain_multi_val_if_fixed() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_get_plain_multi_val_if_fixed(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val set::get_plain_multi_val_if_fixed() const
+{
+  return plain_multi_val_if_fixed();
+}
+
 isl::basic_set set::polyhedral_hull() const
 {
   if (!ptr)
@@ -15026,6 +22520,13 @@
   return manage(res);
 }
 
+isl::union_set set::preimage(const isl::union_pw_multi_aff &upma) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).preimage(upma);
+}
+
 isl::set set::product(isl::set set2) const
 {
   if (!ptr || set2.is_null())
@@ -15081,6 +22582,18 @@
   return manage(res);
 }
 
+isl::pw_multi_aff set::pw_multi_aff_on_domain(isl::multi_val mv) const
+{
+  if (!ptr || mv.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_pw_multi_aff_on_domain_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::basic_set set::sample() const
 {
   if (!ptr)
@@ -15105,6 +22618,57 @@
   return manage(res);
 }
 
+isl::fixed_box set::simple_fixed_box_hull() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_get_simple_fixed_box_hull(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::fixed_box set::get_simple_fixed_box_hull() const
+{
+  return simple_fixed_box_hull();
+}
+
+isl::space set::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space set::get_space() const
+{
+  return space();
+}
+
+isl::val set::stride(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_get_stride(get(), pos);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::val set::get_stride(int pos) const
+{
+  return stride(pos);
+}
+
 isl::set set::subtract(isl::set set2) const
 {
   if (!ptr || set2.is_null())
@@ -15117,6 +22681,46 @@
   return manage(res);
 }
 
+isl::union_set set::subtract(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).subtract(uset2);
+}
+
+isl::set set::subtract(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract(isl::set(set2));
+}
+
+isl::set set::subtract(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->subtract(isl::set(set2));
+}
+
+isl::union_set_list set::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).to_list();
+}
+
+isl::union_set set::to_union_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_to_union_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::map set::translation() const
 {
   if (!ptr)
@@ -15129,6 +22733,18 @@
   return manage(res);
 }
 
+unsigned set::tuple_dim() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_set_tuple_dim(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
 isl::set set::unbind_params(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -15165,6 +22781,27 @@
   return manage(res);
 }
 
+isl::union_set set::unite(const isl::union_set &uset2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_set(*this).unite(uset2);
+}
+
+isl::set set::unite(const isl::basic_set &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->unite(isl::set(set2));
+}
+
+isl::set set::unite(const isl::point &set2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->unite(isl::set(set2));
+}
+
 isl::set set::universe(isl::space space)
 {
   if (space.is_null())
@@ -15325,6 +22962,25 @@
   return this->add_named_tuple(isl::id(ctx(), tuple_id), dim);
 }
 
+isl::space space::add_param(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_add_param_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space space::add_param(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add_param(isl::id(ctx(), id));
+}
+
 isl::space space::add_unnamed_tuple(unsigned int dim) const
 {
   if (!ptr)
@@ -15361,6 +23017,47 @@
   return manage(res);
 }
 
+isl::multi_aff space::domain_map_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_domain_map_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff space::domain_map_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_domain_map_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id space::domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_get_domain_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id space::get_domain_tuple_id() const
+{
+  return domain_tuple_id();
+}
+
 isl::space space::flatten_domain() const
 {
   if (!ptr)
@@ -15385,6 +23082,66 @@
   return manage(res);
 }
 
+bool space::has_domain_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_has_domain_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+bool space::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_has_range_tuple_id(get());
+  if (res < 0)
+    exception::throw_last_error(saved_ctx);
+  return res;
+}
+
+isl::multi_aff space::identity_multi_aff_on_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_identity_multi_aff_on_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff space::identity_multi_pw_aff_on_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_identity_multi_pw_aff_on_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff space::identity_pw_multi_aff_on_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_identity_pw_multi_aff_on_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 bool space::is_equal(const isl::space &space2) const
 {
   if (!ptr || space2.is_null())
@@ -15421,6 +23178,97 @@
   return manage(res);
 }
 
+isl::multi_aff space::multi_aff(isl::aff_list list) const
+{
+  if (!ptr || list.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_aff(copy(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff space::multi_aff_on_domain(isl::multi_val mv) const
+{
+  if (!ptr || mv.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_aff_on_domain_multi_val(copy(), mv.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_id space::multi_id(isl::id_list list) const
+{
+  if (!ptr || list.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_id(copy(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff space::multi_pw_aff(isl::pw_aff_list list) const
+{
+  if (!ptr || list.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_pw_aff(copy(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff space::multi_union_pw_aff(isl::union_pw_aff_list list) const
+{
+  if (!ptr || list.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_union_pw_aff(copy(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val space::multi_val(isl::val_list list) const
+{
+  if (!ptr || list.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_multi_val(copy(), list.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::aff space::param_aff_on_domain(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_param_aff_on_domain_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::aff space::param_aff_on_domain(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->param_aff_on_domain(isl::id(ctx(), id));
+}
+
 isl::space space::params() const
 {
   if (!ptr)
@@ -15457,6 +23305,30 @@
   return manage(res);
 }
 
+isl::multi_aff space::range_map_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_range_map_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff space::range_map_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_range_map_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::space space::range_reverse() const
 {
   if (!ptr)
@@ -15469,6 +23341,23 @@
   return manage(res);
 }
 
+isl::id space::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_get_range_tuple_id(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::id space::get_range_tuple_id() const
+{
+  return range_tuple_id();
+}
+
 isl::space space::reverse() const
 {
   if (!ptr)
@@ -15481,6 +23370,44 @@
   return manage(res);
 }
 
+isl::space space::set_domain_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_set_domain_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space space::set_domain_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_domain_tuple(isl::id(ctx(), id));
+}
+
+isl::space space::set_range_tuple(isl::id id) const
+{
+  if (!ptr || id.is_null())
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_set_range_tuple_id(copy(), id.release());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space space::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
 isl::space space::uncurry() const
 {
   if (!ptr)
@@ -15503,6 +23430,30 @@
   return manage(res);
 }
 
+isl::map space::universe_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_universe_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::set space::universe_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_universe_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::space space::unwrap() const
 {
   if (!ptr)
@@ -15527,6 +23478,66 @@
   return manage(res);
 }
 
+isl::aff space::zero_aff_on_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_zero_aff_on_domain(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_aff space::zero_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_zero_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_pw_aff space::zero_multi_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_zero_multi_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff space::zero_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_zero_multi_union_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_val space::zero_multi_val() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_space_zero_multi_val(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 inline std::ostream &operator<<(std::ostream &os, const space &obj)
 {
   if (!obj.get())
@@ -16026,6 +24037,42 @@
   return manage(res);
 }
 
+isl::map union_map::as_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_as_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff union_map::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_as_multi_union_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_multi_aff union_map::as_union_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_as_union_pw_multi_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_set union_map::bind_range(isl::multi_id tuple) const
 {
   if (!ptr || tuple.is_null())
@@ -16363,23 +24410,6 @@
   return manage(res);
 }
 
-isl::space union_map::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_map_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space union_map::get_space() const
-{
-  return space();
-}
-
 isl::union_map union_map::gist(isl::union_map context) const
 {
   if (!ptr || context.is_null())
@@ -16680,6 +24710,23 @@
   return manage(res);
 }
 
+isl::map_list union_map::map_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_get_map_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::map_list union_map::get_map_list() const
+{
+  return map_list();
+}
+
 isl::union_map union_map::polyhedral_hull() const
 {
   if (!ptr)
@@ -16884,6 +24931,23 @@
   return manage(res);
 }
 
+isl::space union_map::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_map_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space union_map::get_space() const
+{
+  return space();
+}
+
 isl::union_map union_map::subtract(isl::union_map umap2) const
 {
   if (!ptr || umap2.is_null())
@@ -17095,6 +25159,13 @@
   return isl::ctx(isl_union_pw_aff_get_ctx(ptr));
 }
 
+isl::multi_union_pw_aff union_pw_aff::add(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).add(multi2);
+}
+
 isl::union_pw_aff union_pw_aff::add(isl::union_pw_aff upa2) const
 {
   if (!ptr || upa2.is_null())
@@ -17107,6 +25178,69 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff union_pw_aff::add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).add(upma2);
+}
+
+isl::union_pw_aff union_pw_aff::add(const isl::aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::union_pw_aff(upa2));
+}
+
+isl::union_pw_aff union_pw_aff::add(const isl::pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->add(isl::union_pw_aff(upa2));
+}
+
+isl::union_pw_multi_aff union_pw_aff::apply(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).apply(upma2);
+}
+
+isl::multi_union_pw_aff union_pw_aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_multi_union_pw_aff();
+}
+
+isl::pw_multi_aff union_pw_aff::as_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_pw_multi_aff();
+}
+
+isl::union_map union_pw_aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).as_union_map();
+}
+
+isl::union_pw_aff union_pw_aff::at(int pos) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).at(pos);
+}
+
+isl::union_set union_pw_aff::bind(const isl::multi_id &tuple) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).bind(tuple);
+}
+
 isl::union_set union_pw_aff::bind(isl::id id) const
 {
   if (!ptr || id.is_null())
@@ -17150,21 +25284,25 @@
   return manage(res);
 }
 
-isl::space union_pw_aff::space() const
+isl::pw_multi_aff union_pw_aff::extract_pw_multi_aff(const isl::space &space) const
 {
   if (!ptr)
     exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
+  return isl::union_pw_multi_aff(*this).extract_pw_multi_aff(space);
 }
 
-isl::space union_pw_aff::get_space() const
+isl::multi_union_pw_aff union_pw_aff::flat_range_product(const isl::multi_union_pw_aff &multi2) const
 {
-  return space();
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).flat_range_product(multi2);
+}
+
+isl::union_pw_multi_aff union_pw_aff::flat_range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).flat_range_product(upma2);
 }
 
 isl::union_pw_aff union_pw_aff::gist(isl::union_set context) const
@@ -17179,6 +25317,13 @@
   return manage(res);
 }
 
+bool union_pw_aff::has_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).has_range_tuple_id();
+}
+
 isl::union_pw_aff union_pw_aff::intersect_domain(isl::space space) const
 {
   if (!ptr || space.is_null())
@@ -17239,6 +25384,62 @@
   return manage(res);
 }
 
+bool union_pw_aff::involves_locals() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).involves_locals();
+}
+
+bool union_pw_aff::involves_nan() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).involves_nan();
+}
+
+bool union_pw_aff::isa_pw_multi_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).isa_pw_multi_aff();
+}
+
+isl::union_pw_aff_list union_pw_aff::list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).list();
+}
+
+isl::multi_union_pw_aff union_pw_aff::neg() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).neg();
+}
+
+bool union_pw_aff::plain_is_empty() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).plain_is_empty();
+}
+
+bool union_pw_aff::plain_is_equal(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).plain_is_equal(multi2);
+}
+
+isl::union_pw_multi_aff union_pw_aff::preimage_domain_wrapped_domain(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).preimage_domain_wrapped_domain(upma2);
+}
+
 isl::union_pw_aff union_pw_aff::pullback(isl::union_pw_multi_aff upma) const
 {
   if (!ptr || upma.is_null())
@@ -17251,6 +25452,149 @@
   return manage(res);
 }
 
+isl::pw_multi_aff_list union_pw_aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).pw_multi_aff_list();
+}
+
+isl::union_pw_multi_aff union_pw_aff::range_factor_domain() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).range_factor_domain();
+}
+
+isl::union_pw_multi_aff union_pw_aff::range_factor_range() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).range_factor_range();
+}
+
+isl::multi_union_pw_aff union_pw_aff::range_product(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).range_product(multi2);
+}
+
+isl::union_pw_multi_aff union_pw_aff::range_product(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).range_product(upma2);
+}
+
+isl::id union_pw_aff::range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).range_tuple_id();
+}
+
+isl::multi_union_pw_aff union_pw_aff::reset_range_tuple_id() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).reset_range_tuple_id();
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).scale(mv);
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale(const isl::val &v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).scale(v);
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale(isl::val(ctx(), v));
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale_down(const isl::multi_val &mv) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).scale_down(mv);
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale_down(const isl::val &v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).scale_down(v);
+}
+
+isl::multi_union_pw_aff union_pw_aff::scale_down(long v) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->scale_down(isl::val(ctx(), v));
+}
+
+isl::multi_union_pw_aff union_pw_aff::set_at(int pos, const isl::union_pw_aff &el) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).set_at(pos, el);
+}
+
+isl::multi_union_pw_aff union_pw_aff::set_range_tuple(const isl::id &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).set_range_tuple(id);
+}
+
+isl::multi_union_pw_aff union_pw_aff::set_range_tuple(const std::string &id) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->set_range_tuple(isl::id(ctx(), id));
+}
+
+unsigned union_pw_aff::size() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).size();
+}
+
+isl::space union_pw_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space union_pw_aff::get_space() const
+{
+  return space();
+}
+
+isl::multi_union_pw_aff union_pw_aff::sub(const isl::multi_union_pw_aff &multi2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).sub(multi2);
+}
+
 isl::union_pw_aff union_pw_aff::sub(isl::union_pw_aff upa2) const
 {
   if (!ptr || upa2.is_null())
@@ -17263,6 +25607,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff union_pw_aff::sub(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).sub(upma2);
+}
+
+isl::union_pw_aff union_pw_aff::sub(const isl::aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::union_pw_aff(upa2));
+}
+
+isl::union_pw_aff union_pw_aff::sub(const isl::pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->sub(isl::union_pw_aff(upa2));
+}
+
 isl::union_pw_aff union_pw_aff::subtract_domain(isl::space space) const
 {
   if (!ptr || space.is_null())
@@ -17287,6 +25652,25 @@
   return manage(res);
 }
 
+isl::union_pw_aff_list union_pw_aff::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_aff_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::multi_union_pw_aff union_pw_aff::union_add(const isl::multi_union_pw_aff &mupa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::multi_union_pw_aff(*this).union_add(mupa2);
+}
+
 isl::union_pw_aff union_pw_aff::union_add(isl::union_pw_aff upa2) const
 {
   if (!ptr || upa2.is_null())
@@ -17299,6 +25683,27 @@
   return manage(res);
 }
 
+isl::union_pw_multi_aff union_pw_aff::union_add(const isl::union_pw_multi_aff &upma2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return isl::union_pw_multi_aff(*this).union_add(upma2);
+}
+
+isl::union_pw_aff union_pw_aff::union_add(const isl::aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::union_pw_aff(upa2));
+}
+
+isl::union_pw_aff union_pw_aff::union_add(const isl::pw_aff &upa2) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  return this->union_add(isl::union_pw_aff(upa2));
+}
+
 inline std::ostream &operator<<(std::ostream &os, const union_pw_aff &obj)
 {
   if (!obj.get())
@@ -17370,6 +25775,16 @@
   ptr = res;
 }
 
+union_pw_aff_list::union_pw_aff_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_aff_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 union_pw_aff_list &union_pw_aff_list::operator=(union_pw_aff_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -17414,6 +25829,23 @@
   return manage(res);
 }
 
+isl::union_pw_aff union_pw_aff_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_aff_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_pw_aff union_pw_aff_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::union_pw_aff_list union_pw_aff_list::clear() const
 {
   if (!ptr)
@@ -17478,23 +25910,6 @@
   return;
 }
 
-isl::union_pw_aff union_pw_aff_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_aff_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_pw_aff union_pw_aff_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::union_pw_aff_list union_pw_aff_list::insert(unsigned int pos, isl::union_pw_aff el) const
 {
   if (!ptr || el.is_null())
@@ -17670,6 +26085,18 @@
   return manage(res);
 }
 
+isl::multi_union_pw_aff union_pw_multi_aff::as_multi_union_pw_aff() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_multi_aff_as_multi_union_pw_aff(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::pw_multi_aff union_pw_multi_aff::as_pw_multi_aff() const
 {
   if (!ptr)
@@ -17682,6 +26109,18 @@
   return manage(res);
 }
 
+isl::union_map union_pw_multi_aff::as_union_map() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_multi_aff_as_union_map(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_pw_multi_aff union_pw_multi_aff::coalesce() const
 {
   if (!ptr)
@@ -17740,23 +26179,6 @@
   return manage(res);
 }
 
-isl::space union_pw_multi_aff::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_pw_multi_aff_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space union_pw_multi_aff::get_space() const
-{
-  return space();
-}
-
 isl::union_pw_multi_aff union_pw_multi_aff::gist(isl::union_set context) const
 {
   if (!ptr || context.is_null())
@@ -17889,6 +26311,23 @@
   return manage(res);
 }
 
+isl::pw_multi_aff_list union_pw_multi_aff::pw_multi_aff_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_multi_aff_get_pw_multi_aff_list(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::pw_multi_aff_list union_pw_multi_aff::get_pw_multi_aff_list() const
+{
+  return pw_multi_aff_list();
+}
+
 isl::union_pw_multi_aff union_pw_multi_aff::range_factor_domain() const
 {
   if (!ptr)
@@ -17925,6 +26364,23 @@
   return manage(res);
 }
 
+isl::space union_pw_multi_aff::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_pw_multi_aff_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space union_pw_multi_aff::get_space() const
+{
+  return space();
+}
+
 isl::union_pw_multi_aff union_pw_multi_aff::sub(isl::union_pw_multi_aff upma2) const
 {
   if (!ptr || upma2.is_null())
@@ -18124,6 +26580,18 @@
   return manage(res);
 }
 
+isl::set union_set::as_set() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_set_as_set(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_set union_set::coalesce() const
 {
   if (!ptr)
@@ -18266,23 +26734,6 @@
   return;
 }
 
-isl::space union_set::space() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_set_get_space(get());
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::space union_set::get_space() const
-{
-  return space();
-}
-
 isl::union_set union_set::gist(isl::union_set context) const
 {
   if (!ptr || context.is_null())
@@ -18499,6 +26950,23 @@
   return manage(res);
 }
 
+isl::space union_set::space() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_set_get_space(get());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::space union_set::get_space() const
+{
+  return space();
+}
+
 isl::union_set union_set::subtract(isl::union_set uset2) const
 {
   if (!ptr || uset2.is_null())
@@ -18511,6 +26979,18 @@
   return manage(res);
 }
 
+isl::union_set_list union_set::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_set_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::union_set union_set::unite(isl::union_set uset2) const
 {
   if (!ptr || uset2.is_null())
@@ -18618,6 +27098,16 @@
   ptr = res;
 }
 
+union_set_list::union_set_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_set_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 union_set_list &union_set_list::operator=(union_set_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -18662,6 +27152,23 @@
   return manage(res);
 }
 
+isl::union_set union_set_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_union_set_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::union_set union_set_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::union_set_list union_set_list::clear() const
 {
   if (!ptr)
@@ -18726,23 +27233,6 @@
   return;
 }
 
-isl::union_set union_set_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_union_set_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::union_set union_set_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::union_set_list union_set_list::insert(unsigned int pos, isl::union_set el) const
 {
   if (!ptr || el.is_null())
@@ -18940,6 +27430,21 @@
   return res;
 }
 
+long val::den_si() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_val_get_den_si(get());
+  return res;
+}
+
+long val::get_den_si() const
+{
+  return den_si();
+}
+
 isl::val val::div(isl::val v2) const
 {
   if (!ptr || v2.is_null())
@@ -19028,36 +27533,6 @@
   return this->ge(isl::val(ctx(), v2));
 }
 
-long val::den_si() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_val_get_den_si(get());
-  return res;
-}
-
-long val::get_den_si() const
-{
-  return den_si();
-}
-
-long val::num_si() const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_val_get_num_si(get());
-  return res;
-}
-
-long val::get_num_si() const
-{
-  return num_si();
-}
-
 bool val::gt(const isl::val &v2) const
 {
   if (!ptr || v2.is_null())
@@ -19437,6 +27912,21 @@
   return manage(res);
 }
 
+long val::num_si() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_val_get_num_si(get());
+  return res;
+}
+
+long val::get_num_si() const
+{
+  return num_si();
+}
+
 isl::val val::one(isl::ctx ctx)
 {
   auto saved_ctx = ctx;
@@ -19488,6 +27978,18 @@
   return this->sub(isl::val(ctx(), v2));
 }
 
+isl::val_list val::to_list() const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_val_to_list(copy());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
 isl::val val::trunc() const
 {
   if (!ptr)
@@ -19581,6 +28083,16 @@
   ptr = res;
 }
 
+val_list::val_list(isl::ctx ctx, const std::string &str)
+{
+  auto saved_ctx = ctx;
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_val_list_read_from_str(ctx.release(), str.c_str());
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  ptr = res;
+}
+
 val_list &val_list::operator=(val_list obj) {
   std::swap(this->ptr, obj.ptr);
   return *this;
@@ -19632,6 +28144,23 @@
   return this->add(isl::val(ctx(), el));
 }
 
+isl::val val_list::at(int index) const
+{
+  if (!ptr)
+    exception::throw_invalid("NULL input", __FILE__, __LINE__);
+  auto saved_ctx = ctx();
+  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
+  auto res = isl_val_list_get_at(get(), index);
+  if (!res)
+    exception::throw_last_error(saved_ctx);
+  return manage(res);
+}
+
+isl::val val_list::get_at(int index) const
+{
+  return at(index);
+}
+
 isl::val_list val_list::clear() const
 {
   if (!ptr)
@@ -19696,23 +28225,6 @@
   return;
 }
 
-isl::val val_list::at(int index) const
-{
-  if (!ptr)
-    exception::throw_invalid("NULL input", __FILE__, __LINE__);
-  auto saved_ctx = ctx();
-  options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
-  auto res = isl_val_list_get_at(get(), index);
-  if (!res)
-    exception::throw_last_error(saved_ctx);
-  return manage(res);
-}
-
-isl::val val_list::get_at(int index) const
-{
-  return at(index);
-}
-
 isl::val_list val_list::insert(unsigned int pos, isl::val el) const
 {
   if (!ptr || el.is_null())
diff --git a/lib/External/isl/include/isl/id.h b/lib/External/isl/include/isl/id.h
index 956b962..3e71cb0 100644
--- a/lib/External/isl/include/isl/id.h
+++ b/lib/External/isl/include/isl/id.h
@@ -13,6 +13,7 @@
 #endif
 
 ISL_DECLARE_EXPORTED_LIST_FN(id)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(id)
 
 ISL_DECLARE_MULTI(id)
 
diff --git a/lib/External/isl/include/isl/list.h b/lib/External/isl/include/isl/list.h
index 47fcef7..3d8dabe 100644
--- a/lib/External/isl/include/isl/list.h
+++ b/lib/External/isl/include/isl/list.h
@@ -27,6 +27,8 @@
 	ISL_DECLARE_LIST_TYPE2(EL,__isl_export)
 #define ISL_DECLARE_LIST_FN3(EL,CONSTRUCTOR,EXPORT)			\
 isl_ctx *isl_##EL##_list_get_ctx(__isl_keep isl_##EL##_list *list);	\
+EXPORT									\
+__isl_give isl_##EL##_list *isl_##EL##_to_list(__isl_take isl_##EL *el);\
 CONSTRUCTOR								\
 __isl_give isl_##EL##_list *isl_##EL##_list_from_##EL(			\
 	__isl_take isl_##EL *el);					\
@@ -102,6 +104,14 @@
 	ISL_DECLARE_LIST_FN3(EL,,)
 #define ISL_DECLARE_EXPORTED_LIST_FN(EL)				\
 	ISL_DECLARE_LIST_FN3(EL,__isl_constructor,__isl_export)
+#define ISL_DECLARE_LIST_FN_READ2(EL,CONSTRUCTOR)			\
+CONSTRUCTOR								\
+__isl_give isl_##EL##_list *isl_##EL##_list_read_from_str(		\
+	isl_ctx *ctx, const char *str);
+#define ISL_DECLARE_LIST_FN_READ(EL)					\
+	ISL_DECLARE_LIST_FN_READ2(EL,)
+#define ISL_DECLARE_EXPORTED_LIST_FN_READ(EL)				\
+	ISL_DECLARE_LIST_FN_READ2(EL,__isl_constructor)
 
 #define ISL_DECLARE_LIST(EL)						\
 	ISL_DECLARE_LIST_TYPE(EL)					\
diff --git a/lib/External/isl/include/isl/map.h b/lib/External/isl/include/isl/map.h
index 7fdd356..ede0463 100644
--- a/lib/External/isl/include/isl/map.h
+++ b/lib/External/isl/include/isl/map.h
@@ -34,6 +34,10 @@
 isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
 				enum isl_dim_type type);
 
+__isl_export
+isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map);
+__isl_export
+isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map);
 isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type);
 
 isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap);
@@ -81,11 +85,25 @@
 	enum isl_dim_type type, unsigned pos);
 __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
 	enum isl_dim_type type, unsigned pos);
+__isl_overload
+__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
+	__isl_take isl_id *id);
+__isl_overload
+__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
+	__isl_take isl_id *id);
 __isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
 	enum isl_dim_type type, __isl_take isl_id *id);
 __isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
 	enum isl_dim_type type);
+__isl_export
+isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map);
+__isl_export
+isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map);
 isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type);
+__isl_export
+__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map);
+__isl_export
+__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map);
 __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
 	enum isl_dim_type type);
 __isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map);
@@ -285,6 +303,8 @@
 
 __isl_export
 __isl_give isl_map *isl_map_universe(__isl_take isl_space *space);
+__isl_export
+__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space);
 __isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space);
 __isl_export
 __isl_give isl_map *isl_map_empty(__isl_take isl_space *space);
@@ -664,6 +684,9 @@
 __isl_give isl_stride_info *isl_map_get_range_stride_info(
 	__isl_keep isl_map *map, int pos);
 __isl_export
+__isl_give isl_fixed_box *isl_map_get_range_lattice_tile(
+	__isl_keep isl_map *map);
+__isl_export
 __isl_give isl_fixed_box *isl_map_get_range_simple_fixed_box_hull(
 	__isl_keep isl_map *map);
 
@@ -744,13 +767,16 @@
 	__isl_take isl_space *domain_space, __isl_take isl_aff_list *list);
 
 __isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff);
+__isl_export
+__isl_give isl_map *isl_multi_aff_as_map(__isl_take isl_multi_aff *ma);
 __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *maff);
 
 __isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos);
 __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos);
 
 ISL_DECLARE_LIST_FN(basic_map)
-ISL_DECLARE_LIST_FN(map)
+ISL_DECLARE_EXPORTED_LIST_FN(map)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(map)
 
 #if defined(__cplusplus)
 }
diff --git a/lib/External/isl/include/isl/map_type.h b/lib/External/isl/include/isl/map_type.h
index 7c30056..8802584 100644
--- a/lib/External/isl/include/isl/map_type.h
+++ b/lib/External/isl/include/isl/map_type.h
@@ -13,7 +13,7 @@
 ISL_DECLARE_LIST_TYPE(basic_map)
 struct __isl_subclass(isl_union_map) isl_map;
 typedef struct isl_map isl_map;
-ISL_DECLARE_LIST_TYPE(map)
+ISL_DECLARE_EXPORTED_LIST_TYPE(map)
 
 #ifndef isl_basic_set
 struct __isl_subclass(isl_set) isl_basic_set;
diff --git a/lib/External/isl/include/isl/multi.h b/lib/External/isl/include/isl/multi.h
index 52bac4a..3c39778 100644
--- a/lib/External/isl/include/isl/multi.h
+++ b/lib/External/isl/include/isl/multi.h
@@ -24,6 +24,9 @@
 __isl_constructor							\
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_from_##BASE##_list(	\
 	__isl_take isl_space *space, __isl_take isl_##BASE##_list *list); \
+__isl_export								\
+__isl_give isl_multi_##BASE *isl_space_multi_##BASE(			\
+	__isl_take isl_space *space, __isl_take isl_##BASE##_list *list); \
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_copy(			\
 	__isl_keep isl_multi_##BASE *multi);				\
 __isl_null isl_multi_##BASE *isl_multi_##BASE##_free(			\
@@ -84,6 +87,10 @@
 __isl_overload								\
 __isl_give isl_multi_##BASE *						\
 isl_multi_##BASE##_identity_on_domain_space(				\
+	__isl_take isl_space *space);					\
+__isl_export								\
+__isl_give isl_multi_##BASE *						\
+isl_space_identity_multi_##BASE##_on_domain(				\
 	__isl_take isl_space *space);
 
 #define ISL_DECLARE_MULTI_CMP(BASE)					\
@@ -141,6 +148,9 @@
 #define ISL_DECLARE_MULTI_ZERO(BASE)					\
 __isl_export								\
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_zero(			\
+	__isl_take isl_space *space);					\
+__isl_export								\
+__isl_give isl_multi_##BASE *isl_space_zero_multi_##BASE(		\
 	__isl_take isl_space *space);
 
 #define ISL_DECLARE_MULTI_NAN(BASE)					\
@@ -200,16 +210,28 @@
 #define ISL_DECLARE_MULTI_TUPLE_ID(BASE)				\
 const char *isl_multi_##BASE##_get_tuple_name(				\
 	__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type);	\
+__isl_export								\
+isl_bool isl_multi_##BASE##_has_range_tuple_id(				\
+	__isl_keep isl_multi_##BASE *multi);				\
 isl_bool isl_multi_##BASE##_has_tuple_id(				\
 	__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type);	\
+__isl_export								\
+__isl_give isl_id *isl_multi_##BASE##_get_range_tuple_id(		\
+	__isl_keep isl_multi_##BASE *multi);				\
 __isl_give isl_id *isl_multi_##BASE##_get_tuple_id(			\
 	__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type);	\
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_name(		\
 	__isl_take isl_multi_##BASE *multi,				\
 	enum isl_dim_type type, const char *s);				\
+__isl_overload								\
+__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_range_tuple_id(	\
+	__isl_take isl_multi_##BASE *multi,  __isl_take isl_id *id);	\
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_id(		\
 	__isl_take isl_multi_##BASE *multi,				\
 	enum isl_dim_type type, __isl_take isl_id *id);			\
+__isl_export								\
+__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_range_tuple_id(	\
+	__isl_take isl_multi_##BASE *multi);				\
 __isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_tuple_id(		\
 	__isl_take isl_multi_##BASE *multi, enum isl_dim_type type);
 
diff --git a/lib/External/isl/include/isl/polynomial.h b/lib/External/isl/include/isl/polynomial.h
index 0be4f0a..2d5baaf 100644
--- a/lib/External/isl/include/isl/polynomial.h
+++ b/lib/External/isl/include/isl/polynomial.h
@@ -535,6 +535,8 @@
 	__isl_keep isl_union_pw_qpolynomial *upwqp1,
 	__isl_keep isl_union_pw_qpolynomial *upwqp2);
 
+__isl_give isl_union_pw_qpolynomial *isl_pw_qpolynomial_to_union_pw_qpolynomial(
+	__isl_take isl_pw_qpolynomial *pwqp);
 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_from_pw_qpolynomial(__isl_take isl_pw_qpolynomial *pwqp);
 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_zero_ctx(
 	isl_ctx *ctx);
@@ -676,6 +678,9 @@
 	__isl_keep isl_union_pw_qpolynomial_fold *upwf1,
 	__isl_keep isl_union_pw_qpolynomial_fold *upwf2);
 
+__isl_give isl_union_pw_qpolynomial_fold *
+isl_pw_qpolynomial_fold_to_union_pw_qpolynomial_fold(
+	__isl_take isl_pw_qpolynomial_fold *pwf);
 __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_from_pw_qpolynomial_fold(__isl_take isl_pw_qpolynomial_fold *pwf);
 __isl_give isl_union_pw_qpolynomial_fold *
 isl_union_pw_qpolynomial_fold_zero_ctx(isl_ctx *ctx, enum isl_fold type);
diff --git a/lib/External/isl/include/isl/set.h b/lib/External/isl/include/isl/set.h
index 2fc8e5f..4b66b82 100644
--- a/lib/External/isl/include/isl/set.h
+++ b/lib/External/isl/include/isl/set.h
@@ -34,6 +34,8 @@
 
 isl_size isl_set_n_dim(__isl_keep isl_set *set);
 isl_size isl_set_n_param(__isl_keep isl_set *set);
+__isl_export
+isl_size isl_set_tuple_dim(__isl_keep isl_set *set);
 isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type);
 
 isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset);
@@ -275,9 +277,13 @@
 __isl_give isl_set *isl_set_empty(__isl_take isl_space *space);
 __isl_export
 __isl_give isl_set *isl_set_universe(__isl_take isl_space *space);
+__isl_export
+__isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space);
 __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space);
 __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set);
 __isl_null isl_set *isl_set_free(__isl_take isl_set *set);
+__isl_export
+__isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset);
 __isl_constructor
 __isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset);
 __isl_export
@@ -520,6 +526,8 @@
 
 __isl_constructor
 __isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt);
+__isl_export
+__isl_give isl_set *isl_point_to_set(__isl_take isl_point *pnt);
 __isl_constructor
 __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt);
 __isl_give isl_basic_set *isl_basic_set_box_from_points(
@@ -563,6 +571,8 @@
 __isl_give isl_basic_set *isl_basic_set_from_multi_aff(
 	__isl_take isl_multi_aff *ma);
 
+__isl_export
+__isl_give isl_set *isl_multi_aff_as_set(__isl_take isl_multi_aff *ma);
 __isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma);
 
 __isl_give isl_mat *isl_basic_set_reduced_basis(__isl_keep isl_basic_set *bset);
diff --git a/lib/External/isl/include/isl/space.h b/lib/External/isl/include/isl/space.h
index 6f3da5b..f3e1d8a 100644
--- a/lib/External/isl/include/isl/space.h
+++ b/lib/External/isl/include/isl/space.h
@@ -34,6 +34,7 @@
 isl_bool isl_space_is_set(__isl_keep isl_space *space);
 isl_bool isl_space_is_map(__isl_keep isl_space *space);
 
+__isl_overload
 __isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space,
 	__isl_take isl_id *id);
 
@@ -43,12 +44,28 @@
 	enum isl_dim_type type);
 __isl_keep const char *isl_space_get_tuple_name(__isl_keep isl_space *space,
 				 enum isl_dim_type type);
+__isl_overload
+__isl_give isl_space *isl_space_set_domain_tuple_id(
+	__isl_take isl_space *space, __isl_take isl_id *id);
+__isl_overload
+__isl_give isl_space *isl_space_set_range_tuple_id(
+	__isl_take isl_space *space, __isl_take isl_id *id);
 __isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space,
 	enum isl_dim_type type, __isl_take isl_id *id);
 __isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space,
 	enum isl_dim_type type);
+__isl_export
+isl_bool isl_space_has_domain_tuple_id(__isl_keep isl_space *space);
+__isl_export
+isl_bool isl_space_has_range_tuple_id(__isl_keep isl_space *space);
 isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space,
 	enum isl_dim_type type);
+__isl_export
+__isl_give isl_id *isl_space_get_domain_tuple_id(
+	__isl_keep isl_space *space);
+__isl_export
+__isl_give isl_id *isl_space_get_range_tuple_id(
+	__isl_keep isl_space *space);
 __isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space,
 	enum isl_dim_type type);
 __isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space);
diff --git a/lib/External/isl/include/isl/typed_cpp.h b/lib/External/isl/include/isl/typed_cpp.h
new file mode 100644
index 0000000..df39c8e
--- /dev/null
+++ b/lib/External/isl/include/isl/typed_cpp.h
@@ -0,0 +1,48308 @@
+/// These are automatically generated templated C++ bindings for isl.
+///
+/// isl is a library for computing with integer sets and maps described by
+/// Presburger formulas. On top of this, isl provides various tools for
+/// polyhedral compilation, ranging from dependence analysis over scheduling
+/// to AST generation.
+
+#ifndef ISL_TYPED_CPP
+#define ISL_TYPED_CPP
+
+#include <type_traits>
+
+#include <isl/cpp.h>
+
+namespace isl {
+namespace typed {
+
+template <typename Domain, typename Range>
+struct pair {};
+
+struct Anonymous;
+
+
+template <typename...>
+struct aff;
+
+template <typename...Ts>
+using aff_on = aff<Ts..., Anonymous>;
+
+template <typename...>
+struct aff_list;
+
+template <typename...Ts>
+using aff_list_on = aff_list<Ts..., Anonymous>;
+
+template <typename...>
+struct basic_map;
+
+template <typename...>
+struct basic_set;
+
+template <typename...>
+struct fixed_box;
+
+template <typename...>
+struct id;
+
+template <typename...>
+struct id_list;
+
+template <typename...>
+struct map;
+
+template <typename...>
+struct map_list;
+
+template <typename...>
+struct multi_aff;
+
+template <typename...>
+struct multi_id;
+
+template <typename...>
+struct multi_pw_aff;
+
+template <typename...>
+struct multi_union_pw_aff;
+
+template <typename...>
+struct multi_val;
+
+template <typename...>
+struct point;
+
+template <typename...>
+struct pw_aff;
+
+template <typename...Ts>
+using pw_aff_on = pw_aff<Ts..., Anonymous>;
+
+template <typename...>
+struct pw_aff_list;
+
+template <typename...Ts>
+using pw_aff_list_on = pw_aff_list<Ts..., Anonymous>;
+
+template <typename...>
+struct pw_multi_aff;
+
+template <typename...>
+struct pw_multi_aff_list;
+
+template <typename...>
+struct set;
+
+template <typename...>
+struct space;
+
+template <typename...>
+struct union_map;
+
+template <typename...>
+struct union_pw_aff;
+
+template <typename...Ts>
+using union_pw_aff_on = union_pw_aff<Ts..., Anonymous>;
+
+template <typename...>
+struct union_pw_aff_list;
+
+template <typename...Ts>
+using union_pw_aff_list_on = union_pw_aff_list<Ts..., Anonymous>;
+
+template <typename...>
+struct union_pw_multi_aff;
+
+template <typename...>
+struct union_set;
+
+template <typename...>
+struct union_set_list;
+
+template <typename...>
+struct val;
+
+template <typename...>
+struct val_list;
+
+template <>
+struct aff<Anonymous> : public isl::aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  aff() = default;
+  aff(const isl::aff &obj) : isl::aff(obj) {}
+  static aff from(const isl::aff &obj) {
+    return aff(obj);
+  }
+  inline explicit aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::aff<Anonymous> add(const typed::aff<Anonymous> &aff2) const;
+  inline typed::multi_aff<Anonymous> add(const typed::multi_aff<Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<Anonymous> add(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Anonymous> add(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> add(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> add(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::aff<Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Anonymous> add_constant(long v) const;
+  inline typed::multi_aff<Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const;
+  inline typed::aff<Anonymous> as_aff() const;
+  inline typed::map<Anonymous> as_map() const = delete;
+  inline typed::multi_aff<Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Anonymous> as_pw_multi_aff() const;
+  inline typed::set<Anonymous> as_set() const;
+  inline typed::union_map<Anonymous> as_union_map() const = delete;
+  inline typed::aff<Anonymous> at(int pos) const;
+  inline typed::basic_set<> bind(const typed::id<Anonymous> &id) const;
+  inline typed::basic_set<> bind(const std::string &id) const;
+  inline typed::basic_set<> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_aff<Anonymous> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::aff<Anonymous> ceil() const;
+  inline typed::pw_aff<Anonymous> coalesce() const;
+  inline typed::pw_aff<Anonymous> cond(const typed::pw_aff<Anonymous> &pwaff_true, const typed::pw_aff<Anonymous> &pwaff_false) const;
+  inline typed::multi_val<Anonymous> constant_multi_val() const;
+  inline typed::val<Anonymous> get_constant_val() const = delete;
+  inline typed::set<> domain() const;
+  inline typed::pw_multi_aff<Anonymous> extract_pw_multi_aff(const typed::space<Anonymous> &space) const;
+  inline typed::aff<Anonymous> floor() const;
+  inline typed::set<Anonymous> ge_set(const typed::aff<> &aff2) const = delete;
+  inline typed::set<Anonymous> ge_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::aff<Anonymous> gist(const typed::set<> &context) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::union_set<> &context) const;
+  inline typed::aff<Anonymous> gist(const typed::basic_set<> &context) const;
+  inline typed::aff<Anonymous> gist(const typed::point<> &context) const;
+  inline typed::set<Anonymous> gt_set(const typed::aff<> &aff2) const = delete;
+  inline typed::set<Anonymous> gt_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::multi_aff<Anonymous, Anonymous> identity() const;
+  template <typename Domain>
+  inline typed::pw_aff<Domain, Anonymous> insert_domain(const typed::space<Domain> &domain) const;
+  inline typed::pw_aff<Anonymous> intersect_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_aff<Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::set<Anonymous> le_set(const typed::aff<> &aff2) const = delete;
+  inline typed::set<Anonymous> le_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::aff_list<Anonymous> list() const;
+  inline typed::set<Anonymous> lt_set(const typed::aff<> &aff2) const = delete;
+  inline typed::set<Anonymous> lt_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::multi_pw_aff<Anonymous> max(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> max(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<Anonymous> min(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> min(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::aff<Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::aff<Anonymous> mod(long mod) const;
+  inline typed::aff<Anonymous> neg() const;
+  inline typed::pw_multi_aff<Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Range>
+  inline typed::multi_aff<pair<Anonymous, Range>> product(const typed::multi_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Anonymous, Range>> product(const typed::multi_pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Anonymous, Range>> product(const typed::pw_multi_aff<Range> &pma2) const;
+  inline typed::aff<Anonymous> pullback(const typed::multi_aff<> &ma) const = delete;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::aff<Anonymous> pullback(const typed::aff<> &ma) const = delete;
+  inline typed::pw_multi_aff_list<Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Anonymous> range_factor_range() const = delete;
+  inline typed::multi_aff<Anonymous> range_product(const typed::multi_aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Anonymous> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::pw_multi_aff<Anonymous> range_product(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::aff<Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Anonymous> scale(long v) const;
+  inline typed::multi_aff<Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::aff<Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Anonymous> scale_down(long v) const;
+  inline typed::multi_aff<Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_aff<Anonymous> set_at(int pos, const typed::aff<Anonymous> &el) const;
+  inline typed::multi_pw_aff<Anonymous> set_at(int pos, const typed::pw_aff<Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Anonymous> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Anonymous> space() const;
+  inline typed::aff<Anonymous> sub(const typed::aff<Anonymous> &aff2) const;
+  inline typed::multi_aff<Anonymous> sub(const typed::multi_aff<Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<Anonymous> sub(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Anonymous> sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> sub(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> sub(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> sub(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::pw_aff<Anonymous> subtract_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::multi_pw_aff<Anonymous> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Anonymous> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Anonymous> to_pw_multi_aff() const;
+  inline typed::union_pw_aff<Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Anonymous> to_union_pw_multi_aff() const;
+  template <typename Domain>
+  inline typed::aff<Domain, Anonymous> unbind_params_insert_domain(const typed::multi_id<Domain> &domain) const;
+  inline typed::multi_pw_aff<Anonymous> union_add(const typed::multi_pw_aff<Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<Anonymous> union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const;
+  inline typed::pw_aff<Anonymous> union_add(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> union_add(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> union_add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+};
+
+template <typename Domain>
+struct aff<Domain, Anonymous> : public isl::aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  aff(const aff<Arg1, Anonymous> &obj) : isl::aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::aff>{}, bool>::type = true>
+  aff(const base &obj) : isl::aff(obj) {}
+ public:
+  static aff from(const isl::aff &obj) {
+    return aff(obj);
+  }
+  inline explicit aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::aff<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::multi_aff<Domain, Anonymous> add(const typed::multi_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> add(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::aff<Domain, Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Domain, Anonymous> add_constant(long v) const;
+  inline typed::multi_aff<Domain, Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const;
+  inline typed::aff<Domain, Anonymous> as_aff() const;
+  inline typed::map<Domain, Anonymous> as_map() const;
+  inline typed::multi_aff<Domain, Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> as_pw_multi_aff() const;
+  inline typed::set<Domain, Anonymous> as_set() const = delete;
+  inline typed::union_map<Domain, Anonymous> as_union_map() const;
+  inline typed::aff<Domain, Anonymous> at(int pos) const;
+  inline typed::basic_set<Domain> bind(const typed::id<Anonymous> &id) const;
+  inline typed::basic_set<Domain> bind(const std::string &id) const;
+  inline typed::basic_set<Domain> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::pw_aff<Domain, Anonymous> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::aff<Domain, Anonymous> ceil() const;
+  inline typed::pw_aff<Domain, Anonymous> coalesce() const;
+  inline typed::pw_aff<Domain, Anonymous> cond(const typed::pw_aff<Domain, Anonymous> &pwaff_true, const typed::pw_aff<Domain, Anonymous> &pwaff_false) const;
+  inline typed::multi_val<Anonymous> constant_multi_val() const;
+  inline typed::val<Domain, Anonymous> get_constant_val() const = delete;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const;
+  inline typed::aff<Domain, Anonymous> floor() const;
+  inline typed::set<Domain> ge_set(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::set<Domain> ge_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::aff<Domain, Anonymous> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::union_set<Domain> &context) const;
+  inline typed::aff<Domain, Anonymous> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::aff<Domain, Anonymous> gist(const typed::point<Domain> &context) const;
+  inline typed::set<Domain> gt_set(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::set<Domain> gt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_aff<Domain, Anonymous> identity() const;
+  inline typed::pw_aff<Domain, Anonymous> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_aff<Domain, Anonymous> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::set<Domain> le_set(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::set<Domain> le_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::aff_list<Domain, Anonymous> list() const;
+  inline typed::set<Domain> lt_set(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::set<Domain> lt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> max(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> max(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Anonymous> min(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> min(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::aff<Domain, Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::aff<Domain, Anonymous> mod(long mod) const;
+  inline typed::aff<Domain, Anonymous> neg() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> product(const typed::multi_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2>
+  inline typed::aff<Domain2, Anonymous> pullback(const typed::multi_aff<Domain2, Domain> &ma) const;
+  inline typed::aff<Anonymous> pullback(const typed::multi_aff<Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::pw_aff<Domain2, Anonymous> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::pw_aff<Domain2, Anonymous> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::aff<Domain2, Anonymous> pullback(const typed::aff<Domain2, Domain> &ma) const;
+  inline typed::aff<Anonymous> pullback(const typed::aff<Domain> &ma) const;
+  inline typed::pw_multi_aff_list<Domain, Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, Anonymous> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  inline typed::aff<Domain, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Domain, Anonymous> scale(long v) const;
+  inline typed::multi_aff<Domain, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::aff<Domain, Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::aff<Domain, Anonymous> scale_down(long v) const;
+  inline typed::multi_aff<Domain, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_aff<Domain, Anonymous> set_at(int pos, const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Anonymous> space() const;
+  inline typed::aff<Domain, Anonymous> sub(const typed::aff<Domain, Anonymous> &aff2) const;
+  inline typed::multi_aff<Domain, Anonymous> sub(const typed::multi_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> sub(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> sub(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> sub(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::pw_aff<Domain, Anonymous> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> to_pw_multi_aff() const;
+  inline typed::union_pw_aff<Domain, Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> to_union_pw_multi_aff() const;
+  inline typed::aff<Domain, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Anonymous> union_add(const typed::multi_pw_aff<Domain, Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const;
+  inline typed::pw_aff<Domain, Anonymous> union_add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> union_add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+};
+
+template <typename Domain2, typename Range2>
+struct aff<pair<Domain2, Range2>, Anonymous> : public isl::aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain2, Arg1>{} &&
+              std::is_base_of<Range2, Arg2>{},
+            bool>::type = true>
+  aff(const aff<pair<Arg1, Arg2>, Anonymous> &obj) : isl::aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::aff>{}, bool>::type = true>
+  aff(const base &obj) : isl::aff(obj) {}
+ public:
+  static aff from(const isl::aff &obj) {
+    return aff(obj);
+  }
+  inline explicit aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> add(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> add(const typed::multi_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> add_constant(long v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Arg1>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> apply(const typed::union_pw_multi_aff<Anonymous, Arg1> &upma2) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> as_aff() const;
+  inline typed::map<pair<Domain2, Range2>, Anonymous> as_map() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain2, Range2>, Anonymous> as_set() const = delete;
+  inline typed::union_map<pair<Domain2, Range2>, Anonymous> as_union_map() const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> at(int pos) const;
+  inline typed::basic_set<pair<Domain2, Range2>> bind(const typed::id<Anonymous> &id) const;
+  inline typed::basic_set<pair<Domain2, Range2>> bind(const std::string &id) const;
+  inline typed::basic_set<pair<Domain2, Range2>> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const;
+  inline typed::pw_aff<Range2, Anonymous> bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> ceil() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> coalesce() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> cond(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_true, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_false) const;
+  inline typed::multi_val<Anonymous> constant_multi_val() const;
+  inline typed::val<pair<Domain2, Range2>, Anonymous> get_constant_val() const = delete;
+  inline typed::set<pair<Domain2, Range2>> domain() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Anonymous> &space) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> floor() const;
+  inline typed::set<pair<Domain2, Range2>> ge_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::set<pair<Domain2, Range2>> ge_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> gist(const typed::set<pair<Domain2, Range2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> gist(const typed::union_set<pair<Domain2, Range2>> &context) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> gist(const typed::basic_set<pair<Domain2, Range2>> &context) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> gist(const typed::point<pair<Domain2, Range2>> &context) const;
+  inline typed::set<pair<Domain2, Range2>> gt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::set<pair<Domain2, Range2>> gt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> identity() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::set<pair<Domain2, Range2>> le_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::set<pair<Domain2, Range2>> le_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::aff_list<pair<Domain2, Range2>, Anonymous> list() const;
+  inline typed::set<pair<Domain2, Range2>> lt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::set<pair<Domain2, Range2>> lt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> max(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> max(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> min(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> min(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> mod(long mod) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const;
+  template <typename Arg1, typename Arg2>
+  inline typed::multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> product(const typed::multi_aff<Arg1, Arg2> &multi2) const;
+  template <typename Arg1, typename Arg2>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> product(const typed::multi_pw_aff<Arg1, Arg2> &multi2) const;
+  template <typename Arg1, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> product(const typed::pw_multi_aff<Arg1, Arg2> &pma2) const;
+  template <typename Arg1>
+  inline typed::aff<Arg1, Anonymous> pullback(const typed::multi_aff<Arg1, pair<Domain2, Range2>> &ma) const;
+  inline typed::aff<Anonymous> pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const;
+  template <typename Arg1>
+  inline typed::pw_aff<Arg1, Anonymous> pullback(const typed::multi_pw_aff<Arg1, pair<Domain2, Range2>> &mpa) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa) const;
+  template <typename Arg1>
+  inline typed::pw_aff<Arg1, Anonymous> pullback(const typed::pw_multi_aff<Arg1, pair<Domain2, Range2>> &pma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const;
+  template <typename Arg1>
+  inline typed::union_pw_aff<Arg1, Anonymous> pullback(const typed::union_pw_multi_aff<Arg1, pair<Domain2, Range2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const;
+  template <typename Arg1>
+  inline typed::aff<Arg1, Anonymous> pullback(const typed::aff<Arg1, pair<Domain2, Range2>> &ma) const;
+  inline typed::aff<Anonymous> pullback(const typed::aff<pair<Domain2, Range2>> &ma) const;
+  inline typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> range_factor_range() const = delete;
+  template <typename Arg1>
+  inline typed::multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg1> &multi2) const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const;
+  template <typename Arg1>
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> &pma2) const;
+  template <typename Arg1>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> &upma2) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> scale(long v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> scale_down(long v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> set_at(int pos, const typed::aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  template <typename Arg1>
+  inline typed::multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg1>
+  inline typed::multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain2, Range2>, Anonymous> space() const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> sub(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::multi_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> to_pw_multi_aff() const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> to_union_pw_multi_aff() const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &mupa2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+};
+
+template <>
+struct aff_list<Anonymous> : public isl::aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  aff_list() = default;
+  aff_list(const isl::aff_list &obj) : isl::aff_list(obj) {}
+  static aff_list from(const isl::aff_list &obj) {
+    return aff_list(obj);
+  }
+  inline explicit aff_list(const isl::ctx &ctx, int n);
+  inline explicit aff_list(const typed::aff<Anonymous> &el);
+  inline explicit aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::aff_list<Anonymous> add(const typed::aff<Anonymous> &el) const;
+  inline typed::aff<Anonymous> at(int index) const;
+  inline typed::aff<Anonymous> get_at(int index) const = delete;
+  inline typed::aff_list<Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::aff<Anonymous>)> &fn) const;
+};
+
+template <typename Domain>
+struct aff_list<Domain, Anonymous> : public isl::aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  aff_list() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  aff_list(const aff_list<Arg1, Anonymous> &obj) : isl::aff_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::aff_list>{}, bool>::type = true>
+  aff_list(const base &obj) : isl::aff_list(obj) {}
+ public:
+  static aff_list from(const isl::aff_list &obj) {
+    return aff_list(obj);
+  }
+  inline explicit aff_list(const isl::ctx &ctx, int n);
+  inline explicit aff_list(const typed::aff<Domain, Anonymous> &el);
+  inline explicit aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::aff_list<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::aff<Domain, Anonymous> at(int index) const;
+  inline typed::aff<Domain, Anonymous> get_at(int index) const = delete;
+  inline typed::aff_list<Domain, Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::aff<Domain, Anonymous>)> &fn) const;
+};
+
+template <typename Domain, typename Range>
+struct basic_map<Domain, Range> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  basic_map(const basic_map<Arg1, Arg2> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, Range> apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::basic_map<Domain, Range2> apply_range(const typed::basic_map<Range, Range2> &bmap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::map<Range, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Range, Range2> &umap2) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Range> as_union_pw_multi_aff() const;
+  inline typed::set<Range> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<Range> &tuple) const;
+  inline typed::map<Domain, Range> coalesce() const;
+  inline typed::map<Domain, Range> curry() const = delete;
+  inline typed::basic_set<Domain, Range> deltas() const = delete;
+  inline typed::basic_map<Domain, Range> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, Range> domain_factor_domain() const = delete;
+  inline typed::map<Domain, Range> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Range> domain_product(const typed::map<Domain2, Range> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Range> domain_product(const typed::union_map<Domain2, Range> &umap2) const;
+  inline typed::map<Domain, Range> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<Domain, Range> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const;
+  inline typed::map<Domain, Range> extract_map(const typed::space<Domain, Range> &space) const;
+  inline typed::basic_map<Domain, Range> flatten_domain() const = delete;
+  inline typed::basic_map<Domain, Range> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, Range>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const;
+  inline typed::basic_map<Domain, Range> gist(const typed::basic_map<Domain, Range> &context) const;
+  inline typed::map<Domain, Range> gist(const typed::map<Domain, Range> &context) const;
+  inline typed::union_map<Domain, Range> gist(const typed::union_map<Domain, Range> &context) const;
+  inline typed::map<Domain, Range> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, Range> intersect(const typed::basic_map<Domain, Range> &bmap2) const;
+  inline typed::map<Domain, Range> intersect(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> intersect(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::basic_map<Domain, Range> intersect_domain(const typed::basic_set<Domain> &bset) const;
+  inline typed::map<Domain, Range> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, Range> intersect_domain(const typed::point<Domain> &bset) const;
+  inline typed::map<Domain, Range> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<Domain, Range> intersect_range(const typed::basic_set<Range> &bset) const;
+  inline typed::map<Domain, Range> intersect_range(const typed::set<Range> &set) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::space<Range> &space) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::union_set<Range> &uset) const;
+  inline typed::basic_map<Domain, Range> intersect_range(const typed::point<Range> &bset) const;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lexmax() const;
+  inline typed::pw_multi_aff<Domain, Range> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, Range> lexmin() const;
+  inline typed::pw_multi_aff<Domain, Range> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, Range> lower_bound(const typed::multi_pw_aff<Domain, Range> &lower) const;
+  inline typed::map_list<Domain, Range> map_list() const;
+  inline typed::multi_pw_aff<Domain, Range> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, Range> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Range> &ma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  inline typed::map<Domain, Range> project_out_all_params() const;
+  inline typed::set<Range> range() const;
+  inline typed::map<Domain, Range> range_factor_domain() const = delete;
+  inline typed::map<Domain, Range> range_factor_range() const = delete;
+  inline typed::fixed_box<Domain, Range> range_lattice_tile() const;
+  inline typed::union_map<pair<Domain, Range>, Range> range_map() const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Range, Range2>> range_product(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Range, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  inline typed::map<Domain, Range> range_reverse() const = delete;
+  inline typed::fixed_box<Domain, Range> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<Range, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> set_domain_tuple(const std::string &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::map<Domain, Range> subtract(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> subtract(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::union_set<Range> &dom) const;
+  inline typed::union_map<Domain, Range> to_union_map() const;
+  inline typed::map<Domain, Range> uncurry() const = delete;
+  inline typed::map<Domain, Range> unite(const typed::basic_map<Domain, Range> &bmap2) const;
+  inline typed::map<Domain, Range> unite(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> unite(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::map<Domain, Range> upper_bound(const typed::multi_pw_aff<Domain, Range> &upper) const;
+  inline typed::set<pair<Domain, Range>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct basic_map<pair<Domain, Range>, Range2> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  basic_map(const basic_map<pair<Arg1, Arg2>, Arg3> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, Range2> apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> apply_domain(const typed::map<pair<Domain, Range>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const;
+  template <typename Arg3>
+  inline typed::basic_map<pair<Domain, Range>, Arg3> apply_range(const typed::basic_map<Range2, Arg3> &bmap2) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> apply_range(const typed::map<Range2, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> apply_range(const typed::union_map<Range2, Arg3> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> as_map() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>, Range2> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Range2> as_union_pw_multi_aff() const;
+  inline typed::set<Range2> bind_domain(const typed::multi_id<pair<Domain, Range>> &tuple) const;
+  inline typed::set<pair<Domain, Range>> bind_range(const typed::multi_id<Range2> &tuple) const;
+  inline typed::map<pair<Domain, Range>, Range2> coalesce() const;
+  inline typed::map<Domain, pair<Range, Range2>> curry() const;
+  inline typed::basic_set<pair<Domain, Range>, Range2> deltas() const = delete;
+  inline typed::basic_map<pair<Domain, Range>, Range2> detect_equalities() const;
+  inline typed::set<pair<Domain, Range>> domain() const;
+  inline typed::map<Domain, Range2> domain_factor_domain() const;
+  inline typed::map<Range, Range2> domain_factor_range() const;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::union_map<Domain2, Range2> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const;
+  inline typed::map<pair<Domain, Range>, Range2> extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const;
+  inline typed::basic_map<Anonymous, Range2> flatten_domain() const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<Domain, Range>, Range2>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist(const typed::map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist_domain(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> intersect(const typed::basic_map<pair<Domain, Range>, Range2> &bmap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> intersect_domain(const typed::basic_set<pair<Domain, Range>> &bset) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_domain(const typed::set<pair<Domain, Range>> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::space<pair<Domain, Range>> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> intersect_domain(const typed::point<pair<Domain, Range>> &bset) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> intersect_range(const typed::basic_set<Range2> &bset) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_range(const typed::set<Range2> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::space<Range2> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::union_set<Range2> &uset) const;
+  inline typed::basic_map<pair<Domain, Range>, Range2> intersect_range(const typed::point<Range2> &bset) const;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lexmax() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<Domain, Range>, Range2> lexmin() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map_list<pair<Domain, Range>, Range2> map_list() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::map<Domain2, Arg3> &map2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> project_out_all_params() const;
+  inline typed::set<Range2> range() const;
+  inline typed::map<pair<Domain, Range>, Range2> range_factor_domain() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> range_factor_range() const = delete;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> range_lattice_tile() const;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> range_map() const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::map<pair<Domain, Range>, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> range_reverse() const = delete;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<Range2, pair<Domain, Range>> reverse() const;
+  inline typed::map<pair<Domain, Range>, Range2> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> set_domain_tuple(const std::string &id) const = delete;
+  template <typename Arg2>
+  inline typed::map<pair<Domain, Range>, Arg2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg2>
+  inline typed::map<pair<Domain, Range>, Arg2> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain, Range>, Range2> space() const;
+  inline typed::map<pair<Domain, Range>, Range2> subtract(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::union_set<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> to_union_map() const;
+  inline typed::map<pair<Domain, Range>, Range2> uncurry() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> unite(const typed::basic_map<pair<Domain, Range>, Range2> &bmap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> unite(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::set<pair<pair<Domain, Range>, Range2>> wrap() const;
+};
+
+template <typename Domain>
+struct basic_map<Domain, Domain> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  basic_map(const basic_map<Arg1, Arg1> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, Domain> apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::basic_map<Domain, Range2> apply_range(const typed::basic_map<Domain, Range2> &bmap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Domain, Range2> &umap2) const;
+  inline typed::map<Domain, Domain> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Domain> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Domain> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Domain> as_union_pw_multi_aff() const;
+  inline typed::set<Domain> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<Domain> &tuple) const;
+  inline typed::map<Domain, Domain> coalesce() const;
+  inline typed::map<Domain, Domain> curry() const = delete;
+  inline typed::basic_set<Domain> deltas() const;
+  inline typed::basic_map<Domain, Domain> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, Domain> domain_factor_domain() const = delete;
+  inline typed::map<Domain, Domain> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Domain>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Domain> domain_product(const typed::map<Domain2, Domain> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Domain> domain_product(const typed::union_map<Domain2, Domain> &umap2) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::union_map<Domain, Domain> eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const;
+  inline typed::map<Domain, Domain> extract_map(const typed::space<Domain, Domain> &space) const;
+  inline typed::basic_map<Domain, Domain> flatten_domain() const = delete;
+  inline typed::basic_map<Domain, Domain> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, Domain>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const;
+  inline typed::basic_map<Domain, Domain> gist(const typed::basic_map<Domain, Domain> &context) const;
+  inline typed::map<Domain, Domain> gist(const typed::map<Domain, Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist(const typed::union_map<Domain, Domain> &context) const;
+  inline typed::map<Domain, Domain> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, Domain> intersect(const typed::basic_map<Domain, Domain> &bmap2) const;
+  inline typed::map<Domain, Domain> intersect(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> intersect(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::basic_map<Domain, Domain> intersect_domain(const typed::basic_set<Domain> &bset) const;
+  inline typed::map<Domain, Domain> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, Domain> intersect_domain(const typed::point<Domain> &bset) const;
+  inline typed::map<Domain, Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<Domain, Domain> intersect_range(const typed::basic_set<Domain> &bset) const;
+  inline typed::map<Domain, Domain> intersect_range(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, Domain> intersect_range(const typed::point<Domain> &bset) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  inline typed::map<Domain, Domain> lexmax() const;
+  inline typed::pw_multi_aff<Domain, Domain> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, Domain> lexmin() const;
+  inline typed::pw_multi_aff<Domain, Domain> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::multi_pw_aff<Domain, Domain> &lower) const;
+  inline typed::map_list<Domain, Domain> map_list() const;
+  inline typed::multi_pw_aff<Domain, Domain> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, Domain> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Domain> &ma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  inline typed::map<Domain, Domain> project_out_all_params() const;
+  inline typed::set<Domain> range() const;
+  inline typed::map<Domain, Domain> range_factor_domain() const = delete;
+  inline typed::map<Domain, Domain> range_factor_range() const = delete;
+  inline typed::fixed_box<Domain, Domain> range_lattice_tile() const;
+  inline typed::union_map<pair<Domain, Domain>, Domain> range_map() const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Domain, Range2>> range_product(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Domain, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  inline typed::map<Domain, Domain> range_reverse() const = delete;
+  inline typed::fixed_box<Domain, Domain> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<Domain, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> set_domain_tuple(const std::string &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Domain> space() const;
+  inline typed::map<Domain, Domain> subtract(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> subtract(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> to_union_map() const;
+  inline typed::map<Domain, Domain> uncurry() const = delete;
+  inline typed::map<Domain, Domain> unite(const typed::basic_map<Domain, Domain> &bmap2) const;
+  inline typed::map<Domain, Domain> unite(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> unite(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::map<Domain, Domain> upper_bound(const typed::multi_pw_aff<Domain, Domain> &upper) const;
+  inline typed::set<pair<Domain, Domain>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct basic_map<Domain, pair<Range, Range2>> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  basic_map(const basic_map<Arg1, pair<Arg2, Arg3>> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Arg3>
+  inline typed::basic_map<Domain, Arg3> apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &bmap2) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> apply_range(const typed::map<pair<Range, Range2>, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<Range, Range2>> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::map<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::map<Domain, pair<Range, Range2>> curry() const = delete;
+  inline typed::basic_set<Domain, pair<Range, Range2>> deltas() const = delete;
+  inline typed::basic_map<Domain, pair<Range, Range2>> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, pair<Range, Range2>> domain_factor_domain() const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const;
+  inline typed::map<Domain, pair<Range, Range2>> extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> flatten_domain() const = delete;
+  inline typed::basic_map<Domain, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, pair<Range, Range2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist(const typed::map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> intersect(const typed::basic_map<Domain, pair<Range, Range2>> &bmap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> intersect_domain(const typed::basic_set<Domain> &bset) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> intersect_domain(const typed::point<Domain> &bset) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> intersect_range(const typed::basic_set<pair<Range, Range2>> &bset) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_range(const typed::set<pair<Range, Range2>> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::basic_map<Domain, pair<Range, Range2>> intersect_range(const typed::point<pair<Range, Range2>> &bset) const;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lexmax() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, pair<Range, Range2>> lexmin() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map_list<Domain, pair<Range, Range2>> map_list() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::map<Domain2, Arg3> &map2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::set<pair<Range, Range2>> range() const;
+  inline typed::map<Domain, Range> range_factor_domain() const;
+  inline typed::map<Domain, Range2> range_factor_range() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> range_lattice_tile() const;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg3>
+  inline typed::map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::map<Domain, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_map<Domain, Arg3> &umap2) const;
+  inline typed::map<Domain, pair<Range2, Range>> range_reverse() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<pair<Range, Range2>, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> set_domain_tuple(const std::string &id) const;
+  inline typed::map<Domain, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> space() const;
+  inline typed::map<Domain, pair<Range, Range2>> subtract(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> to_union_map() const;
+  inline typed::map<pair<Domain, Range>, Range2> uncurry() const;
+  inline typed::map<Domain, pair<Range, Range2>> unite(const typed::basic_map<Domain, pair<Range, Range2>> &bmap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> unite(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::set<pair<Domain, pair<Range, Range2>>> wrap() const;
+};
+
+template <typename T1, typename T2>
+struct basic_map<pair<T1, T2>, pair<T1, T2>> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{},
+            bool>::type = true>
+  basic_map(const basic_map<pair<Arg1, Arg2>, pair<Arg1, Arg2>> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, pair<T1, T2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::basic_map<pair<T1, T2>, Range2> apply_range(const typed::basic_map<pair<T1, T2>, Range2> &bmap2) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> apply_range(const typed::map<pair<T1, T2>, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<T1, T2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::set<pair<T1, T2>> bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> coalesce() const;
+  inline typed::map<T1, pair<T2, pair<T1, T2>>> curry() const;
+  inline typed::basic_set<pair<T1, T2>> deltas() const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> detect_equalities() const;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::map<T1, pair<T1, T2>> domain_factor_domain() const;
+  inline typed::map<T2, pair<T1, T2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::map<Domain2, pair<T1, T2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const;
+  inline typed::basic_map<Anonymous, pair<T1, T2>> flatten_domain() const;
+  inline typed::basic_map<pair<T1, T2>, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<T1, T2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::basic_set<pair<T1, T2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::point<pair<T1, T2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::basic_set<pair<T1, T2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::point<pair<T1, T2>> &bset) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lexmax() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lexmin() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map_list<pair<T1, T2>, pair<T1, T2>> map_list() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> project_out_all_params() const;
+  inline typed::set<pair<T1, T2>> range() const;
+  inline typed::map<pair<T1, T2>, T1> range_factor_domain() const;
+  inline typed::map<pair<T1, T2>, T2> range_factor_range() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> range_lattice_tile() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> range_map() const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::map<pair<T1, T2>, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T2, T1>> range_reverse() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<pair<T1, T2>, pair<T1, T2>> reverse() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<T1, T2>> space() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> to_union_map() const;
+  inline typed::map<pair<pair<T1, T2>, T1>, T2> uncurry() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::set<pair<pair<T1, T2>, pair<T1, T2>>> wrap() const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct basic_map<pair<T1, T2>, pair<Range, Range2>> : public isl::basic_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  basic_map(const basic_map<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::basic_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_map>{}, bool>::type = true>
+  basic_map(const base &obj) : isl::basic_map(obj) {}
+ public:
+  static basic_map from(const isl::basic_map &obj) {
+    return basic_map(obj);
+  }
+  inline explicit basic_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::basic_map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &bmap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Arg2>
+  inline typed::basic_map<pair<T1, T2>, Arg2> apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &bmap2) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> apply_range(const typed::map<pair<Range, Range2>, Arg2> &map2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<Range, Range2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::set<pair<T1, T2>> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::map<T1, pair<T2, pair<Range, Range2>>> curry() const;
+  inline typed::basic_set<pair<T1, T2>, pair<Range, Range2>> deltas() const = delete;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> detect_equalities() const;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::map<T1, pair<Range, Range2>> domain_factor_domain() const;
+  inline typed::map<T2, pair<Range, Range2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline typed::basic_map<Anonymous, pair<Range, Range2>> flatten_domain() const;
+  inline typed::basic_map<pair<T1, T2>, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::basic_set<pair<T1, T2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::point<pair<T1, T2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::basic_set<pair<Range, Range2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::set<pair<Range, Range2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::basic_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::point<pair<Range, Range2>> &bset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lexmax() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lexmin() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map_list<pair<T1, T2>, pair<Range, Range2>> map_list() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::map<Domain2, Arg2> &map2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::union_map<Domain2, Arg2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::set<pair<Range, Range2>> range() const;
+  inline typed::map<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::map<pair<T1, T2>, Range2> range_factor_range() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> range_lattice_tile() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::map<pair<T1, T2>, Arg2> &map2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range2, Range>> range_reverse() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> range_simple_fixed_box_hull() const;
+  inline typed::basic_map<pair<Range, Range2>, pair<T1, T2>> reverse() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> space() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> to_union_map() const;
+  inline typed::map<pair<pair<T1, T2>, Range>, Range2> uncurry() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::set<pair<pair<T1, T2>, pair<Range, Range2>>> wrap() const;
+};
+
+template <>
+struct basic_set<> : public isl::basic_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_set() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_set>{}, bool>::type = true>
+  basic_set(const base &obj) : isl::basic_set(obj) {}
+ public:
+  static basic_set from(const isl::basic_set &obj) {
+    return basic_set(obj);
+  }
+  inline /* implicit */ basic_set(const typed::point<> &pnt);
+  inline explicit basic_set(const isl::ctx &ctx, const std::string &str);
+  inline typed::basic_set<> apply(const typed::basic_map<> &bmap) const = delete;
+  inline typed::set<> apply(const typed::map<> &map) const = delete;
+  inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete;
+  inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete;
+  inline typed::set<> as_set() const = delete;
+  inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete;
+  inline typed::set<> coalesce() const;
+  inline typed::basic_set<> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<>)> &test) const;
+  inline typed::set<> extract_set(const typed::space<> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<>)> &fn) const;
+  inline typed::basic_set<> gist(const typed::basic_set<> &context) const;
+  inline typed::set<> gist(const typed::set<> &context) const;
+  inline typed::union_set<> gist(const typed::union_set<> &context) const;
+  inline typed::basic_set<> gist(const typed::point<> &context) const;
+  inline typed::map<> identity() const = delete;
+  inline typed::pw_aff<Anonymous> indicator_function() const;
+  inline typed::map<> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::basic_set<> intersect(const typed::basic_set<> &bset2) const;
+  inline typed::set<> intersect(const typed::set<> &set2) const;
+  inline typed::union_set<> intersect(const typed::union_set<> &uset2) const;
+  inline typed::basic_set<> intersect(const typed::point<> &bset2) const;
+  inline typed::basic_set<> intersect_params(const typed::basic_set<> &bset2) const = delete;
+  inline typed::set<> intersect_params(const typed::set<> &params) const = delete;
+  inline typed::basic_set<> intersect_params(const typed::point<> &bset2) const = delete;
+  inline typed::set<> lexmax() const = delete;
+  inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete;
+  inline typed::set<> lexmin() const = delete;
+  inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete;
+  inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete;
+  inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete;
+  inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete;
+  inline typed::val<> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete;
+  inline typed::val<> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::basic_set<> params() const = delete;
+  inline typed::multi_val<> plain_multi_val_if_fixed() const = delete;
+  inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete;
+  inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::set<> product(const typed::set<> &set2) const = delete;
+  inline typed::set<> project_out_all_params() const;
+  inline typed::set<> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<> project_out_param(const std::string &id) const;
+  inline typed::set<> project_out_param(const typed::id_list<Anonymous> &list) const;
+  inline typed::pw_multi_aff<> pw_multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::fixed_box<> simple_fixed_box_hull() const = delete;
+  inline typed::space<> space() const;
+  inline typed::set<> subtract(const typed::set<> &set2) const;
+  inline typed::union_set<> subtract(const typed::union_set<> &uset2) const;
+  inline typed::set<> to_set() const;
+  inline typed::union_set<> to_union_set() const;
+  inline typed::map<> translation() const = delete;
+  template <typename Domain>
+  inline typed::set<Domain> unbind_params(const typed::multi_id<Domain> &tuple) const;
+  inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::set<> unite(const typed::basic_set<> &bset2) const;
+  inline typed::set<> unite(const typed::set<> &set2) const;
+  inline typed::union_set<> unite(const typed::union_set<> &uset2) const;
+  inline typed::set<> unite(const typed::point<> &bset2) const;
+  inline typed::map<> unwrap() const = delete;
+  inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete;
+  inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete;
+};
+
+template <typename Domain>
+struct basic_set<Domain> : public isl::basic_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_set() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  basic_set(const basic_set<Arg1> &obj) : isl::basic_set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_set>{}, bool>::type = true>
+  basic_set(const base &obj) : isl::basic_set(obj) {}
+ public:
+  static basic_set from(const isl::basic_set &obj) {
+    return basic_set(obj);
+  }
+  inline /* implicit */ basic_set(const typed::point<Domain> &pnt);
+  inline explicit basic_set(const isl::ctx &ctx, const std::string &str);
+  template <typename Range>
+  inline typed::basic_set<Range> apply(const typed::basic_map<Domain, Range> &bmap) const;
+  template <typename Range>
+  inline typed::set<Range> apply(const typed::map<Domain, Range> &map) const;
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::union_map<Domain, Range> &umap) const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> coalesce() const;
+  inline typed::basic_set<Domain> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<Domain>)> &test) const;
+  inline typed::set<Domain> extract_set(const typed::space<Domain> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<Domain>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<Domain>)> &fn) const;
+  inline typed::basic_set<Domain> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::set<Domain> gist(const typed::set<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::union_set<Domain> &context) const;
+  inline typed::basic_set<Domain> gist(const typed::point<Domain> &context) const;
+  inline typed::map<Domain, Domain> identity() const;
+  inline typed::pw_aff<Domain, Anonymous> indicator_function() const;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::basic_set<Domain> intersect(const typed::basic_set<Domain> &bset2) const;
+  inline typed::set<Domain> intersect(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> intersect(const typed::union_set<Domain> &uset2) const;
+  inline typed::basic_set<Domain> intersect(const typed::point<Domain> &bset2) const;
+  inline typed::basic_set<Domain> intersect_params(const typed::basic_set<> &bset2) const;
+  inline typed::set<Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_set<Domain> intersect_params(const typed::point<> &bset2) const;
+  inline typed::set<Domain> lexmax() const;
+  inline typed::pw_multi_aff<Domain> lexmax_pw_multi_aff() const;
+  inline typed::set<Domain> lexmin() const;
+  inline typed::pw_multi_aff<Domain> lexmin_pw_multi_aff() const;
+  inline typed::set<Domain> lower_bound(const typed::multi_pw_aff<Domain> &lower) const;
+  inline typed::set<Domain> lower_bound(const typed::multi_val<Domain> &lower) const;
+  inline typed::multi_pw_aff<Domain> max_multi_pw_aff() const;
+  inline typed::val<Domain> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<Domain> min_multi_pw_aff() const;
+  inline typed::val<Domain> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::basic_set<> params() const;
+  inline typed::multi_val<Domain> plain_multi_val_if_fixed() const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range>
+  inline typed::set<pair<Domain, Range>> product(const typed::set<Range> &set2) const;
+  inline typed::set<Domain> project_out_all_params() const;
+  inline typed::set<Domain> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<Domain> project_out_param(const std::string &id) const;
+  inline typed::set<Domain> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<Domain, Range> pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const;
+  inline typed::fixed_box<Domain> simple_fixed_box_hull() const;
+  inline typed::space<Domain> space() const;
+  inline typed::set<Domain> subtract(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> subtract(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> to_set() const;
+  inline typed::union_set<Domain> to_union_set() const;
+  inline typed::map<Domain, Domain> translation() const;
+  inline typed::set<Domain> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::set<Domain> unite(const typed::basic_set<Domain> &bset2) const;
+  inline typed::set<Domain> unite(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> unite(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> unite(const typed::point<Domain> &bset2) const;
+  inline typed::map<Domain> unwrap() const = delete;
+  inline typed::set<Domain> upper_bound(const typed::multi_pw_aff<Domain> &upper) const;
+  inline typed::set<Domain> upper_bound(const typed::multi_val<Domain> &upper) const;
+};
+
+template <typename Domain, typename Range>
+struct basic_set<pair<Domain, Range>> : public isl::basic_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  basic_set() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  basic_set(const basic_set<pair<Arg1, Arg2>> &obj) : isl::basic_set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::basic_set>{}, bool>::type = true>
+  basic_set(const base &obj) : isl::basic_set(obj) {}
+ public:
+  static basic_set from(const isl::basic_set &obj) {
+    return basic_set(obj);
+  }
+  inline /* implicit */ basic_set(const typed::point<pair<Domain, Range>> &pnt);
+  inline explicit basic_set(const isl::ctx &ctx, const std::string &str);
+  template <typename Arg2>
+  inline typed::basic_set<Arg2> apply(const typed::basic_map<pair<Domain, Range>, Arg2> &bmap) const;
+  template <typename Arg2>
+  inline typed::set<Arg2> apply(const typed::map<pair<Domain, Range>, Arg2> &map) const;
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<pair<Domain, Range>> &tuple) const;
+  inline typed::set<pair<Domain, Range>> coalesce() const;
+  inline typed::basic_set<pair<Domain, Range>> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const;
+  inline typed::set<pair<Domain, Range>> extract_set(const typed::space<pair<Domain, Range>> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const;
+  inline typed::basic_set<pair<Domain, Range>> gist(const typed::basic_set<pair<Domain, Range>> &context) const;
+  inline typed::set<pair<Domain, Range>> gist(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::union_set<pair<Domain, Range>> &context) const;
+  inline typed::basic_set<pair<Domain, Range>> gist(const typed::point<pair<Domain, Range>> &context) const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> identity() const;
+  inline typed::pw_aff<pair<Domain, Range>, Anonymous> indicator_function() const;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> insert_domain(const typed::space<Arg2> &domain) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect(const typed::basic_set<pair<Domain, Range>> &bset2) const;
+  inline typed::set<pair<Domain, Range>> intersect(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect(const typed::point<pair<Domain, Range>> &bset2) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect_params(const typed::basic_set<> &bset2) const;
+  inline typed::set<pair<Domain, Range>> intersect_params(const typed::set<> &params) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect_params(const typed::point<> &bset2) const;
+  inline typed::set<pair<Domain, Range>> lexmax() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmax_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lexmin() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmin_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const;
+  inline typed::multi_pw_aff<pair<Domain, Range>> max_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<pair<Domain, Range>> min_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::basic_set<> params() const;
+  inline typed::multi_val<pair<Domain, Range>> plain_multi_val_if_fixed() const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg2>
+  inline typed::set<pair<pair<Domain, Range>, Arg2>> product(const typed::set<Arg2> &set2) const;
+  inline typed::set<pair<Domain, Range>> project_out_all_params() const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const std::string &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain, Range>, Arg2> pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const;
+  inline typed::fixed_box<pair<Domain, Range>> simple_fixed_box_hull() const;
+  inline typed::space<pair<Domain, Range>> space() const;
+  inline typed::set<pair<Domain, Range>> subtract(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> to_set() const;
+  inline typed::union_set<pair<Domain, Range>> to_union_set() const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> translation() const;
+  inline typed::set<pair<Domain, Range>> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::basic_set<pair<Domain, Range>> &bset2) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::point<pair<Domain, Range>> &bset2) const;
+  inline typed::map<Domain, Range> unwrap() const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const;
+};
+
+template <typename Domain>
+struct fixed_box<Domain> : public isl::fixed_box {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  fixed_box() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  fixed_box(const fixed_box<Arg1> &obj) : isl::fixed_box(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::fixed_box>{}, bool>::type = true>
+  fixed_box(const base &obj) : isl::fixed_box(obj) {}
+ public:
+  static fixed_box from(const isl::fixed_box &obj) {
+    return fixed_box(obj);
+  }
+  inline typed::multi_aff<Domain> offset() const;
+  inline typed::multi_aff<Domain> get_offset() const = delete;
+  inline typed::multi_val<Domain> size() const;
+  inline typed::multi_val<Domain> get_size() const = delete;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+};
+
+template <typename Domain, typename Range>
+struct fixed_box<Domain, Range> : public isl::fixed_box {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  fixed_box() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  fixed_box(const fixed_box<Arg1, Arg2> &obj) : isl::fixed_box(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::fixed_box>{}, bool>::type = true>
+  fixed_box(const base &obj) : isl::fixed_box(obj) {}
+ public:
+  static fixed_box from(const isl::fixed_box &obj) {
+    return fixed_box(obj);
+  }
+  inline typed::multi_aff<Domain, Range> offset() const;
+  inline typed::multi_aff<Domain, Range> get_offset() const = delete;
+  inline typed::multi_val<Range> size() const;
+  inline typed::multi_val<Domain, Range> get_size() const = delete;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+};
+
+template <>
+struct id<Anonymous> : public isl::id {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  id() = default;
+  id(const isl::id &obj) : isl::id(obj) {}
+  static id from(const isl::id &obj) {
+    return id(obj);
+  }
+  inline explicit id(const isl::ctx &ctx, const std::string &str);
+  inline std::string get_name() const = delete;
+};
+
+template <>
+struct id_list<Anonymous> : public isl::id_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  id_list() = default;
+  id_list(const isl::id_list &obj) : isl::id_list(obj) {}
+  static id_list from(const isl::id_list &obj) {
+    return id_list(obj);
+  }
+  inline explicit id_list(const isl::ctx &ctx, int n);
+  inline explicit id_list(const typed::id<Anonymous> &el);
+  inline explicit id_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::id_list<Anonymous> add(const typed::id<Anonymous> &el) const;
+  inline typed::id_list<Anonymous> add(const std::string &el) const;
+  inline typed::id<Anonymous> at(int index) const;
+  inline typed::id<Anonymous> get_at(int index) const = delete;
+  inline typed::id_list<Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::id<Anonymous>)> &fn) const;
+};
+
+template <typename Domain, typename Range>
+struct map<Domain, Range> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  map(const map<Arg1, Arg2> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<Domain, Range> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> apply_domain(const typed::basic_map<Domain, Domain2> &map2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::map<Range, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Range, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::basic_map<Range, Range2> &map2) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Range> as_union_pw_multi_aff() const;
+  inline typed::set<Range> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<Range> &tuple) const;
+  inline typed::map<Domain, Range> coalesce() const;
+  inline typed::map<Domain, Range> curry() const = delete;
+  inline typed::set<Domain, Range> deltas() const = delete;
+  inline typed::map<Domain, Range> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, Range> domain_factor_domain() const = delete;
+  inline typed::map<Domain, Range> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Range> domain_product(const typed::map<Domain2, Range> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Range> domain_product(const typed::union_map<Domain2, Range> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Range> domain_product(const typed::basic_map<Domain2, Range> &map2) const;
+  inline typed::id<Domain, Range> get_domain_tuple_id() const = delete;
+  inline typed::map<Domain, Range> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<Domain, Range> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::map<Domain, Range> eq_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> eq_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> eq_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> eq_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const;
+  inline typed::map<Domain, Range> extract_map(const typed::space<Domain, Range> &space) const;
+  inline typed::map<Domain, Range> flatten_domain() const = delete;
+  inline typed::map<Domain, Range> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, Range>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const;
+  inline typed::map<Domain, Range> gist(const typed::map<Domain, Range> &context) const;
+  inline typed::union_map<Domain, Range> gist(const typed::union_map<Domain, Range> &context) const;
+  inline typed::map<Domain, Range> gist(const typed::basic_map<Domain, Range> &context) const;
+  inline typed::map<Domain, Range> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, Range> gist_domain(const typed::basic_set<Domain> &context) const;
+  inline typed::map<Domain, Range> gist_domain(const typed::point<Domain> &context) const;
+  inline typed::map<Domain, Range> intersect(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> intersect(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::map<Domain, Range> intersect(const typed::basic_map<Domain, Range> &map2) const;
+  inline typed::map<Domain, Range> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, Range> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::map<Domain, Range> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::map<Domain, Range> intersect_params(const typed::set<> &params) const;
+  inline typed::map<Domain, Range> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<Domain, Range> intersect_params(const typed::point<> &params) const;
+  inline typed::map<Domain, Range> intersect_range(const typed::set<Range> &set) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::space<Range> &space) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::union_set<Range> &uset) const;
+  inline typed::map<Domain, Range> intersect_range(const typed::basic_set<Range> &set) const;
+  inline typed::map<Domain, Range> intersect_range(const typed::point<Range> &set) const;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, Range> lexmax() const;
+  inline typed::pw_multi_aff<Domain, Range> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, Range> lexmin() const;
+  inline typed::pw_multi_aff<Domain, Range> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, Range> lower_bound(const typed::multi_pw_aff<Domain, Range> &lower) const;
+  inline typed::map<Domain, Range> lower_bound(const typed::aff<Domain, Range> &lower) const;
+  inline typed::map<Domain, Range> lower_bound(const typed::multi_aff<Domain, Range> &lower) const;
+  inline typed::map<Domain, Range> lower_bound(const typed::pw_aff<Domain, Range> &lower) const;
+  inline typed::map<Domain, Range> lower_bound(const typed::pw_multi_aff<Domain, Range> &lower) const;
+  inline typed::map_list<Domain, Range> map_list() const;
+  inline typed::multi_pw_aff<Domain, Range> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, Range> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Range> &ma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::basic_map<Domain2, Range2> &map2) const;
+  inline typed::map<Domain, Range> project_out_all_params() const;
+  inline typed::set<Range> range() const;
+  inline typed::map<Domain, Range> range_factor_domain() const = delete;
+  inline typed::map<Domain, Range> range_factor_range() const = delete;
+  inline typed::fixed_box<Domain, Range> range_lattice_tile() const;
+  inline typed::fixed_box<Domain, Range> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range> range_map() const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Range, Range2>> range_product(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Range, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Range, Range2>> range_product(const typed::basic_map<Domain, Range2> &map2) const;
+  inline typed::map<Domain, Range> range_reverse() const = delete;
+  inline typed::fixed_box<Domain, Range> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<Domain, Range> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::map<Range, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range> set_domain_tuple(const std::string &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::map<Domain, Range> subtract(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> subtract(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::map<Domain, Range> subtract(const typed::basic_map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::union_set<Range> &dom) const;
+  inline typed::union_map<Domain, Range> to_union_map() const;
+  inline typed::map<Domain, Range> uncurry() const = delete;
+  inline typed::map<Domain, Range> unite(const typed::map<Domain, Range> &map2) const;
+  inline typed::union_map<Domain, Range> unite(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::map<Domain, Range> unite(const typed::basic_map<Domain, Range> &map2) const;
+  static inline typed::map<Domain, Range> universe(const typed::space<Domain, Range> &space);
+  inline typed::map<Domain, Range> upper_bound(const typed::multi_pw_aff<Domain, Range> &upper) const;
+  inline typed::map<Domain, Range> upper_bound(const typed::aff<Domain, Range> &upper) const;
+  inline typed::map<Domain, Range> upper_bound(const typed::multi_aff<Domain, Range> &upper) const;
+  inline typed::map<Domain, Range> upper_bound(const typed::pw_aff<Domain, Range> &upper) const;
+  inline typed::map<Domain, Range> upper_bound(const typed::pw_multi_aff<Domain, Range> &upper) const;
+  inline typed::set<pair<Domain, Range>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct map<pair<Domain, Range>, Range2> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  map(const map<pair<Arg1, Arg2>, Arg3> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<pair<Domain, Range>, Range2> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> apply_domain(const typed::map<pair<Domain, Range>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &map2) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> apply_range(const typed::map<Range2, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> apply_range(const typed::union_map<Range2, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> apply_range(const typed::basic_map<Range2, Arg3> &map2) const;
+  inline typed::map<pair<Domain, Range>, Range2> as_map() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>, Range2> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Range2> as_union_pw_multi_aff() const;
+  inline typed::set<Range2> bind_domain(const typed::multi_id<pair<Domain, Range>> &tuple) const;
+  inline typed::set<pair<Domain, Range>> bind_range(const typed::multi_id<Range2> &tuple) const;
+  inline typed::map<pair<Domain, Range>, Range2> coalesce() const;
+  inline typed::map<Domain, pair<Range, Range2>> curry() const;
+  inline typed::set<pair<Domain, Range>, Range2> deltas() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> detect_equalities() const;
+  inline typed::set<pair<Domain, Range>> domain() const;
+  inline typed::map<Domain, Range2> domain_factor_domain() const;
+  inline typed::map<Range, Range2> domain_factor_range() const;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::basic_map<Domain2, Range2> &map2) const;
+  inline typed::id<pair<Domain, Range>, Range2> get_domain_tuple_id() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> eq_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const;
+  inline typed::map<pair<Domain, Range>, Range2> extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const;
+  inline typed::map<Anonymous, Range2> flatten_domain() const;
+  inline typed::map<pair<Domain, Range>, Range2> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<Domain, Range>, Range2>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist(const typed::map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist_domain(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist_domain(const typed::basic_set<pair<Domain, Range>> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> gist_domain(const typed::point<pair<Domain, Range>> &context) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_domain(const typed::set<pair<Domain, Range>> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::space<pair<Domain, Range>> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_domain(const typed::basic_set<pair<Domain, Range>> &set) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_domain(const typed::point<pair<Domain, Range>> &set) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_params(const typed::set<> &params) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_params(const typed::point<> &params) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_range(const typed::set<Range2> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::space<Range2> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::union_set<Range2> &uset) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_range(const typed::basic_set<Range2> &set) const;
+  inline typed::map<pair<Domain, Range>, Range2> intersect_range(const typed::point<Range2> &set) const;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> lexmax() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<Domain, Range>, Range2> lexmin() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::multi_aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::pw_aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map<pair<Domain, Range>, Range2> lower_bound(const typed::pw_multi_aff<pair<Domain, Range>, Range2> &lower) const;
+  inline typed::map_list<pair<Domain, Range>, Range2> map_list() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Range2> preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::map<Domain2, Arg3> &map2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::basic_map<Domain2, Arg3> &map2) const;
+  inline typed::map<pair<Domain, Range>, Range2> project_out_all_params() const;
+  inline typed::set<Range2> range() const;
+  inline typed::map<pair<Domain, Range>, Range2> range_factor_domain() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> range_factor_range() const = delete;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> range_lattice_tile() const;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> range_map() const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::map<pair<Domain, Range>, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::basic_map<pair<Domain, Range>, Arg3> &map2) const;
+  inline typed::map<pair<Domain, Range>, Range2> range_reverse() const = delete;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<pair<Domain, Range>, Range2> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<pair<Domain, Range>, Range2> get_range_tuple_id() const = delete;
+  inline typed::map<Range2, pair<Domain, Range>> reverse() const;
+  inline typed::map<pair<Domain, Range>, Range2> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> set_domain_tuple(const std::string &id) const = delete;
+  template <typename Arg2>
+  inline typed::map<pair<Domain, Range>, Arg2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg2>
+  inline typed::map<pair<Domain, Range>, Arg2> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain, Range>, Range2> space() const;
+  inline typed::space<pair<Domain, Range>, Range2> get_space() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> subtract(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> subtract(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::union_set<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> to_union_map() const;
+  inline typed::map<pair<Domain, Range>, Range2> uncurry() const = delete;
+  inline typed::map<pair<Domain, Range>, Range2> unite(const typed::map<pair<Domain, Range>, Range2> &map2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> unite(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const;
+  static inline typed::map<pair<Domain, Range>, Range2> universe(const typed::space<pair<Domain, Range>, Range2> &space);
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::multi_aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::pw_aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::map<pair<Domain, Range>, Range2> upper_bound(const typed::pw_multi_aff<pair<Domain, Range>, Range2> &upper) const;
+  inline typed::set<pair<pair<Domain, Range>, Range2>> wrap() const;
+};
+
+template <typename Domain>
+struct map<Domain, Domain> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  map(const map<Arg1, Arg1> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<Domain, Domain> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> apply_domain(const typed::basic_map<Domain, Domain2> &map2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> apply_range(const typed::basic_map<Domain, Range2> &map2) const;
+  inline typed::map<Domain, Domain> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Domain> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Domain> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Domain> as_union_pw_multi_aff() const;
+  inline typed::set<Domain> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<Domain> &tuple) const;
+  inline typed::map<Domain, Domain> coalesce() const;
+  inline typed::map<Domain, Domain> curry() const = delete;
+  inline typed::set<Domain> deltas() const;
+  inline typed::map<Domain, Domain> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, Domain> domain_factor_domain() const = delete;
+  inline typed::map<Domain, Domain> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Domain>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Domain> domain_product(const typed::map<Domain2, Domain> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Domain> domain_product(const typed::union_map<Domain2, Domain> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, Domain> domain_product(const typed::basic_map<Domain2, Domain> &map2) const;
+  inline typed::id<Domain, Domain> get_domain_tuple_id() const = delete;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::union_map<Domain, Domain> eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> eq_at(const typed::pw_multi_aff<Domain, Range> &mpa) const;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const;
+  inline typed::map<Domain, Domain> extract_map(const typed::space<Domain, Domain> &space) const;
+  inline typed::map<Domain, Domain> flatten_domain() const = delete;
+  inline typed::map<Domain, Domain> flatten_range() const = delete;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, Domain>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const;
+  inline typed::map<Domain, Domain> gist(const typed::map<Domain, Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist(const typed::union_map<Domain, Domain> &context) const;
+  inline typed::map<Domain, Domain> gist(const typed::basic_map<Domain, Domain> &context) const;
+  inline typed::map<Domain, Domain> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, Domain> gist_domain(const typed::basic_set<Domain> &context) const;
+  inline typed::map<Domain, Domain> gist_domain(const typed::point<Domain> &context) const;
+  inline typed::map<Domain, Domain> intersect(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> intersect(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::map<Domain, Domain> intersect(const typed::basic_map<Domain, Domain> &map2) const;
+  inline typed::map<Domain, Domain> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, Domain> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::map<Domain, Domain> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::map<Domain, Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::map<Domain, Domain> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<Domain, Domain> intersect_params(const typed::point<> &params) const;
+  inline typed::map<Domain, Domain> intersect_range(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, Domain> intersect_range(const typed::basic_set<Domain> &set) const;
+  inline typed::map<Domain, Domain> intersect_range(const typed::point<Domain> &set) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_ge_at(const typed::pw_multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_gt_at(const typed::pw_multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_le_at(const typed::pw_multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::multi_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::pw_aff<Domain, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<Domain, Domain> lex_lt_at(const typed::pw_multi_aff<Domain, Range> &mpa) const;
+  inline typed::map<Domain, Domain> lexmax() const;
+  inline typed::pw_multi_aff<Domain, Domain> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, Domain> lexmin() const;
+  inline typed::pw_multi_aff<Domain, Domain> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::multi_pw_aff<Domain, Domain> &lower) const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::aff<Domain, Domain> &lower) const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::multi_aff<Domain, Domain> &lower) const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::pw_aff<Domain, Domain> &lower) const;
+  inline typed::map<Domain, Domain> lower_bound(const typed::pw_multi_aff<Domain, Domain> &lower) const;
+  inline typed::map_list<Domain, Domain> map_list() const;
+  inline typed::multi_pw_aff<Domain, Domain> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, Domain> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Domain> &ma) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::basic_map<Domain2, Range2> &map2) const;
+  inline typed::map<Domain, Domain> project_out_all_params() const;
+  inline typed::set<Domain> range() const;
+  inline typed::map<Domain, Domain> range_factor_domain() const = delete;
+  inline typed::map<Domain, Domain> range_factor_range() const = delete;
+  inline typed::fixed_box<Domain, Domain> range_lattice_tile() const;
+  inline typed::fixed_box<Domain, Domain> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<Domain, Domain>, Domain> range_map() const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Domain, Range2>> range_product(const typed::map<Domain, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Domain, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<Domain, pair<Domain, Range2>> range_product(const typed::basic_map<Domain, Range2> &map2) const;
+  inline typed::map<Domain, Domain> range_reverse() const = delete;
+  inline typed::fixed_box<Domain, Domain> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<Domain, Domain> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<Domain, Domain> get_range_tuple_id() const = delete;
+  inline typed::map<Domain, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, Domain> set_domain_tuple(const std::string &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::map<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Domain> space() const;
+  inline typed::space<Domain, Domain> get_space() const = delete;
+  inline typed::map<Domain, Domain> subtract(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> subtract(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::map<Domain, Domain> subtract(const typed::basic_map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> to_union_map() const;
+  inline typed::map<Domain, Domain> uncurry() const = delete;
+  inline typed::map<Domain, Domain> unite(const typed::map<Domain, Domain> &map2) const;
+  inline typed::union_map<Domain, Domain> unite(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::map<Domain, Domain> unite(const typed::basic_map<Domain, Domain> &map2) const;
+  static inline typed::map<Domain, Domain> universe(const typed::space<Domain, Domain> &space);
+  inline typed::map<Domain, Domain> upper_bound(const typed::multi_pw_aff<Domain, Domain> &upper) const;
+  inline typed::map<Domain, Domain> upper_bound(const typed::aff<Domain, Domain> &upper) const;
+  inline typed::map<Domain, Domain> upper_bound(const typed::multi_aff<Domain, Domain> &upper) const;
+  inline typed::map<Domain, Domain> upper_bound(const typed::pw_aff<Domain, Domain> &upper) const;
+  inline typed::map<Domain, Domain> upper_bound(const typed::pw_multi_aff<Domain, Domain> &upper) const;
+  inline typed::set<pair<Domain, Domain>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct map<Domain, pair<Range, Range2>> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  map(const map<Arg1, pair<Arg2, Arg3>> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<Domain, pair<Range, Range2>> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<Domain, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<Domain, Domain2> &map2) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> apply_range(const typed::map<pair<Range, Range2>, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &map2) const;
+  inline typed::map<Domain, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<Range, Range2>> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::map<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::map<Domain, pair<Range, Range2>> curry() const = delete;
+  inline typed::set<Domain, pair<Range, Range2>> deltas() const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> detect_equalities() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::map<Domain, pair<Range, Range2>> domain_factor_domain() const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &map2) const;
+  inline typed::id<Domain, pair<Range, Range2>> get_domain_tuple_id() const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> eq_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const;
+  inline typed::map<Domain, pair<Range, Range2>> extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline typed::map<Domain, pair<Range, Range2>> flatten_domain() const = delete;
+  inline typed::map<Domain, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<Domain, pair<Range, Range2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist(const typed::map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist_domain(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist_domain(const typed::basic_set<Domain> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> gist_domain(const typed::point<Domain> &context) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &params) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_params(const typed::point<> &params) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_range(const typed::set<pair<Range, Range2>> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_range(const typed::basic_set<pair<Range, Range2>> &set) const;
+  inline typed::map<Domain, pair<Range, Range2>> intersect_range(const typed::point<pair<Range, Range2>> &set) const;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> lexmax() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> lexmax_pw_multi_aff() const;
+  inline typed::map<Domain, pair<Range, Range2>> lexmin() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> lexmin_pw_multi_aff() const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::multi_aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::pw_aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map<Domain, pair<Range, Range2>> lower_bound(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &lower) const;
+  inline typed::map_list<Domain, pair<Range, Range2>> map_list() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const;
+  template <typename Arg3>
+  inline typed::map<Domain, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::map<Domain2, Arg3> &map2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::basic_map<Domain2, Arg3> &map2) const;
+  inline typed::map<Domain, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::set<pair<Range, Range2>> range() const;
+  inline typed::map<Domain, Range> range_factor_domain() const;
+  inline typed::map<Domain, Range2> range_factor_range() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> range_lattice_tile() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg3>
+  inline typed::map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::map<Domain, Arg3> &map2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_map<Domain, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::basic_map<Domain, Arg3> &map2) const;
+  inline typed::map<Domain, pair<Range2, Range>> range_reverse() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<Domain, pair<Range, Range2>> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<Domain, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::map<pair<Range, Range2>, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> set_domain_tuple(const std::string &id) const;
+  inline typed::map<Domain, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> space() const;
+  inline typed::space<Domain, pair<Range, Range2>> get_space() const = delete;
+  inline typed::map<Domain, pair<Range, Range2>> subtract(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> subtract(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> to_union_map() const;
+  inline typed::map<pair<Domain, Range>, Range2> uncurry() const;
+  inline typed::map<Domain, pair<Range, Range2>> unite(const typed::map<Domain, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> unite(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const;
+  static inline typed::map<Domain, pair<Range, Range2>> universe(const typed::space<Domain, pair<Range, Range2>> &space);
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::multi_aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::pw_aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::map<Domain, pair<Range, Range2>> upper_bound(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upper) const;
+  inline typed::set<pair<Domain, pair<Range, Range2>>> wrap() const;
+};
+
+template <typename T1, typename T2>
+struct map<pair<T1, T2>, pair<T1, T2>> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{},
+            bool>::type = true>
+  map(const map<pair<Arg1, Arg2>, pair<Arg1, Arg2>> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> apply_range(const typed::map<pair<T1, T2>, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> apply_range(const typed::basic_map<pair<T1, T2>, Range2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<T1, T2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::set<pair<T1, T2>> bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> coalesce() const;
+  inline typed::map<T1, pair<T2, pair<T1, T2>>> curry() const;
+  inline typed::set<pair<T1, T2>> deltas() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> detect_equalities() const;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::map<T1, pair<T1, T2>> domain_factor_domain() const;
+  inline typed::map<T2, pair<T1, T2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::map<Domain2, pair<T1, T2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::basic_map<Domain2, pair<T1, T2>> &map2) const;
+  inline typed::id<pair<T1, T2>, pair<T1, T2>> get_domain_tuple_id() const = delete;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const;
+  inline typed::map<Anonymous, pair<T1, T2>> flatten_domain() const;
+  inline typed::map<pair<T1, T2>, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<T1, T2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::basic_set<pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::point<pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::point<pair<T1, T2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::set<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::point<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::point<pair<T1, T2>> &set) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_ge_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_gt_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_le_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const;
+  template <typename Range>
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lex_lt_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lexmax() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lexmin() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::multi_aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> lower_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> &lower) const;
+  inline typed::map_list<pair<T1, T2>, pair<T1, T2>> map_list() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<T1, T2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, Range2> preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::map<Domain2, Range2> &map2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::basic_map<Domain2, Range2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> project_out_all_params() const;
+  inline typed::set<pair<T1, T2>> range() const;
+  inline typed::map<pair<T1, T2>, T1> range_factor_domain() const;
+  inline typed::map<pair<T1, T2>, T2> range_factor_range() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> range_lattice_tile() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> range_map() const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::map<pair<T1, T2>, Range2> &map2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::basic_map<pair<T1, T2>, Range2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<T2, T1>> range_reverse() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<T1, T2>> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<pair<T1, T2>, pair<T1, T2>> get_range_tuple_id() const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> reverse() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<T1, T2>> space() const;
+  inline typed::space<pair<T1, T2>, pair<T1, T2>> get_space() const = delete;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> to_union_map() const;
+  inline typed::map<pair<pair<T1, T2>, T1>, T2> uncurry() const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const;
+  static inline typed::map<pair<T1, T2>, pair<T1, T2>> universe(const typed::space<pair<T1, T2>, pair<T1, T2>> &space);
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::multi_aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> upper_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> &upper) const;
+  inline typed::set<pair<pair<T1, T2>, pair<T1, T2>>> wrap() const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct map<pair<T1, T2>, pair<Range, Range2>> : public isl::map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  map(const map<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map>{}, bool>::type = true>
+  map(const base &obj) : isl::map(obj) {}
+ public:
+  static map from(const isl::map &obj) {
+    return map(obj);
+  }
+  inline /* implicit */ map(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap);
+  inline explicit map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &map2) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> apply_range(const typed::map<pair<Range, Range2>, Arg2> &map2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::set<pair<Range, Range2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::set<pair<T1, T2>> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::map<T1, pair<T2, pair<Range, Range2>>> curry() const;
+  inline typed::set<pair<T1, T2>, pair<Range, Range2>> deltas() const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> detect_equalities() const;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::map<T1, pair<Range, Range2>> domain_factor_domain() const;
+  inline typed::map<T2, pair<Range, Range2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &map2) const;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_domain_tuple_id() const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline typed::map<Anonymous, pair<Range, Range2>> flatten_domain() const;
+  inline typed::map<pair<T1, T2>, Anonymous> flatten_range() const;
+  inline void foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::basic_set<pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::point<pair<T1, T2>> &context) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::point<pair<T1, T2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::point<> &params) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::set<pair<Range, Range2>> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::basic_set<pair<Range, Range2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::point<pair<Range, Range2>> &set) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_ge_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_gt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_le_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::pw_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lex_lt_at(const typed::pw_multi_aff<> &mpa) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lexmax() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> lexmax_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lexmin() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> lexmin_pw_multi_aff() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> lower_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const;
+  inline typed::map_list<pair<T1, T2>, pair<Range, Range2>> map_list() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> max_multi_pw_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> min_multi_pw_aff() const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, Arg2> preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::map<Domain2, Arg2> &map2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::union_map<Domain2, Arg2> &umap2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::basic_map<Domain2, Arg2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::set<pair<Range, Range2>> range() const;
+  inline typed::map<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::map<pair<T1, T2>, Range2> range_factor_range() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> range_lattice_tile() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> get_range_lattice_tile() const = delete;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::map<pair<T1, T2>, Arg2> &map2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::basic_map<pair<T1, T2>, Arg2> &map2) const;
+  inline typed::map<pair<T1, T2>, pair<Range2, Range>> range_reverse() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> range_simple_fixed_box_hull() const;
+  inline typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> get_range_simple_fixed_box_hull() const = delete;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::map<pair<Range, Range2>, pair<T1, T2>> reverse() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> space() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> get_space() const = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> to_union_map() const;
+  inline typed::map<pair<pair<T1, T2>, Range>, Range2> uncurry() const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const;
+  static inline typed::map<pair<T1, T2>, pair<Range, Range2>> universe(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space);
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> upper_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const;
+  inline typed::set<pair<pair<T1, T2>, pair<Range, Range2>>> wrap() const;
+};
+
+template <typename Domain, typename Range>
+struct map_list<Domain, Range> : public isl::map_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  map_list() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  map_list(const map_list<Arg1, Arg2> &obj) : isl::map_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::map_list>{}, bool>::type = true>
+  map_list(const base &obj) : isl::map_list(obj) {}
+ public:
+  static map_list from(const isl::map_list &obj) {
+    return map_list(obj);
+  }
+  inline explicit map_list(const isl::ctx &ctx, int n);
+  inline explicit map_list(const typed::map<Domain, Range> &el);
+  inline explicit map_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::map_list<Domain, Range> add(const typed::map<Domain, Range> &el) const;
+  inline typed::map_list<Domain, Range> add(const typed::basic_map<Domain, Range> &el) const;
+  inline typed::map<Domain, Range> at(int index) const;
+  inline typed::map<Domain, Range> get_at(int index) const = delete;
+  inline typed::map_list<Domain, Range> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::map<Domain, Range>)> &fn) const;
+};
+
+template <typename Domain>
+struct multi_aff<Domain> : public isl::multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  multi_aff(const multi_aff<Arg1> &obj) : isl::multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_aff>{}, bool>::type = true>
+  multi_aff(const base &obj) : isl::multi_aff(obj) {}
+ public:
+  static multi_aff from(const isl::multi_aff &obj) {
+    return multi_aff(obj);
+  }
+  inline /* implicit */ multi_aff(const typed::aff<Domain> &aff);
+  inline explicit multi_aff(const typed::space<Domain> &space, const typed::aff_list<Anonymous> &list);
+  inline explicit multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_aff<Domain> add(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> add(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::pw_multi_aff<Domain> add(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::multi_aff<Domain> add(const typed::aff<Domain> &multi2) const;
+  inline typed::multi_aff<Domain> add_constant(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_aff<Domain> add_constant(const typed::val<Domain> &v) const;
+  inline typed::multi_aff<Domain> add_constant(long v) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::map<Domain> as_map() const = delete;
+  inline typed::multi_aff<Domain> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::union_map<Domain> as_union_map() const = delete;
+  inline typed::aff<Anonymous> at(int pos) const;
+  inline typed::aff<Domain> get_at(int pos) const = delete;
+  inline typed::basic_set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_aff<Domain> bind_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::multi_aff<Domain> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain> coalesce() const;
+  inline typed::multi_val<Domain> constant_multi_val() const;
+  inline typed::multi_val<Domain> get_constant_multi_val() const = delete;
+  inline typed::set<> domain() const;
+  inline typed::pw_multi_aff<Domain> extract_pw_multi_aff(const typed::space<Domain> &space) const;
+  inline typed::multi_aff<Domain> floor() const;
+  inline typed::multi_aff<Domain> gist(const typed::set<> &context) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::union_set<> &context) const;
+  inline typed::multi_aff<Domain> gist(const typed::basic_set<> &context) const;
+  inline typed::multi_aff<Domain> gist(const typed::point<> &context) const;
+  inline typed::multi_aff<Domain, Domain> identity() const;
+  template <typename Arg1>
+  inline typed::multi_aff<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::pw_multi_aff<Domain> intersect_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_multi_aff<Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::aff_list<Anonymous> list() const;
+  inline typed::aff_list<Domain> get_list() const = delete;
+  inline typed::multi_pw_aff<Domain> max(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain> min(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> min_multi_val() const;
+  inline typed::multi_aff<Domain> neg() const;
+  inline typed::pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Range>
+  inline typed::multi_aff<pair<Domain, Range>> product(const typed::multi_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::multi_pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Domain, Range>> product(const typed::pw_multi_aff<Range> &pma2) const;
+  template <typename Range>
+  inline typed::multi_aff<pair<Domain, Range>> product(const typed::aff<Range> &multi2) const;
+  inline typed::multi_aff<Domain> pullback(const typed::multi_aff<> &ma2) const = delete;
+  inline typed::multi_pw_aff<Domain> pullback(const typed::multi_pw_aff<> &mpa2) const = delete;
+  inline typed::pw_multi_aff<Domain> pullback(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::multi_aff<Domain> pullback(const typed::aff<> &ma2) const = delete;
+  inline typed::pw_multi_aff_list<Domain> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain> range_factor_range() const = delete;
+  inline typed::multi_aff<Domain> range_product(const typed::multi_aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::pw_multi_aff<Domain> range_product(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::multi_aff<Domain> range_product(const typed::aff<> &multi2) const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::multi_aff<Domain> scale(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_aff<Domain> scale(const typed::val<Domain> &v) const;
+  inline typed::multi_aff<Domain> scale(long v) const;
+  inline typed::multi_aff<Domain> scale_down(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_aff<Domain> scale_down(const typed::val<Domain> &v) const;
+  inline typed::multi_aff<Domain> scale_down(long v) const;
+  inline typed::multi_aff<Domain> set_at(int pos, const typed::aff<Anonymous> &el) const;
+  inline typed::multi_pw_aff<Domain> set_at(int pos, const typed::pw_aff<Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::multi_aff<Domain> sub(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> sub(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::pw_multi_aff<Domain> sub(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::multi_aff<Domain> sub(const typed::aff<Domain> &multi2) const;
+  inline typed::pw_multi_aff<Domain> subtract_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::multi_pw_aff<Domain> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain> to_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain> to_union_pw_multi_aff() const;
+  template <typename Arg1>
+  inline typed::multi_aff<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::multi_pw_aff<Domain> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const;
+  inline typed::pw_multi_aff<Domain> union_add(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+};
+
+template <typename Domain, typename Range>
+struct multi_aff<Domain, Range> : public isl::multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  multi_aff(const multi_aff<Arg1, Arg2> &obj) : isl::multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_aff>{}, bool>::type = true>
+  multi_aff(const base &obj) : isl::multi_aff(obj) {}
+ public:
+  static multi_aff from(const isl::multi_aff &obj) {
+    return multi_aff(obj);
+  }
+  inline /* implicit */ multi_aff(const typed::aff<Domain, Range> &aff);
+  inline explicit multi_aff(const typed::space<Domain, Range> &space, const typed::aff_list<Domain, Anonymous> &list);
+  inline explicit multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_aff<Domain, Range> add(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::pw_multi_aff<Domain, Range> add(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::multi_aff<Domain, Range> add(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::multi_aff<Domain, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<Domain, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::multi_aff<Domain, Range> add_constant(long v) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_aff<Domain, Range> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> as_pw_multi_aff() const;
+  inline typed::set<Domain, Range> as_set() const = delete;
+  inline typed::union_map<Domain, Range> as_union_map() const;
+  inline typed::aff<Domain, Anonymous> at(int pos) const;
+  inline typed::aff<Domain, Range> get_at(int pos) const = delete;
+  inline typed::basic_set<Domain> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::multi_aff<Range> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_aff<Domain, Range> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> coalesce() const;
+  inline typed::multi_val<Range> constant_multi_val() const;
+  inline typed::multi_val<Domain, Range> get_constant_multi_val() const = delete;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, Range> extract_pw_multi_aff(const typed::space<Domain, Range> &space) const;
+  inline typed::multi_aff<Domain, Range> floor() const;
+  inline typed::multi_aff<Domain, Range> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::union_set<Domain> &context) const;
+  inline typed::multi_aff<Domain, Range> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::multi_aff<Domain, Range> gist(const typed::point<Domain> &context) const;
+  inline typed::multi_aff<Domain, Range> identity() const;
+  inline typed::multi_aff<Domain, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::aff_list<Domain, Anonymous> list() const;
+  inline typed::aff_list<Domain, Range> get_list() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_aff<Domain, Range> neg() const;
+  inline typed::pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, Range> pullback(const typed::multi_aff<Domain2, Domain> &ma2) const;
+  inline typed::multi_aff<Range> pullback(const typed::multi_aff<Domain> &ma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, Range> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<Domain> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, Range> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::pw_multi_aff<Domain> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, Range> pullback(const typed::aff<Domain2, Domain> &ma2) const;
+  inline typed::multi_aff<Range> pullback(const typed::aff<Domain> &ma2) const;
+  inline typed::pw_multi_aff_list<Domain, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, pair<Range, Range2>> range_product(const typed::aff<Domain, Range2> &multi2) const;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_aff<Domain, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<Domain, Range> scale(const typed::val<Range> &v) const;
+  inline typed::multi_aff<Domain, Range> scale(long v) const;
+  inline typed::multi_aff<Domain, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<Domain, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::multi_aff<Domain, Range> scale_down(long v) const;
+  inline typed::multi_aff<Domain, Range> set_at(int pos, const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::multi_pw_aff<Domain, Range> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, Range> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::multi_aff<Domain, Range> sub(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::pw_multi_aff<Domain, Range> sub(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::multi_aff<Domain, Range> sub(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::pw_multi_aff<Domain, Range> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_pw_aff<Domain, Range> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Range> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> to_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Range> to_union_pw_multi_aff() const;
+  inline typed::multi_aff<Domain, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const;
+  inline typed::pw_multi_aff<Domain, Range> union_add(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+};
+
+template <typename Domain2, typename Range2, typename Range>
+struct multi_aff<pair<Domain2, Range2>, Range> : public isl::multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain2, Arg1>{} &&
+              std::is_base_of<Range2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{},
+            bool>::type = true>
+  multi_aff(const multi_aff<pair<Arg1, Arg2>, Arg3> &obj) : isl::multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_aff>{}, bool>::type = true>
+  multi_aff(const base &obj) : isl::multi_aff(obj) {}
+ public:
+  static multi_aff from(const isl::multi_aff &obj) {
+    return multi_aff(obj);
+  }
+  inline /* implicit */ multi_aff(const typed::aff<pair<Domain2, Range2>, Range> &aff);
+  inline explicit multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space, const typed::aff_list<pair<Domain2, Range2>, Anonymous> &list);
+  inline explicit multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> add(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> add(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> add_constant(long v) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> apply(const typed::union_pw_multi_aff<Range, Arg2> &upma2) const;
+  inline typed::map<pair<Domain2, Range2>, Range> as_map() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain2, Range2>, Range> as_set() const = delete;
+  inline typed::union_map<pair<Domain2, Range2>, Range> as_union_map() const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> at(int pos) const;
+  inline typed::aff<pair<Domain2, Range2>, Range> get_at(int pos) const = delete;
+  inline typed::basic_set<pair<Domain2, Range2>> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::multi_aff<Range> bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const;
+  inline typed::multi_aff<Range2, Range> bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> coalesce() const;
+  inline typed::multi_val<Range> constant_multi_val() const;
+  inline typed::multi_val<pair<Domain2, Range2>, Range> get_constant_multi_val() const = delete;
+  inline typed::set<pair<Domain2, Range2>> domain() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> floor() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> gist(const typed::set<pair<Domain2, Range2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> gist(const typed::union_set<pair<Domain2, Range2>> &context) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> gist(const typed::basic_set<pair<Domain2, Range2>> &context) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> gist(const typed::point<pair<Domain2, Range2>> &context) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> identity() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::aff_list<pair<Domain2, Range2>, Anonymous> list() const;
+  inline typed::aff_list<pair<Domain2, Range2>, Range> get_list() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::pw_multi_aff<Arg2, Arg3> &pma2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_aff<Arg2, Range> pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma2) const;
+  inline typed::multi_aff<Range> pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<Arg2, Range> pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<Arg2, Range> pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<Arg2, Range> pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma2) const;
+  template <typename Arg2>
+  inline typed::multi_aff<Arg2, Range> pullback(const typed::aff<Arg2, pair<Domain2, Range2>> &ma2) const;
+  inline typed::multi_aff<Range> pullback(const typed::aff<pair<Domain2, Range2>> &ma2) const;
+  inline typed::pw_multi_aff_list<pair<Domain2, Range2>, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> range_factor_range() const = delete;
+  template <typename Arg2>
+  inline typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  inline typed::id<pair<Domain2, Range2>, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale(const typed::val<Range> &v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale(long v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> scale_down(long v) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  template <typename Arg1>
+  inline typed::multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg1>
+  inline typed::multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain2, Range2>, Range> space() const;
+  inline typed::space<pair<Domain2, Range2>, Range> get_space() const = delete;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> sub(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> to_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> to_union_pw_multi_aff() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct multi_aff<Domain, pair<Range, Range2>> : public isl::multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  multi_aff(const multi_aff<Arg1, pair<Arg2, Arg3>> &obj) : isl::multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_aff>{}, bool>::type = true>
+  multi_aff(const base &obj) : isl::multi_aff(obj) {}
+ public:
+  static multi_aff from(const isl::multi_aff &obj) {
+    return multi_aff(obj);
+  }
+  inline /* implicit */ multi_aff(const typed::aff<Domain, pair<Range, Range2>> &aff);
+  inline explicit multi_aff(const typed::space<Domain, pair<Range, Range2>> &space, const typed::aff_list<Domain, Anonymous> &list);
+  inline explicit multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_aff<Domain, pair<Range, Range2>> add(const typed::multi_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> add(const typed::aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> add_constant(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> add_constant(long v) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  inline typed::map<Domain, pair<Range, Range2>> as_map() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::set<Domain, pair<Range, Range2>> as_set() const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> as_union_map() const;
+  inline typed::aff<Domain, Anonymous> at(int pos) const;
+  inline typed::aff<Domain, pair<Range, Range2>> get_at(int pos) const = delete;
+  inline typed::basic_set<Domain> bind(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::multi_aff<pair<Range, Range2>> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::multi_val<pair<Range, Range2>> constant_multi_val() const;
+  inline typed::multi_val<Domain, pair<Range, Range2>> get_constant_multi_val() const = delete;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> floor() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::union_set<Domain> &context) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> gist(const typed::point<Domain> &context) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> identity() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::aff_list<Domain, Anonymous> list() const;
+  inline typed::aff_list<Domain, pair<Range, Range2>> get_list() const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> max(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> min(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> min_multi_val() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> neg() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Domain2, typename Arg3>
+  inline typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::multi_aff<Domain2, Arg3> &multi2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::multi_pw_aff<Domain2, Arg3> &multi2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::pw_multi_aff<Domain2, Arg3> &pma2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::aff<Domain2, Arg3> &multi2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, Domain> &ma2) const;
+  inline typed::multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<Domain> &ma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::aff<Domain2, Domain> &ma2) const;
+  inline typed::multi_aff<pair<Range, Range2>> pullback(const typed::aff<Domain> &ma2) const;
+  inline typed::pw_multi_aff_list<Domain, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_domain() const;
+  inline typed::pw_multi_aff<Domain, Range2> range_factor_range() const;
+  template <typename Arg3>
+  inline typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_aff<Domain, Arg3> &multi2) const;
+  template <typename Arg3>
+  inline typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_pw_aff<Domain, Arg3> &multi2) const;
+  template <typename Arg3>
+  inline typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_union_pw_aff<Domain, Arg3> &multi2) const;
+  template <typename Arg3>
+  inline typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::pw_multi_aff<Domain, Arg3> &pma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::aff<Domain, Arg3> &multi2) const;
+  inline typed::id<Domain, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale(long v) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale_down(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> scale_down(long v) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> set_at(int pos, const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> space() const;
+  inline typed::space<Domain, pair<Range, Range2>> get_space() const = delete;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> sub(const typed::multi_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> sub(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> sub(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> sub(const typed::aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> to_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> to_union_pw_multi_aff() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &mupa2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct multi_aff<pair<T1, T2>, pair<Range, Range2>> : public isl::multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  multi_aff(const multi_aff<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_aff>{}, bool>::type = true>
+  multi_aff(const base &obj) : isl::multi_aff(obj) {}
+ public:
+  static multi_aff from(const isl::multi_aff &obj) {
+    return multi_aff(obj);
+  }
+  inline /* implicit */ multi_aff(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &aff);
+  inline explicit multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space, const typed::aff_list<pair<T1, T2>, Anonymous> &list);
+  inline explicit multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(long v) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> as_map() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::set<pair<T1, T2>, pair<Range, Range2>> as_set() const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> as_union_map() const;
+  inline typed::aff<pair<T1, T2>, Anonymous> at(int pos) const;
+  inline typed::aff<pair<T1, T2>, pair<Range, Range2>> get_at(int pos) const = delete;
+  inline typed::basic_set<pair<T1, T2>> bind(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::multi_aff<pair<Range, Range2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::multi_aff<T2, pair<Range, Range2>> bind_domain_wrapped_domain(const typed::multi_id<T1> &tuple) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::multi_val<pair<Range, Range2>> constant_multi_val() const;
+  inline typed::multi_val<pair<T1, T2>, pair<Range, Range2>> get_constant_multi_val() const = delete;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> floor() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_set<pair<T1, T2>> &context) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_set<pair<T1, T2>> &context) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::point<pair<T1, T2>> &context) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> identity() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::aff_list<pair<T1, T2>, Anonymous> list() const;
+  inline typed::aff_list<pair<T1, T2>, pair<Range, Range2>> get_list() const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> max(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> min(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> min_multi_val() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::multi_aff<Domain2, Arg2> &multi2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::multi_pw_aff<Domain2, Arg2> &multi2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::pw_multi_aff<Domain2, Arg2> &pma2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::aff<Domain2, Arg2> &multi2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &ma2) const;
+  inline typed::multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<pair<T1, T2>> &ma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Range, Range2>> pullback(const typed::multi_pw_aff<pair<T1, T2>> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<pair<T1, T2>> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const;
+  template <typename Domain2>
+  inline typed::multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::aff<Domain2, pair<T1, T2>> &ma2) const;
+  inline typed::multi_aff<pair<Range, Range2>> pullback(const typed::aff<pair<T1, T2>> &ma2) const;
+  inline typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, Range2> range_factor_range() const;
+  template <typename Arg2>
+  inline typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_pw_aff<pair<T1, T2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_union_pw_aff<pair<T1, T2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::aff<pair<T1, T2>, Arg2> &multi2) const;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale(long v) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(long v) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> set_at(int pos, const typed::aff<pair<T1, T2>, Anonymous> &el) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> set_at(int pos, const typed::pw_aff<pair<T1, T2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> set_at(int pos, const typed::union_pw_aff<pair<T1, T2>, Anonymous> &el) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> space() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> get_space() const = delete;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> to_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> to_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> to_pw_multi_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> to_union_pw_multi_aff() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mupa2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+};
+
+template <typename Domain>
+struct multi_id<Domain> : public isl::multi_id {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_id() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  multi_id(const multi_id<Arg1> &obj) : isl::multi_id(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_id>{}, bool>::type = true>
+  multi_id(const base &obj) : isl::multi_id(obj) {}
+ public:
+  static multi_id from(const isl::multi_id &obj) {
+    return multi_id(obj);
+  }
+  inline explicit multi_id(const typed::space<Domain> &space, const typed::id_list<Anonymous> &list);
+  inline explicit multi_id(const isl::ctx &ctx, const std::string &str);
+  inline typed::id<Anonymous> at(int pos) const;
+  inline typed::id<Domain> get_at(int pos) const = delete;
+  inline typed::id_list<Anonymous> list() const;
+  inline typed::id_list<Domain> get_list() const = delete;
+  inline typed::multi_id<Domain> range_product(const typed::multi_id<> &multi2) const = delete;
+  inline typed::multi_id<Domain> set_at(int pos, const typed::id<Anonymous> &el) const;
+  inline typed::multi_id<Domain> set_at(int pos, const std::string &el) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+};
+
+template <typename Domain>
+struct multi_pw_aff<Domain> : public isl::multi_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_pw_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  multi_pw_aff(const multi_pw_aff<Arg1> &obj) : isl::multi_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_pw_aff>{}, bool>::type = true>
+  multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {}
+ public:
+  static multi_pw_aff from(const isl::multi_pw_aff &obj) {
+    return multi_pw_aff(obj);
+  }
+  inline /* implicit */ multi_pw_aff(const typed::aff<Domain> &aff);
+  inline /* implicit */ multi_pw_aff(const typed::multi_aff<Domain> &ma);
+  inline /* implicit */ multi_pw_aff(const typed::pw_aff<Domain> &pa);
+  inline explicit multi_pw_aff(const typed::space<Domain> &space, const typed::pw_aff_list<Anonymous> &list);
+  inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff<Domain> &pma);
+  inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain> add(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> add(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add(const typed::aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add(const typed::pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add(const typed::pw_multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> add_constant(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_pw_aff<Domain> add_constant(const typed::val<Domain> &v) const;
+  inline typed::multi_pw_aff<Domain> add_constant(long v) const;
+  inline typed::map<Domain> as_map() const = delete;
+  inline typed::multi_aff<Domain> as_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::pw_aff<Anonymous> at(int pos) const;
+  inline typed::pw_aff<Domain> get_at(int pos) const = delete;
+  inline typed::set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_pw_aff<Domain> bind_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::multi_pw_aff<Domain> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::multi_pw_aff<Domain> coalesce() const;
+  inline typed::set<> domain() const;
+  inline typed::multi_pw_aff<Domain> gist(const typed::set<> &set) const;
+  inline typed::multi_union_pw_aff<Domain> gist(const typed::union_set<> &context) const;
+  inline typed::multi_pw_aff<Domain> gist(const typed::basic_set<> &set) const;
+  inline typed::multi_pw_aff<Domain> gist(const typed::point<> &set) const;
+  inline typed::multi_pw_aff<Domain, Domain> identity() const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::multi_pw_aff<Domain> intersect_domain(const typed::set<> &domain) const = delete;
+  inline typed::multi_union_pw_aff<Domain> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::multi_pw_aff<Domain> intersect_domain(const typed::basic_set<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain> intersect_domain(const typed::point<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::multi_pw_aff<Domain> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::multi_pw_aff<Domain> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<Anonymous> list() const;
+  inline typed::pw_aff_list<Domain> get_list() const = delete;
+  inline typed::multi_pw_aff<Domain> max(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> max(const typed::aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> max(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> max(const typed::pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> max(const typed::pw_multi_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain> min(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> min(const typed::aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> min(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> min(const typed::pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> min(const typed::pw_multi_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> min_multi_val() const;
+  inline typed::multi_pw_aff<Domain> neg() const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::multi_pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::multi_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::pw_multi_aff<Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain> pullback(const typed::multi_aff<> &ma) const = delete;
+  inline typed::multi_pw_aff<Domain> pullback(const typed::multi_pw_aff<> &mpa2) const = delete;
+  inline typed::multi_pw_aff<Domain> pullback(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::multi_union_pw_aff<Domain> pullback(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::multi_aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::pw_aff<> &multi2) const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::pw_multi_aff<> &multi2) const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<Domain> scale(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_pw_aff<Domain> scale(const typed::val<Domain> &v) const;
+  inline typed::multi_pw_aff<Domain> scale(long v) const;
+  inline typed::multi_pw_aff<Domain> scale_down(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_pw_aff<Domain> scale_down(const typed::val<Domain> &v) const;
+  inline typed::multi_pw_aff<Domain> scale_down(long v) const;
+  inline typed::multi_pw_aff<Domain> set_at(int pos, const typed::pw_aff<Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::multi_pw_aff<Domain> sub(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> sub(const typed::aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> sub(const typed::multi_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> sub(const typed::pw_aff<Domain> &multi2) const;
+  inline typed::multi_pw_aff<Domain> sub(const typed::pw_multi_aff<Domain> &multi2) const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::multi_pw_aff<Domain> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::aff<Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::multi_aff<Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::pw_aff<Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::pw_multi_aff<Domain> &mpa2) const;
+};
+
+template <typename Domain, typename Range>
+struct multi_pw_aff<Domain, Range> : public isl::multi_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_pw_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  multi_pw_aff(const multi_pw_aff<Arg1, Arg2> &obj) : isl::multi_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_pw_aff>{}, bool>::type = true>
+  multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {}
+ public:
+  static multi_pw_aff from(const isl::multi_pw_aff &obj) {
+    return multi_pw_aff(obj);
+  }
+  inline /* implicit */ multi_pw_aff(const typed::aff<Domain, Range> &aff);
+  inline /* implicit */ multi_pw_aff(const typed::multi_aff<Domain, Range> &ma);
+  inline /* implicit */ multi_pw_aff(const typed::pw_aff<Domain, Range> &pa);
+  inline explicit multi_pw_aff(const typed::space<Domain, Range> &space, const typed::pw_aff_list<Domain, Anonymous> &list);
+  inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff<Domain, Range> &pma);
+  inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::pw_multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<Domain, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<Domain, Range> add_constant(long v) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_aff<Domain, Range> as_multi_aff() const;
+  inline typed::set<Domain, Range> as_set() const = delete;
+  inline typed::pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::pw_aff<Domain, Range> get_at(int pos) const = delete;
+  inline typed::set<Domain> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::multi_pw_aff<Range> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_pw_aff<Domain, Range> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> coalesce() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::multi_pw_aff<Domain, Range> gist(const typed::set<Domain> &set) const;
+  inline typed::multi_union_pw_aff<Domain, Range> gist(const typed::union_set<Domain> &context) const;
+  inline typed::multi_pw_aff<Domain, Range> gist(const typed::basic_set<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> gist(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> identity() const;
+  inline typed::multi_pw_aff<Domain, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> intersect_domain(const typed::set<Domain> &domain) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_pw_aff<Domain, Range> intersect_domain(const typed::basic_set<Domain> &domain) const;
+  inline typed::multi_pw_aff<Domain, Range> intersect_domain(const typed::point<Domain> &domain) const;
+  inline typed::multi_pw_aff<Domain, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::pw_aff_list<Domain, Range> get_list() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::pw_multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::pw_multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Range> neg() const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::pw_multi_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, Range> pullback(const typed::multi_aff<Domain2, Domain> &ma) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_aff<Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, Range> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<Domain> &mpa2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, Range> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::pw_multi_aff<Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2, Range> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::union_pw_multi_aff<Domain> &upma) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &multi2) const;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<Domain, Range> scale(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<Domain, Range> scale(long v) const;
+  inline typed::multi_pw_aff<Domain, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<Domain, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<Domain, Range> scale_down(long v) const;
+  inline typed::multi_pw_aff<Domain, Range> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, Range> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::pw_multi_aff<Domain, Range> &multi2) const;
+  inline typed::multi_pw_aff<Domain, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::aff<Domain, Range> &mpa2) const;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::multi_aff<Domain, Range> &mpa2) const;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::pw_aff<Domain, Range> &mpa2) const;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::pw_multi_aff<Domain, Range> &mpa2) const;
+};
+
+template <typename Domain2, typename Range2, typename Range>
+struct multi_pw_aff<pair<Domain2, Range2>, Range> : public isl::multi_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_pw_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain2, Arg1>{} &&
+              std::is_base_of<Range2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{},
+            bool>::type = true>
+  multi_pw_aff(const multi_pw_aff<pair<Arg1, Arg2>, Arg3> &obj) : isl::multi_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_pw_aff>{}, bool>::type = true>
+  multi_pw_aff(const base &obj) : isl::multi_pw_aff(obj) {}
+ public:
+  static multi_pw_aff from(const isl::multi_pw_aff &obj) {
+    return multi_pw_aff(obj);
+  }
+  inline /* implicit */ multi_pw_aff(const typed::aff<pair<Domain2, Range2>, Range> &aff);
+  inline /* implicit */ multi_pw_aff(const typed::multi_aff<pair<Domain2, Range2>, Range> &ma);
+  inline /* implicit */ multi_pw_aff(const typed::pw_aff<pair<Domain2, Range2>, Range> &pa);
+  inline explicit multi_pw_aff(const typed::space<pair<Domain2, Range2>, Range> &space, const typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> &list);
+  inline /* implicit */ multi_pw_aff(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma);
+  inline explicit multi_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add_constant(long v) const;
+  inline typed::map<pair<Domain2, Range2>, Range> as_map() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> as_multi_aff() const;
+  inline typed::set<pair<Domain2, Range2>, Range> as_set() const = delete;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> at(int pos) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Range> get_at(int pos) const = delete;
+  inline typed::set<pair<Domain2, Range2>> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::multi_pw_aff<Range> bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const;
+  inline typed::multi_pw_aff<Range2, Range> bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> coalesce() const;
+  inline typed::set<pair<Domain2, Range2>> domain() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> gist(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> gist(const typed::union_set<pair<Domain2, Range2>> &context) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> gist(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> gist(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> identity() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::set<pair<Domain2, Range2>> &domain) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &domain) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::point<pair<Domain2, Range2>> &domain) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> list() const;
+  inline typed::pw_aff_list<pair<Domain2, Range2>, Range> get_list() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> neg() const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::pw_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::pw_multi_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<Arg2, Range> pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<Arg2, Range> pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<Arg2, Range> pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<Arg2, Range> pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  inline typed::id<pair<Domain2, Range2>, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale(long v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale_down(long v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain2, Range2>, Range> space() const;
+  inline typed::space<pair<Domain2, Range2>, Range> get_space() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::pw_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+};
+
+template <typename Domain>
+struct multi_union_pw_aff<Domain> : public isl::multi_union_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_union_pw_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  multi_union_pw_aff(const multi_union_pw_aff<Arg1> &obj) : isl::multi_union_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_union_pw_aff>{}, bool>::type = true>
+  multi_union_pw_aff(const base &obj) : isl::multi_union_pw_aff(obj) {}
+ public:
+  static multi_union_pw_aff from(const isl::multi_union_pw_aff &obj) {
+    return multi_union_pw_aff(obj);
+  }
+  inline /* implicit */ multi_union_pw_aff(const typed::multi_pw_aff<Domain> &mpa);
+  inline /* implicit */ multi_union_pw_aff(const typed::union_pw_aff<Domain> &upa);
+  inline explicit multi_union_pw_aff(const typed::space<Domain> &space, const typed::union_pw_aff_list<Anonymous> &list);
+  inline explicit multi_union_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_union_pw_aff<Domain> add(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> add(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> add(const typed::union_pw_aff<Domain> &multi2) const;
+  inline typed::union_pw_aff<Anonymous> at(int pos) const;
+  inline typed::union_pw_aff<Domain> get_at(int pos) const = delete;
+  inline typed::union_set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::multi_union_pw_aff<Domain> coalesce() const;
+  inline typed::union_set<> domain() const;
+  inline typed::multi_union_pw_aff<Domain> gist(const typed::union_set<> &context) const;
+  inline typed::multi_union_pw_aff<Domain> gist(const typed::basic_set<> &context) const;
+  inline typed::multi_union_pw_aff<Domain> gist(const typed::point<> &context) const;
+  inline typed::multi_union_pw_aff<Domain> gist(const typed::set<> &context) const;
+  inline typed::multi_union_pw_aff<Domain> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::multi_union_pw_aff<Domain> intersect_domain(const typed::basic_set<> &uset) const = delete;
+  inline typed::multi_union_pw_aff<Domain> intersect_domain(const typed::point<> &uset) const = delete;
+  inline typed::multi_union_pw_aff<Domain> intersect_domain(const typed::set<> &uset) const = delete;
+  inline typed::multi_union_pw_aff<Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::multi_union_pw_aff<Domain> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::multi_union_pw_aff<Domain> intersect_params(const typed::point<> &params) const;
+  inline typed::union_pw_aff_list<Anonymous> list() const;
+  inline typed::union_pw_aff_list<Domain> get_list() const = delete;
+  inline typed::multi_union_pw_aff<Domain> neg() const;
+  inline typed::multi_union_pw_aff<Domain> pullback(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::multi_union_pw_aff<Domain> pullback(const typed::multi_aff<> &upma) const = delete;
+  inline typed::multi_union_pw_aff<Domain> pullback(const typed::pw_multi_aff<> &upma) const = delete;
+  inline typed::multi_union_pw_aff<Domain> pullback(const typed::union_pw_aff<> &upma) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::union_pw_aff<> &multi2) const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::multi_union_pw_aff<Domain> scale(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_union_pw_aff<Domain> scale(const typed::val<Domain> &v) const;
+  inline typed::multi_union_pw_aff<Domain> scale(long v) const;
+  inline typed::multi_union_pw_aff<Domain> scale_down(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_union_pw_aff<Domain> scale_down(const typed::val<Domain> &v) const;
+  inline typed::multi_union_pw_aff<Domain> scale_down(long v) const;
+  inline typed::multi_union_pw_aff<Domain> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::union_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::multi_pw_aff<Domain> &mupa2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::union_pw_aff<Domain> &mupa2) const;
+};
+
+template <typename Domain, typename Range>
+struct multi_union_pw_aff<Domain, Range> : public isl::multi_union_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_union_pw_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  multi_union_pw_aff(const multi_union_pw_aff<Arg1, Arg2> &obj) : isl::multi_union_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_union_pw_aff>{}, bool>::type = true>
+  multi_union_pw_aff(const base &obj) : isl::multi_union_pw_aff(obj) {}
+ public:
+  static multi_union_pw_aff from(const isl::multi_union_pw_aff &obj) {
+    return multi_union_pw_aff(obj);
+  }
+  inline /* implicit */ multi_union_pw_aff(const typed::multi_pw_aff<Domain, Range> &mpa);
+  inline /* implicit */ multi_union_pw_aff(const typed::union_pw_aff<Domain, Range> &upa);
+  inline explicit multi_union_pw_aff(const typed::space<Domain, Range> &space, const typed::union_pw_aff_list<Domain, Anonymous> &list);
+  inline explicit multi_union_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::union_pw_aff<Domain, Range> get_at(int pos) const = delete;
+  inline typed::union_set<Domain> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::multi_union_pw_aff<Domain, Range> coalesce() const;
+  inline typed::union_set<Domain> domain() const;
+  inline typed::multi_union_pw_aff<Domain, Range> gist(const typed::union_set<Domain> &context) const;
+  inline typed::multi_union_pw_aff<Domain, Range> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::multi_union_pw_aff<Domain, Range> gist(const typed::point<Domain> &context) const;
+  inline typed::multi_union_pw_aff<Domain, Range> gist(const typed::set<Domain> &context) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_domain(const typed::basic_set<Domain> &uset) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_domain(const typed::point<Domain> &uset) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_domain(const typed::set<Domain> &uset) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_params(const typed::set<> &params) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::multi_union_pw_aff<Domain, Range> intersect_params(const typed::point<> &params) const;
+  inline typed::union_pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::union_pw_aff_list<Domain, Range> get_list() const = delete;
+  inline typed::multi_union_pw_aff<Domain, Range> neg() const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2, Range> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::union_pw_multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2, Range> pullback(const typed::multi_aff<Domain2, Domain> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2, Range> pullback(const typed::pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::pw_multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2, Range> pullback(const typed::union_pw_aff<Domain2, Domain> &upma) const;
+  inline typed::multi_union_pw_aff<Range> pullback(const typed::union_pw_aff<Domain> &upma) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::union_pw_aff<Domain, Range2> &multi2) const;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_union_pw_aff<Domain, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_union_pw_aff<Domain, Range> scale(const typed::val<Range> &v) const;
+  inline typed::multi_union_pw_aff<Domain, Range> scale(long v) const;
+  inline typed::multi_union_pw_aff<Domain, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_union_pw_aff<Domain, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::multi_union_pw_aff<Domain, Range> scale_down(long v) const;
+  inline typed::multi_union_pw_aff<Domain, Range> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::multi_pw_aff<Domain, Range> &mupa2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::union_pw_aff<Domain, Range> &mupa2) const;
+};
+
+template <typename Domain>
+struct multi_val<Domain> : public isl::multi_val {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  multi_val() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  multi_val(const multi_val<Arg1> &obj) : isl::multi_val(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::multi_val>{}, bool>::type = true>
+  multi_val(const base &obj) : isl::multi_val(obj) {}
+ public:
+  static multi_val from(const isl::multi_val &obj) {
+    return multi_val(obj);
+  }
+  inline explicit multi_val(const typed::space<Domain> &space, const typed::val_list<Anonymous> &list);
+  inline explicit multi_val(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_val<Domain> add(const typed::multi_val<Domain> &multi2) const;
+  inline typed::multi_val<Domain> add(const typed::val<Domain> &v) const;
+  inline typed::multi_val<Domain> add(long v) const;
+  inline typed::val<Anonymous> at(int pos) const;
+  inline typed::val<Domain> get_at(int pos) const = delete;
+  inline typed::val_list<Anonymous> list() const;
+  inline typed::val_list<Domain> get_list() const = delete;
+  inline typed::multi_val<Domain> max(const typed::multi_val<Domain> &multi2) const;
+  inline typed::multi_val<Domain> min(const typed::multi_val<Domain> &multi2) const;
+  inline typed::multi_val<Domain> neg() const;
+  template <typename Range>
+  inline typed::multi_val<pair<Domain, Range>> product(const typed::multi_val<Range> &multi2) const;
+  inline typed::multi_val<Domain> range_product(const typed::multi_val<> &multi2) const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::multi_val<Domain> scale(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_val<Domain> scale(const typed::val<Domain> &v) const;
+  inline typed::multi_val<Domain> scale(long v) const;
+  inline typed::multi_val<Domain> scale_down(const typed::multi_val<Domain> &mv) const;
+  inline typed::multi_val<Domain> scale_down(const typed::val<Domain> &v) const;
+  inline typed::multi_val<Domain> scale_down(long v) const;
+  inline typed::multi_val<Domain> set_at(int pos, const typed::val<Anonymous> &el) const;
+  inline typed::multi_val<Domain> set_at(int pos, long el) const;
+  template <typename Domain2>
+  inline typed::multi_val<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_val<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::multi_val<Domain> sub(const typed::multi_val<Domain> &multi2) const;
+};
+
+template <>
+struct point<> : public isl::point {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  point() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::point>{}, bool>::type = true>
+  point(const base &obj) : isl::point(obj) {}
+ public:
+  static point from(const isl::point &obj) {
+    return point(obj);
+  }
+  inline typed::basic_set<> apply(const typed::basic_map<> &bmap) const = delete;
+  inline typed::set<> apply(const typed::map<> &map) const = delete;
+  inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete;
+  inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete;
+  inline typed::set<> as_set() const = delete;
+  inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete;
+  inline typed::set<> coalesce() const;
+  inline typed::basic_set<> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<>)> &test) const;
+  inline typed::set<> extract_set(const typed::space<> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<>)> &fn) const;
+  inline typed::basic_set<> gist(const typed::basic_set<> &context) const;
+  inline typed::set<> gist(const typed::set<> &context) const;
+  inline typed::union_set<> gist(const typed::union_set<> &context) const;
+  inline typed::map<> identity() const = delete;
+  inline typed::pw_aff<Anonymous> indicator_function() const;
+  inline typed::map<> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::basic_set<> intersect(const typed::basic_set<> &bset2) const;
+  inline typed::set<> intersect(const typed::set<> &set2) const;
+  inline typed::union_set<> intersect(const typed::union_set<> &uset2) const;
+  inline typed::basic_set<> intersect_params(const typed::basic_set<> &bset2) const = delete;
+  inline typed::set<> intersect_params(const typed::set<> &params) const = delete;
+  inline typed::set<> lexmax() const = delete;
+  inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete;
+  inline typed::set<> lexmin() const = delete;
+  inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete;
+  inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete;
+  inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete;
+  inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete;
+  inline typed::val<> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete;
+  inline typed::val<> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_val<> multi_val() const = delete;
+  inline typed::multi_val<> get_multi_val() const = delete;
+  inline typed::basic_set<> params() const = delete;
+  inline typed::multi_val<> plain_multi_val_if_fixed() const = delete;
+  inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete;
+  inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::set<> product(const typed::set<> &set2) const = delete;
+  inline typed::set<> project_out_all_params() const;
+  inline typed::set<> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<> project_out_param(const std::string &id) const;
+  inline typed::set<> project_out_param(const typed::id_list<Anonymous> &list) const;
+  inline typed::pw_multi_aff<> pw_multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::fixed_box<> simple_fixed_box_hull() const = delete;
+  inline typed::space<> space() const;
+  inline typed::set<> subtract(const typed::set<> &set2) const;
+  inline typed::union_set<> subtract(const typed::union_set<> &uset2) const;
+  inline typed::set<> to_set() const;
+  inline typed::union_set<> to_union_set() const;
+  inline typed::map<> translation() const = delete;
+  template <typename Domain>
+  inline typed::set<Domain> unbind_params(const typed::multi_id<Domain> &tuple) const;
+  inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::set<> unite(const typed::basic_set<> &bset2) const;
+  inline typed::set<> unite(const typed::set<> &set2) const;
+  inline typed::union_set<> unite(const typed::union_set<> &uset2) const;
+  inline typed::map<> unwrap() const = delete;
+  inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete;
+  inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete;
+};
+
+template <typename Domain>
+struct point<Domain> : public isl::point {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  point() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  point(const point<Arg1> &obj) : isl::point(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::point>{}, bool>::type = true>
+  point(const base &obj) : isl::point(obj) {}
+ public:
+  static point from(const isl::point &obj) {
+    return point(obj);
+  }
+  template <typename Range>
+  inline typed::basic_set<Range> apply(const typed::basic_map<Domain, Range> &bmap) const;
+  template <typename Range>
+  inline typed::set<Range> apply(const typed::map<Domain, Range> &map) const;
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::union_map<Domain, Range> &umap) const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> coalesce() const;
+  inline typed::basic_set<Domain> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<Domain>)> &test) const;
+  inline typed::set<Domain> extract_set(const typed::space<Domain> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<Domain>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<Domain>)> &fn) const;
+  inline typed::basic_set<Domain> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::set<Domain> gist(const typed::set<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::union_set<Domain> &context) const;
+  inline typed::map<Domain, Domain> identity() const;
+  inline typed::pw_aff<Domain, Anonymous> indicator_function() const;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::basic_set<Domain> intersect(const typed::basic_set<Domain> &bset2) const;
+  inline typed::set<Domain> intersect(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> intersect(const typed::union_set<Domain> &uset2) const;
+  inline typed::basic_set<Domain> intersect_params(const typed::basic_set<> &bset2) const;
+  inline typed::set<Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::set<Domain> lexmax() const;
+  inline typed::pw_multi_aff<Domain> lexmax_pw_multi_aff() const;
+  inline typed::set<Domain> lexmin() const;
+  inline typed::pw_multi_aff<Domain> lexmin_pw_multi_aff() const;
+  inline typed::set<Domain> lower_bound(const typed::multi_pw_aff<Domain> &lower) const;
+  inline typed::set<Domain> lower_bound(const typed::multi_val<Domain> &lower) const;
+  inline typed::multi_pw_aff<Domain> max_multi_pw_aff() const;
+  inline typed::val<Domain> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<Domain> min_multi_pw_aff() const;
+  inline typed::val<Domain> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_val<Domain> multi_val() const;
+  inline typed::multi_val<Domain> get_multi_val() const = delete;
+  inline typed::basic_set<> params() const;
+  inline typed::multi_val<Domain> plain_multi_val_if_fixed() const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range>
+  inline typed::set<pair<Domain, Range>> product(const typed::set<Range> &set2) const;
+  inline typed::set<Domain> project_out_all_params() const;
+  inline typed::set<Domain> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<Domain> project_out_param(const std::string &id) const;
+  inline typed::set<Domain> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<Domain, Range> pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const;
+  inline typed::fixed_box<Domain> simple_fixed_box_hull() const;
+  inline typed::space<Domain> space() const;
+  inline typed::set<Domain> subtract(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> subtract(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> to_set() const;
+  inline typed::union_set<Domain> to_union_set() const;
+  inline typed::map<Domain, Domain> translation() const;
+  inline typed::set<Domain> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::set<Domain> unite(const typed::basic_set<Domain> &bset2) const;
+  inline typed::set<Domain> unite(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> unite(const typed::union_set<Domain> &uset2) const;
+  inline typed::map<Domain> unwrap() const = delete;
+  inline typed::set<Domain> upper_bound(const typed::multi_pw_aff<Domain> &upper) const;
+  inline typed::set<Domain> upper_bound(const typed::multi_val<Domain> &upper) const;
+};
+
+template <typename Domain, typename Range>
+struct point<pair<Domain, Range>> : public isl::point {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  point() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  point(const point<pair<Arg1, Arg2>> &obj) : isl::point(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::point>{}, bool>::type = true>
+  point(const base &obj) : isl::point(obj) {}
+ public:
+  static point from(const isl::point &obj) {
+    return point(obj);
+  }
+  template <typename Arg2>
+  inline typed::basic_set<Arg2> apply(const typed::basic_map<pair<Domain, Range>, Arg2> &bmap) const;
+  template <typename Arg2>
+  inline typed::set<Arg2> apply(const typed::map<pair<Domain, Range>, Arg2> &map) const;
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<pair<Domain, Range>> &tuple) const;
+  inline typed::set<pair<Domain, Range>> coalesce() const;
+  inline typed::basic_set<pair<Domain, Range>> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const;
+  inline typed::set<pair<Domain, Range>> extract_set(const typed::space<pair<Domain, Range>> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const;
+  inline typed::basic_set<pair<Domain, Range>> gist(const typed::basic_set<pair<Domain, Range>> &context) const;
+  inline typed::set<pair<Domain, Range>> gist(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::union_set<pair<Domain, Range>> &context) const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> identity() const;
+  inline typed::pw_aff<pair<Domain, Range>, Anonymous> indicator_function() const;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> insert_domain(const typed::space<Arg2> &domain) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect(const typed::basic_set<pair<Domain, Range>> &bset2) const;
+  inline typed::set<pair<Domain, Range>> intersect(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::basic_set<pair<Domain, Range>> intersect_params(const typed::basic_set<> &bset2) const;
+  inline typed::set<pair<Domain, Range>> intersect_params(const typed::set<> &params) const;
+  inline typed::set<pair<Domain, Range>> lexmax() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmax_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lexmin() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmin_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const;
+  inline typed::multi_pw_aff<pair<Domain, Range>> max_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<pair<Domain, Range>> min_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_val<pair<Domain, Range>> multi_val() const;
+  inline typed::multi_val<pair<Domain, Range>> get_multi_val() const = delete;
+  inline typed::basic_set<> params() const;
+  inline typed::multi_val<pair<Domain, Range>> plain_multi_val_if_fixed() const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg2>
+  inline typed::set<pair<pair<Domain, Range>, Arg2>> product(const typed::set<Arg2> &set2) const;
+  inline typed::set<pair<Domain, Range>> project_out_all_params() const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const std::string &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain, Range>, Arg2> pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const;
+  inline typed::fixed_box<pair<Domain, Range>> simple_fixed_box_hull() const;
+  inline typed::space<pair<Domain, Range>> space() const;
+  inline typed::set<pair<Domain, Range>> subtract(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> to_set() const;
+  inline typed::union_set<pair<Domain, Range>> to_union_set() const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> translation() const;
+  inline typed::set<pair<Domain, Range>> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::basic_set<pair<Domain, Range>> &bset2) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::map<Domain, Range> unwrap() const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const;
+};
+
+template <>
+struct pw_aff<Anonymous> : public isl::pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_aff() = default;
+  pw_aff(const isl::pw_aff &obj) : isl::pw_aff(obj) {}
+  static pw_aff from(const isl::pw_aff &obj) {
+    return pw_aff(obj);
+  }
+  inline /* implicit */ pw_aff(const typed::aff<Anonymous> &aff);
+  inline explicit pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Anonymous> add(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Anonymous> add(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> add(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> add(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::pw_aff<Anonymous> add(const typed::aff<Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<Anonymous> add_constant(long v) const;
+  inline typed::pw_multi_aff<Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const;
+  inline typed::aff<Anonymous> as_aff() const;
+  inline typed::map<Anonymous> as_map() const = delete;
+  inline typed::multi_aff<Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Anonymous> as_pw_multi_aff() const;
+  inline typed::set<Anonymous> as_set() const;
+  inline typed::union_map<Anonymous> as_union_map() const = delete;
+  inline typed::pw_aff<Anonymous> at(int pos) const;
+  inline typed::set<> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::set<> bind(const typed::id<Anonymous> &id) const;
+  inline typed::set<> bind(const std::string &id) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_aff<Anonymous> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_aff<Anonymous> ceil() const;
+  inline typed::pw_aff<Anonymous> coalesce() const;
+  inline typed::pw_aff<Anonymous> cond(const typed::pw_aff<Anonymous> &pwaff_true, const typed::pw_aff<Anonymous> &pwaff_false) const;
+  inline typed::set<> domain() const;
+  inline typed::pw_multi_aff<Anonymous> extract_pw_multi_aff(const typed::space<Anonymous> &space) const;
+  inline typed::pw_aff<Anonymous> floor() const;
+  inline typed::set<Anonymous> ge_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::set<Anonymous> ge_set(const typed::aff<> &pwaff2) const = delete;
+  inline typed::pw_aff<Anonymous> gist(const typed::set<> &context) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::union_set<> &context) const;
+  inline typed::pw_aff<Anonymous> gist(const typed::basic_set<> &context) const;
+  inline typed::pw_aff<Anonymous> gist(const typed::point<> &context) const;
+  inline typed::set<Anonymous> gt_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::set<Anonymous> gt_set(const typed::aff<> &pwaff2) const = delete;
+  inline typed::multi_pw_aff<Anonymous, Anonymous> identity() const;
+  template <typename Domain>
+  inline typed::pw_aff<Domain, Anonymous> insert_domain(const typed::space<Domain> &domain) const;
+  inline typed::pw_aff<Anonymous> intersect_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_aff<Anonymous> intersect_domain(const typed::basic_set<> &set) const = delete;
+  inline typed::pw_aff<Anonymous> intersect_domain(const typed::point<> &set) const = delete;
+  inline typed::pw_aff<Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_aff<Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_aff<Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::set<Anonymous> le_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::set<Anonymous> le_set(const typed::aff<> &pwaff2) const = delete;
+  inline typed::pw_aff_list<Anonymous> list() const;
+  inline typed::set<Anonymous> lt_set(const typed::pw_aff<> &pwaff2) const = delete;
+  inline typed::set<Anonymous> lt_set(const typed::aff<> &pwaff2) const = delete;
+  inline typed::multi_pw_aff<Anonymous> max(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> max(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Anonymous> max(const typed::aff<Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<Anonymous> min(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> min(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Anonymous> min(const typed::aff<Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::pw_aff<Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::pw_aff<Anonymous> mod(long mod) const;
+  inline typed::pw_aff<Anonymous> neg() const;
+  inline typed::pw_multi_aff<Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Anonymous, Range>> product(const typed::multi_pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Anonymous, Range>> product(const typed::pw_multi_aff<Range> &pma2) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_aff<> &ma) const = delete;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::pw_multi_aff_list<Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Anonymous> range_factor_range() const = delete;
+  inline typed::multi_pw_aff<Anonymous> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::pw_multi_aff<Anonymous> range_product(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::multi_pw_aff<Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<Anonymous> scale(long v) const;
+  inline typed::multi_pw_aff<Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<Anonymous> scale_down(const typed::val<Anonymous> &f) const;
+  inline typed::pw_aff<Anonymous> scale_down(long f) const;
+  inline typed::multi_pw_aff<Anonymous> set_at(int pos, const typed::pw_aff<Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Anonymous> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Anonymous> space() const;
+  inline typed::multi_pw_aff<Anonymous> sub(const typed::multi_pw_aff<Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Anonymous> sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::pw_aff<Anonymous> sub(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> sub(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> sub(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::pw_aff<Anonymous> sub(const typed::aff<Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Anonymous> subtract_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_aff<Anonymous> subtract_domain(const typed::basic_set<> &set) const = delete;
+  inline typed::pw_aff<Anonymous> subtract_domain(const typed::point<> &set) const = delete;
+  inline typed::multi_pw_aff<Anonymous> to_multi_pw_aff() const;
+  inline typed::union_pw_aff<Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Anonymous> to_union_pw_multi_aff() const;
+  template <typename Domain>
+  inline typed::multi_pw_aff<Domain, Anonymous> unbind_params_insert_domain(const typed::multi_id<Domain> &domain) const;
+  inline typed::multi_pw_aff<Anonymous> union_add(const typed::multi_pw_aff<Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<Anonymous> union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const;
+  inline typed::pw_aff<Anonymous> union_add(const typed::pw_aff<Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Anonymous> union_add(const typed::pw_multi_aff<Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Anonymous> union_add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::pw_aff<Anonymous> union_add(const typed::aff<Anonymous> &pwaff2) const;
+};
+
+template <typename Domain>
+struct pw_aff<Domain, Anonymous> : public isl::pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  pw_aff(const pw_aff<Arg1, Anonymous> &obj) : isl::pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_aff>{}, bool>::type = true>
+  pw_aff(const base &obj) : isl::pw_aff(obj) {}
+ public:
+  static pw_aff from(const isl::pw_aff &obj) {
+    return pw_aff(obj);
+  }
+  inline /* implicit */ pw_aff(const typed::aff<Domain, Anonymous> &aff);
+  inline explicit pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain, Anonymous> add(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::pw_aff<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Domain, Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<Domain, Anonymous> add_constant(long v) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const;
+  inline typed::aff<Domain, Anonymous> as_aff() const;
+  inline typed::map<Domain, Anonymous> as_map() const;
+  inline typed::multi_aff<Domain, Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> as_pw_multi_aff() const;
+  inline typed::set<Domain, Anonymous> as_set() const = delete;
+  inline typed::union_map<Domain, Anonymous> as_union_map() const;
+  inline typed::pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::set<Domain> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::set<Domain> bind(const typed::id<Anonymous> &id) const;
+  inline typed::set<Domain> bind(const std::string &id) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::pw_aff<Domain, Anonymous> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_aff<Domain, Anonymous> ceil() const;
+  inline typed::pw_aff<Domain, Anonymous> coalesce() const;
+  inline typed::pw_aff<Domain, Anonymous> cond(const typed::pw_aff<Domain, Anonymous> &pwaff_true, const typed::pw_aff<Domain, Anonymous> &pwaff_false) const;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const;
+  inline typed::pw_aff<Domain, Anonymous> floor() const;
+  inline typed::set<Domain> ge_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::set<Domain> ge_set(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Domain, Anonymous> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::union_set<Domain> &context) const;
+  inline typed::pw_aff<Domain, Anonymous> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::pw_aff<Domain, Anonymous> gist(const typed::point<Domain> &context) const;
+  inline typed::set<Domain> gt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::set<Domain> gt_set(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> identity() const;
+  inline typed::pw_aff<Domain, Anonymous> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_aff<Domain, Anonymous> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_aff<Domain, Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::set<Domain> le_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::set<Domain> le_set(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::set<Domain> lt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::set<Domain> lt_set(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> max(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> max(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Domain, Anonymous> max(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Anonymous> min(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> min(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Domain, Anonymous> min(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::pw_aff<Domain, Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::pw_aff<Domain, Anonymous> mod(long mod) const;
+  inline typed::pw_aff<Domain, Anonymous> neg() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2>
+  inline typed::pw_aff<Domain2, Anonymous> pullback(const typed::multi_aff<Domain2, Domain> &ma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_aff<Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::pw_aff<Domain2, Anonymous> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::pw_aff<Domain2, Anonymous> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<Domain> &upma) const;
+  inline typed::pw_multi_aff_list<Domain, Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, Anonymous> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<Domain, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<Domain, Anonymous> scale(long v) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<Domain, Anonymous> scale_down(const typed::val<Anonymous> &f) const;
+  inline typed::pw_aff<Domain, Anonymous> scale_down(long f) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Anonymous> space() const;
+  inline typed::multi_pw_aff<Domain, Anonymous> sub(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::pw_aff<Domain, Anonymous> sub(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> sub(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::pw_aff<Domain, Anonymous> sub(const typed::aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<Domain, Anonymous> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_aff<Domain, Anonymous> subtract_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_aff<Domain, Anonymous> subtract_domain(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, Anonymous> to_multi_pw_aff() const;
+  inline typed::union_pw_aff<Domain, Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<Domain, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Anonymous> union_add(const typed::multi_pw_aff<Domain, Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const;
+  inline typed::pw_aff<Domain, Anonymous> union_add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<Domain, Anonymous> union_add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::pw_aff<Domain, Anonymous> union_add(const typed::aff<Domain, Anonymous> &pwaff2) const;
+};
+
+template <typename Domain2, typename Range2>
+struct pw_aff<pair<Domain2, Range2>, Anonymous> : public isl::pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain2, Arg1>{} &&
+              std::is_base_of<Range2, Arg2>{},
+            bool>::type = true>
+  pw_aff(const pw_aff<pair<Arg1, Arg2>, Anonymous> &obj) : isl::pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_aff>{}, bool>::type = true>
+  pw_aff(const base &obj) : isl::pw_aff(obj) {}
+ public:
+  static pw_aff from(const isl::pw_aff &obj) {
+    return pw_aff(obj);
+  }
+  inline /* implicit */ pw_aff(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff);
+  inline explicit pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> add(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> add_constant(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> add_constant(long v) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> add_constant(const typed::multi_val<Anonymous> &mv) const;
+  template <typename Arg1>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> apply(const typed::union_pw_multi_aff<Anonymous, Arg1> &upma2) const;
+  inline typed::aff<pair<Domain2, Range2>, Anonymous> as_aff() const;
+  inline typed::map<pair<Domain2, Range2>, Anonymous> as_map() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Anonymous> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain2, Range2>, Anonymous> as_set() const = delete;
+  inline typed::union_map<pair<Domain2, Range2>, Anonymous> as_union_map() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> at(int pos) const;
+  inline typed::set<pair<Domain2, Range2>> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::set<pair<Domain2, Range2>> bind(const typed::id<Anonymous> &id) const;
+  inline typed::set<pair<Domain2, Range2>> bind(const std::string &id) const;
+  inline typed::pw_aff<Anonymous> bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const;
+  inline typed::pw_aff<Range2, Anonymous> bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> ceil() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> coalesce() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> cond(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_true, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_false) const;
+  inline typed::set<pair<Domain2, Range2>> domain() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Anonymous> &space) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> floor() const;
+  inline typed::set<pair<Domain2, Range2>> ge_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::set<pair<Domain2, Range2>> ge_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> gist(const typed::set<pair<Domain2, Range2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> gist(const typed::union_set<pair<Domain2, Range2>> &context) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> gist(const typed::basic_set<pair<Domain2, Range2>> &context) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> gist(const typed::point<pair<Domain2, Range2>> &context) const;
+  inline typed::set<pair<Domain2, Range2>> gt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::set<pair<Domain2, Range2>> gt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> identity() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_domain(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::set<pair<Domain2, Range2>> le_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::set<pair<Domain2, Range2>> le_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> list() const;
+  inline typed::set<pair<Domain2, Range2>> lt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::set<pair<Domain2, Range2>> lt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> max(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> max(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> max(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> min(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> min(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> min(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::multi_val<Anonymous> min_multi_val() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> mod(const typed::val<Anonymous> &mod) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> mod(long mod) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const;
+  template <typename Arg1, typename Arg2>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> product(const typed::multi_pw_aff<Arg1, Arg2> &multi2) const;
+  template <typename Arg1, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> product(const typed::pw_multi_aff<Arg1, Arg2> &pma2) const;
+  template <typename Arg1>
+  inline typed::pw_aff<Arg1, Anonymous> pullback(const typed::multi_aff<Arg1, pair<Domain2, Range2>> &ma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const;
+  template <typename Arg1>
+  inline typed::pw_aff<Arg1, Anonymous> pullback(const typed::multi_pw_aff<Arg1, pair<Domain2, Range2>> &mpa) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa) const;
+  template <typename Arg1>
+  inline typed::pw_aff<Arg1, Anonymous> pullback(const typed::pw_multi_aff<Arg1, pair<Domain2, Range2>> &pma) const;
+  inline typed::pw_aff<Anonymous> pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const;
+  template <typename Arg1>
+  inline typed::union_pw_aff<Arg1, Anonymous> pullback(const typed::union_pw_multi_aff<Arg1, pair<Domain2, Range2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const;
+  inline typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> range_factor_range() const = delete;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const;
+  template <typename Arg1>
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> &pma2) const;
+  template <typename Arg1>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> &upma2) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> scale(long v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> scale_down(const typed::val<Anonymous> &f) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> scale_down(long f) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain2, Range2>, Anonymous> space() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> sub(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> subtract_domain(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> to_multi_pw_aff() const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> to_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &mupa2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const;
+  inline typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> union_add(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const;
+};
+
+template <>
+struct pw_aff_list<Anonymous> : public isl::pw_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_aff_list() = default;
+  pw_aff_list(const isl::pw_aff_list &obj) : isl::pw_aff_list(obj) {}
+  static pw_aff_list from(const isl::pw_aff_list &obj) {
+    return pw_aff_list(obj);
+  }
+  inline explicit pw_aff_list(const isl::ctx &ctx, int n);
+  inline explicit pw_aff_list(const typed::pw_aff<Anonymous> &el);
+  inline explicit pw_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::pw_aff_list<Anonymous> add(const typed::pw_aff<Anonymous> &el) const;
+  inline typed::pw_aff_list<Anonymous> add(const typed::aff<Anonymous> &el) const;
+  inline typed::pw_aff<Anonymous> at(int index) const;
+  inline typed::pw_aff<Anonymous> get_at(int index) const = delete;
+  inline typed::pw_aff_list<Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::pw_aff<Anonymous>)> &fn) const;
+};
+
+template <typename Domain>
+struct pw_aff_list<Domain, Anonymous> : public isl::pw_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_aff_list() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  pw_aff_list(const pw_aff_list<Arg1, Anonymous> &obj) : isl::pw_aff_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_aff_list>{}, bool>::type = true>
+  pw_aff_list(const base &obj) : isl::pw_aff_list(obj) {}
+ public:
+  static pw_aff_list from(const isl::pw_aff_list &obj) {
+    return pw_aff_list(obj);
+  }
+  inline explicit pw_aff_list(const isl::ctx &ctx, int n);
+  inline explicit pw_aff_list(const typed::pw_aff<Domain, Anonymous> &el);
+  inline explicit pw_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::pw_aff_list<Domain, Anonymous> add(const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::pw_aff_list<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::pw_aff<Domain, Anonymous> at(int index) const;
+  inline typed::pw_aff<Domain, Anonymous> get_at(int index) const = delete;
+  inline typed::pw_aff_list<Domain, Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::pw_aff<Domain, Anonymous>)> &fn) const;
+};
+
+template <typename Domain>
+struct pw_multi_aff<Domain> : public isl::pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  pw_multi_aff(const pw_multi_aff<Arg1> &obj) : isl::pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff>{}, bool>::type = true>
+  pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {}
+ public:
+  static pw_multi_aff from(const isl::pw_multi_aff &obj) {
+    return pw_multi_aff(obj);
+  }
+  inline /* implicit */ pw_multi_aff(const typed::multi_aff<Domain> &ma);
+  inline /* implicit */ pw_multi_aff(const typed::pw_aff<Domain> &pa);
+  inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain> add(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> add(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::pw_multi_aff<Domain> add(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff<Domain> add(const typed::multi_aff<Domain> &pma2) const;
+  inline typed::pw_multi_aff<Domain> add(const typed::pw_aff<Domain> &pma2) const;
+  inline typed::pw_multi_aff<Domain> add_constant(const typed::multi_val<Domain> &mv) const;
+  inline typed::pw_multi_aff<Domain> add_constant(const typed::val<Domain> &v) const;
+  inline typed::pw_multi_aff<Domain> add_constant(long v) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::map<Domain> as_map() const = delete;
+  inline typed::multi_aff<Domain> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::union_map<Domain> as_union_map() const = delete;
+  inline typed::pw_aff<Anonymous> at(int pos) const;
+  inline typed::pw_aff<Domain> get_at(int pos) const = delete;
+  inline typed::set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::pw_multi_aff<Domain> bind_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain> coalesce() const;
+  inline typed::set<> domain() const;
+  inline typed::pw_multi_aff<Domain> extract_pw_multi_aff(const typed::space<Domain> &space) const;
+  inline typed::pw_multi_aff<Domain> gist(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::union_set<> &context) const;
+  inline typed::pw_multi_aff<Domain> gist(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<Domain> gist(const typed::point<> &set) const;
+  inline typed::multi_pw_aff<Domain, Domain> identity() const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::pw_multi_aff<Domain> intersect_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_multi_aff<Domain> intersect_domain(const typed::basic_set<> &set) const = delete;
+  inline typed::pw_multi_aff<Domain> intersect_domain(const typed::point<> &set) const = delete;
+  inline typed::pw_multi_aff<Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_multi_aff<Domain> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<Domain> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<Anonymous> list() const;
+  inline typed::multi_pw_aff<Domain> max(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain> min(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_val<Domain> min_multi_val() const;
+  inline typed::multi_pw_aff<Domain> neg() const;
+  inline typed::pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete;
+  inline typed::pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete;
+  template <typename Range>
+  inline typed::multi_pw_aff<pair<Domain, Range>> product(const typed::multi_pw_aff<Range> &multi2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Domain, Range>> product(const typed::pw_multi_aff<Range> &pma2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Domain, Range>> product(const typed::multi_aff<Range> &pma2) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<pair<Domain, Range>> product(const typed::pw_aff<Range> &pma2) const;
+  inline typed::multi_pw_aff<Domain> pullback(const typed::multi_pw_aff<> &mpa2) const = delete;
+  inline typed::pw_multi_aff<Domain> pullback(const typed::multi_aff<> &ma) const = delete;
+  inline typed::pw_multi_aff<Domain> pullback(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff_list<Domain> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain> range_factor_range() const = delete;
+  inline typed::multi_pw_aff<Domain> range_product(const typed::multi_pw_aff<> &multi2) const = delete;
+  inline typed::multi_union_pw_aff<Domain> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::pw_multi_aff<Domain> range_product(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff<Domain> range_product(const typed::multi_aff<> &pma2) const = delete;
+  inline typed::pw_multi_aff<Domain> range_product(const typed::pw_aff<> &pma2) const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<Domain> scale(const typed::multi_val<Domain> &mv) const;
+  inline typed::pw_multi_aff<Domain> scale(const typed::val<Domain> &v) const;
+  inline typed::pw_multi_aff<Domain> scale(long v) const;
+  inline typed::multi_pw_aff<Domain> scale_down(const typed::multi_val<Domain> &mv) const;
+  inline typed::pw_multi_aff<Domain> scale_down(const typed::val<Domain> &v) const;
+  inline typed::pw_multi_aff<Domain> scale_down(long v) const;
+  inline typed::multi_pw_aff<Domain> set_at(int pos, const typed::pw_aff<Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::multi_pw_aff<Domain> sub(const typed::multi_pw_aff<Domain> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain> sub(const typed::multi_union_pw_aff<Domain> &multi2) const;
+  inline typed::pw_multi_aff<Domain> sub(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff<Domain> sub(const typed::multi_aff<Domain> &pma2) const;
+  inline typed::pw_multi_aff<Domain> sub(const typed::pw_aff<Domain> &pma2) const;
+  inline typed::pw_multi_aff<Domain> subtract_domain(const typed::set<> &set) const = delete;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::pw_multi_aff<Domain> subtract_domain(const typed::basic_set<> &set) const = delete;
+  inline typed::pw_multi_aff<Domain> subtract_domain(const typed::point<> &set) const = delete;
+  inline typed::multi_pw_aff<Domain> to_multi_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain> to_union_pw_multi_aff() const;
+  template <typename Arg1>
+  inline typed::multi_pw_aff<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::multi_pw_aff<Domain> union_add(const typed::multi_pw_aff<Domain> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain> union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const;
+  inline typed::pw_multi_aff<Domain> union_add(const typed::pw_multi_aff<Domain> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff<Domain> union_add(const typed::multi_aff<Domain> &pma2) const;
+  inline typed::pw_multi_aff<Domain> union_add(const typed::pw_aff<Domain> &pma2) const;
+};
+
+template <typename Domain, typename Range>
+struct pw_multi_aff<Domain, Range> : public isl::pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  pw_multi_aff(const pw_multi_aff<Arg1, Arg2> &obj) : isl::pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff>{}, bool>::type = true>
+  pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {}
+ public:
+  static pw_multi_aff from(const isl::pw_multi_aff &obj) {
+    return pw_multi_aff(obj);
+  }
+  inline /* implicit */ pw_multi_aff(const typed::multi_aff<Domain, Range> &ma);
+  inline /* implicit */ pw_multi_aff(const typed::pw_aff<Domain, Range> &pa);
+  inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain, Range> add(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::pw_multi_aff<Domain, Range> add(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::pw_multi_aff<Domain, Range> add(const typed::multi_aff<Domain, Range> &pma2) const;
+  inline typed::pw_multi_aff<Domain, Range> add(const typed::pw_aff<Domain, Range> &pma2) const;
+  inline typed::pw_multi_aff<Domain, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<Domain, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<Domain, Range> add_constant(long v) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_aff<Domain, Range> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> as_pw_multi_aff() const;
+  inline typed::set<Domain, Range> as_set() const = delete;
+  inline typed::union_map<Domain, Range> as_union_map() const;
+  inline typed::pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::pw_aff<Domain, Range> get_at(int pos) const = delete;
+  inline typed::set<Domain> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::pw_multi_aff<Range> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::pw_multi_aff<Domain, Range> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> coalesce() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, Range> extract_pw_multi_aff(const typed::space<Domain, Range> &space) const;
+  inline typed::pw_multi_aff<Domain, Range> gist(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::union_set<Domain> &context) const;
+  inline typed::pw_multi_aff<Domain, Range> gist(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> gist(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> identity() const;
+  inline typed::pw_multi_aff<Domain, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::multi_pw_aff<Domain, Range> max(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Range> min(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_pw_aff<Domain, Range> neg() const;
+  inline typed::pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete;
+  inline typed::pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete;
+  template <typename Domain2, typename Range2>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::multi_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::pw_aff<Domain2, Range2> &pma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, Range> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<Domain> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, Range> pullback(const typed::multi_aff<Domain2, Domain> &ma) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::multi_aff<Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, Range> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::pw_multi_aff<Domain> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff_list<Domain, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_aff<Domain, Range2> &pma2) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_aff<Domain, Range2> &pma2) const;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<Domain, Range> scale(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<Domain, Range> scale(long v) const;
+  inline typed::multi_pw_aff<Domain, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<Domain, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<Domain, Range> scale_down(long v) const;
+  inline typed::multi_pw_aff<Domain, Range> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, Range> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::pw_multi_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> sub(const typed::multi_pw_aff<Domain, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const;
+  inline typed::pw_multi_aff<Domain, Range> sub(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::pw_multi_aff<Domain, Range> sub(const typed::multi_aff<Domain, Range> &pma2) const;
+  inline typed::pw_multi_aff<Domain, Range> sub(const typed::pw_aff<Domain, Range> &pma2) const;
+  inline typed::pw_multi_aff<Domain, Range> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, Range> subtract_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, Range> subtract_domain(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, Range> to_multi_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Range> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<Domain, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const;
+  inline typed::pw_multi_aff<Domain, Range> union_add(const typed::pw_multi_aff<Domain, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::pw_multi_aff<Domain, Range> union_add(const typed::multi_aff<Domain, Range> &pma2) const;
+  inline typed::pw_multi_aff<Domain, Range> union_add(const typed::pw_aff<Domain, Range> &pma2) const;
+};
+
+template <typename Domain2, typename Range2, typename Range>
+struct pw_multi_aff<pair<Domain2, Range2>, Range> : public isl::pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain2, Arg1>{} &&
+              std::is_base_of<Range2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{},
+            bool>::type = true>
+  pw_multi_aff(const pw_multi_aff<pair<Arg1, Arg2>, Arg3> &obj) : isl::pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff>{}, bool>::type = true>
+  pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {}
+ public:
+  static pw_multi_aff from(const isl::pw_multi_aff &obj) {
+    return pw_multi_aff(obj);
+  }
+  inline /* implicit */ pw_multi_aff(const typed::multi_aff<pair<Domain2, Range2>, Range> &ma);
+  inline /* implicit */ pw_multi_aff(const typed::pw_aff<pair<Domain2, Range2>, Range> &pa);
+  inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add_constant(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add_constant(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> add_constant(long v) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> apply(const typed::union_pw_multi_aff<Range, Arg2> &upma2) const;
+  inline typed::map<pair<Domain2, Range2>, Range> as_map() const;
+  inline typed::multi_aff<pair<Domain2, Range2>, Range> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain2, Range2>, Range> as_set() const = delete;
+  inline typed::union_map<pair<Domain2, Range2>, Range> as_union_map() const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Anonymous> at(int pos) const;
+  inline typed::pw_aff<pair<Domain2, Range2>, Range> get_at(int pos) const = delete;
+  inline typed::set<pair<Domain2, Range2>> bind(const typed::multi_id<Range> &tuple) const;
+  inline typed::pw_multi_aff<Range> bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const;
+  inline typed::pw_multi_aff<Range2, Range> bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> coalesce() const;
+  inline typed::set<pair<Domain2, Range2>> domain() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> gist(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> gist(const typed::union_set<pair<Domain2, Range2>> &context) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> gist(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> gist(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> identity() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_domain(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> list() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_val<Range> min_multi_val() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, Domain2> &pma2) const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, Range2>, Range> preimage_domain_wrapped_domain(const typed::pw_aff<Domain3, Domain2> &pma2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::pw_multi_aff<Arg2, Arg3> &pma2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::multi_aff<Arg2, Arg3> &pma2) const;
+  template <typename Arg2, typename Arg3>
+  inline typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> product(const typed::pw_aff<Arg2, Arg3> &pma2) const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<Arg2, Range> pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const;
+  inline typed::multi_pw_aff<Range> pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<Arg2, Range> pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<Arg2, Range> pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Range> pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<Arg2, Range> pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma2) const;
+  inline typed::pw_multi_aff_list<pair<Domain2, Range2>, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> range_factor_domain() const = delete;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> range_factor_range() const = delete;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> range_product(const typed::pw_aff<pair<Domain2, Range2>, Arg2> &pma2) const;
+  inline typed::id<pair<Domain2, Range2>, Range> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> scale(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> scale(long v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> scale_down(const typed::multi_val<Range> &mv) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> scale_down(const typed::val<Range> &v) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> scale_down(long v) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg1>
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain2, Range2>, Range> space() const;
+  inline typed::space<pair<Domain2, Range2>, Range> get_space() const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> sub(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> subtract_domain(const typed::point<pair<Domain2, Range2>> &set) const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> to_multi_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const;
+  inline typed::pw_multi_aff<pair<Domain2, Range2>, Range> union_add(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct pw_multi_aff<Domain, pair<Range, Range2>> : public isl::pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  pw_multi_aff(const pw_multi_aff<Arg1, pair<Arg2, Arg3>> &obj) : isl::pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff>{}, bool>::type = true>
+  pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {}
+ public:
+  static pw_multi_aff from(const isl::pw_multi_aff &obj) {
+    return pw_multi_aff(obj);
+  }
+  inline /* implicit */ pw_multi_aff(const typed::multi_aff<Domain, pair<Range, Range2>> &ma);
+  inline /* implicit */ pw_multi_aff(const typed::pw_aff<Domain, pair<Range, Range2>> &pa);
+  inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add_constant(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> add_constant(long v) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  inline typed::map<Domain, pair<Range, Range2>> as_map() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::set<Domain, pair<Range, Range2>> as_set() const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> as_union_map() const;
+  inline typed::pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::pw_aff<Domain, pair<Range, Range2>> get_at(int pos) const = delete;
+  inline typed::set<Domain> bind(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> bind_domain(const typed::multi_id<Domain> &tuple) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> bind_domain_wrapped_domain(const typed::multi_id<> &tuple) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::union_set<Domain> &context) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> identity() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::point<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> max(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> max_multi_val() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> min(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> min_multi_val() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> neg() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &pma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::multi_aff<> &pma2) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_aff<> &pma2) const = delete;
+  template <typename Domain2, typename Arg3>
+  inline typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::multi_pw_aff<Domain2, Arg3> &multi2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::pw_multi_aff<Domain2, Arg3> &pma2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::multi_aff<Domain2, Arg3> &pma2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::pw_aff<Domain2, Arg3> &pma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, Domain> &ma) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff_list<Domain, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<Domain, Range> range_factor_domain() const;
+  inline typed::pw_multi_aff<Domain, Range2> range_factor_range() const;
+  template <typename Arg3>
+  inline typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_pw_aff<Domain, Arg3> &multi2) const;
+  template <typename Arg3>
+  inline typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_union_pw_aff<Domain, Arg3> &multi2) const;
+  template <typename Arg3>
+  inline typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::pw_multi_aff<Domain, Arg3> &pma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_aff<Domain, Arg3> &pma2) const;
+  template <typename Arg3>
+  inline typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::pw_aff<Domain, Arg3> &pma2) const;
+  inline typed::id<Domain, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> scale(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> scale(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> scale(long v) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> scale_down(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> scale_down(long v) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> space() const;
+  inline typed::space<Domain, pair<Range, Range2>> get_space() const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> sub(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> sub(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::set<Domain> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::basic_set<Domain> &set) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::point<Domain> &set) const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> to_multi_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &mpa2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &mupa2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> : public isl::pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  pw_multi_aff(const pw_multi_aff<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff>{}, bool>::type = true>
+  pw_multi_aff(const base &obj) : isl::pw_multi_aff(obj) {}
+ public:
+  static pw_multi_aff from(const isl::pw_multi_aff &obj) {
+    return pw_multi_aff(obj);
+  }
+  inline /* implicit */ pw_multi_aff(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &ma);
+  inline /* implicit */ pw_multi_aff(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pa);
+  inline explicit pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add_constant(long v) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> as_map() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_aff() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::set<pair<T1, T2>, pair<Range, Range2>> as_set() const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> as_union_map() const;
+  inline typed::pw_aff<pair<T1, T2>, Anonymous> at(int pos) const;
+  inline typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> get_at(int pos) const = delete;
+  inline typed::set<pair<T1, T2>> bind(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::pw_multi_aff<T2, pair<Range, Range2>> bind_domain_wrapped_domain(const typed::multi_id<T1> &tuple) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::set<pair<T1, T2>> domain() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_set<pair<T1, T2>> &context) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::point<pair<T1, T2>> &set) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> identity() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::point<pair<T1, T2>> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  inline typed::pw_aff_list<pair<T1, T2>, Anonymous> list() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> max(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> max_multi_val() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> min(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_val<pair<Range, Range2>> min_multi_val() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> neg() const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &pma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, T1> &pma2) const;
+  template <typename Domain3>
+  inline typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_aff<Domain3, T1> &pma2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::multi_pw_aff<Domain2, Arg2> &multi2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::pw_multi_aff<Domain2, Arg2> &pma2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::multi_aff<Domain2, Arg2> &pma2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::pw_aff<Domain2, Arg2> &pma2) const;
+  template <typename Domain2>
+  inline typed::multi_pw_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa2) const;
+  inline typed::multi_pw_aff<pair<Range, Range2>> pullback(const typed::multi_pw_aff<pair<T1, T2>> &mpa2) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<pair<T1, T2>> &pma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const;
+  inline typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, Range2> range_factor_range() const;
+  template <typename Arg2>
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_pw_aff<pair<T1, T2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_union_pw_aff<pair<T1, T2>, Arg2> &multi2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &pma2) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::pw_aff<pair<T1, T2>, Arg2> &pma2) const;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> scale(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> scale(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> scale(long v) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(const typed::val<pair<Range, Range2>> &v) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> scale_down(long v) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> set_at(int pos, const typed::pw_aff<pair<T1, T2>, Anonymous> &el) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> set_at(int pos, const typed::union_pw_aff<pair<T1, T2>, Anonymous> &el) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> space() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> get_space() const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::set<pair<T1, T2>> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::basic_set<pair<T1, T2>> &set) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::point<pair<T1, T2>> &set) const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> to_multi_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> to_union_pw_multi_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mpa2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mupa2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const;
+};
+
+template <typename Domain>
+struct pw_multi_aff_list<Domain> : public isl::pw_multi_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff_list() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  pw_multi_aff_list(const pw_multi_aff_list<Arg1> &obj) : isl::pw_multi_aff_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff_list>{}, bool>::type = true>
+  pw_multi_aff_list(const base &obj) : isl::pw_multi_aff_list(obj) {}
+ public:
+  static pw_multi_aff_list from(const isl::pw_multi_aff_list &obj) {
+    return pw_multi_aff_list(obj);
+  }
+  inline explicit pw_multi_aff_list(const isl::ctx &ctx, int n);
+  inline explicit pw_multi_aff_list(const typed::pw_multi_aff<Domain> &el);
+  inline explicit pw_multi_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::pw_multi_aff_list<Domain> add(const typed::pw_multi_aff<Domain> &el) const;
+  inline typed::pw_multi_aff_list<Domain> add(const typed::multi_aff<Domain> &el) const;
+  inline typed::pw_multi_aff_list<Domain> add(const typed::pw_aff<Domain> &el) const;
+  inline typed::pw_multi_aff<Domain> at(int index) const;
+  inline typed::pw_multi_aff<Domain> get_at(int index) const = delete;
+  inline typed::pw_multi_aff_list<Domain> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::pw_multi_aff<Domain>)> &fn) const;
+};
+
+template <typename Domain, typename Range>
+struct pw_multi_aff_list<Domain, Range> : public isl::pw_multi_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  pw_multi_aff_list() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  pw_multi_aff_list(const pw_multi_aff_list<Arg1, Arg2> &obj) : isl::pw_multi_aff_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::pw_multi_aff_list>{}, bool>::type = true>
+  pw_multi_aff_list(const base &obj) : isl::pw_multi_aff_list(obj) {}
+ public:
+  static pw_multi_aff_list from(const isl::pw_multi_aff_list &obj) {
+    return pw_multi_aff_list(obj);
+  }
+  inline explicit pw_multi_aff_list(const isl::ctx &ctx, int n);
+  inline explicit pw_multi_aff_list(const typed::pw_multi_aff<Domain, Range> &el);
+  inline explicit pw_multi_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::pw_multi_aff_list<Domain, Range> add(const typed::pw_multi_aff<Domain, Range> &el) const;
+  inline typed::pw_multi_aff_list<Domain, Range> add(const typed::multi_aff<Domain, Range> &el) const;
+  inline typed::pw_multi_aff_list<Domain, Range> add(const typed::pw_aff<Domain, Range> &el) const;
+  inline typed::pw_multi_aff<Domain, Range> at(int index) const;
+  inline typed::pw_multi_aff<Domain, Range> get_at(int index) const = delete;
+  inline typed::pw_multi_aff_list<Domain, Range> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::pw_multi_aff<Domain, Range>)> &fn) const;
+};
+
+template <>
+struct set<> : public isl::set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  set() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::set>{}, bool>::type = true>
+  set(const base &obj) : isl::set(obj) {}
+ public:
+  static set from(const isl::set &obj) {
+    return set(obj);
+  }
+  inline /* implicit */ set(const typed::basic_set<> &bset);
+  inline /* implicit */ set(const typed::point<> &pnt);
+  inline explicit set(const isl::ctx &ctx, const std::string &str);
+  inline typed::set<> apply(const typed::map<> &map) const = delete;
+  inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete;
+  inline typed::set<> apply(const typed::basic_map<> &map) const = delete;
+  inline typed::pw_multi_aff<> as_pw_multi_aff() const = delete;
+  inline typed::set<> as_set() const = delete;
+  inline typed::set<> bind(const typed::multi_id<> &tuple) const = delete;
+  inline typed::set<> coalesce() const;
+  inline typed::set<> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<>)> &test) const;
+  inline typed::set<> extract_set(const typed::space<> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<>)> &fn) const;
+  inline typed::set<> gist(const typed::set<> &context) const;
+  inline typed::union_set<> gist(const typed::union_set<> &context) const;
+  inline typed::set<> gist(const typed::basic_set<> &context) const;
+  inline typed::set<> gist(const typed::point<> &context) const;
+  inline typed::map<> identity() const = delete;
+  inline typed::pw_aff<Anonymous> indicator_function() const;
+  inline typed::map<> insert_domain(const typed::space<> &domain) const = delete;
+  inline typed::set<> intersect(const typed::set<> &set2) const;
+  inline typed::union_set<> intersect(const typed::union_set<> &uset2) const;
+  inline typed::set<> intersect(const typed::basic_set<> &set2) const;
+  inline typed::set<> intersect(const typed::point<> &set2) const;
+  inline typed::set<> intersect_params(const typed::set<> &params) const = delete;
+  inline typed::set<> intersect_params(const typed::basic_set<> &params) const = delete;
+  inline typed::set<> intersect_params(const typed::point<> &params) const = delete;
+  inline typed::set<> lexmax() const = delete;
+  inline typed::pw_multi_aff<> lexmax_pw_multi_aff() const = delete;
+  inline typed::set<> lexmin() const = delete;
+  inline typed::pw_multi_aff<> lexmin_pw_multi_aff() const = delete;
+  inline typed::set<> lower_bound(const typed::multi_pw_aff<> &lower) const = delete;
+  inline typed::set<> lower_bound(const typed::multi_val<> &lower) const = delete;
+  inline typed::multi_pw_aff<> max_multi_pw_aff() const = delete;
+  inline typed::val<> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<> min_multi_pw_aff() const = delete;
+  inline typed::val<> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::set<> params() const = delete;
+  inline typed::multi_val<> plain_multi_val_if_fixed() const = delete;
+  inline typed::multi_val<> get_plain_multi_val_if_fixed() const = delete;
+  inline typed::set<> preimage(const typed::multi_aff<> &ma) const = delete;
+  inline typed::set<> preimage(const typed::multi_pw_aff<> &mpa) const = delete;
+  inline typed::set<> preimage(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::set<> product(const typed::set<> &set2) const = delete;
+  inline typed::set<> product(const typed::basic_set<> &set2) const = delete;
+  inline typed::set<> product(const typed::point<> &set2) const = delete;
+  inline typed::set<> project_out_all_params() const;
+  inline typed::set<> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<> project_out_param(const std::string &id) const;
+  inline typed::set<> project_out_param(const typed::id_list<Anonymous> &list) const;
+  inline typed::pw_multi_aff<> pw_multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::fixed_box<> simple_fixed_box_hull() const = delete;
+  inline typed::fixed_box<> get_simple_fixed_box_hull() const = delete;
+  inline typed::space<> space() const;
+  inline typed::space<> get_space() const = delete;
+  inline typed::val<> get_stride(int pos) const = delete;
+  inline typed::set<> subtract(const typed::set<> &set2) const;
+  inline typed::union_set<> subtract(const typed::union_set<> &uset2) const;
+  inline typed::set<> subtract(const typed::basic_set<> &set2) const;
+  inline typed::set<> subtract(const typed::point<> &set2) const;
+  inline typed::union_set<> to_union_set() const;
+  inline typed::map<> translation() const = delete;
+  template <typename Domain>
+  inline typed::set<Domain> unbind_params(const typed::multi_id<Domain> &tuple) const;
+  inline typed::map<> unbind_params_insert_domain(const typed::multi_id<> &domain) const = delete;
+  inline typed::set<> unite(const typed::set<> &set2) const;
+  inline typed::union_set<> unite(const typed::union_set<> &uset2) const;
+  inline typed::set<> unite(const typed::basic_set<> &set2) const;
+  inline typed::set<> unite(const typed::point<> &set2) const;
+  static inline typed::set<> universe(const typed::space<> &space);
+  inline typed::map<> unwrap() const = delete;
+  inline typed::set<> upper_bound(const typed::multi_pw_aff<> &upper) const = delete;
+  inline typed::set<> upper_bound(const typed::multi_val<> &upper) const = delete;
+};
+
+template <typename Domain>
+struct set<Domain> : public isl::set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  set() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  set(const set<Arg1> &obj) : isl::set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::set>{}, bool>::type = true>
+  set(const base &obj) : isl::set(obj) {}
+ public:
+  static set from(const isl::set &obj) {
+    return set(obj);
+  }
+  inline /* implicit */ set(const typed::basic_set<Domain> &bset);
+  inline /* implicit */ set(const typed::point<Domain> &pnt);
+  inline explicit set(const isl::ctx &ctx, const std::string &str);
+  template <typename Range>
+  inline typed::set<Range> apply(const typed::map<Domain, Range> &map) const;
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::union_map<Domain, Range> &umap) const;
+  template <typename Range>
+  inline typed::set<Range> apply(const typed::basic_map<Domain, Range> &map) const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<Domain> &tuple) const;
+  inline typed::set<Domain> coalesce() const;
+  inline typed::set<Domain> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<Domain>)> &test) const;
+  inline typed::set<Domain> extract_set(const typed::space<Domain> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<Domain>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<Domain>)> &fn) const;
+  inline typed::set<Domain> gist(const typed::set<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::union_set<Domain> &context) const;
+  inline typed::set<Domain> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::set<Domain> gist(const typed::point<Domain> &context) const;
+  inline typed::map<Domain, Domain> identity() const;
+  inline typed::pw_aff<Domain, Anonymous> indicator_function() const;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> insert_domain(const typed::space<Arg1> &domain) const;
+  inline typed::set<Domain> intersect(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> intersect(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> intersect(const typed::basic_set<Domain> &set2) const;
+  inline typed::set<Domain> intersect(const typed::point<Domain> &set2) const;
+  inline typed::set<Domain> intersect_params(const typed::set<> &params) const;
+  inline typed::set<Domain> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::set<Domain> intersect_params(const typed::point<> &params) const;
+  inline typed::set<Domain> lexmax() const;
+  inline typed::pw_multi_aff<Domain> lexmax_pw_multi_aff() const;
+  inline typed::set<Domain> lexmin() const;
+  inline typed::pw_multi_aff<Domain> lexmin_pw_multi_aff() const;
+  inline typed::set<Domain> lower_bound(const typed::multi_pw_aff<Domain> &lower) const;
+  inline typed::set<Domain> lower_bound(const typed::multi_val<Domain> &lower) const;
+  inline typed::multi_pw_aff<Domain> max_multi_pw_aff() const;
+  inline typed::val<Domain> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<Domain> min_multi_pw_aff() const;
+  inline typed::val<Domain> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::set<> params() const;
+  inline typed::multi_val<Domain> plain_multi_val_if_fixed() const;
+  inline typed::multi_val<Domain> get_plain_multi_val_if_fixed() const = delete;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range>
+  inline typed::set<pair<Domain, Range>> product(const typed::set<Range> &set2) const;
+  template <typename Range>
+  inline typed::set<pair<Domain, Range>> product(const typed::basic_set<Range> &set2) const;
+  template <typename Range>
+  inline typed::set<pair<Domain, Range>> product(const typed::point<Range> &set2) const;
+  inline typed::set<Domain> project_out_all_params() const;
+  inline typed::set<Domain> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<Domain> project_out_param(const std::string &id) const;
+  inline typed::set<Domain> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Range>
+  inline typed::pw_multi_aff<Domain, Range> pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const;
+  inline typed::fixed_box<Domain> simple_fixed_box_hull() const;
+  inline typed::fixed_box<Domain> get_simple_fixed_box_hull() const = delete;
+  inline typed::space<Domain> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::val<Domain> get_stride(int pos) const = delete;
+  inline typed::set<Domain> subtract(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> subtract(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> subtract(const typed::basic_set<Domain> &set2) const;
+  inline typed::set<Domain> subtract(const typed::point<Domain> &set2) const;
+  inline typed::union_set<Domain> to_union_set() const;
+  inline typed::map<Domain, Domain> translation() const;
+  inline typed::set<Domain> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg1>
+  inline typed::map<Arg1, Domain> unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const;
+  inline typed::set<Domain> unite(const typed::set<Domain> &set2) const;
+  inline typed::union_set<Domain> unite(const typed::union_set<Domain> &uset2) const;
+  inline typed::set<Domain> unite(const typed::basic_set<Domain> &set2) const;
+  inline typed::set<Domain> unite(const typed::point<Domain> &set2) const;
+  static inline typed::set<Domain> universe(const typed::space<Domain> &space);
+  inline typed::map<Domain> unwrap() const = delete;
+  inline typed::set<Domain> upper_bound(const typed::multi_pw_aff<Domain> &upper) const;
+  inline typed::set<Domain> upper_bound(const typed::multi_val<Domain> &upper) const;
+};
+
+template <typename Domain, typename Range>
+struct set<pair<Domain, Range>> : public isl::set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  set() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  set(const set<pair<Arg1, Arg2>> &obj) : isl::set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::set>{}, bool>::type = true>
+  set(const base &obj) : isl::set(obj) {}
+ public:
+  static set from(const isl::set &obj) {
+    return set(obj);
+  }
+  inline /* implicit */ set(const typed::basic_set<pair<Domain, Range>> &bset);
+  inline /* implicit */ set(const typed::point<pair<Domain, Range>> &pnt);
+  inline explicit set(const isl::ctx &ctx, const std::string &str);
+  template <typename Arg2>
+  inline typed::set<Arg2> apply(const typed::map<pair<Domain, Range>, Arg2> &map) const;
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const;
+  template <typename Arg2>
+  inline typed::set<Arg2> apply(const typed::basic_map<pair<Domain, Range>, Arg2> &map) const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> as_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> as_set() const;
+  inline typed::set<> bind(const typed::multi_id<pair<Domain, Range>> &tuple) const;
+  inline typed::set<pair<Domain, Range>> coalesce() const;
+  inline typed::set<pair<Domain, Range>> detect_equalities() const;
+  inline bool every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const;
+  inline typed::set<pair<Domain, Range>> extract_set(const typed::space<pair<Domain, Range>> &space) const;
+  inline void foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const;
+  inline typed::set<pair<Domain, Range>> gist(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::union_set<pair<Domain, Range>> &context) const;
+  inline typed::set<pair<Domain, Range>> gist(const typed::basic_set<pair<Domain, Range>> &context) const;
+  inline typed::set<pair<Domain, Range>> gist(const typed::point<pair<Domain, Range>> &context) const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> identity() const;
+  inline typed::pw_aff<pair<Domain, Range>, Anonymous> indicator_function() const;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> insert_domain(const typed::space<Arg2> &domain) const;
+  inline typed::set<pair<Domain, Range>> intersect(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> intersect(const typed::basic_set<pair<Domain, Range>> &set2) const;
+  inline typed::set<pair<Domain, Range>> intersect(const typed::point<pair<Domain, Range>> &set2) const;
+  inline typed::set<pair<Domain, Range>> intersect_params(const typed::set<> &params) const;
+  inline typed::set<pair<Domain, Range>> intersect_params(const typed::basic_set<> &params) const;
+  inline typed::set<pair<Domain, Range>> intersect_params(const typed::point<> &params) const;
+  inline typed::set<pair<Domain, Range>> lexmax() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmax_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lexmin() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>> lexmin_pw_multi_aff() const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const;
+  inline typed::set<pair<Domain, Range>> lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const;
+  inline typed::multi_pw_aff<pair<Domain, Range>> max_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> max_val(const typed::aff<> &obj) const = delete;
+  inline typed::multi_pw_aff<pair<Domain, Range>> min_multi_pw_aff() const;
+  inline typed::val<pair<Domain, Range>> min_val(const typed::aff<> &obj) const = delete;
+  inline typed::set<> params() const;
+  inline typed::multi_val<pair<Domain, Range>> plain_multi_val_if_fixed() const;
+  inline typed::multi_val<pair<Domain, Range>> get_plain_multi_val_if_fixed() const = delete;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::set<Domain2> preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg2>
+  inline typed::set<pair<pair<Domain, Range>, Arg2>> product(const typed::set<Arg2> &set2) const;
+  template <typename Arg2>
+  inline typed::set<pair<pair<Domain, Range>, Arg2>> product(const typed::basic_set<Arg2> &set2) const;
+  template <typename Arg2>
+  inline typed::set<pair<pair<Domain, Range>, Arg2>> product(const typed::point<Arg2> &set2) const;
+  inline typed::set<pair<Domain, Range>> project_out_all_params() const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id<Anonymous> &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const std::string &id) const;
+  inline typed::set<pair<Domain, Range>> project_out_param(const typed::id_list<Anonymous> &list) const;
+  template <typename Arg2>
+  inline typed::pw_multi_aff<pair<Domain, Range>, Arg2> pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const;
+  inline typed::fixed_box<pair<Domain, Range>> simple_fixed_box_hull() const;
+  inline typed::fixed_box<pair<Domain, Range>> get_simple_fixed_box_hull() const = delete;
+  inline typed::space<pair<Domain, Range>> space() const;
+  inline typed::space<pair<Domain, Range>> get_space() const = delete;
+  inline typed::val<pair<Domain, Range>> get_stride(int pos) const = delete;
+  inline typed::set<pair<Domain, Range>> subtract(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> subtract(const typed::basic_set<pair<Domain, Range>> &set2) const;
+  inline typed::set<pair<Domain, Range>> subtract(const typed::point<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> to_union_set() const;
+  inline typed::map<pair<Domain, Range>, pair<Domain, Range>> translation() const;
+  inline typed::set<pair<Domain, Range>> unbind_params(const typed::multi_id<> &tuple) const = delete;
+  template <typename Arg2>
+  inline typed::map<Arg2, pair<Domain, Range>> unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::set<pair<Domain, Range>> &set2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::basic_set<pair<Domain, Range>> &set2) const;
+  inline typed::set<pair<Domain, Range>> unite(const typed::point<pair<Domain, Range>> &set2) const;
+  static inline typed::set<pair<Domain, Range>> universe(const typed::space<pair<Domain, Range>> &space);
+  inline typed::map<Domain, Range> unwrap() const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const;
+  inline typed::set<pair<Domain, Range>> upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const;
+};
+
+template <>
+struct space<> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  template <typename Domain>
+  inline typed::space<Domain> add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const;
+  template <typename Domain>
+  inline typed::space<Domain> add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
+  inline typed::space<> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<> add_param(const std::string &id) const;
+  template <typename Domain>
+  inline typed::space<Domain> add_unnamed_tuple(unsigned int dim) const;
+  inline typed::space<> curry() const = delete;
+  inline typed::space<> domain() const = delete;
+  inline typed::multi_aff<> domain_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<> domain_map_pw_multi_aff() const = delete;
+  inline typed::id<> get_domain_tuple_id() const = delete;
+  inline typed::space<> flatten_domain() const = delete;
+  inline typed::space<> flatten_range() const = delete;
+  inline typed::multi_aff<> identity_multi_aff_on_domain() const = delete;
+  inline typed::multi_pw_aff<> identity_multi_pw_aff_on_domain() const = delete;
+  inline typed::pw_multi_aff<> identity_pw_multi_aff_on_domain() const = delete;
+  inline typed::space<> map_from_set() const = delete;
+  inline typed::multi_aff<> multi_aff(const typed::aff_list<> &list) const = delete;
+  inline typed::multi_aff<> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::multi_id<> multi_id(const typed::id_list<> &list) const = delete;
+  inline typed::multi_pw_aff<> multi_pw_aff(const typed::pw_aff_list<> &list) const = delete;
+  inline typed::multi_union_pw_aff<> multi_union_pw_aff(const typed::union_pw_aff_list<> &list) const = delete;
+  inline typed::multi_val<> multi_val(const typed::val_list<> &list) const = delete;
+  inline typed::aff<Anonymous> param_aff_on_domain(const typed::id<Anonymous> &id) const;
+  inline typed::aff<Anonymous> param_aff_on_domain(const std::string &id) const;
+  inline typed::space<> params() const = delete;
+  inline typed::space<> product(const typed::space<> &right) const = delete;
+  inline typed::space<> range() const = delete;
+  inline typed::multi_aff<> range_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<> range_map_pw_multi_aff() const = delete;
+  inline typed::space<> range_reverse() const = delete;
+  inline typed::id<> get_range_tuple_id() const = delete;
+  inline typed::space<> reverse() const = delete;
+  inline typed::space<> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::space<> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<> uncurry() const = delete;
+  static inline typed::space<> unit(const isl::ctx &ctx);
+  inline typed::map<> universe_map() const = delete;
+  inline typed::set<> universe_set() const;
+  inline typed::space<> unwrap() const = delete;
+  inline typed::space<> wrap() const = delete;
+  inline typed::aff<> zero_aff_on_domain() const = delete;
+  inline typed::multi_aff<> zero_multi_aff() const = delete;
+  inline typed::multi_pw_aff<> zero_multi_pw_aff() const = delete;
+  inline typed::multi_union_pw_aff<> zero_multi_union_pw_aff() const = delete;
+  inline typed::multi_val<> zero_multi_val() const = delete;
+};
+
+template <typename Domain>
+struct space<Domain> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  space(const space<Arg1> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  template <typename Range>
+  inline typed::space<Domain, Range> add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const;
+  template <typename Range>
+  inline typed::space<Domain, Range> add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
+  inline typed::space<Domain> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<Domain> add_param(const std::string &id) const;
+  template <typename Range>
+  inline typed::space<Domain, Range> add_unnamed_tuple(unsigned int dim) const;
+  inline typed::space<Domain> curry() const = delete;
+  inline typed::space<> domain() const;
+  inline typed::multi_aff<Domain> domain_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<Domain> domain_map_pw_multi_aff() const = delete;
+  inline typed::id<Domain> get_domain_tuple_id() const = delete;
+  inline typed::space<Domain> flatten_domain() const = delete;
+  inline typed::space<Domain> flatten_range() const = delete;
+  inline typed::multi_aff<Domain, Domain> identity_multi_aff_on_domain() const;
+  inline typed::multi_pw_aff<Domain, Domain> identity_multi_pw_aff_on_domain() const;
+  inline typed::pw_multi_aff<Domain, Domain> identity_pw_multi_aff_on_domain() const;
+  inline typed::space<Domain, Domain> map_from_set() const;
+  inline typed::multi_aff<Domain> multi_aff(const typed::aff_list<Anonymous> &list) const;
+  template <typename Range>
+  inline typed::multi_aff<Domain, Range> multi_aff_on_domain(const typed::multi_val<Range> &mv) const;
+  inline typed::multi_id<Domain> multi_id(const typed::id_list<Anonymous> &list) const;
+  inline typed::multi_pw_aff<Domain> multi_pw_aff(const typed::pw_aff_list<Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<Domain> multi_union_pw_aff(const typed::union_pw_aff_list<Anonymous> &list) const;
+  inline typed::multi_val<Domain> multi_val(const typed::val_list<Anonymous> &list) const;
+  inline typed::aff<Domain, Anonymous> param_aff_on_domain(const typed::id<Anonymous> &id) const;
+  inline typed::aff<Domain, Anonymous> param_aff_on_domain(const std::string &id) const;
+  inline typed::space<> params() const;
+  template <typename Range>
+  inline typed::space<pair<Domain, Range>> product(const typed::space<Range> &right) const;
+  inline typed::space<Domain> range() const = delete;
+  inline typed::multi_aff<Domain> range_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<Domain> range_map_pw_multi_aff() const = delete;
+  inline typed::space<Domain> range_reverse() const = delete;
+  inline typed::id<Domain> get_range_tuple_id() const = delete;
+  inline typed::space<Domain> reverse() const = delete;
+  inline typed::space<Domain> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<Domain> set_domain_tuple(const std::string &id) const = delete;
+  template <typename Domain2>
+  inline typed::space<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::space<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain> uncurry() const = delete;
+  static inline typed::space<Domain> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<Domain> universe_map() const = delete;
+  inline typed::set<Domain> universe_set() const;
+  inline typed::space<Domain> unwrap() const = delete;
+  inline typed::space<Domain> wrap() const = delete;
+  inline typed::aff<Domain, Anonymous> zero_aff_on_domain() const;
+  inline typed::multi_aff<Domain> zero_multi_aff() const;
+  inline typed::multi_pw_aff<Domain> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<Domain> zero_multi_val() const;
+};
+
+template <typename Domain, typename Range>
+struct space<Domain, Range> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  space(const space<Arg1, Arg2> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  inline typed::space<Domain, Range> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<Domain, Range> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<Domain, Range> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<Domain, Range> add_param(const std::string &id) const;
+  inline typed::space<Domain, Range> add_unnamed_tuple(unsigned int dim) const = delete;
+  inline typed::space<Domain, Range> curry() const = delete;
+  inline typed::space<Domain> domain() const;
+  inline typed::multi_aff<pair<Domain, Range>, Domain> domain_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Domain> domain_map_pw_multi_aff() const;
+  inline typed::id<Domain, Range> get_domain_tuple_id() const = delete;
+  inline typed::space<Domain, Range> flatten_domain() const = delete;
+  inline typed::space<Domain, Range> flatten_range() const = delete;
+  inline typed::multi_aff<Domain, Range> identity_multi_aff_on_domain() const = delete;
+  inline typed::multi_pw_aff<Domain, Range> identity_multi_pw_aff_on_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, Range> identity_pw_multi_aff_on_domain() const = delete;
+  inline typed::space<Domain, Range> map_from_set() const = delete;
+  inline typed::multi_aff<Domain, Range> multi_aff(const typed::aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_aff<Domain, Range> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::multi_id<Domain, Range> multi_id(const typed::id_list<> &list) const = delete;
+  inline typed::multi_pw_aff<Domain, Range> multi_pw_aff(const typed::pw_aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<Domain, Range> multi_union_pw_aff(const typed::union_pw_aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_val<Domain, Range> multi_val(const typed::val_list<> &list) const = delete;
+  inline typed::aff<Domain, Range> param_aff_on_domain(const typed::id<> &id) const = delete;
+  inline typed::aff<Domain, Range> param_aff_on_domain(const std::string &id) const = delete;
+  inline typed::space<> params() const;
+  template <typename Domain2, typename Range2>
+  inline typed::space<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::space<Domain2, Range2> &right) const;
+  inline typed::space<Range> range() const;
+  inline typed::multi_aff<pair<Domain, Range>, Range> range_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range> range_map_pw_multi_aff() const;
+  inline typed::space<Domain, Range> range_reverse() const = delete;
+  inline typed::id<Domain, Range> get_range_tuple_id() const = delete;
+  inline typed::space<Range, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::space<Domain2, Range> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::space<Domain2, Range> set_domain_tuple(const std::string &id) const;
+  template <typename Range2>
+  inline typed::space<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::space<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<Domain, Range> uncurry() const = delete;
+  static inline typed::space<Domain, Range> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<Domain, Range> universe_map() const;
+  inline typed::set<Domain, Range> universe_set() const = delete;
+  inline typed::space<Domain, Range> unwrap() const = delete;
+  inline typed::space<pair<Domain, Range>> wrap() const;
+  inline typed::aff<Domain, Range> zero_aff_on_domain() const = delete;
+  inline typed::multi_aff<Domain, Range> zero_multi_aff() const;
+  inline typed::multi_pw_aff<Domain, Range> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain, Range> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<Domain, Range> zero_multi_val() const = delete;
+};
+
+template <typename Domain, typename Range>
+struct space<pair<Domain, Range>> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  space(const space<pair<Arg1, Arg2>> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  template <typename Arg2>
+  inline typed::space<pair<Domain, Range>, Arg2> add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const;
+  template <typename Arg2>
+  inline typed::space<pair<Domain, Range>, Arg2> add_named_tuple(const std::string &tuple_id, unsigned int dim) const;
+  inline typed::space<pair<Domain, Range>> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<pair<Domain, Range>> add_param(const std::string &id) const;
+  template <typename Arg2>
+  inline typed::space<pair<Domain, Range>, Arg2> add_unnamed_tuple(unsigned int dim) const;
+  inline typed::space<pair<Domain, Range>> curry() const = delete;
+  inline typed::space<> domain() const;
+  inline typed::multi_aff<pair<Domain, Range>> domain_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<pair<Domain, Range>> domain_map_pw_multi_aff() const = delete;
+  inline typed::id<pair<Domain, Range>> get_domain_tuple_id() const = delete;
+  inline typed::space<pair<Domain, Range>> flatten_domain() const = delete;
+  inline typed::space<pair<Domain, Range>> flatten_range() const = delete;
+  inline typed::multi_aff<pair<Domain, Range>, pair<Domain, Range>> identity_multi_aff_on_domain() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, pair<Domain, Range>> identity_multi_pw_aff_on_domain() const;
+  inline typed::pw_multi_aff<pair<Domain, Range>, pair<Domain, Range>> identity_pw_multi_aff_on_domain() const;
+  inline typed::space<pair<Domain, Range>, pair<Domain, Range>> map_from_set() const;
+  inline typed::multi_aff<pair<Domain, Range>> multi_aff(const typed::aff_list<Anonymous> &list) const;
+  template <typename Arg2>
+  inline typed::multi_aff<pair<Domain, Range>, Arg2> multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const;
+  inline typed::multi_id<pair<Domain, Range>> multi_id(const typed::id_list<Anonymous> &list) const;
+  inline typed::multi_pw_aff<pair<Domain, Range>> multi_pw_aff(const typed::pw_aff_list<Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>> multi_union_pw_aff(const typed::union_pw_aff_list<Anonymous> &list) const;
+  inline typed::multi_val<pair<Domain, Range>> multi_val(const typed::val_list<Anonymous> &list) const;
+  inline typed::aff<pair<Domain, Range>, Anonymous> param_aff_on_domain(const typed::id<Anonymous> &id) const;
+  inline typed::aff<pair<Domain, Range>, Anonymous> param_aff_on_domain(const std::string &id) const;
+  inline typed::space<> params() const;
+  template <typename Arg2>
+  inline typed::space<pair<pair<Domain, Range>, Arg2>> product(const typed::space<Arg2> &right) const;
+  inline typed::space<pair<Domain, Range>> range() const = delete;
+  inline typed::multi_aff<pair<Domain, Range>> range_map_multi_aff() const = delete;
+  inline typed::pw_multi_aff<pair<Domain, Range>> range_map_pw_multi_aff() const = delete;
+  inline typed::space<pair<Domain, Range>> range_reverse() const = delete;
+  inline typed::id<pair<Domain, Range>> get_range_tuple_id() const = delete;
+  inline typed::space<pair<Domain, Range>> reverse() const = delete;
+  inline typed::space<pair<Domain, Range>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<pair<Domain, Range>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<Domain, Range>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<pair<Domain, Range>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<Domain, Range>> uncurry() const = delete;
+  static inline typed::space<pair<Domain, Range>> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<pair<Domain, Range>> universe_map() const = delete;
+  inline typed::set<pair<Domain, Range>> universe_set() const;
+  inline typed::space<Domain, Range> unwrap() const;
+  inline typed::space<pair<Domain, Range>> wrap() const = delete;
+  inline typed::aff<pair<Domain, Range>, Anonymous> zero_aff_on_domain() const;
+  inline typed::multi_aff<pair<Domain, Range>> zero_multi_aff() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<pair<Domain, Range>> zero_multi_val() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct space<pair<Domain, Range>, Range2> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  space(const space<pair<Arg1, Arg2>, Arg3> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  inline typed::space<pair<Domain, Range>, Range2> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<pair<Domain, Range>, Range2> add_param(const std::string &id) const;
+  inline typed::space<pair<Domain, Range>, Range2> add_unnamed_tuple(unsigned int dim) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> curry() const;
+  inline typed::space<pair<Domain, Range>> domain() const;
+  inline typed::multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map_pw_multi_aff() const;
+  inline typed::id<pair<Domain, Range>, Range2> get_domain_tuple_id() const = delete;
+  inline typed::space<Anonymous, Range2> flatten_domain() const;
+  inline typed::space<pair<Domain, Range>, Range2> flatten_range() const = delete;
+  inline typed::multi_aff<pair<Domain, Range>, Range2> identity_multi_aff_on_domain() const = delete;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> identity_multi_pw_aff_on_domain() const = delete;
+  inline typed::pw_multi_aff<pair<Domain, Range>, Range2> identity_pw_multi_aff_on_domain() const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> map_from_set() const = delete;
+  inline typed::multi_aff<pair<Domain, Range>, Range2> multi_aff(const typed::aff_list<pair<Domain, Range>, Anonymous> &list) const;
+  inline typed::multi_aff<pair<Domain, Range>, Range2> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::multi_id<pair<Domain, Range>, Range2> multi_id(const typed::id_list<> &list) const = delete;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> multi_pw_aff(const typed::pw_aff_list<pair<Domain, Range>, Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>, Range2> multi_union_pw_aff(const typed::union_pw_aff_list<pair<Domain, Range>, Anonymous> &list) const;
+  inline typed::multi_val<pair<Domain, Range>, Range2> multi_val(const typed::val_list<> &list) const = delete;
+  inline typed::aff<pair<Domain, Range>, Range2> param_aff_on_domain(const typed::id<> &id) const = delete;
+  inline typed::aff<pair<Domain, Range>, Range2> param_aff_on_domain(const std::string &id) const = delete;
+  inline typed::space<> params() const;
+  template <typename Domain2, typename Arg3>
+  inline typed::space<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::space<Domain2, Arg3> &right) const;
+  inline typed::space<Range2> range() const;
+  inline typed::multi_aff<pair<pair<Domain, Range>, Range2>, Range2> range_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, Range2> range_map_pw_multi_aff() const;
+  inline typed::space<pair<Domain, Range>, Range2> range_reverse() const = delete;
+  inline typed::id<pair<Domain, Range>, Range2> get_range_tuple_id() const = delete;
+  inline typed::space<Range2, pair<Domain, Range>> reverse() const;
+  inline typed::space<pair<Domain, Range>, Range2> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> set_domain_tuple(const std::string &id) const = delete;
+  template <typename Arg2>
+  inline typed::space<pair<Domain, Range>, Arg2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Arg2>
+  inline typed::space<pair<Domain, Range>, Arg2> set_range_tuple(const std::string &id) const;
+  inline typed::space<pair<Domain, Range>, Range2> uncurry() const = delete;
+  static inline typed::space<pair<Domain, Range>, Range2> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<pair<Domain, Range>, Range2> universe_map() const;
+  inline typed::set<pair<Domain, Range>, Range2> universe_set() const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> unwrap() const = delete;
+  inline typed::space<pair<pair<Domain, Range>, Range2>> wrap() const;
+  inline typed::aff<pair<Domain, Range>, Range2> zero_aff_on_domain() const = delete;
+  inline typed::multi_aff<pair<Domain, Range>, Range2> zero_multi_aff() const;
+  inline typed::multi_pw_aff<pair<Domain, Range>, Range2> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>, Range2> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<pair<Domain, Range>, Range2> zero_multi_val() const = delete;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct space<Domain, pair<Range, Range2>> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  space(const space<Arg1, pair<Arg2, Arg3>> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  inline typed::space<Domain, pair<Range, Range2>> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<Domain, pair<Range, Range2>> add_param(const std::string &id) const;
+  inline typed::space<Domain, pair<Range, Range2>> add_unnamed_tuple(unsigned int dim) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> curry() const = delete;
+  inline typed::space<Domain> domain() const;
+  inline typed::multi_aff<pair<Domain, pair<Range, Range2>>, Domain> domain_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> domain_map_pw_multi_aff() const;
+  inline typed::id<Domain, pair<Range, Range2>> get_domain_tuple_id() const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> flatten_domain() const = delete;
+  inline typed::space<Domain, Anonymous> flatten_range() const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> identity_multi_aff_on_domain() const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> identity_multi_pw_aff_on_domain() const = delete;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> identity_pw_multi_aff_on_domain() const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> map_from_set() const = delete;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> multi_aff(const typed::aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::multi_id<Domain, pair<Range, Range2>> multi_id(const typed::id_list<> &list) const = delete;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> multi_pw_aff(const typed::pw_aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> multi_union_pw_aff(const typed::union_pw_aff_list<Domain, Anonymous> &list) const;
+  inline typed::multi_val<Domain, pair<Range, Range2>> multi_val(const typed::val_list<> &list) const = delete;
+  inline typed::aff<Domain, pair<Range, Range2>> param_aff_on_domain(const typed::id<> &id) const = delete;
+  inline typed::aff<Domain, pair<Range, Range2>> param_aff_on_domain(const std::string &id) const = delete;
+  inline typed::space<> params() const;
+  template <typename Domain2, typename Arg3>
+  inline typed::space<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::space<Domain2, Arg3> &right) const;
+  inline typed::space<pair<Range, Range2>> range() const;
+  inline typed::multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> range_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> range_map_pw_multi_aff() const;
+  inline typed::space<Domain, pair<Range2, Range>> range_reverse() const;
+  inline typed::id<Domain, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::space<pair<Range, Range2>, Domain> reverse() const;
+  template <typename Domain2>
+  inline typed::space<Domain2, pair<Range, Range2>> set_domain_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::space<Domain2, pair<Range, Range2>> set_domain_tuple(const std::string &id) const;
+  inline typed::space<Domain, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<Domain, Range>, Range2> uncurry() const;
+  static inline typed::space<Domain, pair<Range, Range2>> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<Domain, pair<Range, Range2>> universe_map() const;
+  inline typed::set<Domain, pair<Range, Range2>> universe_set() const = delete;
+  inline typed::space<Domain, pair<Range, Range2>> unwrap() const = delete;
+  inline typed::space<pair<Domain, pair<Range, Range2>>> wrap() const;
+  inline typed::aff<Domain, pair<Range, Range2>> zero_aff_on_domain() const = delete;
+  inline typed::multi_aff<Domain, pair<Range, Range2>> zero_multi_aff() const;
+  inline typed::multi_pw_aff<Domain, pair<Range, Range2>> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<Domain, pair<Range, Range2>> zero_multi_val() const = delete;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct space<pair<T1, T2>, pair<Range, Range2>> : public isl::space {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  space() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  space(const space<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::space(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::space>{}, bool>::type = true>
+  space(const base &obj) : isl::space(obj) {}
+ public:
+  static space from(const isl::space &obj) {
+    return space(obj);
+  }
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> add_named_tuple(const typed::id<> &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> add_named_tuple(const std::string &tuple_id, unsigned int dim) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> add_param(const typed::id<Anonymous> &id) const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> add_param(const std::string &id) const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> add_unnamed_tuple(unsigned int dim) const = delete;
+  inline typed::space<T1, pair<T2, pair<Range, Range2>>> curry() const;
+  inline typed::space<pair<T1, T2>> domain() const;
+  inline typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map_pw_multi_aff() const;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_domain_tuple_id() const = delete;
+  inline typed::space<Anonymous, pair<Range, Range2>> flatten_domain() const;
+  inline typed::space<pair<T1, T2>, Anonymous> flatten_range() const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> identity_multi_aff_on_domain() const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> identity_multi_pw_aff_on_domain() const = delete;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> identity_pw_multi_aff_on_domain() const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> map_from_set() const = delete;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> multi_aff(const typed::aff_list<pair<T1, T2>, Anonymous> &list) const;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> multi_aff_on_domain(const typed::multi_val<> &mv) const = delete;
+  inline typed::multi_id<pair<T1, T2>, pair<Range, Range2>> multi_id(const typed::id_list<> &list) const = delete;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> multi_pw_aff(const typed::pw_aff_list<pair<T1, T2>, Anonymous> &list) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> multi_union_pw_aff(const typed::union_pw_aff_list<pair<T1, T2>, Anonymous> &list) const;
+  inline typed::multi_val<pair<T1, T2>, pair<Range, Range2>> multi_val(const typed::val_list<> &list) const = delete;
+  inline typed::aff<pair<T1, T2>, pair<Range, Range2>> param_aff_on_domain(const typed::id<> &id) const = delete;
+  inline typed::aff<pair<T1, T2>, pair<Range, Range2>> param_aff_on_domain(const std::string &id) const = delete;
+  inline typed::space<> params() const;
+  template <typename Domain2, typename Arg2>
+  inline typed::space<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::space<Domain2, Arg2> &right) const;
+  inline typed::space<pair<Range, Range2>> range() const;
+  inline typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> range_map_multi_aff() const;
+  inline typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> range_map_pw_multi_aff() const;
+  inline typed::space<pair<T1, T2>, pair<Range2, Range>> range_reverse() const;
+  inline typed::id<pair<T1, T2>, pair<Range, Range2>> get_range_tuple_id() const = delete;
+  inline typed::space<pair<Range, Range2>, pair<T1, T2>> reverse() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> set_domain_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const typed::id<> &id) const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> set_range_tuple(const std::string &id) const = delete;
+  inline typed::space<pair<pair<T1, T2>, Range>, Range2> uncurry() const;
+  static inline typed::space<pair<T1, T2>, pair<Range, Range2>> unit(const isl::ctx &ctx) = delete;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> universe_map() const;
+  inline typed::set<pair<T1, T2>, pair<Range, Range2>> universe_set() const = delete;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> unwrap() const = delete;
+  inline typed::space<pair<pair<T1, T2>, pair<Range, Range2>>> wrap() const;
+  inline typed::aff<pair<T1, T2>, pair<Range, Range2>> zero_aff_on_domain() const = delete;
+  inline typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> zero_multi_aff() const;
+  inline typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> zero_multi_pw_aff() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> zero_multi_union_pw_aff() const;
+  inline typed::multi_val<pair<T1, T2>, pair<Range, Range2>> zero_multi_val() const = delete;
+};
+
+template <typename Domain, typename Range>
+struct union_map<Domain, Range> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  union_map(const union_map<Arg1, Arg2> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<Domain, Range> &bmap);
+  inline /* implicit */ union_map(const typed::map<Domain, Range> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> apply_domain(const typed::map<Domain, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Range, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::basic_map<Range, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::map<Range, Range2> &umap2) const;
+  inline typed::map<Domain, Range> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Range> as_union_pw_multi_aff() const;
+  inline typed::union_set<Domain> bind_range(const typed::multi_id<Range> &tuple) const;
+  inline typed::union_map<Domain, Range> coalesce() const;
+  inline typed::union_map<Domain, Range> curry() const = delete;
+  inline typed::union_set<Domain, Range> deltas() const = delete;
+  inline typed::union_map<Domain, Range> detect_equalities() const;
+  inline typed::union_set<Domain> domain() const;
+  inline typed::union_map<Domain, Range> domain_factor_domain() const = delete;
+  inline typed::union_map<Domain, Range> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Range> domain_product(const typed::union_map<Domain2, Range> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Range> domain_product(const typed::basic_map<Domain2, Range> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Range> domain_product(const typed::map<Domain2, Range> &umap2) const;
+  static inline typed::union_map<Domain, Range> empty(const isl::ctx &ctx);
+  inline typed::union_map<Domain, Range> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<Domain, Range> eq_at(const typed::multi_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<Domain, Range> eq_at(const typed::union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const;
+  inline typed::map<Domain, Range> extract_map(const typed::space<Domain, Range> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const;
+  inline typed::union_map<Domain, Range> gist(const typed::union_map<Domain, Range> &context) const;
+  inline typed::union_map<Domain, Range> gist(const typed::basic_map<Domain, Range> &context) const;
+  inline typed::union_map<Domain, Range> gist(const typed::map<Domain, Range> &context) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::basic_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::point<Domain> &uset) const;
+  inline typed::union_map<Domain, Range> gist_domain(const typed::set<Domain> &uset) const;
+  inline typed::union_map<Domain, Range> intersect(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> intersect(const typed::basic_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> intersect(const typed::map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<Domain, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<Domain, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::space<Range> &space) const;
+  inline typed::union_map<Domain, Range> intersect_range(const typed::union_set<Range> &uset) const;
+  inline typed::union_map<Domain, Range> lexmax() const;
+  inline typed::union_map<Domain, Range> lexmin() const;
+  inline typed::map_list<Domain, Range> map_list() const;
+  inline typed::map_list<Domain, Range> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Range> &ma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::basic_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> product(const typed::map<Domain2, Range2> &umap2) const;
+  inline typed::union_map<Domain, Range> project_out_all_params() const;
+  inline typed::union_set<Range> range() const;
+  inline typed::union_map<Domain, Range> range_factor_domain() const = delete;
+  inline typed::union_map<Domain, Range> range_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range> range_map() const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Range, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Range, Range2>> range_product(const typed::basic_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Range, Range2>> range_product(const typed::map<Domain, Range2> &umap2) const;
+  inline typed::union_map<Domain, Range> range_reverse() const = delete;
+  inline typed::union_map<Range, Domain> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::union_map<Domain, Range> subtract(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> subtract(const typed::basic_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> subtract(const typed::map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::basic_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::point<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_domain(const typed::set<Domain> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::union_set<Range> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::basic_set<Range> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::point<Range> &dom) const;
+  inline typed::union_map<Domain, Range> subtract_range(const typed::set<Range> &dom) const;
+  inline typed::union_map<Domain, Range> uncurry() const = delete;
+  inline typed::union_map<Domain, Range> unite(const typed::union_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> unite(const typed::basic_map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> unite(const typed::map<Domain, Range> &umap2) const;
+  inline typed::union_map<Domain, Range> universe() const;
+  inline typed::union_set<pair<Domain, Range>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct union_map<pair<Domain, Range>, Range2> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  union_map(const union_map<pair<Arg1, Arg2>, Arg3> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<pair<Domain, Range>, Range2> &bmap);
+  inline /* implicit */ union_map(const typed::map<pair<Domain, Range>, Range2> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> apply_domain(const typed::map<pair<Domain, Range>, Domain2> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> apply_range(const typed::union_map<Range2, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> apply_range(const typed::basic_map<Range2, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> apply_range(const typed::map<Range2, Arg3> &umap2) const;
+  inline typed::map<pair<Domain, Range>, Range2> as_map() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Range>, Range2> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Range>, Range2> as_union_pw_multi_aff() const;
+  inline typed::union_set<pair<Domain, Range>> bind_range(const typed::multi_id<Range2> &tuple) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> coalesce() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> curry() const;
+  inline typed::union_set<pair<Domain, Range>, Range2> deltas() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> detect_equalities() const;
+  inline typed::union_set<pair<Domain, Range>> domain() const;
+  inline typed::union_map<Domain, Range2> domain_factor_domain() const;
+  inline typed::union_map<Range, Range2> domain_factor_range() const;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::basic_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> domain_product(const typed::map<Domain2, Range2> &umap2) const;
+  static inline typed::union_map<pair<Domain, Range>, Range2> empty(const isl::ctx &ctx);
+  inline typed::union_map<pair<Domain, Range>, Range2> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> eq_at(const typed::multi_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> eq_at(const typed::union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const;
+  inline typed::map<pair<Domain, Range>, Range2> extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist(const typed::map<pair<Domain, Range>, Range2> &context) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::basic_set<pair<Domain, Range>> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::point<pair<Domain, Range>> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> gist_domain(const typed::set<pair<Domain, Range>> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect(const typed::map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::space<pair<Domain, Range>> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::space<Range2> &space) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> intersect_range(const typed::union_set<Range2> &uset) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> lexmax() const;
+  inline typed::union_map<pair<Domain, Range>, Range2> lexmin() const;
+  inline typed::map_list<pair<Domain, Range>, Range2> map_list() const;
+  inline typed::map_list<pair<Domain, Range>, Range2> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Range2> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::basic_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> product(const typed::map<Domain2, Arg3> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> project_out_all_params() const;
+  inline typed::union_set<Range2> range() const;
+  inline typed::union_map<pair<Domain, Range>, Range2> range_factor_domain() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> range_factor_range() const = delete;
+  inline typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> range_map() const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::basic_map<pair<Domain, Range>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> range_product(const typed::map<pair<Domain, Range>, Arg3> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> range_reverse() const = delete;
+  inline typed::union_map<Range2, pair<Domain, Range>> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<Domain, Range>, Range2> get_space() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract(const typed::map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::basic_set<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::point<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_domain(const typed::set<pair<Domain, Range>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::union_set<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::basic_set<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::point<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> subtract_range(const typed::set<Range2> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> uncurry() const = delete;
+  inline typed::union_map<pair<Domain, Range>, Range2> unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> unite(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> unite(const typed::map<pair<Domain, Range>, Range2> &umap2) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> universe() const;
+  inline typed::union_set<pair<pair<Domain, Range>, Range2>> wrap() const;
+};
+
+template <typename Domain>
+struct union_map<Domain, Domain> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_map(const union_map<Arg1, Arg1> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<Domain, Domain> &bmap);
+  inline /* implicit */ union_map(const typed::map<Domain, Domain> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> apply_domain(const typed::map<Domain, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::basic_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> apply_range(const typed::map<Domain, Range2> &umap2) const;
+  inline typed::map<Domain, Domain> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, Domain> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, Domain> as_union_pw_multi_aff() const;
+  inline typed::union_set<Domain> bind_range(const typed::multi_id<Domain> &tuple) const;
+  inline typed::union_map<Domain, Domain> coalesce() const;
+  inline typed::union_map<Domain, Domain> curry() const = delete;
+  inline typed::union_set<Domain> deltas() const;
+  inline typed::union_map<Domain, Domain> detect_equalities() const;
+  inline typed::union_set<Domain> domain() const;
+  inline typed::union_map<Domain, Domain> domain_factor_domain() const = delete;
+  inline typed::union_map<Domain, Domain> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Domain>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Domain> domain_product(const typed::union_map<Domain2, Domain> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Domain> domain_product(const typed::basic_map<Domain2, Domain> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, Domain> domain_product(const typed::map<Domain2, Domain> &umap2) const;
+  static inline typed::union_map<Domain, Domain> empty(const isl::ctx &ctx);
+  template <typename Range>
+  inline typed::union_map<Domain, Domain> eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const;
+  template <typename Range>
+  inline typed::union_map<Domain, Domain> eq_at(const typed::multi_pw_aff<Domain, Range> &mupa) const;
+  template <typename Range>
+  inline typed::union_map<Domain, Domain> eq_at(const typed::union_pw_aff<Domain, Range> &mupa) const;
+  inline bool every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const;
+  inline typed::map<Domain, Domain> extract_map(const typed::space<Domain, Domain> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const;
+  inline typed::union_map<Domain, Domain> gist(const typed::union_map<Domain, Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist(const typed::basic_map<Domain, Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist(const typed::map<Domain, Domain> &context) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::basic_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::point<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> gist_domain(const typed::set<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> intersect(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> intersect(const typed::basic_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> intersect(const typed::map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, Domain> intersect_range(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, Domain> lexmax() const;
+  inline typed::union_map<Domain, Domain> lexmin() const;
+  inline typed::map_list<Domain, Domain> map_list() const;
+  inline typed::map_list<Domain, Domain> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, Domain> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::multi_aff<Range2, Domain> &ma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::basic_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> product(const typed::map<Domain2, Range2> &umap2) const;
+  inline typed::union_map<Domain, Domain> project_out_all_params() const;
+  inline typed::union_set<Domain> range() const;
+  inline typed::union_map<Domain, Domain> range_factor_domain() const = delete;
+  inline typed::union_map<Domain, Domain> range_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, Domain>, Domain> range_map() const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Domain, Range2>> range_product(const typed::union_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Domain, Range2>> range_product(const typed::basic_map<Domain, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<Domain, pair<Domain, Range2>> range_product(const typed::map<Domain, Range2> &umap2) const;
+  inline typed::union_map<Domain, Domain> range_reverse() const = delete;
+  inline typed::union_map<Domain, Domain> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, Domain> get_space() const = delete;
+  inline typed::union_map<Domain, Domain> subtract(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> subtract(const typed::basic_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> subtract(const typed::map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::basic_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::point<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_domain(const typed::set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::basic_set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::point<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> subtract_range(const typed::set<Domain> &dom) const;
+  inline typed::union_map<Domain, Domain> uncurry() const = delete;
+  inline typed::union_map<Domain, Domain> unite(const typed::union_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> unite(const typed::basic_map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> unite(const typed::map<Domain, Domain> &umap2) const;
+  inline typed::union_map<Domain, Domain> universe() const;
+  inline typed::union_set<pair<Domain, Domain>> wrap() const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct union_map<Domain, pair<Range, Range2>> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  union_map(const union_map<Arg1, pair<Arg2, Arg3>> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<Domain, pair<Range, Range2>> &bmap);
+  inline /* implicit */ union_map(const typed::map<Domain, pair<Range, Range2>> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<Domain, Domain2> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> apply_range(const typed::map<pair<Range, Range2>, Arg3> &umap2) const;
+  inline typed::map<Domain, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::union_set<Domain> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> curry() const = delete;
+  inline typed::union_set<Domain, pair<Range, Range2>> deltas() const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> detect_equalities() const;
+  inline typed::union_set<Domain> domain() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> domain_factor_domain() const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> domain_factor_range() const = delete;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &umap2) const;
+  static inline typed::union_map<Domain, pair<Range, Range2>> empty(const isl::ctx &ctx);
+  inline typed::union_map<Domain, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> eq_at(const typed::union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const;
+  inline typed::map<Domain, pair<Range, Range2>> extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist(const typed::map<Domain, pair<Range, Range2>> &context) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::basic_set<Domain> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::point<Domain> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> gist_domain(const typed::set<Domain> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect(const typed::map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> lexmax() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> lexmin() const;
+  inline typed::map_list<Domain, pair<Range, Range2>> map_list() const;
+  inline typed::map_list<Domain, pair<Range, Range2>> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, Arg3> preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::union_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::basic_map<Domain2, Arg3> &umap2) const;
+  template <typename Domain2, typename Arg3>
+  inline typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> product(const typed::map<Domain2, Arg3> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::union_set<pair<Range, Range2>> range() const;
+  inline typed::union_map<Domain, Range> range_factor_domain() const;
+  inline typed::union_map<Domain, Range2> range_factor_range() const;
+  inline typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_map<Domain, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::basic_map<Domain, Arg3> &umap2) const;
+  template <typename Arg3>
+  inline typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::map<Domain, Arg3> &umap2) const;
+  inline typed::union_map<Domain, pair<Range2, Range>> range_reverse() const;
+  inline typed::union_map<pair<Range, Range2>, Domain> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, pair<Range, Range2>> get_space() const = delete;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract(const typed::map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::basic_set<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::point<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_domain(const typed::set<Domain> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::basic_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::point<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> subtract_range(const typed::set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<Domain, Range>, Range2> uncurry() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> unite(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> unite(const typed::map<Domain, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<Domain, pair<Range, Range2>> universe() const;
+  inline typed::union_set<pair<Domain, pair<Range, Range2>>> wrap() const;
+};
+
+template <typename T1, typename T2>
+struct union_map<pair<T1, T2>, pair<T1, T2>> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{},
+            bool>::type = true>
+  union_map(const union_map<pair<Arg1, Arg2>, pair<Arg1, Arg2>> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap);
+  inline /* implicit */ union_map(const typed::map<pair<T1, T2>, pair<T1, T2>> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> apply_range(const typed::basic_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> apply_range(const typed::map<pair<T1, T2>, Range2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> as_union_pw_multi_aff() const;
+  inline typed::union_set<pair<T1, T2>> bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> coalesce() const;
+  inline typed::union_map<T1, pair<T2, pair<T1, T2>>> curry() const;
+  inline typed::union_set<pair<T1, T2>> deltas() const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> detect_equalities() const;
+  inline typed::union_set<pair<T1, T2>> domain() const;
+  inline typed::union_map<T1, pair<T1, T2>> domain_factor_domain() const;
+  inline typed::union_map<T2, pair<T1, T2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::basic_map<Domain2, pair<T1, T2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> domain_product(const typed::map<Domain2, pair<T1, T2>> &umap2) const;
+  static inline typed::union_map<pair<T1, T2>, pair<T1, T2>> empty(const isl::ctx &ctx);
+  template <typename Range>
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const;
+  template <typename Range>
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mupa) const;
+  template <typename Range>
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> eq_at(const typed::union_pw_aff<pair<T1, T2>, Range> &mupa) const;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<T1, T2>> extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::basic_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::point<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> gist_domain(const typed::set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> intersect_range(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> lexmax() const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> lexmin() const;
+  inline typed::map_list<pair<T1, T2>, pair<T1, T2>> map_list() const;
+  inline typed::map_list<pair<T1, T2>, pair<T1, T2>> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<T1, T2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, Range2> preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::union_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::basic_map<Domain2, Range2> &umap2) const;
+  template <typename Domain2, typename Range2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> product(const typed::map<Domain2, Range2> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> project_out_all_params() const;
+  inline typed::union_set<pair<T1, T2>> range() const;
+  inline typed::union_map<pair<T1, T2>, T1> range_factor_domain() const;
+  inline typed::union_map<pair<T1, T2>, T2> range_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> range_map() const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::basic_map<pair<T1, T2>, Range2> &umap2) const;
+  template <typename Range2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> range_product(const typed::map<pair<T1, T2>, Range2> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T2, T1>> range_reverse() const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<T1, T2>, pair<T1, T2>> get_space() const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::basic_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::point<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_domain(const typed::set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::basic_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::point<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> subtract_range(const typed::set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<pair<T1, T2>, T1>, T2> uncurry() const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<T1, T2>> universe() const;
+  inline typed::union_set<pair<pair<T1, T2>, pair<T1, T2>>> wrap() const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct union_map<pair<T1, T2>, pair<Range, Range2>> : public isl::union_map {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_map() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  union_map(const union_map<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::union_map(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_map>{}, bool>::type = true>
+  union_map(const base &obj) : isl::union_map(obj) {}
+ public:
+  static union_map from(const isl::union_map &obj) {
+    return union_map(obj);
+  }
+  inline /* implicit */ union_map(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap);
+  inline /* implicit */ union_map(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map);
+  inline explicit union_map(const isl::ctx &ctx, const std::string &str);
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> apply_domain(const typed::map<pair<T1, T2>, Domain2> &umap2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> apply_range(const typed::map<pair<Range, Range2>, Arg2> &umap2) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> as_map() const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_union_pw_multi_aff() const;
+  inline typed::union_set<pair<T1, T2>> bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::union_map<T1, pair<T2, pair<Range, Range2>>> curry() const;
+  inline typed::union_set<pair<T1, T2>, pair<Range, Range2>> deltas() const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> detect_equalities() const;
+  inline typed::union_set<pair<T1, T2>> domain() const;
+  inline typed::union_map<T1, pair<Range, Range2>> domain_factor_domain() const;
+  inline typed::union_map<T2, pair<Range, Range2>> domain_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map() const;
+  inline typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> domain_map_union_pw_multi_aff() const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &umap2) const;
+  template <typename Domain2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> domain_product(const typed::map<Domain2, pair<Range, Range2>> &umap2) const;
+  static inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> empty(const isl::ctx &ctx);
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_union_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::multi_pw_aff<> &mupa) const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> eq_at(const typed::union_pw_aff<> &mupa) const = delete;
+  inline bool every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const;
+  inline typed::map<pair<T1, T2>, pair<Range, Range2>> extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline void foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::basic_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::point<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> gist_domain(const typed::set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::space<pair<Range, Range2>> &space) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> lexmax() const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> lexmin() const;
+  inline typed::map_list<pair<T1, T2>, pair<Range, Range2>> map_list() const;
+  inline typed::map_list<pair<T1, T2>, pair<Range, Range2>> get_map_list() const = delete;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_map<Domain2, pair<Range, Range2>> preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, Arg2> preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::union_map<Domain2, Arg2> &umap2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::basic_map<Domain2, Arg2> &umap2) const;
+  template <typename Domain2, typename Arg2>
+  inline typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> product(const typed::map<Domain2, Arg2> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> project_out_all_params() const;
+  inline typed::union_set<pair<Range, Range2>> range() const;
+  inline typed::union_map<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::union_map<pair<T1, T2>, Range2> range_factor_range() const;
+  inline typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> range_map() const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::basic_map<pair<T1, T2>, Arg2> &umap2) const;
+  template <typename Arg2>
+  inline typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::map<pair<T1, T2>, Arg2> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range2, Range>> range_reverse() const;
+  inline typed::union_map<pair<Range, Range2>, pair<T1, T2>> reverse() const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> get_space() const = delete;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::basic_set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::point<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::set<pair<T1, T2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::basic_set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::point<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> subtract_range(const typed::set<pair<Range, Range2>> &dom) const;
+  inline typed::union_map<pair<pair<T1, T2>, Range>, Range2> uncurry() const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> universe() const;
+  inline typed::union_set<pair<pair<T1, T2>, pair<Range, Range2>>> wrap() const;
+};
+
+template <>
+struct union_pw_aff<Anonymous> : public isl::union_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_aff() = default;
+  union_pw_aff(const isl::union_pw_aff &obj) : isl::union_pw_aff(obj) {}
+  static union_pw_aff from(const isl::union_pw_aff &obj) {
+    return union_pw_aff(obj);
+  }
+  inline /* implicit */ union_pw_aff(const typed::aff<Anonymous> &aff);
+  inline /* implicit */ union_pw_aff(const typed::pw_aff<Anonymous> &pa);
+  inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_union_pw_aff<Anonymous> add(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::union_pw_aff<Anonymous> add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Anonymous> add(const typed::aff<Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Anonymous> add(const typed::pw_aff<Anonymous> &upa2) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const;
+  inline typed::multi_union_pw_aff<Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Anonymous> as_pw_multi_aff() const;
+  inline typed::union_map<Anonymous> as_union_map() const = delete;
+  inline typed::union_pw_aff<Anonymous> at(int pos) const;
+  inline typed::union_set<> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::union_set<> bind(const typed::id<Anonymous> &id) const;
+  inline typed::union_set<> bind(const std::string &id) const;
+  inline typed::union_pw_aff<Anonymous> coalesce() const;
+  inline typed::union_set<> domain() const;
+  inline typed::pw_multi_aff<Anonymous> extract_pw_multi_aff(const typed::space<Anonymous> &space) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::union_set<> &context) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::basic_set<> &context) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::point<> &context) const;
+  inline typed::union_pw_aff<Anonymous> gist(const typed::set<> &context) const;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::union_pw_aff<Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_aff<Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_aff<Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_aff_list<Anonymous> list() const;
+  inline typed::multi_union_pw_aff<Anonymous> neg() const;
+  inline typed::union_pw_multi_aff<Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::multi_aff<> &upma) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::pw_multi_aff<> &upma) const = delete;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_aff<> &upma) const = delete;
+  inline typed::pw_multi_aff_list<Anonymous> pw_multi_aff_list() const;
+  inline typed::union_pw_multi_aff<Anonymous> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> range_factor_range() const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> range_product(const typed::multi_union_pw_aff<> &multi2) const = delete;
+  inline typed::union_pw_multi_aff<Anonymous> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<Anonymous> scale(long v) const;
+  inline typed::multi_union_pw_aff<Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<Anonymous> scale_down(long v) const;
+  inline typed::multi_union_pw_aff<Anonymous> set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Domain2>
+  inline typed::multi_union_pw_aff<Domain2> set_range_tuple(const std::string &id) const;
+  inline typed::space<> space() const;
+  inline typed::space<Anonymous> get_space() const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const;
+  inline typed::union_pw_aff<Anonymous> sub(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Anonymous> sub(const typed::aff<Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Anonymous> sub(const typed::pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_aff<Anonymous> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::multi_union_pw_aff<Anonymous> union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const;
+  inline typed::union_pw_aff<Anonymous> union_add(const typed::union_pw_aff<Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Anonymous> union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Anonymous> union_add(const typed::aff<Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Anonymous> union_add(const typed::pw_aff<Anonymous> &upa2) const;
+};
+
+template <typename Domain>
+struct union_pw_aff<Domain, Anonymous> : public isl::union_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_pw_aff(const union_pw_aff<Arg1, Anonymous> &obj) : isl::union_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_aff>{}, bool>::type = true>
+  union_pw_aff(const base &obj) : isl::union_pw_aff(obj) {}
+ public:
+  static union_pw_aff from(const isl::union_pw_aff &obj) {
+    return union_pw_aff(obj);
+  }
+  inline /* implicit */ union_pw_aff(const typed::aff<Domain, Anonymous> &aff);
+  inline /* implicit */ union_pw_aff(const typed::pw_aff<Domain, Anonymous> &pa);
+  inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_union_pw_aff<Domain, Anonymous> add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> add(const typed::pw_aff<Domain, Anonymous> &upa2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> as_pw_multi_aff() const;
+  inline typed::union_map<Domain, Anonymous> as_union_map() const;
+  inline typed::union_pw_aff<Domain, Anonymous> at(int pos) const;
+  inline typed::union_set<Domain> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::union_set<Domain> bind(const typed::id<Anonymous> &id) const;
+  inline typed::union_set<Domain> bind(const std::string &id) const;
+  inline typed::union_pw_aff<Domain, Anonymous> coalesce() const;
+  inline typed::union_set<Domain> domain() const;
+  inline typed::pw_multi_aff<Domain, Anonymous> extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::union_set<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::point<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_aff<Domain, Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_aff_list<Domain, Anonymous> list() const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> neg() const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::multi_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::pw_multi_aff<Domain> &upma) const;
+  template <typename Domain2>
+  inline typed::union_pw_aff<Domain2, Anonymous> pullback(const typed::union_pw_aff<Domain2, Domain> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_aff<Domain> &upma) const;
+  inline typed::pw_multi_aff_list<Domain, Anonymous> pw_multi_aff_list() const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale(long v) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> scale_down(long v) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<Domain, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, Anonymous> get_space() const = delete;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> sub(const typed::aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> sub(const typed::pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_aff<Domain, Anonymous> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::multi_union_pw_aff<Domain, Anonymous> union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<Domain, Anonymous> union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> union_add(const typed::aff<Domain, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<Domain, Anonymous> union_add(const typed::pw_aff<Domain, Anonymous> &upa2) const;
+};
+
+template <typename Domain, typename Domain2>
+struct union_pw_aff<pair<Domain, Domain2>, Anonymous> : public isl::union_pw_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Domain2, Arg2>{},
+            bool>::type = true>
+  union_pw_aff(const union_pw_aff<pair<Arg1, Arg2>, Anonymous> &obj) : isl::union_pw_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_aff>{}, bool>::type = true>
+  union_pw_aff(const base &obj) : isl::union_pw_aff(obj) {}
+ public:
+  static union_pw_aff from(const isl::union_pw_aff &obj) {
+    return union_pw_aff(obj);
+  }
+  inline /* implicit */ union_pw_aff(const typed::aff<pair<Domain, Domain2>, Anonymous> &aff);
+  inline /* implicit */ union_pw_aff(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &pa);
+  inline explicit union_pw_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> add(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &multi2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> add(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> add(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> add(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous> as_pw_multi_aff() const;
+  inline typed::union_map<pair<Domain, Domain2>, Anonymous> as_union_map() const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> at(int pos) const;
+  inline typed::union_set<pair<Domain, Domain2>> bind(const typed::multi_id<Anonymous> &tuple) const;
+  inline typed::union_set<pair<Domain, Domain2>> bind(const typed::id<Anonymous> &id) const;
+  inline typed::union_set<pair<Domain, Domain2>> bind(const std::string &id) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> coalesce() const;
+  inline typed::union_set<pair<Domain, Domain2>> domain() const;
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous> extract_pw_multi_aff(const typed::space<pair<Domain, Domain2>, Anonymous> &space) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> gist(const typed::union_set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> gist(const typed::basic_set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> gist(const typed::point<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> gist(const typed::set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> intersect_domain(const typed::space<pair<Domain, Domain2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> intersect_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_aff_list<pair<Domain, Domain2>, Anonymous> list() const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> neg() const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Domain2>, Anonymous> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_aff<Arg2, Anonymous> pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain, Domain2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_multi_aff<pair<Domain, Domain2>> &upma) const;
+  template <typename Arg2>
+  inline typed::union_pw_aff<Arg2, Anonymous> pullback(const typed::multi_aff<Arg2, pair<Domain, Domain2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::multi_aff<pair<Domain, Domain2>> &upma) const;
+  template <typename Arg2>
+  inline typed::union_pw_aff<Arg2, Anonymous> pullback(const typed::pw_multi_aff<Arg2, pair<Domain, Domain2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::pw_multi_aff<pair<Domain, Domain2>> &upma) const;
+  template <typename Arg2>
+  inline typed::union_pw_aff<Arg2, Anonymous> pullback(const typed::union_pw_aff<Arg2, pair<Domain, Domain2>> &upma) const;
+  inline typed::union_pw_aff<Anonymous> pullback(const typed::union_pw_aff<pair<Domain, Domain2>> &upma) const;
+  inline typed::pw_multi_aff_list<pair<Domain, Domain2>, Anonymous> pw_multi_aff_list() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> range_product(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> &multi2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> range_product(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale(long v) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale_down(const typed::multi_val<Anonymous> &mv) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale_down(const typed::val<Anonymous> &v) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> scale_down(long v) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> set_at(int pos, const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &el) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> set_range_tuple(const typed::id<Anonymous> &id) const;
+  template <typename Range2>
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> set_range_tuple(const std::string &id) const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<Domain, Domain2>, Anonymous> get_space() const = delete;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> sub(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &multi2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> sub(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> sub(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> sub(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> sub(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> subtract_domain(const typed::space<pair<Domain, Domain2>> &space) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> subtract_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> union_add(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &mupa2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> union_add(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> union_add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> union_add(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+  inline typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> union_add(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const;
+};
+
+template <>
+struct union_pw_aff_list<Anonymous> : public isl::union_pw_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_aff_list() = default;
+  union_pw_aff_list(const isl::union_pw_aff_list &obj) : isl::union_pw_aff_list(obj) {}
+  static union_pw_aff_list from(const isl::union_pw_aff_list &obj) {
+    return union_pw_aff_list(obj);
+  }
+  inline explicit union_pw_aff_list(const isl::ctx &ctx, int n);
+  inline explicit union_pw_aff_list(const typed::union_pw_aff<Anonymous> &el);
+  inline explicit union_pw_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_aff_list<Anonymous> add(const typed::union_pw_aff<Anonymous> &el) const;
+  inline typed::union_pw_aff_list<Anonymous> add(const typed::aff<Anonymous> &el) const;
+  inline typed::union_pw_aff_list<Anonymous> add(const typed::pw_aff<Anonymous> &el) const;
+  inline typed::union_pw_aff<Anonymous> at(int index) const;
+  inline typed::union_pw_aff<Anonymous> get_at(int index) const = delete;
+  inline typed::union_pw_aff_list<Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::union_pw_aff<Anonymous>)> &fn) const;
+};
+
+template <typename Domain>
+struct union_pw_aff_list<Domain, Anonymous> : public isl::union_pw_aff_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_aff_list() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_pw_aff_list(const union_pw_aff_list<Arg1, Anonymous> &obj) : isl::union_pw_aff_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_aff_list>{}, bool>::type = true>
+  union_pw_aff_list(const base &obj) : isl::union_pw_aff_list(obj) {}
+ public:
+  static union_pw_aff_list from(const isl::union_pw_aff_list &obj) {
+    return union_pw_aff_list(obj);
+  }
+  inline explicit union_pw_aff_list(const isl::ctx &ctx, int n);
+  inline explicit union_pw_aff_list(const typed::union_pw_aff<Domain, Anonymous> &el);
+  inline explicit union_pw_aff_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_aff_list<Domain, Anonymous> add(const typed::union_pw_aff<Domain, Anonymous> &el) const;
+  inline typed::union_pw_aff_list<Domain, Anonymous> add(const typed::aff<Domain, Anonymous> &el) const;
+  inline typed::union_pw_aff_list<Domain, Anonymous> add(const typed::pw_aff<Domain, Anonymous> &el) const;
+  inline typed::union_pw_aff<Domain, Anonymous> at(int index) const;
+  inline typed::union_pw_aff<Domain, Anonymous> get_at(int index) const = delete;
+  inline typed::union_pw_aff_list<Domain, Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::union_pw_aff<Domain, Anonymous>)> &fn) const;
+};
+
+template <typename Domain>
+struct union_pw_multi_aff<Domain> : public isl::union_pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_multi_aff() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_pw_multi_aff(const union_pw_multi_aff<Arg1> &obj) : isl::union_pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_multi_aff>{}, bool>::type = true>
+  union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {}
+ public:
+  static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) {
+    return union_pw_multi_aff(obj);
+  }
+  inline /* implicit */ union_pw_multi_aff(const typed::multi_aff<Domain> &ma);
+  inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff<Domain> &pma);
+  inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff<Domain> &upa);
+  inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_multi_aff<Domain> add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> add(const typed::multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> add(const typed::pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> add(const typed::union_pw_aff<Domain> &upma2) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::multi_aff<Domain, Range> &upma2) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::pw_multi_aff<Domain, Range> &upma2) const;
+  template <typename Range>
+  inline typed::union_pw_multi_aff<Range> apply(const typed::union_pw_aff<Domain, Range> &upma2) const;
+  inline typed::multi_union_pw_aff<Domain> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain> as_pw_multi_aff() const;
+  inline typed::union_map<Domain> as_union_map() const = delete;
+  inline typed::union_pw_multi_aff<Domain> coalesce() const;
+  inline typed::union_set<> domain() const;
+  static inline typed::union_pw_multi_aff<Domain> empty(const isl::ctx &ctx);
+  inline typed::pw_multi_aff<Domain> extract_pw_multi_aff(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::union_set<> &context) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::basic_set<> &context) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::point<> &context) const;
+  inline typed::union_pw_multi_aff<Domain> gist(const typed::set<> &context) const;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::union_pw_multi_aff<Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> pullback(const typed::union_pw_aff<> &upma2) const = delete;
+  inline typed::pw_multi_aff_list<Domain> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff_list<Domain> get_pw_multi_aff_list() const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_factor_range() const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain> range_product(const typed::union_pw_aff<> &upma2) const = delete;
+  inline typed::space<> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> sub(const typed::union_pw_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::space<> &space) const = delete;
+  inline typed::union_pw_multi_aff<Domain> subtract_domain(const typed::union_set<> &uset) const = delete;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::pw_multi_aff<Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain> union_add(const typed::union_pw_aff<Domain> &upma2) const;
+};
+
+template <typename Domain, typename Range>
+struct union_pw_multi_aff<Domain, Range> : public isl::union_pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  union_pw_multi_aff(const union_pw_multi_aff<Arg1, Arg2> &obj) : isl::union_pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_multi_aff>{}, bool>::type = true>
+  union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {}
+ public:
+  static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) {
+    return union_pw_multi_aff(obj);
+  }
+  inline /* implicit */ union_pw_multi_aff(const typed::multi_aff<Domain, Range> &ma);
+  inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff<Domain, Range> &pma);
+  inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff<Domain, Range> &upa);
+  inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> add(const typed::union_pw_aff<Domain, Range> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::pw_multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, Range2> apply(const typed::union_pw_aff<Range, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<Domain, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, Range> as_pw_multi_aff() const;
+  inline typed::union_map<Domain, Range> as_union_map() const;
+  inline typed::union_pw_multi_aff<Domain, Range> coalesce() const;
+  inline typed::union_set<Domain> domain() const;
+  static inline typed::union_pw_multi_aff<Domain, Range> empty(const isl::ctx &ctx);
+  inline typed::pw_multi_aff<Domain, Range> extract_pw_multi_aff(const typed::space<Domain, Range> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::union_set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::point<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, Range> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, Range> pullback(const typed::union_pw_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff_list<Domain, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff_list<Domain, Range> get_pw_multi_aff_list() const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::multi_aff<Domain, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::pw_multi_aff<Domain, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> range_product(const typed::union_pw_aff<Domain, Range2> &upma2) const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, Range> get_space() const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> sub(const typed::union_pw_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, Range> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::pw_multi_aff<Domain, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, Range> union_add(const typed::union_pw_aff<Domain, Range> &upma2) const;
+};
+
+template <typename Domain, typename Domain2, typename Range>
+struct union_pw_multi_aff<pair<Domain, Domain2>, Range> : public isl::union_pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Domain2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{},
+            bool>::type = true>
+  union_pw_multi_aff(const union_pw_multi_aff<pair<Arg1, Arg2>, Arg3> &obj) : isl::union_pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_multi_aff>{}, bool>::type = true>
+  union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {}
+ public:
+  static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) {
+    return union_pw_multi_aff(obj);
+  }
+  inline /* implicit */ union_pw_multi_aff(const typed::multi_aff<pair<Domain, Domain2>, Range> &ma);
+  inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &pma);
+  inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upa);
+  inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> add(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> add(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> add(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> apply(const typed::multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> apply(const typed::pw_multi_aff<Range, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> apply(const typed::union_pw_aff<Range, Range2> &upma2) const;
+  inline typed::multi_union_pw_aff<pair<Domain, Domain2>, Range> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, Range> as_pw_multi_aff() const;
+  inline typed::union_map<pair<Domain, Domain2>, Range> as_union_map() const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> coalesce() const;
+  inline typed::union_set<pair<Domain, Domain2>> domain() const;
+  static inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> empty(const isl::ctx &ctx);
+  inline typed::pw_multi_aff<pair<Domain, Domain2>, Range> extract_pw_multi_aff(const typed::space<pair<Domain, Domain2>, Range> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> gist(const typed::union_set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> gist(const typed::basic_set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> gist(const typed::point<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> gist(const typed::set<pair<Domain, Domain2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> intersect_domain(const typed::space<pair<Domain, Domain2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> intersect_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> intersect_params(const typed::point<> &set) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, Domain> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> preimage_domain_wrapped_domain(const typed::union_pw_aff<Domain3, Domain> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Arg3, Range> pullback(const typed::union_pw_multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_multi_aff<pair<Domain, Domain2>> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Arg3, Range> pullback(const typed::multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::multi_aff<pair<Domain, Domain2>> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Arg3, Range> pullback(const typed::pw_multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::pw_multi_aff<pair<Domain, Domain2>> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Arg3, Range> pullback(const typed::union_pw_aff<Arg3, pair<Domain, Domain2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Range> pullback(const typed::union_pw_aff<pair<Domain, Domain2>> &upma2) const;
+  inline typed::pw_multi_aff_list<pair<Domain, Domain2>, Range> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff_list<pair<Domain, Domain2>, Range> get_pw_multi_aff_list() const = delete;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> range_factor_domain() const = delete;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> range_factor_range() const = delete;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> range_product(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> range_product(const typed::multi_aff<pair<Domain, Domain2>, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> range_product(const typed::pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const;
+  template <typename Range2>
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> range_product(const typed::union_pw_aff<pair<Domain, Domain2>, Range2> &upma2) const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<Domain, Domain2>, Range> get_space() const = delete;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> sub(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> sub(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> sub(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> sub(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> subtract_domain(const typed::space<pair<Domain, Domain2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> subtract_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> union_add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> union_add(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> union_add(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> union_add(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const;
+};
+
+template <typename Domain, typename Range, typename Range2>
+struct union_pw_multi_aff<Domain, pair<Range, Range2>> : public isl::union_pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{} &&
+              std::is_base_of<Range2, Arg3>{},
+            bool>::type = true>
+  union_pw_multi_aff(const union_pw_multi_aff<Arg1, pair<Arg2, Arg3>> &obj) : isl::union_pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_multi_aff>{}, bool>::type = true>
+  union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {}
+ public:
+  static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) {
+    return union_pw_multi_aff(obj);
+  }
+  inline /* implicit */ union_pw_multi_aff(const typed::multi_aff<Domain, pair<Range, Range2>> &ma);
+  inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma);
+  inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upa);
+  inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> add(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::multi_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, Arg3> apply(const typed::union_pw_aff<pair<Range, Range2>, Arg3> &upma2) const;
+  inline typed::multi_union_pw_aff<Domain, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_map<Domain, pair<Range, Range2>> as_union_map() const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> coalesce() const;
+  inline typed::union_set<Domain> domain() const;
+  static inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> empty(const isl::ctx &ctx);
+  inline typed::pw_multi_aff<Domain, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::union_set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::point<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> gist(const typed::set<Domain> &context) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<> &upma2) const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_aff<> &upma2) const = delete;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_aff<Domain2, Domain> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_aff<Domain> &upma2) const;
+  inline typed::pw_multi_aff_list<Domain, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff_list<Domain, pair<Range, Range2>> get_pw_multi_aff_list() const = delete;
+  inline typed::union_pw_multi_aff<Domain, Range> range_factor_domain() const;
+  inline typed::union_pw_multi_aff<Domain, Range2> range_factor_range() const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::multi_aff<Domain, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::pw_multi_aff<Domain, Arg3> &upma2) const;
+  template <typename Arg3>
+  inline typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> range_product(const typed::union_pw_aff<Domain, Arg3> &upma2) const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain, pair<Range, Range2>> get_space() const = delete;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> sub(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::space<Domain> &space) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> subtract_domain(const typed::union_set<Domain> &uset) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<Domain, pair<Range, Range2>> union_add(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const;
+};
+
+template <typename T1, typename T2, typename Range, typename Range2>
+struct union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> : public isl::union_pw_multi_aff {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_pw_multi_aff() = default;
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
+            typename std::enable_if<
+              std::is_base_of<T1, Arg1>{} &&
+              std::is_base_of<T2, Arg2>{} &&
+              std::is_base_of<Range, Arg3>{} &&
+              std::is_base_of<Range2, Arg4>{},
+            bool>::type = true>
+  union_pw_multi_aff(const union_pw_multi_aff<pair<Arg1, Arg2>, pair<Arg3, Arg4>> &obj) : isl::union_pw_multi_aff(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_pw_multi_aff>{}, bool>::type = true>
+  union_pw_multi_aff(const base &obj) : isl::union_pw_multi_aff(obj) {}
+ public:
+  static union_pw_multi_aff from(const isl::union_pw_multi_aff &obj) {
+    return union_pw_multi_aff(obj);
+  }
+  inline /* implicit */ union_pw_multi_aff(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &ma);
+  inline /* implicit */ union_pw_multi_aff(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma);
+  inline /* implicit */ union_pw_multi_aff(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upa);
+  inline explicit union_pw_multi_aff(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> add(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::multi_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Arg2> apply(const typed::union_pw_aff<pair<Range, Range2>, Arg2> &upma2) const;
+  inline typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> as_multi_union_pw_aff() const;
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> as_pw_multi_aff() const;
+  inline typed::union_map<pair<T1, T2>, pair<Range, Range2>> as_union_map() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> coalesce() const;
+  inline typed::union_set<pair<T1, T2>> domain() const;
+  static inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> empty(const isl::ctx &ctx);
+  inline typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::union_set<pair<T1, T2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::basic_set<pair<T1, T2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::point<pair<T1, T2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> gist(const typed::set<pair<T1, T2>> &context) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> intersect_params(const typed::point<> &set) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, T1> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &upma2) const;
+  template <typename Domain3>
+  inline typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> preimage_domain_wrapped_domain(const typed::union_pw_aff<Domain3, T1> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::multi_aff<pair<T1, T2>> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::pw_multi_aff<pair<T1, T2>> &upma2) const;
+  template <typename Domain2>
+  inline typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> pullback(const typed::union_pw_aff<Domain2, pair<T1, T2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<Range, Range2>> pullback(const typed::union_pw_aff<pair<T1, T2>> &upma2) const;
+  inline typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> pw_multi_aff_list() const;
+  inline typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> get_pw_multi_aff_list() const = delete;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Range> range_factor_domain() const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, Range2> range_factor_range() const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const;
+  template <typename Arg2>
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> range_product(const typed::union_pw_aff<pair<T1, T2>, Arg2> &upma2) const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<T1, T2>, pair<Range, Range2>> get_space() const = delete;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> sub(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::space<pair<T1, T2>> &space) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+  inline typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> union_add(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const;
+};
+
+template <>
+struct union_set<> : public isl::union_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_set() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_set>{}, bool>::type = true>
+  union_set(const base &obj) : isl::union_set(obj) {}
+ public:
+  static union_set from(const isl::union_set &obj) {
+    return union_set(obj);
+  }
+  inline /* implicit */ union_set(const typed::basic_set<> &bset);
+  inline /* implicit */ union_set(const typed::point<> &pnt);
+  inline /* implicit */ union_set(const typed::set<> &set);
+  inline explicit union_set(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_set<> apply(const typed::union_map<> &umap) const = delete;
+  inline typed::union_set<> apply(const typed::basic_map<> &umap) const = delete;
+  inline typed::union_set<> apply(const typed::map<> &umap) const = delete;
+  inline typed::set<> as_set() const = delete;
+  inline typed::union_set<> coalesce() const;
+  inline typed::union_set<> detect_equalities() const;
+  static inline typed::union_set<> empty(const isl::ctx &ctx);
+  inline bool every_set(const std::function<bool(typed::set<>)> &test) const;
+  inline typed::set<> extract_set(const typed::space<> &space) const;
+  inline void foreach_point(const std::function<void(typed::point<>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<>)> &fn) const;
+  inline typed::union_set<> gist(const typed::union_set<> &context) const;
+  inline typed::union_set<> gist(const typed::basic_set<> &context) const;
+  inline typed::union_set<> gist(const typed::point<> &context) const;
+  inline typed::union_set<> gist(const typed::set<> &context) const;
+  inline typed::union_map<> identity() const = delete;
+  inline typed::union_set<> intersect(const typed::union_set<> &uset2) const;
+  inline typed::union_set<> intersect(const typed::basic_set<> &uset2) const;
+  inline typed::union_set<> intersect(const typed::point<> &uset2) const;
+  inline typed::union_set<> intersect(const typed::set<> &uset2) const;
+  inline typed::union_set<> intersect_params(const typed::set<> &set) const = delete;
+  inline typed::union_set<> intersect_params(const typed::basic_set<> &set) const = delete;
+  inline typed::union_set<> intersect_params(const typed::point<> &set) const = delete;
+  inline typed::union_set<> lexmax() const = delete;
+  inline typed::union_set<> lexmin() const = delete;
+  inline typed::union_set<> preimage(const typed::multi_aff<> &ma) const = delete;
+  inline typed::union_set<> preimage(const typed::pw_multi_aff<> &pma) const = delete;
+  inline typed::union_set<> preimage(const typed::union_pw_multi_aff<> &upma) const = delete;
+  inline typed::space<> space() const;
+  inline typed::space<> get_space() const = delete;
+  inline typed::union_set<> subtract(const typed::union_set<> &uset2) const;
+  inline typed::union_set<> subtract(const typed::basic_set<> &uset2) const;
+  inline typed::union_set<> subtract(const typed::point<> &uset2) const;
+  inline typed::union_set<> subtract(const typed::set<> &uset2) const;
+  inline typed::union_set<> unite(const typed::union_set<> &uset2) const;
+  inline typed::union_set<> unite(const typed::basic_set<> &uset2) const;
+  inline typed::union_set<> unite(const typed::point<> &uset2) const;
+  inline typed::union_set<> unite(const typed::set<> &uset2) const;
+  inline typed::union_set<> universe() const;
+  inline typed::union_map<> unwrap() const = delete;
+};
+
+template <typename Domain>
+struct union_set<Domain> : public isl::union_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_set() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_set(const union_set<Arg1> &obj) : isl::union_set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_set>{}, bool>::type = true>
+  union_set(const base &obj) : isl::union_set(obj) {}
+ public:
+  static union_set from(const isl::union_set &obj) {
+    return union_set(obj);
+  }
+  inline /* implicit */ union_set(const typed::basic_set<Domain> &bset);
+  inline /* implicit */ union_set(const typed::point<Domain> &pnt);
+  inline /* implicit */ union_set(const typed::set<Domain> &set);
+  inline explicit union_set(const isl::ctx &ctx, const std::string &str);
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::union_map<Domain, Range> &umap) const;
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::basic_map<Domain, Range> &umap) const;
+  template <typename Range>
+  inline typed::union_set<Range> apply(const typed::map<Domain, Range> &umap) const;
+  inline typed::set<Domain> as_set() const;
+  inline typed::union_set<Domain> coalesce() const;
+  inline typed::union_set<Domain> detect_equalities() const;
+  static inline typed::union_set<Domain> empty(const isl::ctx &ctx);
+  inline bool every_set(const std::function<bool(typed::set<Domain>)> &test) const;
+  inline typed::set<Domain> extract_set(const typed::space<Domain> &space) const;
+  inline void foreach_point(const std::function<void(typed::point<Domain>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<Domain>)> &fn) const;
+  inline typed::union_set<Domain> gist(const typed::union_set<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::basic_set<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::point<Domain> &context) const;
+  inline typed::union_set<Domain> gist(const typed::set<Domain> &context) const;
+  inline typed::union_map<Domain, Domain> identity() const;
+  inline typed::union_set<Domain> intersect(const typed::union_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> intersect(const typed::basic_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> intersect(const typed::point<Domain> &uset2) const;
+  inline typed::union_set<Domain> intersect(const typed::set<Domain> &uset2) const;
+  inline typed::union_set<Domain> intersect_params(const typed::set<> &set) const;
+  inline typed::union_set<Domain> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_set<Domain> intersect_params(const typed::point<> &set) const;
+  inline typed::union_set<Domain> lexmax() const;
+  inline typed::union_set<Domain> lexmin() const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::multi_aff<Domain2, Domain> &ma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const;
+  inline typed::space<> space() const;
+  inline typed::space<Domain> get_space() const = delete;
+  inline typed::union_set<Domain> subtract(const typed::union_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> subtract(const typed::basic_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> subtract(const typed::point<Domain> &uset2) const;
+  inline typed::union_set<Domain> subtract(const typed::set<Domain> &uset2) const;
+  inline typed::union_set<Domain> unite(const typed::union_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> unite(const typed::basic_set<Domain> &uset2) const;
+  inline typed::union_set<Domain> unite(const typed::point<Domain> &uset2) const;
+  inline typed::union_set<Domain> unite(const typed::set<Domain> &uset2) const;
+  inline typed::union_set<Domain> universe() const;
+  inline typed::union_map<Domain> unwrap() const = delete;
+};
+
+template <typename Domain, typename Range>
+struct union_set<pair<Domain, Range>> : public isl::union_set {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_set() = default;
+  template <typename Arg1, typename Arg2,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{} &&
+              std::is_base_of<Range, Arg2>{},
+            bool>::type = true>
+  union_set(const union_set<pair<Arg1, Arg2>> &obj) : isl::union_set(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_set>{}, bool>::type = true>
+  union_set(const base &obj) : isl::union_set(obj) {}
+ public:
+  static union_set from(const isl::union_set &obj) {
+    return union_set(obj);
+  }
+  inline /* implicit */ union_set(const typed::basic_set<pair<Domain, Range>> &bset);
+  inline /* implicit */ union_set(const typed::point<pair<Domain, Range>> &pnt);
+  inline /* implicit */ union_set(const typed::set<pair<Domain, Range>> &set);
+  inline explicit union_set(const isl::ctx &ctx, const std::string &str);
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const;
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::basic_map<pair<Domain, Range>, Arg2> &umap) const;
+  template <typename Arg2>
+  inline typed::union_set<Arg2> apply(const typed::map<pair<Domain, Range>, Arg2> &umap) const;
+  inline typed::set<pair<Domain, Range>> as_set() const;
+  inline typed::union_set<pair<Domain, Range>> coalesce() const;
+  inline typed::union_set<pair<Domain, Range>> detect_equalities() const;
+  static inline typed::union_set<pair<Domain, Range>> empty(const isl::ctx &ctx);
+  inline bool every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const;
+  inline typed::set<pair<Domain, Range>> extract_set(const typed::space<pair<Domain, Range>> &space) const;
+  inline void foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const;
+  inline void foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::union_set<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::basic_set<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::point<pair<Domain, Range>> &context) const;
+  inline typed::union_set<pair<Domain, Range>> gist(const typed::set<pair<Domain, Range>> &context) const;
+  inline typed::union_map<pair<Domain, Range>, pair<Domain, Range>> identity() const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::basic_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::point<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect(const typed::set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> intersect_params(const typed::set<> &set) const;
+  inline typed::union_set<pair<Domain, Range>> intersect_params(const typed::basic_set<> &set) const;
+  inline typed::union_set<pair<Domain, Range>> intersect_params(const typed::point<> &set) const;
+  inline typed::union_set<pair<Domain, Range>> lexmax() const;
+  inline typed::union_set<pair<Domain, Range>> lexmin() const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const;
+  template <typename Domain2>
+  inline typed::union_set<Domain2> preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const;
+  inline typed::space<> space() const;
+  inline typed::space<pair<Domain, Range>> get_space() const = delete;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::basic_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::point<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> subtract(const typed::set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::union_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::basic_set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::point<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> unite(const typed::set<pair<Domain, Range>> &uset2) const;
+  inline typed::union_set<pair<Domain, Range>> universe() const;
+  inline typed::union_map<Domain, Range> unwrap() const;
+};
+
+template <>
+struct union_set_list<> : public isl::union_set_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_set_list() = default;
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_set_list>{}, bool>::type = true>
+  union_set_list(const base &obj) : isl::union_set_list(obj) {}
+ public:
+  static union_set_list from(const isl::union_set_list &obj) {
+    return union_set_list(obj);
+  }
+  inline explicit union_set_list(const isl::ctx &ctx, int n);
+  inline explicit union_set_list(const typed::union_set<> &el);
+  inline explicit union_set_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_set_list<> add(const typed::union_set<> &el) const;
+  inline typed::union_set_list<> add(const typed::basic_set<> &el) const;
+  inline typed::union_set_list<> add(const typed::point<> &el) const;
+  inline typed::union_set_list<> add(const typed::set<> &el) const;
+  inline typed::union_set<> at(int index) const = delete;
+  inline typed::union_set<> get_at(int index) const = delete;
+  inline typed::union_set_list<> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::union_set<>)> &fn) const;
+};
+
+template <typename Domain>
+struct union_set_list<Domain> : public isl::union_set_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  union_set_list() = default;
+  template <typename Arg1,
+            typename std::enable_if<
+              std::is_base_of<Domain, Arg1>{},
+            bool>::type = true>
+  union_set_list(const union_set_list<Arg1> &obj) : isl::union_set_list(obj) {}
+ private:
+  template <typename base,
+            typename std::enable_if<
+              std::is_same<base, isl::union_set_list>{}, bool>::type = true>
+  union_set_list(const base &obj) : isl::union_set_list(obj) {}
+ public:
+  static union_set_list from(const isl::union_set_list &obj) {
+    return union_set_list(obj);
+  }
+  inline explicit union_set_list(const isl::ctx &ctx, int n);
+  inline explicit union_set_list(const typed::union_set<Domain> &el);
+  inline explicit union_set_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::union_set_list<Domain> add(const typed::union_set<Domain> &el) const;
+  inline typed::union_set_list<Domain> add(const typed::basic_set<Domain> &el) const;
+  inline typed::union_set_list<Domain> add(const typed::point<Domain> &el) const;
+  inline typed::union_set_list<Domain> add(const typed::set<Domain> &el) const;
+  inline typed::union_set<Domain> at(int index) const;
+  inline typed::union_set<Domain> get_at(int index) const = delete;
+  inline typed::union_set_list<Domain> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::union_set<Domain>)> &fn) const;
+};
+
+template <>
+struct val<Anonymous> : public isl::val {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  val() = default;
+  val(const isl::val &obj) : isl::val(obj) {}
+  static val from(const isl::val &obj) {
+    return val(obj);
+  }
+  inline explicit val(const isl::ctx &ctx, long i);
+  inline explicit val(const isl::ctx &ctx, const std::string &str);
+  inline typed::val<Anonymous> add(const typed::val<Anonymous> &v2) const;
+  inline typed::val<Anonymous> add(long v2) const;
+  inline typed::val<Anonymous> ceil() const;
+  inline long get_den_si() const = delete;
+  inline typed::val<Anonymous> floor() const;
+  inline typed::val<Anonymous> max(const typed::val<Anonymous> &v2) const;
+  inline typed::val<Anonymous> max(long v2) const;
+  inline typed::val<Anonymous> min(const typed::val<Anonymous> &v2) const;
+  inline typed::val<Anonymous> min(long v2) const;
+  inline typed::val<Anonymous> mod(const typed::val<Anonymous> &v2) const;
+  inline typed::val<Anonymous> mod(long v2) const;
+  inline typed::val<Anonymous> neg() const;
+  inline long get_num_si() const = delete;
+  inline typed::val<Anonymous> sub(const typed::val<Anonymous> &v2) const;
+  inline typed::val<Anonymous> sub(long v2) const;
+};
+
+template <>
+struct val_list<Anonymous> : public isl::val_list {
+  template <typename...>
+  friend struct aff;
+  template <typename...>
+  friend struct aff_list;
+  template <typename...>
+  friend struct basic_map;
+  template <typename...>
+  friend struct basic_set;
+  template <typename...>
+  friend struct fixed_box;
+  template <typename...>
+  friend struct id;
+  template <typename...>
+  friend struct id_list;
+  template <typename...>
+  friend struct map;
+  template <typename...>
+  friend struct map_list;
+  template <typename...>
+  friend struct multi_aff;
+  template <typename...>
+  friend struct multi_id;
+  template <typename...>
+  friend struct multi_pw_aff;
+  template <typename...>
+  friend struct multi_union_pw_aff;
+  template <typename...>
+  friend struct multi_val;
+  template <typename...>
+  friend struct point;
+  template <typename...>
+  friend struct pw_aff;
+  template <typename...>
+  friend struct pw_aff_list;
+  template <typename...>
+  friend struct pw_multi_aff;
+  template <typename...>
+  friend struct pw_multi_aff_list;
+  template <typename...>
+  friend struct set;
+  template <typename...>
+  friend struct space;
+  template <typename...>
+  friend struct union_map;
+  template <typename...>
+  friend struct union_pw_aff;
+  template <typename...>
+  friend struct union_pw_aff_list;
+  template <typename...>
+  friend struct union_pw_multi_aff;
+  template <typename...>
+  friend struct union_set;
+  template <typename...>
+  friend struct union_set_list;
+  template <typename...>
+  friend struct val;
+  template <typename...>
+  friend struct val_list;
+
+  val_list() = default;
+  val_list(const isl::val_list &obj) : isl::val_list(obj) {}
+  static val_list from(const isl::val_list &obj) {
+    return val_list(obj);
+  }
+  inline explicit val_list(const isl::ctx &ctx, int n);
+  inline explicit val_list(const typed::val<Anonymous> &el);
+  inline explicit val_list(const isl::ctx &ctx, const std::string &str);
+  inline typed::val_list<Anonymous> add(const typed::val<Anonymous> &el) const;
+  inline typed::val_list<Anonymous> add(long el) const;
+  inline typed::val<Anonymous> at(int index) const;
+  inline typed::val<Anonymous> get_at(int index) const = delete;
+  inline typed::val_list<Anonymous> drop(unsigned int first, unsigned int n) const;
+  inline void foreach(const std::function<void(typed::val<Anonymous>)> &fn) const;
+};
+
+typed::aff<Anonymous>::aff(const isl::ctx &ctx, const std::string &str)
+  : isl::aff(ctx, str)
+{
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::add(const typed::aff<Anonymous> &aff2) const
+{
+  auto res = isl::aff::add(aff2);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::add(const typed::multi_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::add(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::add(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::add(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::add(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::aff::add(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::aff<Anonymous>::add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::aff::add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::aff<Anonymous>::add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::aff::add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::add_constant(long v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::add_constant(mv);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::aff<Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const
+{
+  auto res = isl::aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::as_aff() const
+{
+  auto res = isl::aff::as_aff();
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::as_multi_aff() const
+{
+  auto res = isl::aff::as_multi_aff();
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::set<Anonymous> typed::aff<Anonymous>::as_set() const
+{
+  auto res = isl::aff::as_set();
+  return typed::set<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::at(int pos) const
+{
+  auto res = isl::aff::at(pos);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::basic_set<> typed::aff<Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<>(res);
+}
+
+typed::basic_set<> typed::aff<Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<>(res);
+}
+
+typed::basic_set<> typed::aff<Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::aff::bind(tuple);
+  return typed::basic_set<>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::ceil() const
+{
+  auto res = isl::aff::ceil();
+  return typed::aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::coalesce() const
+{
+  auto res = isl::aff::coalesce();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::cond(const typed::pw_aff<Anonymous> &pwaff_true, const typed::pw_aff<Anonymous> &pwaff_false) const
+{
+  auto res = isl::aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_val<Anonymous> typed::aff<Anonymous>::constant_multi_val() const
+{
+  auto res = isl::aff::constant_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+typed::set<> typed::aff<Anonymous>::domain() const
+{
+  auto res = isl::aff::domain();
+  return typed::set<>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::extract_pw_multi_aff(const typed::space<Anonymous> &space) const
+{
+  auto res = isl::aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::floor() const
+{
+  auto res = isl::aff::floor();
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::gist(const typed::set<> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::aff<Anonymous>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::gist(const typed::point<> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous, Anonymous> typed::aff<Anonymous>::identity() const
+{
+  auto res = isl::aff::identity();
+  return typed::multi_aff<Anonymous, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Anonymous>::insert_domain(const typed::space<Domain> &domain) const
+{
+  auto res = isl::aff::insert_domain(domain);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::aff::intersect_params(set);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::aff_list<Anonymous> typed::aff<Anonymous>::list() const
+{
+  auto res = isl::aff::list();
+  return typed::aff_list<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::max(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::max(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::max(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::max(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_val<Anonymous> typed::aff<Anonymous>::max_multi_val() const
+{
+  auto res = isl::aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::min(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::min(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::min(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::min(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_val<Anonymous> typed::aff<Anonymous>::min_multi_val() const
+{
+  auto res = isl::aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::mod(long mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::neg() const
+{
+  auto res = isl::aff::neg();
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Range>
+typed::multi_aff<pair<Anonymous, Range>> typed::aff<Anonymous>::product(const typed::multi_aff<Range> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_aff<pair<Anonymous, Range>>(res);
+}
+
+template <typename Range>
+typed::multi_pw_aff<pair<Anonymous, Range>> typed::aff<Anonymous>::product(const typed::multi_pw_aff<Range> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_pw_aff<pair<Anonymous, Range>>(res);
+}
+
+template <typename Range>
+typed::pw_multi_aff<pair<Anonymous, Range>> typed::aff<Anonymous>::product(const typed::pw_multi_aff<Range> &pma2) const
+{
+  auto res = isl::aff::product(pma2);
+  return typed::pw_multi_aff<pair<Anonymous, Range>>(res);
+}
+
+typed::pw_multi_aff_list<Anonymous> typed::aff<Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::scale(long v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale(mv);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::scale_down(long v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale_down(mv);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::set_at(int pos, const typed::aff<Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::set_at(int pos, const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2>
+typed::multi_aff<Domain2> typed::aff<Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<Domain2>(res);
+}
+
+template <typename Domain2>
+typed::multi_aff<Domain2> typed::aff<Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<Domain2>(res);
+}
+
+typed::space<Anonymous> typed::aff<Anonymous>::space() const
+{
+  auto res = isl::aff::space();
+  return typed::space<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff<Anonymous>::sub(const typed::aff<Anonymous> &aff2) const
+{
+  auto res = isl::aff::sub(aff2);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::multi_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::sub(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::aff::sub(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::aff::sub(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::aff<Anonymous>::sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::aff::sub(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::to_multi_union_pw_aff() const
+{
+  auto res = isl::aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::to_pw_multi_aff() const
+{
+  auto res = isl::aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::aff<Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::aff::to_union_pw_aff();
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::aff<Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Anonymous>::unbind_params_insert_domain(const typed::multi_id<Domain> &domain) const
+{
+  auto res = isl::aff::unbind_params_insert_domain(domain);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::multi_pw_aff<Anonymous> &mpa2) const
+{
+  auto res = isl::aff::union_add(mpa2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const
+{
+  auto res = isl::aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::union_add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::aff::union_add(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::aff::union_add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::aff<Anonymous>::union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous>::aff(const isl::ctx &ctx, const std::string &str)
+  : isl::aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::add(aff2);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::multi_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::aff::add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add_constant(long v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::add_constant(mv);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::aff<Domain, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const
+{
+  auto res = isl::aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_aff() const
+{
+  auto res = isl::aff::as_aff();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_map() const
+{
+  auto res = isl::aff::as_map();
+  return typed::map<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_multi_aff() const
+{
+  auto res = isl::aff::as_multi_aff();
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Anonymous> typed::aff<Domain, Anonymous>::as_union_map() const
+{
+  auto res = isl::aff::as_union_map();
+  return typed::union_map<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::at(int pos) const
+{
+  auto res = isl::aff::at(pos);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::aff<Domain, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::aff<Domain, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::aff<Domain, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::aff::bind(tuple);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::aff<Domain, Anonymous>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::aff::bind_domain(tuple);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::ceil() const
+{
+  auto res = isl::aff::ceil();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::coalesce() const
+{
+  auto res = isl::aff::coalesce();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::cond(const typed::pw_aff<Domain, Anonymous> &pwaff_true, const typed::pw_aff<Domain, Anonymous> &pwaff_false) const
+{
+  auto res = isl::aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Anonymous> typed::aff<Domain, Anonymous>::constant_multi_val() const
+{
+  auto res = isl::aff::constant_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::domain() const
+{
+  auto res = isl::aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const
+{
+  auto res = isl::aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::floor() const
+{
+  auto res = isl::aff::floor();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::ge_set(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::ge_set(aff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::ge_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::ge_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::gt_set(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::gt_set(aff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::gt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::gt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::identity() const
+{
+  auto res = isl::aff::identity();
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::aff::intersect_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::aff::intersect_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::aff::intersect_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::aff::intersect_params(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::le_set(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::le_set(aff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::le_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::le_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous> typed::aff<Domain, Anonymous>::list() const
+{
+  auto res = isl::aff::list();
+  return typed::aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::lt_set(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::lt_set(aff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::aff<Domain, Anonymous>::lt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::lt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::max(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::max(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::max(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Anonymous> typed::aff<Domain, Anonymous>::max_multi_val() const
+{
+  auto res = isl::aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::min(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::min(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::min(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Anonymous> typed::aff<Domain, Anonymous>::min_multi_val() const
+{
+  auto res = isl::aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::mod(long mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::neg() const
+{
+  auto res = isl::aff::neg();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::product(const typed::multi_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::aff<Domain2, Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_aff<Domain2, Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::aff::pullback(mpa);
+  return typed::pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::multi_pw_aff<Domain> &mpa) const
+{
+  auto res = isl::aff::pullback(mpa);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_aff<Domain2, Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::aff::pullback(pma);
+  return typed::pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain> &pma) const
+{
+  auto res = isl::aff::pullback(pma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::aff<Domain2, Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Anonymous> typed::aff<Domain, Anonymous>::pullback(const typed::aff<Domain> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain, Anonymous> typed::aff<Domain, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_aff<Domain, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::range_product(const typed::multi_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> typed::aff<Domain, Anonymous>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale(long v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale(mv);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale_down(long v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale_down(mv);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::set_at(int pos, const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_aff<Domain, Range2> typed::aff<Domain, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_aff<Domain, Range2> typed::aff<Domain, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain, Anonymous> typed::aff<Domain, Anonymous>::space() const
+{
+  auto res = isl::aff::space();
+  return typed::space<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::aff<Domain, Anonymous> &aff2) const
+{
+  auto res = isl::aff::sub(aff2);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::multi_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::sub(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::aff::sub(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::aff::subtract_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::aff::subtract_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::aff::subtract_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::to_multi_union_pw_aff() const
+{
+  auto res = isl::aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::to_pw_multi_aff() const
+{
+  auto res = isl::aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::aff::to_union_pw_aff();
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::multi_pw_aff<Domain, Anonymous> &mpa2) const
+{
+  auto res = isl::aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const
+{
+  auto res = isl::aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::union_add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::aff::union_add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::aff<Domain, Anonymous>::union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous>::aff(const isl::ctx &ctx, const std::string &str)
+  : isl::aff(ctx, str)
+{
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::add(aff2);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::multi_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::aff::add(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add_constant(long v) const
+{
+  auto res = isl::aff::add_constant(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::add_constant(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::aff<pair<Domain2, Range2>, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Arg1> &upma2) const
+{
+  auto res = isl::aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_aff() const
+{
+  auto res = isl::aff::as_aff();
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_map() const
+{
+  auto res = isl::aff::as_map();
+  return typed::map<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_multi_aff() const
+{
+  auto res = isl::aff::as_multi_aff();
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::as_union_map() const
+{
+  auto res = isl::aff::as_union_map();
+  return typed::union_map<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::at(int pos) const
+{
+  auto res = isl::aff::at(pos);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::basic_set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::basic_set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::aff::bind(id);
+  return typed::basic_set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::basic_set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::aff::bind(tuple);
+  return typed::basic_set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const
+{
+  auto res = isl::aff::bind_domain(tuple);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Range2, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const
+{
+  auto res = isl::aff::bind_domain_wrapped_domain(tuple);
+  return typed::pw_aff<Range2, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::ceil() const
+{
+  auto res = isl::aff::ceil();
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::coalesce() const
+{
+  auto res = isl::aff::coalesce();
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::cond(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_true, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_false) const
+{
+  auto res = isl::aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_val<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::constant_multi_val() const
+{
+  auto res = isl::aff::constant_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::domain() const
+{
+  auto res = isl::aff::domain();
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Anonymous> &space) const
+{
+  auto res = isl::aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::floor() const
+{
+  auto res = isl::aff::floor();
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::ge_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::ge_set(aff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::ge_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::ge_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::union_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::basic_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::point<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::aff::gist(context);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::gt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::gt_set(aff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::gt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::gt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::identity() const
+{
+  auto res = isl::aff::identity();
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::aff::intersect_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::aff::intersect_domain(space);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::aff::intersect_domain(uset);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::aff::intersect_params(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::le_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::le_set(aff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::le_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::le_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff_list<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::list() const
+{
+  auto res = isl::aff::list();
+  return typed::aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::lt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::lt_set(aff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::aff<pair<Domain2, Range2>, Anonymous>::lt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::lt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::max(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::max(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::max(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_val<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::max_multi_val() const
+{
+  auto res = isl::aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::min(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::min(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::min(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_val<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::min_multi_val() const
+{
+  auto res = isl::aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::mod(long mod) const
+{
+  auto res = isl::aff::mod(mod);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::neg() const
+{
+  auto res = isl::aff::neg();
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const
+{
+  auto res = isl::aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1, typename Arg2>
+typed::multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> typed::aff<pair<Domain2, Range2>, Anonymous>::product(const typed::multi_aff<Arg1, Arg2> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1, typename Arg2>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> typed::aff<pair<Domain2, Range2>, Anonymous>::product(const typed::multi_pw_aff<Arg1, Arg2> &multi2) const
+{
+  auto res = isl::aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1, typename Arg2>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> typed::aff<pair<Domain2, Range2>, Anonymous>::product(const typed::pw_multi_aff<Arg1, Arg2> &pma2) const
+{
+  auto res = isl::aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::aff<Arg1, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_aff<Arg1, pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_aff<Arg1, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_pw_aff<Arg1, pair<Domain2, Range2>> &mpa) const
+{
+  auto res = isl::aff::pullback(mpa);
+  return typed::pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa) const
+{
+  auto res = isl::aff::pullback(mpa);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_aff<Arg1, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::pw_multi_aff<Arg1, pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::aff::pullback(pma);
+  return typed::pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::aff::pullback(pma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_aff<Arg1, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::union_pw_multi_aff<Arg1, pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::aff::pullback(upma);
+  return typed::union_pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::aff<Arg1, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::aff<Arg1, pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::aff<pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::aff::pullback(ma);
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg1> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const
+{
+  auto res = isl::aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> &pma2) const
+{
+  auto res = isl::aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> &upma2) const
+{
+  auto res = isl::aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale(long v) const
+{
+  auto res = isl::aff::scale(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale_down(long v) const
+{
+  auto res = isl::aff::scale_down(v);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::aff::scale_down(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::set_at(int pos, const typed::aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_aff<pair<Domain2, Range2>, Arg1> typed::aff<pair<Domain2, Range2>, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_aff<pair<Domain2, Range2>, Arg1> typed::aff<pair<Domain2, Range2>, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::aff::set_range_tuple(id);
+  return typed::multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::space<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::space() const
+{
+  auto res = isl::aff::space();
+  return typed::space<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff2) const
+{
+  auto res = isl::aff::sub(aff2);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::multi_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::sub(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::aff::sub(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::aff::subtract_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::aff::subtract_domain(space);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::aff::subtract_domain(uset);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::to_multi_union_pw_aff() const
+{
+  auto res = isl::aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::to_pw_multi_aff() const
+{
+  auto res = isl::aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::aff::to_union_pw_aff();
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &mpa2) const
+{
+  auto res = isl::aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &mupa2) const
+{
+  auto res = isl::aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::aff::union_add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::aff::union_add(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+typed::aff_list<Anonymous>::aff_list(const isl::ctx &ctx, int n)
+  : isl::aff_list(ctx, n)
+{
+}
+
+typed::aff_list<Anonymous>::aff_list(const typed::aff<Anonymous> &el)
+  : isl::aff_list(el)
+{
+}
+
+typed::aff_list<Anonymous>::aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::aff_list(ctx, str)
+{
+}
+
+typed::aff_list<Anonymous> typed::aff_list<Anonymous>::add(const typed::aff<Anonymous> &el) const
+{
+  auto res = isl::aff_list::add(el);
+  return typed::aff_list<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::aff_list<Anonymous>::at(int index) const
+{
+  auto res = isl::aff_list::at(index);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff_list<Anonymous> typed::aff_list<Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::aff_list::drop(first, n);
+  return typed::aff_list<Anonymous>(res);
+}
+
+void typed::aff_list<Anonymous>::foreach(const std::function<void(typed::aff<Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::aff arg0) {
+    return fn(typed::aff<Anonymous>(arg0));
+  };
+  return isl::aff_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous>::aff_list(const isl::ctx &ctx, int n)
+  : isl::aff_list(ctx, n)
+{
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous>::aff_list(const typed::aff<Domain, Anonymous> &el)
+  : isl::aff_list(el)
+{
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous>::aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::aff_list(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous> typed::aff_list<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::aff_list::add(el);
+  return typed::aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::aff_list<Domain, Anonymous>::at(int index) const
+{
+  auto res = isl::aff_list::at(index);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff_list<Domain, Anonymous> typed::aff_list<Domain, Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::aff_list::drop(first, n);
+  return typed::aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+void typed::aff_list<Domain, Anonymous>::foreach(const std::function<void(typed::aff<Domain, Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::aff arg0) {
+    return fn(typed::aff<Domain, Anonymous>(arg0));
+  };
+  return isl::aff_list::foreach(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::basic_map<Domain2, Range> typed::basic_map<Domain, Range>::apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::basic_map<Domain, Range>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::basic_map<Domain, Range2> typed::basic_map<Domain, Range>::apply_range(const typed::basic_map<Range, Range2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Range>::apply_range(const typed::map<Range, Range2> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::basic_map<Domain, Range>::apply_range(const typed::union_map<Range, Range2> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::basic_map<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::basic_map<Domain, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::basic_map<Domain, Range>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Range> typed::basic_map<Domain, Range>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::basic_map<Domain, Range>::bind_range(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::basic_map<Domain, Range>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Domain> typed::basic_map<Domain, Range>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Range>, Domain> typed::basic_map<Domain, Range>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Range> typed::basic_map<Domain, Range>::domain_product(const typed::map<Domain2, Range> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Range> typed::basic_map<Domain, Range>::domain_product(const typed::union_map<Domain2, Range> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::basic_map<Domain, Range>::every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Range>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::extract_map(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::basic_map<Domain, Range>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, Range>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::basic_map<Domain, Range>::foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Range>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::gist(const typed::basic_map<Domain, Range> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::gist(const typed::map<Domain, Range> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::gist(const typed::union_map<Domain, Range> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::intersect(const typed::basic_map<Domain, Range> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::intersect(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::intersect(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_domain(const typed::basic_set<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_domain(const typed::point<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_range(const typed::basic_set<Range> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::intersect_range(const typed::set<Range> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_range(const typed::space<Range> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_range(const typed::union_set<Range> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Domain, Range> typed::basic_map<Domain, Range>::intersect_range(const typed::point<Range> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::basic_map<Domain, Range>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::basic_map<Domain, Range>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::lower_bound(const typed::multi_pw_aff<Domain, Range> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::basic_map<Domain, Range>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::basic_map<Domain, Range>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::basic_map<Domain, Range>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::basic_map<Domain, Range>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Range>::preimage_range(const typed::multi_aff<Range2, Range> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Range>::preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::basic_map<Domain, Range>::preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::basic_map<Domain, Range>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::basic_map<Domain, Range>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Range> typed::basic_map<Domain, Range>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<Domain, Range> typed::basic_map<Domain, Range>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Range> typed::basic_map<Domain, Range>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<Domain, Range>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, Range>::range_product(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, Range>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<Domain, Range> typed::basic_map<Domain, Range>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_map<Range, Domain> typed::basic_map<Domain, Range>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<Range, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::basic_map<Domain, Range>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::basic_map<Domain, Range>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::subtract(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::subtract(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::subtract_range(const typed::union_set<Range> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::unite(const typed::basic_map<Domain, Range> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::unite(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::basic_map<Domain, Range>::unite(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_map<Domain, Range>::upper_bound(const typed::multi_pw_aff<Domain, Range> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_map<Domain, Range>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::basic_map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::apply_domain(const typed::map<pair<Domain, Range>, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::basic_map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::apply_range(const typed::basic_map<Range2, Arg3> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::apply_range(const typed::map<Range2, Arg3> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::apply_range(const typed::union_map<Range2, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Range2> typed::basic_map<pair<Domain, Range>, Range2>::bind_domain(const typed::multi_id<pair<Domain, Range>> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, Range>> typed::basic_map<pair<Domain, Range>, Range2>::bind_range(const typed::multi_id<Range2> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<pair<Domain, Range>, Range2>::curry() const
+{
+  auto res = isl::basic_map::curry();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, Range>> typed::basic_map<pair<Domain, Range>, Range2>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range2> typed::basic_map<pair<Domain, Range>, Range2>::domain_factor_domain() const
+{
+  auto res = isl::basic_map::domain_factor_domain();
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Range, Range2> typed::basic_map<pair<Domain, Range>, Range2>::domain_factor_range() const
+{
+  auto res = isl::basic_map::domain_factor_range();
+  return typed::map<Range, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::basic_map<pair<Domain, Range>, Range2>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::basic_map<pair<Domain, Range>, Range2>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<Domain, Range>, Domain2>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::domain_product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::domain_product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::basic_map<pair<Domain, Range>, Range2>::every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Anonymous, Range2> typed::basic_map<pair<Domain, Range>, Range2>::flatten_domain() const
+{
+  auto res = isl::basic_map::flatten_domain();
+  return typed::basic_map<Anonymous, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::basic_map<pair<Domain, Range>, Range2>::foreach_basic_map(const std::function<void(typed::basic_map<pair<Domain, Range>, Range2>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::basic_map<pair<Domain, Range>, Range2>::foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::gist(const typed::map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::gist_domain(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect(const typed::basic_map<pair<Domain, Range>, Range2> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::basic_set<pair<Domain, Range>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::set<pair<Domain, Range>> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::point<pair<Domain, Range>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_range(const typed::basic_set<Range2> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_range(const typed::set<Range2> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_range(const typed::space<Range2> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_range(const typed::union_set<Range2> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::intersect_range(const typed::point<Range2> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::lower_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::basic_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::basic_map<pair<Domain, Range>, Range2>::preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::basic_map<pair<Domain, Range>, Range2>::product(const typed::map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::basic_map<pair<Domain, Range>, Range2>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Range2> typed::basic_map<pair<Domain, Range>, Range2>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, pair<Range2, Arg3>> typed::basic_map<pair<Domain, Range>, Range2>::range_product(const typed::map<pair<Domain, Range>, Arg3> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> typed::basic_map<pair<Domain, Range>, Range2>::range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Range2, pair<Domain, Range>> typed::basic_map<pair<Domain, Range>, Range2>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<Range2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<Domain, Range>, Arg2> typed::basic_map<pair<Domain, Range>, Range2>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<Domain, Range>, Arg2> typed::basic_map<pair<Domain, Range>, Range2>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::subtract(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::subtract_range(const typed::union_set<Range2> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::unite(const typed::basic_map<pair<Domain, Range>, Range2> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::unite(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<pair<Domain, Range>, Range2>::upper_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<pair<Domain, Range>, Range2>> typed::basic_map<pair<Domain, Range>, Range2>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<pair<Domain, Range>, Range2>>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::basic_map<Domain2, Domain> typed::basic_map<Domain, Domain>::apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::basic_map<Domain, Domain>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::basic_map<Domain, Range2> typed::basic_map<Domain, Domain>::apply_range(const typed::basic_map<Domain, Range2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Domain>::apply_range(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::basic_map<Domain, Domain>::apply_range(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Domain> typed::basic_map<Domain, Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::basic_map<Domain, Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Domain> typed::basic_map<Domain, Domain>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_map<Domain, Domain>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_map<Domain, Domain>::bind_range(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_map<Domain, Domain>::deltas() const
+{
+  auto res = isl::basic_map::deltas();
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_map<Domain, Domain>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::basic_map<Domain, Domain>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> typed::basic_map<Domain, Domain>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Domain> typed::basic_map<Domain, Domain>::domain_product(const typed::map<Domain2, Domain> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Domain> typed::basic_map<Domain, Domain>::domain_product(const typed::union_map<Domain2, Domain> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::eq_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::basic_map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const
+{
+  auto res = isl::basic_map::eq_at(mupa);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+bool typed::basic_map<Domain, Domain>::every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::extract_map(const typed::space<Domain, Domain> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+void typed::basic_map<Domain, Domain>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, Domain>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename Domain>
+void typed::basic_map<Domain, Domain>::foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::gist(const typed::basic_map<Domain, Domain> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::gist(const typed::map<Domain, Domain> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::gist(const typed::union_map<Domain, Domain> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect(const typed::basic_map<Domain, Domain> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_domain(const typed::basic_set<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_domain(const typed::point<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_range(const typed::basic_set<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_range(const typed::set<Domain> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_range(const typed::space<Domain> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_range(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::intersect_range(const typed::point<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lex_ge_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lex_gt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lex_le_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lex_lt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::basic_map<Domain, Domain>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::basic_map<Domain, Domain>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::lower_bound(const typed::multi_pw_aff<Domain, Domain> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map_list<Domain, Domain> typed::basic_map<Domain, Domain>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::basic_map<Domain, Domain>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::basic_map<Domain, Domain>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::basic_map<Domain, Domain>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Domain>::preimage_range(const typed::multi_aff<Range2, Domain> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Domain>::preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::basic_map<Domain, Domain>::preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::basic_map<Domain, Domain>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::basic_map<Domain, Domain>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_map<Domain, Domain>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain, Domain> typed::basic_map<Domain, Domain>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::basic_map<Domain, Domain>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, pair<Domain, Range2>> typed::basic_map<Domain, Domain>::range_product(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, pair<Domain, Range2>> typed::basic_map<Domain, Domain>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain, Domain> typed::basic_map<Domain, Domain>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_map<Domain, Domain> typed::basic_map<Domain, Domain>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::basic_map<Domain, Domain>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain, Domain> typed::basic_map<Domain, Domain>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::subtract(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::subtract(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::subtract_range(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::unite(const typed::basic_map<Domain, Domain> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::unite(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::basic_map<Domain, Domain>::unite(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_map<Domain, Domain>::upper_bound(const typed::multi_pw_aff<Domain, Domain> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<pair<Domain, Domain>> typed::basic_map<Domain, Domain>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<Domain, Domain>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::basic_map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::apply_domain(const typed::basic_map<Domain, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::basic_map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg3> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::basic_map<Domain, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::basic_map<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> typed::basic_map<Domain, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> typed::basic_map<Domain, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::basic_map<Domain, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, Anonymous> typed::basic_map<Domain, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::basic_map::flatten_range();
+  return typed::basic_map<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::basic_map<Domain, pair<Range, Range2>>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::basic_map<Domain, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::gist(const typed::map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect(const typed::basic_map<Domain, pair<Range, Range2>> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::basic_set<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::point<Domain> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_range(const typed::basic_set<pair<Range, Range2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_range(const typed::set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::intersect_range(const typed::point<pair<Range, Range2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::lower_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::basic_map<Domain, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::basic_map<Domain, pair<Range, Range2>>::product(const typed::map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::basic_map<Domain, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range> typed::basic_map<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::basic_map::range_factor_domain();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range2> typed::basic_map<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::basic_map::range_factor_range();
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, pair<pair<Range, Range2>, Arg3>> typed::basic_map<Domain, pair<Range, Range2>>::range_product(const typed::map<Domain, Arg3> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> typed::basic_map<Domain, pair<Range, Range2>>::range_product(const typed::union_map<Domain, Arg3> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range2, Range>> typed::basic_map<Domain, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::basic_map::range_reverse();
+  return typed::map<Domain, pair<Range2, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_map<pair<Range, Range2>, Domain> typed::basic_map<Domain, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<pair<Range, Range2>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::basic_map::set_domain_tuple(id);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::subtract(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::basic_map<Domain, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::basic_map::uncurry();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::unite(const typed::basic_map<Domain, pair<Range, Range2>> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::unite(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::basic_map<Domain, pair<Range, Range2>>::upper_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, pair<Range, Range2>>> typed::basic_map<Domain, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<Domain, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::basic_map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::basic_map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::basic_map<pair<T1, T2>, Range2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T1, pair<T2, pair<T1, T2>>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::curry() const
+{
+  auto res = isl::basic_map::curry();
+  return typed::map<T1, pair<T2, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::deltas() const
+{
+  auto res = isl::basic_map::deltas();
+  return typed::basic_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T1, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_factor_domain() const
+{
+  auto res = isl::basic_map::domain_factor_domain();
+  return typed::map<T1, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_factor_range() const
+{
+  auto res = isl::basic_map::domain_factor_range();
+  return typed::map<T2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::map<Domain2, pair<T1, T2>> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::basic_map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const
+{
+  auto res = isl::basic_map::eq_at(mupa);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+bool typed::basic_map<pair<T1, T2>, pair<T1, T2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<Anonymous, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::flatten_domain() const
+{
+  auto res = isl::basic_map::flatten_domain();
+  return typed::basic_map<Anonymous, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, Anonymous> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::flatten_range() const
+{
+  auto res = isl::basic_map::flatten_range();
+  return typed::basic_map<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2>
+void typed::basic_map<pair<T1, T2>, pair<T1, T2>>::foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<T1, T2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename T1, typename T2>
+void typed::basic_map<pair<T1, T2>, pair<T1, T2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::basic_set<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::point<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::basic_set<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::point<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::basic_map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map_list<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, T1> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_factor_domain() const
+{
+  auto res = isl::basic_map::range_factor_domain();
+  return typed::map<pair<T1, T2>, T1>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, T2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_factor_range() const
+{
+  auto res = isl::basic_map::range_factor_range();
+  return typed::map<pair<T1, T2>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::fixed_box<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T2, T1>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_reverse() const
+{
+  auto res = isl::basic_map::range_reverse();
+  return typed::map<pair<T1, T2>, pair<T2, T1>>(res);
+}
+
+template <typename T1, typename T2>
+typed::fixed_box<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::basic_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::space<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<pair<T1, T2>, T1>, T2> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::uncurry() const
+{
+  auto res = isl::basic_map::uncurry();
+  return typed::map<pair<pair<T1, T2>, T1>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<pair<T1, T2>, pair<T1, T2>>> typed::basic_map<pair<T1, T2>, pair<T1, T2>>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<pair<T1, T2>, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::basic_map(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_map(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::basic_map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_domain(bmap2);
+  return typed::basic_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::basic_map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::basic_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::basic_map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &bmap2) const
+{
+  auto res = isl::basic_map::apply_range(bmap2);
+  return typed::basic_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg2> &map2) const
+{
+  auto res = isl::basic_map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const
+{
+  auto res = isl::basic_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::basic_map::as_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::basic_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::basic_map::bind_domain(tuple);
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::basic_map::bind_range(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::basic_map::coalesce();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T1, pair<T2, pair<Range, Range2>>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::curry() const
+{
+  auto res = isl::basic_map::curry();
+  return typed::map<T1, pair<T2, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::basic_map::detect_equalities();
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::basic_map::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T1, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_domain() const
+{
+  auto res = isl::basic_map::domain_factor_domain();
+  return typed::map<T1, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_range() const
+{
+  auto res = isl::basic_map::domain_factor_range();
+  return typed::map<T2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::basic_map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::basic_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+bool typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::every_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::basic_map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<Anonymous, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::flatten_domain() const
+{
+  auto res = isl::basic_map::flatten_domain();
+  return typed::basic_map<Anonymous, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, Anonymous> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::basic_map::flatten_range();
+  return typed::basic_map<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+void typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::foreach_basic_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+void typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::basic_map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::basic_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::basic_map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::basic_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap2) const
+{
+  auto res = isl::basic_map::intersect(bmap2);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::basic_set<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::basic_map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::basic_map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::basic_map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::point<pair<T1, T2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_domain(bset);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::basic_set<pair<Range, Range2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::basic_map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::basic_map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::basic_map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::point<pair<Range, Range2>> &bset) const
+{
+  auto res = isl::basic_map::intersect_range(bset);
+  return typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::basic_map::lexmax();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::basic_map::lexmin();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::basic_map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map_list<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::basic_map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::basic_map::preimage_domain(ma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::basic_map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::basic_map::preimage_domain(pma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::basic_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::basic_map::preimage_range(ma);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::basic_map::preimage_range(pma);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::basic_map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::map<Domain2, Arg2> &map2) const
+{
+  auto res = isl::basic_map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg2> &umap2) const
+{
+  auto res = isl::basic_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::basic_map::project_out_all_params();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range() const
+{
+  auto res = isl::basic_map::range();
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, Range> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::basic_map::range_factor_domain();
+  return typed::map<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::basic_map::range_factor_range();
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_lattice_tile() const
+{
+  auto res = isl::basic_map::range_lattice_tile();
+  return typed::fixed_box<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::basic_map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::map<pair<T1, T2>, Arg2> &map2) const
+{
+  auto res = isl::basic_map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const
+{
+  auto res = isl::basic_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range2, Range>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::basic_map::range_reverse();
+  return typed::map<pair<T1, T2>, pair<Range2, Range>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::basic_map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_map<pair<Range, Range2>, pair<T1, T2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::basic_map::reverse();
+  return typed::basic_map<pair<Range, Range2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::basic_map::space();
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::basic_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::basic_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::to_union_map() const
+{
+  auto res = isl::basic_map::to_union_map();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<pair<T1, T2>, Range>, Range2> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::basic_map::uncurry();
+  return typed::map<pair<pair<T1, T2>, Range>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap2) const
+{
+  auto res = isl::basic_map::unite(bmap2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::basic_map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::basic_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::basic_map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<pair<T1, T2>, pair<Range, Range2>>> typed::basic_map<pair<T1, T2>, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::basic_map::wrap();
+  return typed::set<pair<pair<T1, T2>, pair<Range, Range2>>>(res);
+}
+
+typed::basic_set<>::basic_set(const typed::point<> &pnt)
+  : isl::basic_set(pnt)
+{
+}
+
+typed::basic_set<>::basic_set(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_set(ctx, str)
+{
+}
+
+typed::set<> typed::basic_set<>::coalesce() const
+{
+  auto res = isl::basic_set::coalesce();
+  return typed::set<>(res);
+}
+
+typed::basic_set<> typed::basic_set<>::detect_equalities() const
+{
+  auto res = isl::basic_set::detect_equalities();
+  return typed::basic_set<>(res);
+}
+
+bool typed::basic_set<>::every_set(const std::function<bool(typed::set<>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<>(arg0));
+  };
+  return isl::basic_set::every_set(lambda);
+}
+
+typed::set<> typed::basic_set<>::extract_set(const typed::space<> &space) const
+{
+  auto res = isl::basic_set::extract_set(space);
+  return typed::set<>(res);
+}
+
+void typed::basic_set<>::foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<>(arg0));
+  };
+  return isl::basic_set::foreach_basic_set(lambda);
+}
+
+void typed::basic_set<>::foreach_point(const std::function<void(typed::point<>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<>(arg0));
+  };
+  return isl::basic_set::foreach_point(lambda);
+}
+
+void typed::basic_set<>::foreach_set(const std::function<void(typed::set<>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<>(arg0));
+  };
+  return isl::basic_set::foreach_set(lambda);
+}
+
+typed::basic_set<> typed::basic_set<>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<>(res);
+}
+
+typed::set<> typed::basic_set<>::gist(const typed::set<> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::basic_set<>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::basic_set<> typed::basic_set<>::gist(const typed::point<> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<>(res);
+}
+
+typed::pw_aff<Anonymous> typed::basic_set<>::indicator_function() const
+{
+  auto res = isl::basic_set::indicator_function();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::basic_set<> typed::basic_set<>::intersect(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<>(res);
+}
+
+typed::set<> typed::basic_set<>::intersect(const typed::set<> &set2) const
+{
+  auto res = isl::basic_set::intersect(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::basic_set<>::intersect(const typed::union_set<> &uset2) const
+{
+  auto res = isl::basic_set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::basic_set<> typed::basic_set<>::intersect(const typed::point<> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<>(res);
+}
+
+typed::set<> typed::basic_set<>::project_out_all_params() const
+{
+  auto res = isl::basic_set::project_out_all_params();
+  return typed::set<>(res);
+}
+
+typed::set<> typed::basic_set<>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::basic_set<>::project_out_param(const std::string &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::basic_set<>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::basic_set::project_out_param(list);
+  return typed::set<>(res);
+}
+
+typed::space<> typed::basic_set<>::space() const
+{
+  auto res = isl::basic_set::space();
+  return typed::space<>(res);
+}
+
+typed::set<> typed::basic_set<>::subtract(const typed::set<> &set2) const
+{
+  auto res = isl::basic_set::subtract(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::basic_set<>::subtract(const typed::union_set<> &uset2) const
+{
+  auto res = isl::basic_set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::basic_set<>::to_set() const
+{
+  auto res = isl::basic_set::to_set();
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::basic_set<>::to_union_set() const
+{
+  auto res = isl::basic_set::to_union_set();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<>::unbind_params(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_set::unbind_params(tuple);
+  return typed::set<Domain>(res);
+}
+
+typed::set<> typed::basic_set<>::unite(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::basic_set<>::unite(const typed::set<> &set2) const
+{
+  auto res = isl::basic_set::unite(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::basic_set<>::unite(const typed::union_set<> &uset2) const
+{
+  auto res = isl::basic_set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::basic_set<>::unite(const typed::point<> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain>::basic_set(const typed::point<Domain> &pnt)
+  : isl::basic_set(pnt)
+{
+}
+
+template <typename Domain>
+typed::basic_set<Domain>::basic_set(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_set(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Range>
+typed::basic_set<Range> typed::basic_set<Domain>::apply(const typed::basic_map<Domain, Range> &bmap) const
+{
+  auto res = isl::basic_set::apply(bmap);
+  return typed::basic_set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<Range> typed::basic_set<Domain>::apply(const typed::map<Domain, Range> &map) const
+{
+  auto res = isl::basic_set::apply(map);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::basic_set<Domain>::apply(const typed::union_map<Domain, Range> &umap) const
+{
+  auto res = isl::basic_set::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::basic_set<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_set::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::as_set() const
+{
+  auto res = isl::basic_set::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::basic_set<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::basic_set::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::coalesce() const
+{
+  auto res = isl::basic_set::coalesce();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::detect_equalities() const
+{
+  auto res = isl::basic_set::detect_equalities();
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+bool typed::basic_set<Domain>::every_set(const std::function<bool(typed::set<Domain>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<Domain>(arg0));
+  };
+  return isl::basic_set::every_set(lambda);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::extract_set(const typed::space<Domain> &space) const
+{
+  auto res = isl::basic_set::extract_set(space);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+void typed::basic_set<Domain>::foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<Domain>(arg0));
+  };
+  return isl::basic_set::foreach_basic_set(lambda);
+}
+
+template <typename Domain>
+void typed::basic_set<Domain>::foreach_point(const std::function<void(typed::point<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<Domain>(arg0));
+  };
+  return isl::basic_set::foreach_point(lambda);
+}
+
+template <typename Domain>
+void typed::basic_set<Domain>::foreach_set(const std::function<void(typed::set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<Domain>(arg0));
+  };
+  return isl::basic_set::foreach_set(lambda);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::basic_set<Domain>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_set<Domain>::identity() const
+{
+  auto res = isl::basic_set::identity();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::basic_set<Domain>::indicator_function() const
+{
+  auto res = isl::basic_set::indicator_function();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::basic_set<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::basic_set::insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::intersect(const typed::basic_set<Domain> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::intersect(const typed::set<Domain> &set2) const
+{
+  auto res = isl::basic_set::intersect(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::basic_set<Domain>::intersect(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::basic_set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::intersect(const typed::point<Domain> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::intersect_params(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::basic_set::intersect_params(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_set::intersect_params(params);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::basic_set<Domain>::intersect_params(const typed::point<> &bset2) const
+{
+  auto res = isl::basic_set::intersect_params(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::lexmax() const
+{
+  auto res = isl::basic_set::lexmax();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::basic_set<Domain>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_set::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::lexmin() const
+{
+  auto res = isl::basic_set::lexmin();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::basic_set<Domain>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_set::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::lower_bound(const typed::multi_pw_aff<Domain> &lower) const
+{
+  auto res = isl::basic_set::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::lower_bound(const typed::multi_val<Domain> &lower) const
+{
+  auto res = isl::basic_set::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::basic_set<Domain>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_set::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::basic_set<Domain>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_set::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<> typed::basic_set<Domain>::params() const
+{
+  auto res = isl::basic_set::params();
+  return typed::basic_set<>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::basic_set<Domain>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::basic_set::plain_multi_val_if_fixed();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<Domain>::preimage(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::basic_set::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<Domain>::preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::basic_set::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<Domain>::preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::basic_set::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::basic_set<Domain>::preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::basic_set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<Domain>::product(const typed::set<Range> &set2) const
+{
+  auto res = isl::basic_set::product(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::project_out_all_params() const
+{
+  auto res = isl::basic_set::project_out_all_params();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::project_out_param(const std::string &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::basic_set::project_out_param(list);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<Domain, Range> typed::basic_set<Domain>::pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::basic_set::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain> typed::basic_set<Domain>::simple_fixed_box_hull() const
+{
+  auto res = isl::basic_set::simple_fixed_box_hull();
+  return typed::fixed_box<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::basic_set<Domain>::space() const
+{
+  auto res = isl::basic_set::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::subtract(const typed::set<Domain> &set2) const
+{
+  auto res = isl::basic_set::subtract(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::basic_set<Domain>::subtract(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::basic_set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::to_set() const
+{
+  auto res = isl::basic_set::to_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::basic_set<Domain>::to_union_set() const
+{
+  auto res = isl::basic_set::to_union_set();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::basic_set<Domain>::translation() const
+{
+  auto res = isl::basic_set::translation();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::basic_set<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::basic_set::unbind_params_insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::unite(const typed::basic_set<Domain> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::unite(const typed::set<Domain> &set2) const
+{
+  auto res = isl::basic_set::unite(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::basic_set<Domain>::unite(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::basic_set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::unite(const typed::point<Domain> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::upper_bound(const typed::multi_pw_aff<Domain> &upper) const
+{
+  auto res = isl::basic_set::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::basic_set<Domain>::upper_bound(const typed::multi_val<Domain> &upper) const
+{
+  auto res = isl::basic_set::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>>::basic_set(const typed::point<pair<Domain, Range>> &pnt)
+  : isl::basic_set(pnt)
+{
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>>::basic_set(const isl::ctx &ctx, const std::string &str)
+  : isl::basic_set(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::basic_set<Arg2> typed::basic_set<pair<Domain, Range>>::apply(const typed::basic_map<pair<Domain, Range>, Arg2> &bmap) const
+{
+  auto res = isl::basic_set::apply(bmap);
+  return typed::basic_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<Arg2> typed::basic_set<pair<Domain, Range>>::apply(const typed::map<pair<Domain, Range>, Arg2> &map) const
+{
+  auto res = isl::basic_set::apply(map);
+  return typed::set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::basic_set<pair<Domain, Range>>::apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::basic_set::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::as_pw_multi_aff() const
+{
+  auto res = isl::basic_set::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::as_set() const
+{
+  auto res = isl::basic_set::as_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<> typed::basic_set<pair<Domain, Range>>::bind(const typed::multi_id<pair<Domain, Range>> &tuple) const
+{
+  auto res = isl::basic_set::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::coalesce() const
+{
+  auto res = isl::basic_set::coalesce();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::detect_equalities() const
+{
+  auto res = isl::basic_set::detect_equalities();
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::basic_set<pair<Domain, Range>>::every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::basic_set::every_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::extract_set(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::basic_set::extract_set(space);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::basic_set<pair<Domain, Range>>::foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<pair<Domain, Range>>(arg0));
+  };
+  return isl::basic_set::foreach_basic_set(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::basic_set<pair<Domain, Range>>::foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<pair<Domain, Range>>(arg0));
+  };
+  return isl::basic_set::foreach_point(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::basic_set<pair<Domain, Range>>::foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::basic_set::foreach_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::gist(const typed::basic_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::gist(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::gist(const typed::union_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::gist(const typed::point<pair<Domain, Range>> &context) const
+{
+  auto res = isl::basic_set::gist(context);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::identity() const
+{
+  auto res = isl::basic_set::identity();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff<pair<Domain, Range>, Anonymous> typed::basic_set<pair<Domain, Range>>::indicator_function() const
+{
+  auto res = isl::basic_set::indicator_function();
+  return typed::pw_aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::insert_domain(const typed::space<Arg2> &domain) const
+{
+  auto res = isl::basic_set::insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect(const typed::basic_set<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::basic_set::intersect(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::basic_set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect(const typed::point<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::basic_set::intersect(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect_params(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::basic_set::intersect_params(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::basic_set::intersect_params(params);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::intersect_params(const typed::point<> &bset2) const
+{
+  auto res = isl::basic_set::intersect_params(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lexmax() const
+{
+  auto res = isl::basic_set::lexmax();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::basic_set::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lexmin() const
+{
+  auto res = isl::basic_set::lexmin();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::basic_set::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::basic_set::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::basic_set::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::max_multi_pw_aff() const
+{
+  auto res = isl::basic_set::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::min_multi_pw_aff() const
+{
+  auto res = isl::basic_set::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<> typed::basic_set<pair<Domain, Range>>::params() const
+{
+  auto res = isl::basic_set::params();
+  return typed::basic_set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::basic_set::plain_multi_val_if_fixed();
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<pair<Domain, Range>>::preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::basic_set::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<pair<Domain, Range>>::preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::basic_set::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::basic_set<pair<Domain, Range>>::preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::basic_set::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::basic_set<pair<Domain, Range>>::preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::basic_set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<pair<pair<Domain, Range>, Arg2>> typed::basic_set<pair<Domain, Range>>::product(const typed::set<Arg2> &set2) const
+{
+  auto res = isl::basic_set::product(set2);
+  return typed::set<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::project_out_all_params() const
+{
+  auto res = isl::basic_set::project_out_all_params();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::project_out_param(const std::string &id) const
+{
+  auto res = isl::basic_set::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::basic_set::project_out_param(list);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain, Range>, Arg2> typed::basic_set<pair<Domain, Range>>::pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const
+{
+  auto res = isl::basic_set::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::simple_fixed_box_hull() const
+{
+  auto res = isl::basic_set::simple_fixed_box_hull();
+  return typed::fixed_box<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::space() const
+{
+  auto res = isl::basic_set::space();
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::subtract(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::basic_set::subtract(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::subtract(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::basic_set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::to_set() const
+{
+  auto res = isl::basic_set::to_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::to_union_set() const
+{
+  auto res = isl::basic_set::to_union_set();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::translation() const
+{
+  auto res = isl::basic_set::translation();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const
+{
+  auto res = isl::basic_set::unbind_params_insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::unite(const typed::basic_set<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::unite(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::basic_set::unite(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::unite(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::basic_set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::unite(const typed::point<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::basic_set::unite(bset2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::basic_set<pair<Domain, Range>>::unwrap() const
+{
+  auto res = isl::basic_set::unwrap();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::basic_set::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::basic_set<pair<Domain, Range>>::upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::basic_set::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::fixed_box<Domain>::offset() const
+{
+  auto res = isl::fixed_box::offset();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::fixed_box<Domain>::size() const
+{
+  auto res = isl::fixed_box::size();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::fixed_box<Domain>::space() const
+{
+  auto res = isl::fixed_box::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::fixed_box<Domain, Range>::offset() const
+{
+  auto res = isl::fixed_box::offset();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::fixed_box<Domain, Range>::size() const
+{
+  auto res = isl::fixed_box::size();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::fixed_box<Domain, Range>::space() const
+{
+  auto res = isl::fixed_box::space();
+  return typed::space<Domain, Range>(res);
+}
+
+typed::id<Anonymous>::id(const isl::ctx &ctx, const std::string &str)
+  : isl::id(ctx, str)
+{
+}
+
+typed::id_list<Anonymous>::id_list(const isl::ctx &ctx, int n)
+  : isl::id_list(ctx, n)
+{
+}
+
+typed::id_list<Anonymous>::id_list(const typed::id<Anonymous> &el)
+  : isl::id_list(el)
+{
+}
+
+typed::id_list<Anonymous>::id_list(const isl::ctx &ctx, const std::string &str)
+  : isl::id_list(ctx, str)
+{
+}
+
+typed::id_list<Anonymous> typed::id_list<Anonymous>::add(const typed::id<Anonymous> &el) const
+{
+  auto res = isl::id_list::add(el);
+  return typed::id_list<Anonymous>(res);
+}
+
+typed::id_list<Anonymous> typed::id_list<Anonymous>::add(const std::string &el) const
+{
+  auto res = isl::id_list::add(el);
+  return typed::id_list<Anonymous>(res);
+}
+
+typed::id<Anonymous> typed::id_list<Anonymous>::at(int index) const
+{
+  auto res = isl::id_list::at(index);
+  return typed::id<Anonymous>(res);
+}
+
+typed::id_list<Anonymous> typed::id_list<Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::id_list::drop(first, n);
+  return typed::id_list<Anonymous>(res);
+}
+
+void typed::id_list<Anonymous>::foreach(const std::function<void(typed::id<Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::id arg0) {
+    return fn(typed::id<Anonymous>(arg0));
+  };
+  return isl::id_list::foreach(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range>::map(const typed::basic_map<Domain, Range> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::map<Domain, Range>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::apply_domain(const typed::basic_map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::apply_range(const typed::map<Range, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::map<Domain, Range>::apply_range(const typed::union_map<Range, Range2> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::apply_range(const typed::basic_map<Range, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::map<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::map<Domain, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::map<Domain, Range>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Range> typed::map<Domain, Range>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::map<Domain, Range>::bind_range(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::map<Domain, Range>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Domain> typed::map<Domain, Range>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Range>, Domain> typed::map<Domain, Range>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Range> typed::map<Domain, Range>::domain_product(const typed::map<Domain2, Range> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Range> typed::map<Domain, Range>::domain_product(const typed::union_map<Domain2, Range> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Range> typed::map<Domain, Range>::domain_product(const typed::basic_map<Domain2, Range> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::map<Domain, Range>::every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Range>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::extract_map(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::map<Domain, Range>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, Range>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::map<Domain, Range>::foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Range>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::gist(const typed::map<Domain, Range> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::gist(const typed::union_map<Domain, Range> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::gist(const typed::basic_map<Domain, Range> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::gist_domain(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::gist_domain(const typed::point<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::intersect(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect(const typed::basic_map<Domain, Range> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_range(const typed::set<Range> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::intersect_range(const typed::space<Range> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::intersect_range(const typed::union_set<Range> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_range(const typed::basic_set<Range> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::intersect_range(const typed::point<Range> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::map<Domain, Range>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::map<Domain, Range>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lower_bound(const typed::multi_pw_aff<Domain, Range> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lower_bound(const typed::aff<Domain, Range> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lower_bound(const typed::multi_aff<Domain, Range> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lower_bound(const typed::pw_aff<Domain, Range> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::lower_bound(const typed::pw_multi_aff<Domain, Range> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::map<Domain, Range>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::map<Domain, Range>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::map<Domain, Range>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::map<Domain, Range>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::preimage_range(const typed::multi_aff<Range2, Range> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::map<Domain, Range>::preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, Range>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, Range>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, Range>::product(const typed::basic_map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Range> typed::map<Domain, Range>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<Domain, Range> typed::map<Domain, Range>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Range> typed::map<Domain, Range>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<Domain, Range>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, Range>::range_product(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, Range>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, Range>::range_product(const typed::basic_map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<Domain, Range> typed::map<Domain, Range>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Range, Domain> typed::map<Domain, Range>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<Range, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::map<Domain2, Range> typed::map<Domain, Range>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::map<Domain, Range>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::subtract(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::subtract(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::subtract(const typed::basic_map<Domain, Range> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::subtract_range(const typed::union_set<Range> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::unite(const typed::map<Domain, Range> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::map<Domain, Range>::unite(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::unite(const typed::basic_map<Domain, Range> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::universe(const typed::space<Domain, Range> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::upper_bound(const typed::multi_pw_aff<Domain, Range> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::upper_bound(const typed::aff<Domain, Range> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::upper_bound(const typed::multi_aff<Domain, Range> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::upper_bound(const typed::pw_aff<Domain, Range> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map<Domain, Range>::upper_bound(const typed::pw_multi_aff<Domain, Range> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::map<Domain, Range>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2>::map(const typed::basic_map<pair<Domain, Range>, Range2> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::apply_domain(const typed::map<pair<Domain, Range>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::apply_range(const typed::map<Range2, Arg3> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::apply_range(const typed::union_map<Range2, Arg3> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::apply_range(const typed::basic_map<Range2, Arg3> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Range2> typed::map<pair<Domain, Range>, Range2>::bind_domain(const typed::multi_id<pair<Domain, Range>> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, Range>> typed::map<pair<Domain, Range>, Range2>::bind_range(const typed::multi_id<Range2> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<pair<Domain, Range>, Range2>::curry() const
+{
+  auto res = isl::map::curry();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, Range>> typed::map<pair<Domain, Range>, Range2>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range2> typed::map<pair<Domain, Range>, Range2>::domain_factor_domain() const
+{
+  auto res = isl::map::domain_factor_domain();
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Range, Range2> typed::map<pair<Domain, Range>, Range2>::domain_factor_range() const
+{
+  auto res = isl::map::domain_factor_range();
+  return typed::map<Range, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::map<pair<Domain, Range>, Range2>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::map<pair<Domain, Range>, Range2>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<Domain, Range>, Domain2>, Range2> typed::map<pair<Domain, Range>, Range2>::domain_product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> typed::map<pair<Domain, Range>, Range2>::domain_product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<Domain, Range>, Domain2>, Range2> typed::map<pair<Domain, Range>, Range2>::domain_product(const typed::basic_map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::map<pair<Domain, Range>, Range2>::every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Anonymous, Range2> typed::map<pair<Domain, Range>, Range2>::flatten_domain() const
+{
+  auto res = isl::map::flatten_domain();
+  return typed::map<Anonymous, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::map<pair<Domain, Range>, Range2>::foreach_basic_map(const std::function<void(typed::basic_map<pair<Domain, Range>, Range2>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::map<pair<Domain, Range>, Range2>::foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist(const typed::map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist_domain(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist_domain(const typed::basic_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::gist_domain(const typed::point<pair<Domain, Range>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_domain(const typed::set<pair<Domain, Range>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_domain(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_domain(const typed::basic_set<pair<Domain, Range>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_domain(const typed::point<pair<Domain, Range>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_range(const typed::set<Range2> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_range(const typed::space<Range2> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_range(const typed::union_set<Range2> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_range(const typed::basic_set<Range2> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::intersect_range(const typed::point<Range2> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lower_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lower_bound(const typed::aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lower_bound(const typed::multi_aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lower_bound(const typed::pw_aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::lower_bound(const typed::pw_multi_aff<pair<Domain, Range>, Range2> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::map<pair<Domain, Range>, Range2>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::map<pair<Domain, Range>, Range2>::preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::product(const typed::map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::product(const typed::basic_map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Range2> typed::map<pair<Domain, Range>, Range2>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> typed::map<pair<Domain, Range>, Range2>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::range_product(const typed::map<pair<Domain, Range>, Arg3> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<pair<Domain, Range>, pair<Range2, Arg3>> typed::map<pair<Domain, Range>, Range2>::range_product(const typed::basic_map<pair<Domain, Range>, Arg3> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Range2, pair<Domain, Range>> typed::map<pair<Domain, Range>, Range2>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<Range2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<Domain, Range>, Arg2> typed::map<pair<Domain, Range>, Range2>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<Domain, Range>, Arg2> typed::map<pair<Domain, Range>, Range2>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::subtract(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::subtract(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::subtract_range(const typed::union_set<Range2> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::unite(const typed::map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::unite(const typed::basic_map<pair<Domain, Range>, Range2> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::universe(const typed::space<pair<Domain, Range>, Range2> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::upper_bound(const typed::multi_pw_aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::upper_bound(const typed::aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::upper_bound(const typed::multi_aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::upper_bound(const typed::pw_aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<pair<Domain, Range>, Range2>::upper_bound(const typed::pw_multi_aff<pair<Domain, Range>, Range2> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<pair<Domain, Range>, Range2>> typed::map<pair<Domain, Range>, Range2>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<pair<Domain, Range>, Range2>>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain>::map(const typed::basic_map<Domain, Domain> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename Domain>
+typed::map<Domain, Domain>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::map<Domain, Domain>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::apply_domain(const typed::basic_map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::apply_range(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::map<Domain, Domain>::apply_range(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::apply_range(const typed::basic_map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Domain> typed::map<Domain, Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::map<Domain, Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Domain> typed::map<Domain, Domain>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::map<Domain, Domain>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::map<Domain, Domain>::bind_range(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::map<Domain, Domain>::deltas() const
+{
+  auto res = isl::map::deltas();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::map<Domain, Domain>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::map<Domain, Domain>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> typed::map<Domain, Domain>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Domain> typed::map<Domain, Domain>::domain_product(const typed::map<Domain2, Domain> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Domain> typed::map<Domain, Domain>::domain_product(const typed::union_map<Domain2, Domain> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, Domain> typed::map<Domain, Domain>::domain_product(const typed::basic_map<Domain2, Domain> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const
+{
+  auto res = isl::map::eq_at(mupa);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::eq_at(const typed::pw_multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+bool typed::map<Domain, Domain>::every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::extract_map(const typed::space<Domain, Domain> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+void typed::map<Domain, Domain>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, Domain>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename Domain>
+void typed::map<Domain, Domain>::foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::gist(const typed::map<Domain, Domain> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::gist(const typed::union_map<Domain, Domain> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::gist(const typed::basic_map<Domain, Domain> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::gist_domain(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::gist_domain(const typed::point<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::intersect(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect(const typed::basic_map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_range(const typed::set<Domain> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::intersect_range(const typed::space<Domain> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::intersect_range(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_range(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::intersect_range(const typed::point<Domain> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_ge_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_ge_at(const typed::aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_ge_at(const typed::multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_ge_at(const typed::pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_ge_at(const typed::pw_multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_gt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_gt_at(const typed::aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_gt_at(const typed::multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_gt_at(const typed::pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_gt_at(const typed::pw_multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_le_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_le_at(const typed::aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_le_at(const typed::multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_le_at(const typed::pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_le_at(const typed::pw_multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_lt_at(const typed::multi_pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_lt_at(const typed::aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_lt_at(const typed::multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_lt_at(const typed::pw_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lex_lt_at(const typed::pw_multi_aff<Domain, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::map<Domain, Domain>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::map<Domain, Domain>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lower_bound(const typed::multi_pw_aff<Domain, Domain> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lower_bound(const typed::aff<Domain, Domain> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lower_bound(const typed::multi_aff<Domain, Domain> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lower_bound(const typed::pw_aff<Domain, Domain> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::lower_bound(const typed::pw_multi_aff<Domain, Domain> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map_list<Domain, Domain> typed::map<Domain, Domain>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::map<Domain, Domain>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::map<Domain, Domain>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::map<Domain, Domain>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::preimage_range(const typed::multi_aff<Range2, Domain> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::map<Domain, Domain>::preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::map<Domain, Domain>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::map<Domain, Domain>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::map<Domain, Domain>::product(const typed::basic_map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::map<Domain, Domain>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain, Domain> typed::map<Domain, Domain>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::map<Domain, Domain>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, pair<Domain, Range2>> typed::map<Domain, Domain>::range_product(const typed::map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, pair<Domain, Range2>> typed::map<Domain, Domain>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, pair<Domain, Range2>> typed::map<Domain, Domain>::range_product(const typed::basic_map<Domain, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain, Domain> typed::map<Domain, Domain>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::map<Domain2, Domain> typed::map<Domain, Domain>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_range_tuple(id);
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain, Domain> typed::map<Domain, Domain>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::subtract(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::subtract(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::subtract(const typed::basic_map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::subtract_range(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::unite(const typed::map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::map<Domain, Domain>::unite(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::unite(const typed::basic_map<Domain, Domain> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::universe(const typed::space<Domain, Domain> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::upper_bound(const typed::multi_pw_aff<Domain, Domain> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::upper_bound(const typed::aff<Domain, Domain> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::upper_bound(const typed::multi_aff<Domain, Domain> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::upper_bound(const typed::pw_aff<Domain, Domain> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::map<Domain, Domain>::upper_bound(const typed::pw_multi_aff<Domain, Domain> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<pair<Domain, Domain>> typed::map<Domain, Domain>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<Domain, Domain>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>>::map(const typed::basic_map<Domain, pair<Range, Range2>> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::apply_domain(const typed::map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::apply_domain(const typed::basic_map<Domain, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg3> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::map<Domain, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::map<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> typed::map<Domain, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> typed::map<Domain, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<Domain, Domain2>, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::map<Domain, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Anonymous> typed::map<Domain, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::map::flatten_range();
+  return typed::map<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::map<Domain, pair<Range, Range2>>::foreach_basic_map(const std::function<void(typed::basic_map<Domain, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::map<Domain, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist(const typed::map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist_domain(const typed::set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist_domain(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::gist_domain(const typed::point<Domain> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_range(const typed::set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_range(const typed::basic_set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::intersect_range(const typed::point<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lower_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lower_bound(const typed::aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lower_bound(const typed::multi_aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lower_bound(const typed::pw_aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::lower_bound(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::map<Domain, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::product(const typed::map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::product(const typed::basic_map<Domain2, Arg3> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range> typed::map<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::map::range_factor_domain();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, Range2> typed::map<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::map::range_factor_range();
+  return typed::map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::range_product(const typed::map<Domain, Arg3> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::range_product(const typed::union_map<Domain, Arg3> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::map<Domain, pair<pair<Range, Range2>, Arg3>> typed::map<Domain, pair<Range, Range2>>::range_product(const typed::basic_map<Domain, Arg3> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range2, Range>> typed::map<Domain, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::map::range_reverse();
+  return typed::map<Domain, pair<Range2, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::fixed_box<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Range, Range2>, Domain> typed::map<Domain, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<pair<Range, Range2>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::map::set_domain_tuple(id);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::subtract(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::subtract(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::map<Domain, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::map::uncurry();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::unite(const typed::map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::unite(const typed::basic_map<Domain, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::universe(const typed::space<Domain, pair<Range, Range2>> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::upper_bound(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::upper_bound(const typed::aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::upper_bound(const typed::multi_aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::upper_bound(const typed::pw_aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::map<Domain, pair<Range, Range2>>::upper_bound(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<pair<Domain, pair<Range, Range2>>> typed::map<Domain, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<Domain, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>>::map(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::basic_map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T1, pair<T2, pair<T1, T2>>> typed::map<pair<T1, T2>, pair<T1, T2>>::curry() const
+{
+  auto res = isl::map::curry();
+  return typed::map<T1, pair<T2, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::deltas() const
+{
+  auto res = isl::map::deltas();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T1, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_factor_domain() const
+{
+  auto res = isl::map::domain_factor_domain();
+  return typed::map<T1, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<T2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_factor_range() const
+{
+  auto res = isl::map::domain_factor_range();
+  return typed::map<T2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::map<Domain2, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::basic_map<Domain2, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const
+{
+  auto res = isl::map::eq_at(mupa);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::eq_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+bool typed::map<pair<T1, T2>, pair<T1, T2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<Anonymous, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::flatten_domain() const
+{
+  auto res = isl::map::flatten_domain();
+  return typed::map<Anonymous, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, Anonymous> typed::map<pair<T1, T2>, pair<T1, T2>>::flatten_range() const
+{
+  auto res = isl::map::flatten_range();
+  return typed::map<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2>
+void typed::map<pair<T1, T2>, pair<T1, T2>>::foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<T1, T2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename T1, typename T2>
+void typed::map<pair<T1, T2>, pair<T1, T2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::basic_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::point<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_ge_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_ge_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_gt_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_gt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_le_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_le_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::pw_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lex_lt_at(const typed::pw_multi_aff<pair<T1, T2>, Range> &mpa) const
+{
+  auto res = isl::map::lex_lt_at(mpa);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::multi_aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::pw_aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::lower_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map_list<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::product(const typed::map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::product(const typed::basic_map<Domain2, Range2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, T1> typed::map<pair<T1, T2>, pair<T1, T2>>::range_factor_domain() const
+{
+  auto res = isl::map::range_factor_domain();
+  return typed::map<pair<T1, T2>, T1>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, T2> typed::map<pair<T1, T2>, pair<T1, T2>>::range_factor_range() const
+{
+  auto res = isl::map::range_factor_range();
+  return typed::map<pair<T1, T2>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::fixed_box<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::basic_map<pair<T1, T2>, Range2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T2, T1>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_reverse() const
+{
+  auto res = isl::map::range_reverse();
+  return typed::map<pair<T1, T2>, pair<T2, T1>>(res);
+}
+
+template <typename T1, typename T2>
+typed::fixed_box<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::space<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<pair<T1, T2>, T1>, T2> typed::map<pair<T1, T2>, pair<T1, T2>>::uncurry() const
+{
+  auto res = isl::map::uncurry();
+  return typed::map<pair<pair<T1, T2>, T1>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::universe(const typed::space<pair<T1, T2>, pair<T1, T2>> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::multi_aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::pw_aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<T1, T2>>::upper_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<T1, T2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::set<pair<pair<T1, T2>, pair<T1, T2>>> typed::map<pair<T1, T2>, pair<T1, T2>>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<pair<T1, T2>, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>>::map(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap)
+  : isl::map(bmap)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>>::map(const isl::ctx &ctx, const std::string &str)
+  : isl::map(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &map2) const
+{
+  auto res = isl::map::apply_domain(map2);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const
+{
+  auto res = isl::map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &map2) const
+{
+  auto res = isl::map::apply_range(map2);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::map::as_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::map::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::map::bind_domain(tuple);
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::map::bind_range(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::map::coalesce();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T1, pair<T2, pair<Range, Range2>>> typed::map<pair<T1, T2>, pair<Range, Range2>>::curry() const
+{
+  auto res = isl::map::curry();
+  return typed::map<T1, pair<T2, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::map::detect_equalities();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::map::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T1, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_domain() const
+{
+  auto res = isl::map::domain_factor_domain();
+  return typed::map<T1, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<T2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_range() const
+{
+  auto res = isl::map::domain_factor_range();
+  return typed::map<T2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::domain_product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+bool typed::map<pair<T1, T2>, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::every_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<Anonymous, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::flatten_domain() const
+{
+  auto res = isl::map::flatten_domain();
+  return typed::map<Anonymous, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, Anonymous> typed::map<pair<T1, T2>, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::map::flatten_range();
+  return typed::map<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+void typed::map<pair<T1, T2>, pair<Range, Range2>>::foreach_basic_map(const std::function<void(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_map arg0) {
+    return fn(typed::basic_map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::foreach_basic_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+void typed::map<pair<T1, T2>, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::map::gist(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::basic_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::point<pair<T1, T2>> &context) const
+{
+  auto res = isl::map::gist_domain(context);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::intersect(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::map::intersect_domain(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::map::intersect_params(params);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::basic_set<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::point<pair<Range, Range2>> &set) const
+{
+  auto res = isl::map::intersect_range(set);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::map::lexmax();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::map::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::map::lexmin();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::map::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::lower_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &lower) const
+{
+  auto res = isl::map::lower_bound(lower);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map_list<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::max_multi_pw_aff() const
+{
+  auto res = isl::map::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::min_multi_pw_aff() const
+{
+  auto res = isl::map::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::map::preimage_domain(ma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::map::preimage_domain(mpa);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::map::preimage_domain(pma);
+  return typed::map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::map::preimage_range(ma);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::map::preimage_range(pma);
+  return typed::map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::map<Domain2, Arg2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg2> &umap2) const
+{
+  auto res = isl::map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::basic_map<Domain2, Arg2> &map2) const
+{
+  auto res = isl::map::product(map2);
+  return typed::map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::map::project_out_all_params();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range() const
+{
+  auto res = isl::map::range();
+  return typed::set<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, Range> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::map::range_factor_domain();
+  return typed::map<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, Range2> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::map::range_factor_range();
+  return typed::map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_lattice_tile() const
+{
+  auto res = isl::map::range_lattice_tile();
+  return typed::fixed_box<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::map<pair<T1, T2>, Arg2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const
+{
+  auto res = isl::map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::basic_map<pair<T1, T2>, Arg2> &map2) const
+{
+  auto res = isl::map::range_product(map2);
+  return typed::map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range2, Range>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::map::range_reverse();
+  return typed::map<pair<T1, T2>, pair<Range2, Range>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::fixed_box<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::range_simple_fixed_box_hull() const
+{
+  auto res = isl::map::range_simple_fixed_box_hull();
+  return typed::fixed_box<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<Range, Range2>, pair<T1, T2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::map::reverse();
+  return typed::map<pair<Range, Range2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::map::space();
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::subtract(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::to_union_map() const
+{
+  auto res = isl::map::to_union_map();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<pair<T1, T2>, Range>, Range2> typed::map<pair<T1, T2>, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::map::uncurry();
+  return typed::map<pair<pair<T1, T2>, Range>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &map2) const
+{
+  auto res = isl::map::unite(map2);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::universe(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space)
+{
+  auto res = isl::map::universe(space);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::map<pair<T1, T2>, pair<Range, Range2>>::upper_bound(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upper) const
+{
+  auto res = isl::map::upper_bound(upper);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<pair<T1, T2>, pair<Range, Range2>>> typed::map<pair<T1, T2>, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::map::wrap();
+  return typed::set<pair<pair<T1, T2>, pair<Range, Range2>>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range>::map_list(const isl::ctx &ctx, int n)
+  : isl::map_list(ctx, n)
+{
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range>::map_list(const typed::map<Domain, Range> &el)
+  : isl::map_list(el)
+{
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range>::map_list(const isl::ctx &ctx, const std::string &str)
+  : isl::map_list(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::map_list<Domain, Range>::add(const typed::map<Domain, Range> &el) const
+{
+  auto res = isl::map_list::add(el);
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::map_list<Domain, Range>::add(const typed::basic_map<Domain, Range> &el) const
+{
+  auto res = isl::map_list::add(el);
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::map_list<Domain, Range>::at(int index) const
+{
+  auto res = isl::map_list::at(index);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::map_list<Domain, Range>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::map_list::drop(first, n);
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::map_list<Domain, Range>::foreach(const std::function<void(typed::map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Range>(arg0));
+  };
+  return isl::map_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain>::multi_aff(const typed::aff<Domain> &aff)
+  : isl::multi_aff(aff)
+{
+}
+
+template <typename Domain>
+typed::multi_aff<Domain>::multi_aff(const typed::space<Domain> &space, const typed::aff_list<Anonymous> &list)
+  : isl::multi_aff(space, list)
+{
+}
+
+template <typename Domain>
+typed::multi_aff<Domain>::multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::add(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::add(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::add(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::add(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::multi_aff<Domain>::add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::add(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::add_constant(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_aff::add_constant(mv);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::add_constant(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::add_constant(long v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::multi_aff<Domain>::apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::as_multi_aff() const
+{
+  auto res = isl::multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::multi_aff<Domain>::as_set() const
+{
+  auto res = isl::multi_aff::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff<Anonymous> typed::multi_aff<Domain>::at(int pos) const
+{
+  auto res = isl::multi_aff::at(pos);
+  return typed::aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::basic_set<> typed::multi_aff<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_aff::bind(tuple);
+  return typed::basic_set<>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::coalesce() const
+{
+  auto res = isl::multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_aff<Domain>::constant_multi_val() const
+{
+  auto res = isl::multi_aff::constant_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::multi_aff<Domain>::domain() const
+{
+  auto res = isl::multi_aff::domain();
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::extract_pw_multi_aff(const typed::space<Domain> &space) const
+{
+  auto res = isl::multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::floor() const
+{
+  auto res = isl::multi_aff::floor();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::gist(const typed::set<> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::multi_aff<Domain>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::gist(const typed::point<> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Domain> typed::multi_aff<Domain>::identity() const
+{
+  auto res = isl::multi_aff::identity();
+  return typed::multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::multi_aff<Arg1, Domain> typed::multi_aff<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::multi_aff::insert_domain(domain);
+  return typed::multi_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff_list<Anonymous> typed::multi_aff<Domain>::list() const
+{
+  auto res = isl::multi_aff::list();
+  return typed::aff_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::max(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_aff<Domain>::max_multi_val() const
+{
+  auto res = isl::multi_aff::max_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::min(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_aff<Domain>::min_multi_val() const
+{
+  auto res = isl::multi_aff::min_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::neg() const
+{
+  auto res = isl::multi_aff::neg();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_aff<pair<Domain, Range>> typed::multi_aff<Domain>::product(const typed::multi_aff<Range> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_aff<Domain>::product(const typed::multi_pw_aff<Range> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::multi_aff<Domain>::product(const typed::pw_multi_aff<Range> &pma2) const
+{
+  auto res = isl::multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_aff<pair<Domain, Range>> typed::multi_aff<Domain>::product(const typed::aff<Range> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::multi_aff<Domain>::pw_multi_aff_list() const
+{
+  auto res = isl::multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_aff::scale(mv);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale(long v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale_down(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_aff::scale_down(mv);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale_down(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::scale_down(long v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::set_at(int pos, const typed::aff<Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::set_at(int pos, const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_aff<Domain2> typed::multi_aff<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_aff<Domain2> typed::multi_aff<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::multi_aff<Domain>::space() const
+{
+  auto res = isl::multi_aff::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::sub(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::sub(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::sub(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::sub(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::multi_aff<Domain>::sub(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_aff<Domain>::sub(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::to_multi_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::to_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::to_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::multi_aff<Domain>::to_union_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::multi_aff<Arg1, Domain> typed::multi_aff<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::multi_aff::unbind_params_insert_domain(domain);
+  return typed::multi_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_aff<Domain>::union_add(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_aff<Domain>::union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::multi_aff<Domain>::union_add(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::multi_aff<Domain>::union_add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range>::multi_aff(const typed::aff<Domain, Range> &aff)
+  : isl::multi_aff(aff)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range>::multi_aff(const typed::space<Domain, Range> &space, const typed::aff_list<Domain, Anonymous> &list)
+  : isl::multi_aff(space, list)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range>::multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::add_constant(mv);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::add_constant(long v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::multi_aff<Domain, Range>::apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::multi_aff<Domain, Range>::as_map() const
+{
+  auto res = isl::multi_aff::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::as_multi_aff() const
+{
+  auto res = isl::multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::multi_aff<Domain, Range>::as_union_map() const
+{
+  auto res = isl::multi_aff::as_union_map();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::aff<Domain, Anonymous> typed::multi_aff<Domain, Range>::at(int pos) const
+{
+  auto res = isl::multi_aff::at(pos);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<Domain> typed::multi_aff<Domain, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::multi_aff::bind(tuple);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Range> typed::multi_aff<Domain, Range>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain(tuple);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::coalesce() const
+{
+  auto res = isl::multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::multi_aff<Domain, Range>::constant_multi_val() const
+{
+  auto res = isl::multi_aff::constant_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::multi_aff<Domain, Range>::domain() const
+{
+  auto res = isl::multi_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::extract_pw_multi_aff(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::floor() const
+{
+  auto res = isl::multi_aff::floor();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::identity() const
+{
+  auto res = isl::multi_aff::identity();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::aff_list<Domain, Anonymous> typed::multi_aff<Domain, Range>::list() const
+{
+  auto res = isl::multi_aff::list();
+  return typed::aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::max(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::multi_aff<Domain, Range>::max_multi_val() const
+{
+  auto res = isl::multi_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::min(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::multi_aff<Domain, Range>::min_multi_val() const
+{
+  auto res = isl::multi_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::neg() const
+{
+  auto res = isl::multi_aff::neg();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_aff<Domain, Range>::product(const typed::multi_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_aff<Domain, Range>::product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_aff<Domain, Range>::product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_aff<Domain, Range>::product(const typed::aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_aff<Domain2, Range> typed::multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain2, Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Range> typed::multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, Range> typed::multi_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::multi_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, Range> typed::multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Range> typed::multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_aff<Domain2, Range> typed::multi_aff<Domain, Range>::pullback(const typed::aff<Domain2, Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Range> typed::multi_aff<Domain, Range>::pullback(const typed::aff<Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::multi_aff<Domain, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::multi_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, Range>::range_product(const typed::aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::scale(mv);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale(long v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::scale_down(mv);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::scale_down(long v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::set_at(int pos, const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_aff<Domain, Range2> typed::multi_aff<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_aff<Domain, Range2> typed::multi_aff<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::multi_aff<Domain, Range>::space() const
+{
+  auto res = isl::multi_aff::space();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::sub(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::to_multi_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::to_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::to_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::to_union_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_aff<Domain, Range>::union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::union_add(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::multi_aff<Domain, Range>::union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range>::multi_aff(const typed::aff<pair<Domain2, Range2>, Range> &aff)
+  : isl::multi_aff(aff)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range>::multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space, const typed::aff_list<pair<Domain2, Range2>, Anonymous> &list)
+  : isl::multi_aff(space, list)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range>::multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_aff(ctx, str)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::add_constant(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::add_constant(long v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> typed::multi_aff<pair<Domain2, Range2>, Range>::apply(const typed::union_pw_multi_aff<Range, Arg2> &upma2) const
+{
+  auto res = isl::multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::map<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::as_map() const
+{
+  auto res = isl::multi_aff::as_map();
+  return typed::map<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::as_multi_aff() const
+{
+  auto res = isl::multi_aff::as_multi_aff();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_map<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::as_union_map() const
+{
+  auto res = isl::multi_aff::as_union_map();
+  return typed::union_map<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::multi_aff<pair<Domain2, Range2>, Range>::at(int pos) const
+{
+  auto res = isl::multi_aff::at(pos);
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::basic_set<pair<Domain2, Range2>> typed::multi_aff<pair<Domain2, Range2>, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::multi_aff::bind(tuple);
+  return typed::basic_set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain(tuple);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<Range2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain_wrapped_domain(tuple);
+  return typed::multi_aff<Range2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::coalesce() const
+{
+  auto res = isl::multi_aff::coalesce();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::constant_multi_val() const
+{
+  auto res = isl::multi_aff::constant_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::set<pair<Domain2, Range2>> typed::multi_aff<pair<Domain2, Range2>, Range>::domain() const
+{
+  auto res = isl::multi_aff::domain();
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space) const
+{
+  auto res = isl::multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::floor() const
+{
+  auto res = isl::multi_aff::floor();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::union_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::basic_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::point<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::identity() const
+{
+  auto res = isl::multi_aff::identity();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::aff_list<pair<Domain2, Range2>, Anonymous> typed::multi_aff<pair<Domain2, Range2>, Range>::list() const
+{
+  auto res = isl::multi_aff::list();
+  return typed::aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::max_multi_val() const
+{
+  auto res = isl::multi_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::min_multi_val() const
+{
+  auto res = isl::multi_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::neg() const
+{
+  auto res = isl::multi_aff::neg();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const
+{
+  auto res = isl::multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_aff<pair<Domain2, Range2>, Range>::product(const typed::pw_multi_aff<Arg2, Arg3> &pma2) const
+{
+  auto res = isl::multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_aff<pair<Domain2, Range2>, Range>::product(const typed::aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_aff<Arg2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<Arg2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<Arg2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<Arg2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_aff<Arg2, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::aff<Arg2, pair<Domain2, Range2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::aff<pair<Domain2, Range2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff_list<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const
+{
+  auto res = isl::multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::scale(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale(long v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_aff::scale_down(mv);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::scale_down(long v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::multi_aff<pair<Domain2, Range2>, Arg1> typed::multi_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::multi_aff<pair<Domain2, Range2>, Arg1> typed::multi_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_aff::set_range_tuple(id);
+  return typed::multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::space<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::space() const
+{
+  auto res = isl::multi_aff::space();
+  return typed::space<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::to_multi_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::to_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::to_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::to_union_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const
+{
+  auto res = isl::multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>>::multi_aff(const typed::aff<Domain, pair<Range, Range2>> &aff)
+  : isl::multi_aff(aff)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>>::multi_aff(const typed::space<Domain, pair<Range, Range2>> &space, const typed::aff_list<Domain, Anonymous> &list)
+  : isl::multi_aff(space, list)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>>::multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add(const typed::aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::add_constant(mv);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add_constant(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::add_constant(long v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::multi_aff<Domain, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::multi_aff::as_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::as_multi_aff() const
+{
+  auto res = isl::multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::multi_aff::as_union_map();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::aff<Domain, Anonymous> typed::multi_aff<Domain, pair<Range, Range2>>::at(int pos) const
+{
+  auto res = isl::multi_aff::at(pos);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::basic_set<Domain> typed::multi_aff<Domain, pair<Range, Range2>>::bind(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::multi_aff::bind(tuple);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain(tuple);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::constant_multi_val() const
+{
+  auto res = isl::multi_aff::constant_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::multi_aff<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::multi_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::floor() const
+{
+  auto res = isl::multi_aff::floor();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::identity() const
+{
+  auto res = isl::multi_aff::identity();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::aff_list<Domain, Anonymous> typed::multi_aff<Domain, pair<Range, Range2>>::list() const
+{
+  auto res = isl::multi_aff::list();
+  return typed::aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::max(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::max_multi_val() const
+{
+  auto res = isl::multi_aff::max_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::min(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::min_multi_val() const
+{
+  auto res = isl::multi_aff::min_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::neg() const
+{
+  auto res = isl::multi_aff::neg();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::product(const typed::multi_aff<Domain2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::product(const typed::multi_pw_aff<Domain2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::product(const typed::pw_multi_aff<Domain2, Arg3> &pma2) const
+{
+  auto res = isl::multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::product(const typed::aff<Domain2, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::aff<Domain2, Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::aff<Domain> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff_list<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, Range> typed::multi_aff<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::multi_aff::range_factor_domain();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::multi_aff<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::multi_aff::range_factor_range();
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_pw_aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_union_pw_aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<Domain, Arg3> &pma2) const
+{
+  auto res = isl::multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::scale(mv);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale(long v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::scale_down(mv);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale_down(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::scale_down(long v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::set_at(int pos, const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::multi_aff::space();
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::sub(const typed::aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::to_multi_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::to_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::to_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::to_union_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &mpa2) const
+{
+  auto res = isl::multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &mupa2) const
+{
+  auto res = isl::multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::multi_aff(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &aff)
+  : isl::multi_aff(aff)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space, const typed::aff_list<pair<T1, T2>, Anonymous> &list)
+  : isl::multi_aff(space, list)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_aff(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::add(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::add_constant(mv);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(long v) const
+{
+  auto res = isl::multi_aff::add_constant(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::multi_aff::as_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_multi_aff() const
+{
+  auto res = isl::multi_aff::as_multi_aff();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::multi_aff::as_union_map();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::aff<pair<T1, T2>, Anonymous> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::at(int pos) const
+{
+  auto res = isl::multi_aff::at(pos);
+  return typed::aff<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::basic_set<pair<T1, T2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::multi_aff::bind(tuple);
+  return typed::basic_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain(tuple);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<T2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind_domain_wrapped_domain(const typed::multi_id<T1> &tuple) const
+{
+  auto res = isl::multi_aff::bind_domain_wrapped_domain(tuple);
+  return typed::multi_aff<T2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::multi_aff::coalesce();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::constant_multi_val() const
+{
+  auto res = isl::multi_aff::constant_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::multi_aff::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::floor() const
+{
+  auto res = isl::multi_aff::floor();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::point<pair<T1, T2>> &context) const
+{
+  auto res = isl::multi_aff::gist(context);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::identity() const
+{
+  auto res = isl::multi_aff::identity();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::aff_list<pair<T1, T2>, Anonymous> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::list() const
+{
+  auto res = isl::multi_aff::list();
+  return typed::aff_list<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::max(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::max(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::max_multi_val() const
+{
+  auto res = isl::multi_aff::max_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::min(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::min(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::min_multi_val() const
+{
+  auto res = isl::multi_aff::min_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::neg() const
+{
+  auto res = isl::multi_aff::neg();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &pma2) const
+{
+  auto res = isl::multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::multi_aff<Domain2, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::multi_pw_aff<Domain2, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::pw_multi_aff<Domain2, Arg2> &pma2) const
+{
+  auto res = isl::multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::aff<Domain2, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::product(multi2);
+  return typed::multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<pair<T1, T2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<pair<T1, T2>> &mpa2) const
+{
+  auto res = isl::multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<pair<T1, T2>> &pma2) const
+{
+  auto res = isl::multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_aff<Domain2, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::aff<Domain2, pair<T1, T2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::aff<pair<T1, T2>> &ma2) const
+{
+  auto res = isl::multi_aff::pullback(ma2);
+  return typed::multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, Range> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::multi_aff::range_factor_domain();
+  return typed::pw_multi_aff<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, Range2> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::multi_aff::range_factor_range();
+  return typed::pw_multi_aff<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_pw_aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_union_pw_aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &pma2) const
+{
+  auto res = isl::multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_aff::range_product(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::scale(mv);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(long v) const
+{
+  auto res = isl::multi_aff::scale(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::multi_aff::scale_down(mv);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(long v) const
+{
+  auto res = isl::multi_aff::scale_down(v);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::set_at(int pos, const typed::aff<pair<T1, T2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::set_at(int pos, const typed::pw_aff<pair<T1, T2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::set_at(int pos, const typed::union_pw_aff<pair<T1, T2>, Anonymous> &el) const
+{
+  auto res = isl::multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::multi_aff::space();
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::multi_aff::sub(multi2);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_multi_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_multi_union_pw_aff() const
+{
+  auto res = isl::multi_aff::to_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_union_pw_multi_aff() const
+{
+  auto res = isl::multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mpa2) const
+{
+  auto res = isl::multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mupa2) const
+{
+  auto res = isl::multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain>
+typed::multi_id<Domain>::multi_id(const typed::space<Domain> &space, const typed::id_list<Anonymous> &list)
+  : isl::multi_id(space, list)
+{
+}
+
+template <typename Domain>
+typed::multi_id<Domain>::multi_id(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_id(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::id<Anonymous> typed::multi_id<Domain>::at(int pos) const
+{
+  auto res = isl::multi_id::at(pos);
+  return typed::id<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::id_list<Anonymous> typed::multi_id<Domain>::list() const
+{
+  auto res = isl::multi_id::list();
+  return typed::id_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_id<Domain> typed::multi_id<Domain>::set_at(int pos, const typed::id<Anonymous> &el) const
+{
+  auto res = isl::multi_id::set_at(pos, el);
+  return typed::multi_id<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_id<Domain> typed::multi_id<Domain>::set_at(int pos, const std::string &el) const
+{
+  auto res = isl::multi_id::set_at(pos, el);
+  return typed::multi_id<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::multi_id<Domain>::space() const
+{
+  auto res = isl::multi_id::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const typed::aff<Domain> &aff)
+  : isl::multi_pw_aff(aff)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const typed::multi_aff<Domain> &ma)
+  : isl::multi_pw_aff(ma)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const typed::pw_aff<Domain> &pa)
+  : isl::multi_pw_aff(pa)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const typed::space<Domain> &space, const typed::pw_aff_list<Anonymous> &list)
+  : isl::multi_pw_aff(space, list)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const typed::pw_multi_aff<Domain> &pma)
+  : isl::multi_pw_aff(pma)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain>::multi_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add(const typed::pw_multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add_constant(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_pw_aff::add_constant(mv);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add_constant(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::add_constant(long v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::multi_pw_aff<Domain>::as_multi_aff() const
+{
+  auto res = isl::multi_pw_aff::as_multi_aff();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::multi_pw_aff<Domain>::as_set() const
+{
+  auto res = isl::multi_pw_aff::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::multi_pw_aff<Domain>::at(int pos) const
+{
+  auto res = isl::multi_pw_aff::at(pos);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::multi_pw_aff<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::coalesce() const
+{
+  auto res = isl::multi_pw_aff::coalesce();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::multi_pw_aff<Domain>::domain() const
+{
+  auto res = isl::multi_pw_aff::domain();
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::gist(const typed::set<> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_pw_aff<Domain>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::multi_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::gist(const typed::basic_set<> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::gist(const typed::point<> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::multi_pw_aff<Domain>::identity() const
+{
+  auto res = isl::multi_pw_aff::identity();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::multi_pw_aff<Arg1, Domain> typed::multi_pw_aff<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::multi_pw_aff::insert_domain(domain);
+  return typed::multi_pw_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Anonymous> typed::multi_pw_aff<Domain>::list() const
+{
+  auto res = isl::multi_pw_aff::list();
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::max(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::max(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::max(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::max(const typed::pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::max(const typed::pw_multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_pw_aff<Domain>::max_multi_val() const
+{
+  auto res = isl::multi_pw_aff::max_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::min(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::min(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::min(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::min(const typed::pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::min(const typed::pw_multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_pw_aff<Domain>::min_multi_val() const
+{
+  auto res = isl::multi_pw_aff::min_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::neg() const
+{
+  auto res = isl::multi_pw_aff::neg();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_pw_aff<Domain>::product(const typed::multi_pw_aff<Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_pw_aff<Domain>::product(const typed::aff<Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_pw_aff<Domain>::product(const typed::multi_aff<Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_pw_aff<Domain>::product(const typed::pw_aff<Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::multi_pw_aff<Domain>::product(const typed::pw_multi_aff<Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale(mv);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale(long v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale_down(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale_down(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::scale_down(long v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::set_at(int pos, const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_pw_aff<Domain>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2> typed::multi_pw_aff<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2> typed::multi_pw_aff<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::multi_pw_aff<Domain>::space() const
+{
+  auto res = isl::multi_pw_aff::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::sub(const typed::pw_multi_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::multi_pw_aff<Arg1, Domain> typed::multi_pw_aff<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::multi_pw_aff::unbind_params_insert_domain(domain);
+  return typed::multi_pw_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::multi_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::multi_pw_aff<Domain>::union_add(const typed::pw_multi_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const typed::aff<Domain, Range> &aff)
+  : isl::multi_pw_aff(aff)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const typed::multi_aff<Domain, Range> &ma)
+  : isl::multi_pw_aff(ma)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const typed::pw_aff<Domain, Range> &pa)
+  : isl::multi_pw_aff(pa)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const typed::space<Domain, Range> &space, const typed::pw_aff_list<Domain, Anonymous> &list)
+  : isl::multi_pw_aff(space, list)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const typed::pw_multi_aff<Domain, Range> &pma)
+  : isl::multi_pw_aff(pma)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range>::multi_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add(const typed::pw_multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::add_constant(mv);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::add_constant(long v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::multi_pw_aff<Domain, Range>::as_map() const
+{
+  auto res = isl::multi_pw_aff::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::as_multi_aff() const
+{
+  auto res = isl::multi_pw_aff::as_multi_aff();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff<Domain, Anonymous> typed::multi_pw_aff<Domain, Range>::at(int pos) const
+{
+  auto res = isl::multi_pw_aff::at(pos);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::multi_pw_aff<Domain, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<Domain, Range>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind_domain(tuple);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::coalesce() const
+{
+  auto res = isl::multi_pw_aff::coalesce();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::multi_pw_aff<Domain, Range>::domain() const
+{
+  auto res = isl::multi_pw_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::gist(const typed::set<Domain> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::multi_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::gist(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::gist(const typed::point<Domain> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::identity() const
+{
+  auto res = isl::multi_pw_aff::identity();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_domain(const typed::set<Domain> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_domain(const typed::basic_set<Domain> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_domain(const typed::point<Domain> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff_list<Domain, Anonymous> typed::multi_pw_aff<Domain, Range>::list() const
+{
+  auto res = isl::multi_pw_aff::list();
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::max(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::max(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::max(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::max(const typed::pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::max(const typed::pw_multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::multi_pw_aff<Domain, Range>::max_multi_val() const
+{
+  auto res = isl::multi_pw_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::min(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::min(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::min(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::min(const typed::pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::min(const typed::pw_multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::multi_pw_aff<Domain, Range>::min_multi_val() const
+{
+  auto res = isl::multi_pw_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::neg() const
+{
+  auto res = isl::multi_pw_aff::neg();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::product(const typed::aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::product(const typed::multi_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::product(const typed::pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::product(const typed::pw_multi_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::multi_pw_aff::pullback(ma);
+  return typed::multi_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::multi_aff<Domain> &ma) const
+{
+  auto res = isl::multi_pw_aff::pullback(ma);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::multi_pw_aff::pullback(pma);
+  return typed::multi_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain> &pma) const
+{
+  auto res = isl::multi_pw_aff::pullback(pma);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2, Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::multi_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_pw_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::multi_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::multi_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::multi_pw_aff<Domain, Range>::range_product(const typed::pw_multi_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale(mv);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale(long v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::scale_down(long v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, Range2> typed::multi_pw_aff<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, Range2> typed::multi_pw_aff<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::multi_pw_aff<Domain, Range>::space() const
+{
+  auto res = isl::multi_pw_aff::space();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::sub(const typed::pw_multi_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::multi_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::pw_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::multi_pw_aff<Domain, Range>::union_add(const typed::pw_multi_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const typed::aff<pair<Domain2, Range2>, Range> &aff)
+  : isl::multi_pw_aff(aff)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const typed::multi_aff<pair<Domain2, Range2>, Range> &ma)
+  : isl::multi_pw_aff(ma)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const typed::pw_aff<pair<Domain2, Range2>, Range> &pa)
+  : isl::multi_pw_aff(pa)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const typed::space<pair<Domain2, Range2>, Range> &space, const typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> &list)
+  : isl::multi_pw_aff(space, list)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma)
+  : isl::multi_pw_aff(pma)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range>::multi_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::add_constant(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::add_constant(long v) const
+{
+  auto res = isl::multi_pw_aff::add_constant(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::map<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::as_map() const
+{
+  auto res = isl::multi_pw_aff::as_map();
+  return typed::map<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::as_multi_aff() const
+{
+  auto res = isl::multi_pw_aff::as_multi_aff();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::at(int pos) const
+{
+  auto res = isl::multi_pw_aff::at(pos);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::set<pair<Domain2, Range2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind(tuple);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind_domain(tuple);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range2, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const
+{
+  auto res = isl::multi_pw_aff::bind_domain_wrapped_domain(tuple);
+  return typed::multi_pw_aff<Range2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::coalesce() const
+{
+  auto res = isl::multi_pw_aff::coalesce();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::set<pair<Domain2, Range2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::domain() const
+{
+  auto res = isl::multi_pw_aff::domain();
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::gist(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::gist(const typed::union_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::multi_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::gist(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::gist(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::multi_pw_aff::gist(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::identity() const
+{
+  auto res = isl::multi_pw_aff::identity();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::set<pair<Domain2, Range2>> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::point<pair<Domain2, Range2>> &domain) const
+{
+  auto res = isl::multi_pw_aff::intersect_domain(domain);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::multi_pw_aff::intersect_params(set);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::list() const
+{
+  auto res = isl::multi_pw_aff::list();
+  return typed::pw_aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::max_multi_val() const
+{
+  auto res = isl::multi_pw_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::min_multi_val() const
+{
+  auto res = isl::multi_pw_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::neg() const
+{
+  auto res = isl::multi_pw_aff::neg();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::product(const typed::aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::product(const typed::pw_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::product(const typed::pw_multi_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::multi_pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<Arg2, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::multi_pw_aff::pullback(ma);
+  return typed::multi_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::multi_pw_aff::pullback(ma);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<Arg2, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<Arg2, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::multi_pw_aff::pullback(pma);
+  return typed::multi_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::multi_pw_aff::pullback(pma);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_union_pw_aff<Arg2, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::multi_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::multi_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::multi_pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale(long v) const
+{
+  auto res = isl::multi_pw_aff::scale(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::scale_down(long v) const
+{
+  auto res = isl::multi_pw_aff::scale_down(v);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::multi_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_pw_aff::set_range_tuple(id);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::space<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::space() const
+{
+  auto res = isl::multi_pw_aff::space();
+  return typed::space<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::multi_pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::pw_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::multi_pw_aff<pair<Domain2, Range2>, Range>::union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::multi_pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain>::multi_union_pw_aff(const typed::multi_pw_aff<Domain> &mpa)
+  : isl::multi_union_pw_aff(mpa)
+{
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain>::multi_union_pw_aff(const typed::union_pw_aff<Domain> &upa)
+  : isl::multi_union_pw_aff(upa)
+{
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain>::multi_union_pw_aff(const typed::space<Domain> &space, const typed::union_pw_aff_list<Anonymous> &list)
+  : isl::multi_union_pw_aff(space, list)
+{
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain>::multi_union_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_union_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::add(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::add(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::add(const typed::union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::multi_union_pw_aff<Domain>::at(int pos) const
+{
+  auto res = isl::multi_union_pw_aff::at(pos);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_set<> typed::multi_union_pw_aff<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::multi_union_pw_aff::bind(tuple);
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::coalesce() const
+{
+  auto res = isl::multi_union_pw_aff::coalesce();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<> typed::multi_union_pw_aff<Domain>::domain() const
+{
+  auto res = isl::multi_union_pw_aff::domain();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::gist(const typed::point<> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::gist(const typed::set<> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Anonymous> typed::multi_union_pw_aff<Domain>::list() const
+{
+  auto res = isl::multi_union_pw_aff::list();
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::neg() const
+{
+  auto res = isl::multi_union_pw_aff::neg();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_union_pw_aff::scale(mv);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale(long v) const
+{
+  auto res = isl::multi_union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale_down(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(mv);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale_down(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::scale_down(long v) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::multi_union_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2> typed::multi_union_pw_aff<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2> typed::multi_union_pw_aff<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::multi_union_pw_aff<Domain>::space() const
+{
+  auto res = isl::multi_union_pw_aff::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::sub(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::sub(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::sub(const typed::union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::union_add(const typed::multi_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::multi_union_pw_aff<Domain>::union_add(const typed::union_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range>::multi_union_pw_aff(const typed::multi_pw_aff<Domain, Range> &mpa)
+  : isl::multi_union_pw_aff(mpa)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range>::multi_union_pw_aff(const typed::union_pw_aff<Domain, Range> &upa)
+  : isl::multi_union_pw_aff(upa)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range>::multi_union_pw_aff(const typed::space<Domain, Range> &space, const typed::union_pw_aff_list<Domain, Anonymous> &list)
+  : isl::multi_union_pw_aff(space, list)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range>::multi_union_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_union_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::add(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::add(const typed::union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_aff<Domain, Anonymous> typed::multi_union_pw_aff<Domain, Range>::at(int pos) const
+{
+  auto res = isl::multi_union_pw_aff::at(pos);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Domain> typed::multi_union_pw_aff<Domain, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::multi_union_pw_aff::bind(tuple);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::coalesce() const
+{
+  auto res = isl::multi_union_pw_aff::coalesce();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Domain> typed::multi_union_pw_aff<Domain, Range>::domain() const
+{
+  auto res = isl::multi_union_pw_aff::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::multi_union_pw_aff::gist(context);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_domain(const typed::basic_set<Domain> &uset) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_domain(const typed::point<Domain> &uset) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_domain(const typed::set<Domain> &uset) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_domain(uset);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::multi_union_pw_aff::intersect_params(params);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_aff_list<Domain, Anonymous> typed::multi_union_pw_aff<Domain, Range>::list() const
+{
+  auto res = isl::multi_union_pw_aff::list();
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::neg() const
+{
+  auto res = isl::multi_union_pw_aff::neg();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2, Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2, Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::multi_aff<Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2, Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2, Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::union_pw_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Range> typed::multi_union_pw_aff<Domain, Range>::pullback(const typed::union_pw_aff<Domain> &upma) const
+{
+  auto res = isl::multi_union_pw_aff::pullback(upma);
+  return typed::multi_union_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_union_pw_aff<Domain, Range>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_union_pw_aff<Domain, Range>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::multi_union_pw_aff<Domain, Range>::range_product(const typed::union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_union_pw_aff::scale(mv);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale(long v) const
+{
+  auto res = isl::multi_union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(mv);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::scale_down(long v) const
+{
+  auto res = isl::multi_union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::multi_union_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, Range2> typed::multi_union_pw_aff<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, Range2> typed::multi_union_pw_aff<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Range> typed::multi_union_pw_aff<Domain, Range>::space() const
+{
+  auto res = isl::multi_union_pw_aff::space();
+  return typed::space<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::sub(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::sub(const typed::union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::multi_union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::union_add(const typed::multi_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::multi_union_pw_aff<Domain, Range>::union_add(const typed::union_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::multi_union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain>::multi_val(const typed::space<Domain> &space, const typed::val_list<Anonymous> &list)
+  : isl::multi_val(space, list)
+{
+}
+
+template <typename Domain>
+typed::multi_val<Domain>::multi_val(const isl::ctx &ctx, const std::string &str)
+  : isl::multi_val(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::add(const typed::multi_val<Domain> &multi2) const
+{
+  auto res = isl::multi_val::add(multi2);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::add(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_val::add(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::add(long v) const
+{
+  auto res = isl::multi_val::add(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::val<Anonymous> typed::multi_val<Domain>::at(int pos) const
+{
+  auto res = isl::multi_val::at(pos);
+  return typed::val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::val_list<Anonymous> typed::multi_val<Domain>::list() const
+{
+  auto res = isl::multi_val::list();
+  return typed::val_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::max(const typed::multi_val<Domain> &multi2) const
+{
+  auto res = isl::multi_val::max(multi2);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::min(const typed::multi_val<Domain> &multi2) const
+{
+  auto res = isl::multi_val::min(multi2);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::neg() const
+{
+  auto res = isl::multi_val::neg();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_val<pair<Domain, Range>> typed::multi_val<Domain>::product(const typed::multi_val<Range> &multi2) const
+{
+  auto res = isl::multi_val::product(multi2);
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_val::scale(mv);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_val::scale(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale(long v) const
+{
+  auto res = isl::multi_val::scale(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale_down(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::multi_val::scale_down(mv);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale_down(const typed::val<Domain> &v) const
+{
+  auto res = isl::multi_val::scale_down(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::scale_down(long v) const
+{
+  auto res = isl::multi_val::scale_down(v);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::set_at(int pos, const typed::val<Anonymous> &el) const
+{
+  auto res = isl::multi_val::set_at(pos, el);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::set_at(int pos, long el) const
+{
+  auto res = isl::multi_val::set_at(pos, el);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_val<Domain2> typed::multi_val<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::multi_val::set_range_tuple(id);
+  return typed::multi_val<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::multi_val<Domain2> typed::multi_val<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::multi_val::set_range_tuple(id);
+  return typed::multi_val<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::multi_val<Domain>::space() const
+{
+  auto res = isl::multi_val::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::multi_val<Domain>::sub(const typed::multi_val<Domain> &multi2) const
+{
+  auto res = isl::multi_val::sub(multi2);
+  return typed::multi_val<Domain>(res);
+}
+
+typed::set<> typed::point<>::coalesce() const
+{
+  auto res = isl::point::coalesce();
+  return typed::set<>(res);
+}
+
+typed::basic_set<> typed::point<>::detect_equalities() const
+{
+  auto res = isl::point::detect_equalities();
+  return typed::basic_set<>(res);
+}
+
+bool typed::point<>::every_set(const std::function<bool(typed::set<>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<>(arg0));
+  };
+  return isl::point::every_set(lambda);
+}
+
+typed::set<> typed::point<>::extract_set(const typed::space<> &space) const
+{
+  auto res = isl::point::extract_set(space);
+  return typed::set<>(res);
+}
+
+void typed::point<>::foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<>(arg0));
+  };
+  return isl::point::foreach_basic_set(lambda);
+}
+
+void typed::point<>::foreach_point(const std::function<void(typed::point<>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<>(arg0));
+  };
+  return isl::point::foreach_point(lambda);
+}
+
+void typed::point<>::foreach_set(const std::function<void(typed::set<>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<>(arg0));
+  };
+  return isl::point::foreach_set(lambda);
+}
+
+typed::basic_set<> typed::point<>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::basic_set<>(res);
+}
+
+typed::set<> typed::point<>::gist(const typed::set<> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::point<>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::pw_aff<Anonymous> typed::point<>::indicator_function() const
+{
+  auto res = isl::point::indicator_function();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::basic_set<> typed::point<>::intersect(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::point::intersect(bset2);
+  return typed::basic_set<>(res);
+}
+
+typed::set<> typed::point<>::intersect(const typed::set<> &set2) const
+{
+  auto res = isl::point::intersect(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::point<>::intersect(const typed::union_set<> &uset2) const
+{
+  auto res = isl::point::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::point<>::project_out_all_params() const
+{
+  auto res = isl::point::project_out_all_params();
+  return typed::set<>(res);
+}
+
+typed::set<> typed::point<>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::point<>::project_out_param(const std::string &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::point<>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::point::project_out_param(list);
+  return typed::set<>(res);
+}
+
+typed::space<> typed::point<>::space() const
+{
+  auto res = isl::point::space();
+  return typed::space<>(res);
+}
+
+typed::set<> typed::point<>::subtract(const typed::set<> &set2) const
+{
+  auto res = isl::point::subtract(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::point<>::subtract(const typed::union_set<> &uset2) const
+{
+  auto res = isl::point::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::point<>::to_set() const
+{
+  auto res = isl::point::to_set();
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::point<>::to_union_set() const
+{
+  auto res = isl::point::to_union_set();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<>::unbind_params(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::point::unbind_params(tuple);
+  return typed::set<Domain>(res);
+}
+
+typed::set<> typed::point<>::unite(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::point::unite(bset2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::point<>::unite(const typed::set<> &set2) const
+{
+  auto res = isl::point::unite(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::point<>::unite(const typed::union_set<> &uset2) const
+{
+  auto res = isl::point::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::basic_set<Range> typed::point<Domain>::apply(const typed::basic_map<Domain, Range> &bmap) const
+{
+  auto res = isl::point::apply(bmap);
+  return typed::basic_set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<Range> typed::point<Domain>::apply(const typed::map<Domain, Range> &map) const
+{
+  auto res = isl::point::apply(map);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::point<Domain>::apply(const typed::union_map<Domain, Range> &umap) const
+{
+  auto res = isl::point::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::point<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::point::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::as_set() const
+{
+  auto res = isl::point::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::point<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::point::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::coalesce() const
+{
+  auto res = isl::point::coalesce();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::point<Domain>::detect_equalities() const
+{
+  auto res = isl::point::detect_equalities();
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+bool typed::point<Domain>::every_set(const std::function<bool(typed::set<Domain>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<Domain>(arg0));
+  };
+  return isl::point::every_set(lambda);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::extract_set(const typed::space<Domain> &space) const
+{
+  auto res = isl::point::extract_set(space);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+void typed::point<Domain>::foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<Domain>(arg0));
+  };
+  return isl::point::foreach_basic_set(lambda);
+}
+
+template <typename Domain>
+void typed::point<Domain>::foreach_point(const std::function<void(typed::point<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<Domain>(arg0));
+  };
+  return isl::point::foreach_point(lambda);
+}
+
+template <typename Domain>
+void typed::point<Domain>::foreach_set(const std::function<void(typed::set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<Domain>(arg0));
+  };
+  return isl::point::foreach_set(lambda);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::point<Domain>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::point<Domain>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::point<Domain>::identity() const
+{
+  auto res = isl::point::identity();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::point<Domain>::indicator_function() const
+{
+  auto res = isl::point::indicator_function();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::point<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::point::insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::point<Domain>::intersect(const typed::basic_set<Domain> &bset2) const
+{
+  auto res = isl::point::intersect(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::intersect(const typed::set<Domain> &set2) const
+{
+  auto res = isl::point::intersect(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::point<Domain>::intersect(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::point::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<Domain> typed::point<Domain>::intersect_params(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::point::intersect_params(bset2);
+  return typed::basic_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::point::intersect_params(params);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::lexmax() const
+{
+  auto res = isl::point::lexmax();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::point<Domain>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::point::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::lexmin() const
+{
+  auto res = isl::point::lexmin();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::point<Domain>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::point::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::lower_bound(const typed::multi_pw_aff<Domain> &lower) const
+{
+  auto res = isl::point::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::lower_bound(const typed::multi_val<Domain> &lower) const
+{
+  auto res = isl::point::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::point<Domain>::max_multi_pw_aff() const
+{
+  auto res = isl::point::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::point<Domain>::min_multi_pw_aff() const
+{
+  auto res = isl::point::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::point<Domain>::multi_val() const
+{
+  auto res = isl::point::multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::basic_set<> typed::point<Domain>::params() const
+{
+  auto res = isl::point::params();
+  return typed::basic_set<>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::point<Domain>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::point::plain_multi_val_if_fixed();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::point<Domain>::preimage(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::point::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::point<Domain>::preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::point::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::point<Domain>::preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::point::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::point<Domain>::preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::point::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<pair<Domain, Range>> typed::point<Domain>::product(const typed::set<Range> &set2) const
+{
+  auto res = isl::point::product(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::project_out_all_params() const
+{
+  auto res = isl::point::project_out_all_params();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::project_out_param(const std::string &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::point::project_out_param(list);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<Domain, Range> typed::point<Domain>::pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::point::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain> typed::point<Domain>::simple_fixed_box_hull() const
+{
+  auto res = isl::point::simple_fixed_box_hull();
+  return typed::fixed_box<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::point<Domain>::space() const
+{
+  auto res = isl::point::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::subtract(const typed::set<Domain> &set2) const
+{
+  auto res = isl::point::subtract(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::point<Domain>::subtract(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::point::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::to_set() const
+{
+  auto res = isl::point::to_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::point<Domain>::to_union_set() const
+{
+  auto res = isl::point::to_union_set();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::point<Domain>::translation() const
+{
+  auto res = isl::point::translation();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::point<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::point::unbind_params_insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::unite(const typed::basic_set<Domain> &bset2) const
+{
+  auto res = isl::point::unite(bset2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::unite(const typed::set<Domain> &set2) const
+{
+  auto res = isl::point::unite(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::point<Domain>::unite(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::point::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::upper_bound(const typed::multi_pw_aff<Domain> &upper) const
+{
+  auto res = isl::point::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::point<Domain>::upper_bound(const typed::multi_val<Domain> &upper) const
+{
+  auto res = isl::point::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::basic_set<Arg2> typed::point<pair<Domain, Range>>::apply(const typed::basic_map<pair<Domain, Range>, Arg2> &bmap) const
+{
+  auto res = isl::point::apply(bmap);
+  return typed::basic_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<Arg2> typed::point<pair<Domain, Range>>::apply(const typed::map<pair<Domain, Range>, Arg2> &map) const
+{
+  auto res = isl::point::apply(map);
+  return typed::set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::point<pair<Domain, Range>>::apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::point::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::point<pair<Domain, Range>>::as_pw_multi_aff() const
+{
+  auto res = isl::point::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::as_set() const
+{
+  auto res = isl::point::as_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<> typed::point<pair<Domain, Range>>::bind(const typed::multi_id<pair<Domain, Range>> &tuple) const
+{
+  auto res = isl::point::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::coalesce() const
+{
+  auto res = isl::point::coalesce();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::detect_equalities() const
+{
+  auto res = isl::point::detect_equalities();
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::point<pair<Domain, Range>>::every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::point::every_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::extract_set(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::point::extract_set(space);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::point<pair<Domain, Range>>::foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<pair<Domain, Range>>(arg0));
+  };
+  return isl::point::foreach_basic_set(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::point<pair<Domain, Range>>::foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<pair<Domain, Range>>(arg0));
+  };
+  return isl::point::foreach_point(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::point<pair<Domain, Range>>::foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::point::foreach_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::gist(const typed::basic_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::gist(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::gist(const typed::union_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::point::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::point<pair<Domain, Range>>::identity() const
+{
+  auto res = isl::point::identity();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff<pair<Domain, Range>, Anonymous> typed::point<pair<Domain, Range>>::indicator_function() const
+{
+  auto res = isl::point::indicator_function();
+  return typed::pw_aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::point<pair<Domain, Range>>::insert_domain(const typed::space<Arg2> &domain) const
+{
+  auto res = isl::point::insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::intersect(const typed::basic_set<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::point::intersect(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::intersect(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::point::intersect(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::intersect(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::point::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::intersect_params(const typed::basic_set<> &bset2) const
+{
+  auto res = isl::point::intersect_params(bset2);
+  return typed::basic_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::point::intersect_params(params);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lexmax() const
+{
+  auto res = isl::point::lexmax();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::point::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lexmin() const
+{
+  auto res = isl::point::lexmin();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::point::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::point::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::point::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::point<pair<Domain, Range>>::max_multi_pw_aff() const
+{
+  auto res = isl::point::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::point<pair<Domain, Range>>::min_multi_pw_aff() const
+{
+  auto res = isl::point::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::point<pair<Domain, Range>>::multi_val() const
+{
+  auto res = isl::point::multi_val();
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::basic_set<> typed::point<pair<Domain, Range>>::params() const
+{
+  auto res = isl::point::params();
+  return typed::basic_set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::point<pair<Domain, Range>>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::point::plain_multi_val_if_fixed();
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::point<pair<Domain, Range>>::preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::point::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::point<pair<Domain, Range>>::preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::point::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::point<pair<Domain, Range>>::preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::point::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::point<pair<Domain, Range>>::preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::point::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<pair<pair<Domain, Range>, Arg2>> typed::point<pair<Domain, Range>>::product(const typed::set<Arg2> &set2) const
+{
+  auto res = isl::point::product(set2);
+  return typed::set<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::project_out_all_params() const
+{
+  auto res = isl::point::project_out_all_params();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::project_out_param(const std::string &id) const
+{
+  auto res = isl::point::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::point::project_out_param(list);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain, Range>, Arg2> typed::point<pair<Domain, Range>>::pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const
+{
+  auto res = isl::point::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<pair<Domain, Range>> typed::point<pair<Domain, Range>>::simple_fixed_box_hull() const
+{
+  auto res = isl::point::simple_fixed_box_hull();
+  return typed::fixed_box<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::point<pair<Domain, Range>>::space() const
+{
+  auto res = isl::point::space();
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::subtract(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::point::subtract(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::subtract(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::point::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::to_set() const
+{
+  auto res = isl::point::to_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::to_union_set() const
+{
+  auto res = isl::point::to_union_set();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::point<pair<Domain, Range>>::translation() const
+{
+  auto res = isl::point::translation();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::point<pair<Domain, Range>>::unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const
+{
+  auto res = isl::point::unbind_params_insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::unite(const typed::basic_set<pair<Domain, Range>> &bset2) const
+{
+  auto res = isl::point::unite(bset2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::unite(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::point::unite(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::unite(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::point::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::point<pair<Domain, Range>>::unwrap() const
+{
+  auto res = isl::point::unwrap();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::point::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::point<pair<Domain, Range>>::upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::point::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+typed::pw_aff<Anonymous>::pw_aff(const typed::aff<Anonymous> &aff)
+  : isl::pw_aff(aff)
+{
+}
+
+typed::pw_aff<Anonymous>::pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_aff(ctx, str)
+{
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::add(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::add(const typed::aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::add_constant(long v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::add_constant(mv);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::pw_aff<Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const
+{
+  auto res = isl::pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+typed::aff<Anonymous> typed::pw_aff<Anonymous>::as_aff() const
+{
+  auto res = isl::pw_aff::as_aff();
+  return typed::aff<Anonymous>(res);
+}
+
+typed::multi_aff<Anonymous> typed::pw_aff<Anonymous>::as_multi_aff() const
+{
+  auto res = isl::pw_aff::as_multi_aff();
+  return typed::multi_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::set<Anonymous> typed::pw_aff<Anonymous>::as_set() const
+{
+  auto res = isl::pw_aff::as_set();
+  return typed::set<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::at(int pos) const
+{
+  auto res = isl::pw_aff::at(pos);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::set<> typed::pw_aff<Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::pw_aff::bind(tuple);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::pw_aff<Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::pw_aff<Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::ceil() const
+{
+  auto res = isl::pw_aff::ceil();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::coalesce() const
+{
+  auto res = isl::pw_aff::coalesce();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::cond(const typed::pw_aff<Anonymous> &pwaff_true, const typed::pw_aff<Anonymous> &pwaff_false) const
+{
+  auto res = isl::pw_aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::set<> typed::pw_aff<Anonymous>::domain() const
+{
+  auto res = isl::pw_aff::domain();
+  return typed::set<>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::extract_pw_multi_aff(const typed::space<Anonymous> &space) const
+{
+  auto res = isl::pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::floor() const
+{
+  auto res = isl::pw_aff::floor();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::gist(const typed::set<> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::gist(const typed::point<> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous, Anonymous> typed::pw_aff<Anonymous>::identity() const
+{
+  auto res = isl::pw_aff::identity();
+  return typed::multi_pw_aff<Anonymous, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Anonymous>::insert_domain(const typed::space<Domain> &domain) const
+{
+  auto res = isl::pw_aff::insert_domain(domain);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff_list<Anonymous> typed::pw_aff<Anonymous>::list() const
+{
+  auto res = isl::pw_aff::list();
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::max(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::max(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::max(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::max(const typed::aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_val<Anonymous> typed::pw_aff<Anonymous>::max_multi_val() const
+{
+  auto res = isl::pw_aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::min(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::min(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::min(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::min(const typed::aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_val<Anonymous> typed::pw_aff<Anonymous>::min_multi_val() const
+{
+  auto res = isl::pw_aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::mod(long mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::neg() const
+{
+  auto res = isl::pw_aff::neg();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Range>
+typed::multi_pw_aff<pair<Anonymous, Range>> typed::pw_aff<Anonymous>::product(const typed::multi_pw_aff<Range> &multi2) const
+{
+  auto res = isl::pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Anonymous, Range>>(res);
+}
+
+template <typename Range>
+typed::pw_multi_aff<pair<Anonymous, Range>> typed::pw_aff<Anonymous>::product(const typed::pw_multi_aff<Range> &pma2) const
+{
+  auto res = isl::pw_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Anonymous, Range>>(res);
+}
+
+typed::pw_multi_aff_list<Anonymous> typed::pw_aff<Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale(mv);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale(long v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale_down(const typed::val<Anonymous> &f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::scale_down(long f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::set_at(int pos, const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2>
+typed::pw_multi_aff<Domain2> typed::pw_aff<Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain2>(res);
+}
+
+template <typename Domain2>
+typed::pw_multi_aff<Domain2> typed::pw_aff<Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain2>(res);
+}
+
+typed::space<Anonymous> typed::pw_aff<Anonymous>::space() const
+{
+  auto res = isl::pw_aff::space();
+  return typed::space<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::multi_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::sub(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::sub(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::sub(const typed::aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_aff();
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Anonymous>::unbind_params_insert_domain(const typed::multi_id<Domain> &domain) const
+{
+  auto res = isl::pw_aff::unbind_params_insert_domain(domain);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+typed::multi_pw_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::multi_pw_aff<Anonymous> &mpa2) const
+{
+  auto res = isl::pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const
+{
+  auto res = isl::pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::pw_aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::pw_multi_aff<Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::union_add(pma2);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff<Anonymous>::union_add(const typed::aff<Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous>::pw_aff(const typed::aff<Domain, Anonymous> &aff)
+  : isl::pw_aff(aff)
+{
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous>::pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add_constant(long v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::add_constant(mv);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::pw_aff<Domain, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const
+{
+  auto res = isl::pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_aff() const
+{
+  auto res = isl::pw_aff::as_aff();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_map() const
+{
+  auto res = isl::pw_aff::as_map();
+  return typed::map<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_multi_aff() const
+{
+  auto res = isl::pw_aff::as_multi_aff();
+  return typed::multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::as_union_map() const
+{
+  auto res = isl::pw_aff::as_union_map();
+  return typed::union_map<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::at(int pos) const
+{
+  auto res = isl::pw_aff::at(pos);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::pw_aff::bind(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::pw_aff<Domain, Anonymous>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::pw_aff::bind_domain(tuple);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::ceil() const
+{
+  auto res = isl::pw_aff::ceil();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::coalesce() const
+{
+  auto res = isl::pw_aff::coalesce();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::cond(const typed::pw_aff<Domain, Anonymous> &pwaff_true, const typed::pw_aff<Domain, Anonymous> &pwaff_false) const
+{
+  auto res = isl::pw_aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::domain() const
+{
+  auto res = isl::pw_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const
+{
+  auto res = isl::pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::floor() const
+{
+  auto res = isl::pw_aff::floor();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::ge_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::ge_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::ge_set(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::ge_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::gt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::gt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::gt_set(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::gt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::identity() const
+{
+  auto res = isl::pw_aff::identity();
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_aff::intersect_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_aff::intersect_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::le_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::le_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::le_set(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::le_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::list() const
+{
+  auto res = isl::pw_aff::list();
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::lt_set(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::lt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_aff<Domain, Anonymous>::lt_set(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::lt_set(pwaff2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::max(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::max(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::max(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Anonymous> typed::pw_aff<Domain, Anonymous>::max_multi_val() const
+{
+  auto res = isl::pw_aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::min(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::min(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::min(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Anonymous> typed::pw_aff<Domain, Anonymous>::min_multi_val() const
+{
+  auto res = isl::pw_aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::mod(long mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::neg() const
+{
+  auto res = isl::pw_aff::neg();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::pw_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_aff<Domain2, Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::pw_aff::pullback(ma);
+  return typed::pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain> &ma) const
+{
+  auto res = isl::pw_aff::pullback(ma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_aff<Domain2, Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::pw_aff::pullback(mpa);
+  return typed::pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::multi_pw_aff<Domain> &mpa) const
+{
+  auto res = isl::pw_aff::pullback(mpa);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_aff<Domain2, Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::pw_aff::pullback(pma);
+  return typed::pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain> &pma) const
+{
+  auto res = isl::pw_aff::pullback(pma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::pw_aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::pw_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> typed::pw_aff<Domain, Anonymous>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::pw_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale(mv);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale(long v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale_down(const typed::val<Anonymous> &f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::scale_down(long f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::pw_aff<Domain, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::pw_aff<Domain, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::space() const
+{
+  auto res = isl::pw_aff::space();
+  return typed::space<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::multi_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::sub(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::sub(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_aff::subtract_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_aff::subtract_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::subtract_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::subtract_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_aff();
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::multi_pw_aff<Domain, Anonymous> &mpa2) const
+{
+  auto res = isl::pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const
+{
+  auto res = isl::pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::pw_aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::pw_multi_aff<Domain, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff<Domain, Anonymous>::union_add(const typed::aff<Domain, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pw_aff(const typed::aff<pair<Domain2, Range2>, Anonymous> &aff)
+  : isl::pw_aff(aff)
+{
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_aff(ctx, str)
+{
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::add(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add_constant(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add_constant(long v) const
+{
+  auto res = isl::pw_aff::add_constant(v);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::add_constant(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::add_constant(mv);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Arg1> &upma2) const
+{
+  auto res = isl::pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_aff() const
+{
+  auto res = isl::pw_aff::as_aff();
+  return typed::aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::map<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_map() const
+{
+  auto res = isl::pw_aff::as_map();
+  return typed::map<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_multi_aff() const
+{
+  auto res = isl::pw_aff::as_multi_aff();
+  return typed::multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::as_union_map() const
+{
+  auto res = isl::pw_aff::as_union_map();
+  return typed::union_map<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::at(int pos) const
+{
+  auto res = isl::pw_aff::at(pos);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::pw_aff::bind(tuple);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::pw_aff::bind(id);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const
+{
+  auto res = isl::pw_aff::bind_domain(tuple);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Range2, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const
+{
+  auto res = isl::pw_aff::bind_domain_wrapped_domain(tuple);
+  return typed::pw_aff<Range2, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::ceil() const
+{
+  auto res = isl::pw_aff::ceil();
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::coalesce() const
+{
+  auto res = isl::pw_aff::coalesce();
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::cond(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_true, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff_false) const
+{
+  auto res = isl::pw_aff::cond(pwaff_true, pwaff_false);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::domain() const
+{
+  auto res = isl::pw_aff::domain();
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Anonymous> &space) const
+{
+  auto res = isl::pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::floor() const
+{
+  auto res = isl::pw_aff::floor();
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::ge_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::ge_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::ge_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::ge_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::union_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::basic_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gist(const typed::point<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::pw_aff::gist(context);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::gt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::gt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::gt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::identity() const
+{
+  auto res = isl::pw_aff::identity();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::pw_aff::intersect_domain(space);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::pw_aff::intersect_domain(uset);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_domain(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::intersect_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_aff::intersect_params(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::le_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::le_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::le_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::le_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::list() const
+{
+  auto res = isl::pw_aff::list();
+  return typed::pw_aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::lt_set(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::lt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::set<pair<Domain2, Range2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::lt_set(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::lt_set(pwaff2);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::max(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::max(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::max(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::max(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_val<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::max_multi_val() const
+{
+  auto res = isl::pw_aff::max_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::min(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::min(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::min(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::min(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_val<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::min_multi_val() const
+{
+  auto res = isl::pw_aff::min_multi_val();
+  return typed::multi_val<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::mod(const typed::val<Anonymous> &mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::mod(long mod) const
+{
+  auto res = isl::pw_aff::mod(mod);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::neg() const
+{
+  auto res = isl::pw_aff::neg();
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::pw_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const
+{
+  auto res = isl::pw_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1, typename Arg2>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::product(const typed::multi_pw_aff<Arg1, Arg2> &multi2) const
+{
+  auto res = isl::pw_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1, typename Arg2>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::product(const typed::pw_multi_aff<Arg1, Arg2> &pma2) const
+{
+  auto res = isl::pw_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg1>, pair<Anonymous, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_aff<Arg1, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_aff<Arg1, pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::pw_aff::pullback(ma);
+  return typed::pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::pw_aff::pullback(ma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_aff<Arg1, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_pw_aff<Arg1, pair<Domain2, Range2>> &mpa) const
+{
+  auto res = isl::pw_aff::pullback(mpa);
+  return typed::pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa) const
+{
+  auto res = isl::pw_aff::pullback(mpa);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_aff<Arg1, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::pw_multi_aff<Arg1, pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::pw_aff::pullback(pma);
+  return typed::pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma) const
+{
+  auto res = isl::pw_aff::pullback(pma);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_aff<Arg1, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::union_pw_multi_aff<Arg1, pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::pw_aff::pullback(upma);
+  return typed::union_pw_aff<Arg1, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma) const
+{
+  auto res = isl::pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const
+{
+  auto res = isl::pw_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg1> &multi2) const
+{
+  auto res = isl::pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> &pma2) const
+{
+  auto res = isl::pw_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg1> &upma2) const
+{
+  auto res = isl::pw_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Anonymous, Arg1>>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale(long v) const
+{
+  auto res = isl::pw_aff::scale(v);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::pw_aff::scale_down(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale_down(const typed::val<Anonymous> &f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::scale_down(long f) const
+{
+  auto res = isl::pw_aff::scale_down(f);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::space<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::space() const
+{
+  auto res = isl::pw_aff::space();
+  return typed::space<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &multi2) const
+{
+  auto res = isl::pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::sub(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::sub(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::sub(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::pw_aff::subtract_domain(space);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::pw_aff::subtract_domain(uset);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::subtract_domain(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_aff::subtract_domain(set);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::to_union_pw_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_aff();
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous> &mpa2) const
+{
+  auto res = isl::pw_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous> &mupa2) const
+{
+  auto res = isl::pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous> &pma2) const
+{
+  auto res = isl::pw_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &upa2) const
+{
+  auto res = isl::pw_aff::union_add(upa2);
+  return typed::union_pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous> &upma2) const
+{
+  auto res = isl::pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_aff<pair<Domain2, Range2>, Anonymous>::union_add(const typed::aff<pair<Domain2, Range2>, Anonymous> &pwaff2) const
+{
+  auto res = isl::pw_aff::union_add(pwaff2);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+typed::pw_aff_list<Anonymous>::pw_aff_list(const isl::ctx &ctx, int n)
+  : isl::pw_aff_list(ctx, n)
+{
+}
+
+typed::pw_aff_list<Anonymous>::pw_aff_list(const typed::pw_aff<Anonymous> &el)
+  : isl::pw_aff_list(el)
+{
+}
+
+typed::pw_aff_list<Anonymous>::pw_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_aff_list(ctx, str)
+{
+}
+
+typed::pw_aff_list<Anonymous> typed::pw_aff_list<Anonymous>::add(const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::pw_aff_list::add(el);
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+typed::pw_aff_list<Anonymous> typed::pw_aff_list<Anonymous>::add(const typed::aff<Anonymous> &el) const
+{
+  auto res = isl::pw_aff_list::add(el);
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+typed::pw_aff<Anonymous> typed::pw_aff_list<Anonymous>::at(int index) const
+{
+  auto res = isl::pw_aff_list::at(index);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::pw_aff_list<Anonymous> typed::pw_aff_list<Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::pw_aff_list::drop(first, n);
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+void typed::pw_aff_list<Anonymous>::foreach(const std::function<void(typed::pw_aff<Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::pw_aff arg0) {
+    return fn(typed::pw_aff<Anonymous>(arg0));
+  };
+  return isl::pw_aff_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous>::pw_aff_list(const isl::ctx &ctx, int n)
+  : isl::pw_aff_list(ctx, n)
+{
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous>::pw_aff_list(const typed::pw_aff<Domain, Anonymous> &el)
+  : isl::pw_aff_list(el)
+{
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous>::pw_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_aff_list(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_aff_list<Domain, Anonymous>::add(const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_aff_list::add(el);
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_aff_list<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_aff_list::add(el);
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::pw_aff_list<Domain, Anonymous>::at(int index) const
+{
+  auto res = isl::pw_aff_list::at(index);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_aff_list<Domain, Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::pw_aff_list::drop(first, n);
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+void typed::pw_aff_list<Domain, Anonymous>::foreach(const std::function<void(typed::pw_aff<Domain, Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::pw_aff arg0) {
+    return fn(typed::pw_aff<Domain, Anonymous>(arg0));
+  };
+  return isl::pw_aff_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain>::pw_multi_aff(const typed::multi_aff<Domain> &ma)
+  : isl::pw_multi_aff(ma)
+{
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain>::pw_multi_aff(const typed::pw_aff<Domain> &pa)
+  : isl::pw_multi_aff(pa)
+{
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain>::pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add(const typed::pw_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add_constant(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::pw_multi_aff::add_constant(mv);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add_constant(const typed::val<Domain> &v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::add_constant(long v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::pw_multi_aff<Domain>::apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::pw_multi_aff<Domain>::as_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::pw_multi_aff<Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::pw_multi_aff<Domain>::as_set() const
+{
+  auto res = isl::pw_multi_aff::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Anonymous> typed::pw_multi_aff<Domain>::at(int pos) const
+{
+  auto res = isl::pw_multi_aff::at(pos);
+  return typed::pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::pw_multi_aff<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::coalesce() const
+{
+  auto res = isl::pw_multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::pw_multi_aff<Domain>::domain() const
+{
+  auto res = isl::pw_multi_aff::domain();
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::extract_pw_multi_aff(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::gist(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::gist(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::gist(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::pw_multi_aff<Domain>::identity() const
+{
+  auto res = isl::pw_multi_aff::identity();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::pw_multi_aff<Arg1, Domain> typed::pw_multi_aff<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::pw_multi_aff::insert_domain(domain);
+  return typed::pw_multi_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff_list<Anonymous> typed::pw_multi_aff<Domain>::list() const
+{
+  auto res = isl::pw_multi_aff::list();
+  return typed::pw_aff_list<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::max(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::pw_multi_aff<Domain>::max_multi_val() const
+{
+  auto res = isl::pw_multi_aff::max_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::min(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::pw_multi_aff<Domain>::min_multi_val() const
+{
+  auto res = isl::pw_multi_aff::min_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::neg() const
+{
+  auto res = isl::pw_multi_aff::neg();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::pw_multi_aff<Domain>::product(const typed::multi_pw_aff<Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::pw_multi_aff<Domain>::product(const typed::pw_multi_aff<Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::pw_multi_aff<Domain>::product(const typed::multi_aff<Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::pw_multi_aff<Domain>::product(const typed::pw_aff<Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::pw_multi_aff<Domain>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::scale(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale(mv);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::scale(const typed::val<Domain> &v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::scale(long v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::scale_down(const typed::multi_val<Domain> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::scale_down(const typed::val<Domain> &v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::scale_down(long v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::set_at(int pos, const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::pw_multi_aff<Domain>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2> typed::pw_multi_aff<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2> typed::pw_multi_aff<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::pw_multi_aff<Domain>::space() const
+{
+  auto res = isl::pw_multi_aff::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::multi_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::multi_union_pw_aff<Domain> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::sub(const typed::pw_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::multi_pw_aff<Arg1, Domain> typed::pw_multi_aff<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::pw_multi_aff::unbind_params_insert_domain(domain);
+  return typed::multi_pw_aff<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::multi_union_pw_aff<Domain> &mupa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff<Domain>::union_add(const typed::pw_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range>::pw_multi_aff(const typed::multi_aff<Domain, Range> &ma)
+  : isl::pw_multi_aff(ma)
+{
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range>::pw_multi_aff(const typed::pw_aff<Domain, Range> &pa)
+  : isl::pw_multi_aff(pa)
+{
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range>::pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add(const typed::pw_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::add_constant(mv);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::add_constant(long v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::pw_multi_aff<Domain, Range>::apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::pw_multi_aff<Domain, Range>::as_map() const
+{
+  auto res = isl::pw_multi_aff::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::as_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::pw_multi_aff<Domain, Range>::as_union_map() const
+{
+  auto res = isl::pw_multi_aff::as_union_map();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff<Domain, Anonymous> typed::pw_multi_aff<Domain, Range>::at(int pos) const
+{
+  auto res = isl::pw_multi_aff::at(pos);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::pw_multi_aff<Domain, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<Domain, Range>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain(tuple);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::coalesce() const
+{
+  auto res = isl::pw_multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<Domain> typed::pw_multi_aff<Domain, Range>::domain() const
+{
+  auto res = isl::pw_multi_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::extract_pw_multi_aff(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::gist(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::gist(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::gist(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::identity() const
+{
+  auto res = isl::pw_multi_aff::identity();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_multi_aff<Domain, Range>::list() const
+{
+  auto res = isl::pw_multi_aff::list();
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::max(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::pw_multi_aff<Domain, Range>::max_multi_val() const
+{
+  auto res = isl::pw_multi_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::min(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<Range> typed::pw_multi_aff<Domain, Range>::min_multi_val() const
+{
+  auto res = isl::pw_multi_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::neg() const
+{
+  auto res = isl::pw_multi_aff::neg();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::product(const typed::multi_pw_aff<Domain2, Range2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::product(const typed::pw_multi_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::product(const typed::multi_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::product(const typed::pw_aff<Domain2, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::pw_multi_aff<Domain, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::multi_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::pw_multi_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::multi_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, Range>::range_product(const typed::pw_aff<Domain, Range2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale(mv);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale(long v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::scale_down(long v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::pw_multi_aff<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::pw_multi_aff<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::pw_multi_aff<Domain, Range>::space() const
+{
+  auto res = isl::pw_multi_aff::space();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::multi_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::multi_union_pw_aff<Domain, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::sub(const typed::pw_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::subtract_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::subtract_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::multi_pw_aff<Domain, Range> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::multi_union_pw_aff<Domain, Range> &mupa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::pw_multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::multi_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, Range>::union_add(const typed::pw_aff<Domain, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pw_multi_aff(const typed::multi_aff<pair<Domain2, Range2>, Range> &ma)
+  : isl::pw_multi_aff(ma)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pw_multi_aff(const typed::pw_aff<pair<Domain2, Range2>, Range> &pa)
+  : isl::pw_multi_aff(pa)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::add_constant(mv);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add_constant(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::add_constant(long v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::apply(const typed::union_pw_multi_aff<Range, Arg2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::map<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::as_map() const
+{
+  auto res = isl::pw_multi_aff::as_map();
+  return typed::map<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::as_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_aff();
+  return typed::multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_map<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::as_union_map() const
+{
+  auto res = isl::pw_multi_aff::as_union_map();
+  return typed::union_map<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_aff<pair<Domain2, Range2>, Anonymous> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::at(int pos) const
+{
+  auto res = isl::pw_multi_aff::at(pos);
+  return typed::pw_aff<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::set<pair<Domain2, Range2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::bind(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind(tuple);
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::bind_domain(const typed::multi_id<pair<Domain2, Range2>> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain(tuple);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<Range2, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::bind_domain_wrapped_domain(const typed::multi_id<Domain2> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain_wrapped_domain(tuple);
+  return typed::pw_multi_aff<Range2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::coalesce() const
+{
+  auto res = isl::pw_multi_aff::coalesce();
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::set<pair<Domain2, Range2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::domain() const
+{
+  auto res = isl::pw_multi_aff::domain();
+  return typed::set<pair<Domain2, Range2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::extract_pw_multi_aff(const typed::space<pair<Domain2, Range2>, Range> &space) const
+{
+  auto res = isl::pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::union_set<pair<Domain2, Range2>> &context) const
+{
+  auto res = isl::pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::gist(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::identity() const
+{
+  auto res = isl::pw_multi_aff::identity();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_domain(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_aff_list<pair<Domain2, Range2>, Anonymous> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::list() const
+{
+  auto res = isl::pw_multi_aff::list();
+  return typed::pw_aff_list<pair<Domain2, Range2>, Anonymous>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::max(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::max(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::max_multi_val() const
+{
+  auto res = isl::pw_multi_aff::max_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::min(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::min(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_val<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::min_multi_val() const
+{
+  auto res = isl::pw_multi_aff::min_multi_val();
+  return typed::multi_val<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::neg() const
+{
+  auto res = isl::pw_multi_aff::neg();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::preimage_domain_wrapped_domain(const typed::pw_aff<Domain3, Domain2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_pw_aff<Arg2, Arg3> &multi2) const
+{
+  auto res = isl::pw_multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::product(const typed::pw_multi_aff<Arg2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::product(const typed::multi_aff<Arg2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2, typename Arg3>
+typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::product(const typed::pw_aff<Arg2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<Domain2, Range2>, Arg2>, pair<Range, Arg3>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<Arg2, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<Arg2, pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_pw_aff<pair<Domain2, Range2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<Arg2, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<Arg2, pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::multi_aff<pair<Domain2, Range2>> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<Arg2, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<Arg2, pair<Domain2, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::pw_multi_aff<pair<Domain2, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<Arg2, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain2, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg2, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pullback(const typed::union_pw_multi_aff<pair<Domain2, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff_list<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Arg2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::pw_multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::multi_aff<pair<Domain2, Range2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::range_product(const typed::pw_aff<pair<Domain2, Range2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, pair<Range, Arg2>>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale(long v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale_down(mv);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale_down(const typed::val<Range> &v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::scale_down(long v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::set_at(int pos, const typed::union_pw_aff<pair<Domain2, Range2>, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+template <typename Arg1>
+typed::pw_multi_aff<pair<Domain2, Range2>, Arg1> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::pw_multi_aff::set_range_tuple(id);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Arg1>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::space<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::space() const
+{
+  auto res = isl::pw_multi_aff::space();
+  return typed::space<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::sub(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::space<pair<Domain2, Range2>> &space) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::union_set<pair<Domain2, Range2>> &uset) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::basic_set<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::subtract_domain(const typed::point<pair<Domain2, Range2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_pw_aff<pair<Domain2, Range2>, Range> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_union_pw_aff<pair<Domain2, Range2>, Range> &mupa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::pw_multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::union_pw_multi_aff<pair<Domain2, Range2>, Range> &upma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::multi_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain2, typename Range2, typename Range>
+typed::pw_multi_aff<pair<Domain2, Range2>, Range> typed::pw_multi_aff<pair<Domain2, Range2>, Range>::union_add(const typed::pw_aff<pair<Domain2, Range2>, Range> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<Domain2, Range2>, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff(const typed::multi_aff<Domain, pair<Range, Range2>> &ma)
+  : isl::pw_multi_aff(ma)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff(const typed::pw_aff<Domain, pair<Range, Range2>> &pa)
+  : isl::pw_multi_aff(pa)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::add_constant(mv);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add_constant(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::add_constant(long v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::pw_multi_aff<Domain, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::pw_multi_aff::as_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::as_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_aff();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::pw_multi_aff::as_union_map();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_aff<Domain, Anonymous> typed::pw_multi_aff<Domain, pair<Range, Range2>>::at(int pos) const
+{
+  auto res = isl::pw_multi_aff::at(pos);
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::pw_multi_aff<Domain, pair<Range, Range2>>::bind(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind(tuple);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::bind_domain(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain(tuple);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::pw_multi_aff::coalesce();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::set<Domain> typed::pw_multi_aff<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::pw_multi_aff::domain();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::identity() const
+{
+  auto res = isl::pw_multi_aff::identity();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_aff_list<Domain, Anonymous> typed::pw_multi_aff<Domain, pair<Range, Range2>>::list() const
+{
+  auto res = isl::pw_multi_aff::list();
+  return typed::pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::max(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::max(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::max_multi_val() const
+{
+  auto res = isl::pw_multi_aff::max_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::min(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::min(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::min_multi_val() const
+{
+  auto res = isl::pw_multi_aff::min_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::neg() const
+{
+  auto res = isl::pw_multi_aff::neg();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::product(const typed::multi_pw_aff<Domain2, Arg3> &multi2) const
+{
+  auto res = isl::pw_multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::product(const typed::pw_multi_aff<Domain2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::product(const typed::multi_aff<Domain2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::product(const typed::pw_aff<Domain2, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain2, Domain> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff_list<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::pw_multi_aff::range_factor_domain();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, Range2> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::pw_multi_aff::range_factor_range();
+  return typed::pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_pw_aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_union_pw_aff<Domain, Arg3> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<Domain, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_aff<Domain, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::pw_aff<Domain, Arg3> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale(mv);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale(long v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale_down(mv);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale_down(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::scale_down(long v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::set_at(int pos, const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::pw_multi_aff::space();
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::basic_set<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::point<Domain> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_pw_aff<Domain, pair<Range, Range2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_union_pw_aff<Domain, pair<Range, Range2>> &mupa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::pw_aff<Domain, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &ma)
+  : isl::pw_multi_aff(ma)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pa)
+  : isl::pw_multi_aff(pa)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::add_constant(mv);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add_constant(long v) const
+{
+  auto res = isl::pw_multi_aff::add_constant(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::pw_multi_aff::as_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_aff();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::pw_multi_aff::as_union_map();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_aff<pair<T1, T2>, Anonymous> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::at(int pos) const
+{
+  auto res = isl::pw_multi_aff::at(pos);
+  return typed::pw_aff<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind(tuple);
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind_domain(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain(tuple);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<T2, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::bind_domain_wrapped_domain(const typed::multi_id<T1> &tuple) const
+{
+  auto res = isl::pw_multi_aff::bind_domain_wrapped_domain(tuple);
+  return typed::pw_multi_aff<T2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::pw_multi_aff::coalesce();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::set<pair<T1, T2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::pw_multi_aff::domain();
+  return typed::set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::gist(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::identity() const
+{
+  auto res = isl::pw_multi_aff::identity();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::pw_multi_aff::intersect_params(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_aff_list<pair<T1, T2>, Anonymous> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::list() const
+{
+  auto res = isl::pw_multi_aff::list();
+  return typed::pw_aff_list<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::max(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::max(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::max_multi_val() const
+{
+  auto res = isl::pw_multi_aff::max_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::min(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::min(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_val<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::min_multi_val() const
+{
+  auto res = isl::pw_multi_aff::min_multi_val();
+  return typed::multi_val<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::neg() const
+{
+  auto res = isl::pw_multi_aff::neg();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, T1> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::pw_aff<Domain3, T1> &pma2) const
+{
+  auto res = isl::pw_multi_aff::preimage_domain_wrapped_domain(pma2);
+  return typed::pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::multi_pw_aff<Domain2, Arg2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::product(multi2);
+  return typed::multi_pw_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::pw_multi_aff<Domain2, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::multi_aff<Domain2, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::product(const typed::pw_aff<Domain2, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::product(pma2);
+  return typed::pw_multi_aff<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::multi_pw_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_pw_aff<pair<T1, T2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::pullback(mpa2);
+  return typed::multi_pw_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<pair<T1, T2>> &ma) const
+{
+  auto res = isl::pw_multi_aff::pullback(ma);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<pair<T1, T2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(pma2);
+  return typed::pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, Range> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::pw_multi_aff::range_factor_domain();
+  return typed::pw_multi_aff<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, Range2> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::pw_multi_aff::range_factor_range();
+  return typed::pw_multi_aff<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_pw_aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_union_pw_aff<pair<T1, T2>, Arg2> &multi2) const
+{
+  auto res = isl::pw_multi_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::pw_aff<pair<T1, T2>, Arg2> &pma2) const
+{
+  auto res = isl::pw_multi_aff::range_product(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale(mv);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale(long v) const
+{
+  auto res = isl::pw_multi_aff::scale(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(const typed::multi_val<pair<Range, Range2>> &mv) const
+{
+  auto res = isl::pw_multi_aff::scale_down(mv);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(const typed::val<pair<Range, Range2>> &v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::scale_down(long v) const
+{
+  auto res = isl::pw_multi_aff::scale_down(v);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::set_at(int pos, const typed::pw_aff<pair<T1, T2>, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::set_at(int pos, const typed::union_pw_aff<pair<T1, T2>, Anonymous> &el) const
+{
+  auto res = isl::pw_multi_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::pw_multi_aff::space();
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &multi2) const
+{
+  auto res = isl::pw_multi_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::sub(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::basic_set<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::point<pair<T1, T2>> &set) const
+{
+  auto res = isl::pw_multi_aff::subtract_domain(set);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_multi_pw_aff() const
+{
+  auto res = isl::pw_multi_aff::to_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::to_union_pw_multi_aff() const
+{
+  auto res = isl::pw_multi_aff::to_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mpa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mpa2);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &mupa2) const
+{
+  auto res = isl::pw_multi_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::pw_aff<pair<T1, T2>, pair<Range, Range2>> &pma2) const
+{
+  auto res = isl::pw_multi_aff::union_add(pma2);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain>::pw_multi_aff_list(const isl::ctx &ctx, int n)
+  : isl::pw_multi_aff_list(ctx, n)
+{
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain>::pw_multi_aff_list(const typed::pw_multi_aff<Domain> &el)
+  : isl::pw_multi_aff_list(el)
+{
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain>::pw_multi_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff_list(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::pw_multi_aff_list<Domain>::add(const typed::pw_multi_aff<Domain> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::pw_multi_aff_list<Domain>::add(const typed::multi_aff<Domain> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::pw_multi_aff_list<Domain>::add(const typed::pw_aff<Domain> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::pw_multi_aff_list<Domain>::at(int index) const
+{
+  auto res = isl::pw_multi_aff_list::at(index);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::pw_multi_aff_list<Domain>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::pw_multi_aff_list::drop(first, n);
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+void typed::pw_multi_aff_list<Domain>::foreach(const std::function<void(typed::pw_multi_aff<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::pw_multi_aff arg0) {
+    return fn(typed::pw_multi_aff<Domain>(arg0));
+  };
+  return isl::pw_multi_aff_list::foreach(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range>::pw_multi_aff_list(const isl::ctx &ctx, int n)
+  : isl::pw_multi_aff_list(ctx, n)
+{
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range>::pw_multi_aff_list(const typed::pw_multi_aff<Domain, Range> &el)
+  : isl::pw_multi_aff_list(el)
+{
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range>::pw_multi_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::pw_multi_aff_list(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::pw_multi_aff_list<Domain, Range>::add(const typed::pw_multi_aff<Domain, Range> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::pw_multi_aff_list<Domain, Range>::add(const typed::multi_aff<Domain, Range> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::pw_multi_aff_list<Domain, Range>::add(const typed::pw_aff<Domain, Range> &el) const
+{
+  auto res = isl::pw_multi_aff_list::add(el);
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::pw_multi_aff_list<Domain, Range>::at(int index) const
+{
+  auto res = isl::pw_multi_aff_list::at(index);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::pw_multi_aff_list<Domain, Range>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::pw_multi_aff_list::drop(first, n);
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::pw_multi_aff_list<Domain, Range>::foreach(const std::function<void(typed::pw_multi_aff<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::pw_multi_aff arg0) {
+    return fn(typed::pw_multi_aff<Domain, Range>(arg0));
+  };
+  return isl::pw_multi_aff_list::foreach(lambda);
+}
+
+typed::set<>::set(const typed::basic_set<> &bset)
+  : isl::set(bset)
+{
+}
+
+typed::set<>::set(const typed::point<> &pnt)
+  : isl::set(pnt)
+{
+}
+
+typed::set<>::set(const isl::ctx &ctx, const std::string &str)
+  : isl::set(ctx, str)
+{
+}
+
+typed::set<> typed::set<>::coalesce() const
+{
+  auto res = isl::set::coalesce();
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::detect_equalities() const
+{
+  auto res = isl::set::detect_equalities();
+  return typed::set<>(res);
+}
+
+bool typed::set<>::every_set(const std::function<bool(typed::set<>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<>(arg0));
+  };
+  return isl::set::every_set(lambda);
+}
+
+typed::set<> typed::set<>::extract_set(const typed::space<> &space) const
+{
+  auto res = isl::set::extract_set(space);
+  return typed::set<>(res);
+}
+
+void typed::set<>::foreach_basic_set(const std::function<void(typed::basic_set<>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<>(arg0));
+  };
+  return isl::set::foreach_basic_set(lambda);
+}
+
+void typed::set<>::foreach_point(const std::function<void(typed::point<>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<>(arg0));
+  };
+  return isl::set::foreach_point(lambda);
+}
+
+void typed::set<>::foreach_set(const std::function<void(typed::set<>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<>(arg0));
+  };
+  return isl::set::foreach_set(lambda);
+}
+
+typed::set<> typed::set<>::gist(const typed::set<> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::set<>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::set<>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::gist(const typed::point<> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<>(res);
+}
+
+typed::pw_aff<Anonymous> typed::set<>::indicator_function() const
+{
+  auto res = isl::set::indicator_function();
+  return typed::pw_aff<Anonymous>(res);
+}
+
+typed::set<> typed::set<>::intersect(const typed::set<> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::set<>::intersect(const typed::union_set<> &uset2) const
+{
+  auto res = isl::set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::set<>::intersect(const typed::basic_set<> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::intersect(const typed::point<> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::project_out_all_params() const
+{
+  auto res = isl::set::project_out_all_params();
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::project_out_param(const std::string &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::set::project_out_param(list);
+  return typed::set<>(res);
+}
+
+typed::space<> typed::set<>::space() const
+{
+  auto res = isl::set::space();
+  return typed::space<>(res);
+}
+
+typed::set<> typed::set<>::subtract(const typed::set<> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::set<>::subtract(const typed::union_set<> &uset2) const
+{
+  auto res = isl::set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::set<>::subtract(const typed::basic_set<> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::subtract(const typed::point<> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::set<>::to_union_set() const
+{
+  auto res = isl::set::to_union_set();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<>::unbind_params(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::set::unbind_params(tuple);
+  return typed::set<Domain>(res);
+}
+
+typed::set<> typed::set<>::unite(const typed::set<> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<>(res);
+}
+
+typed::union_set<> typed::set<>::unite(const typed::union_set<> &uset2) const
+{
+  auto res = isl::set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::set<> typed::set<>::unite(const typed::basic_set<> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::unite(const typed::point<> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<>(res);
+}
+
+typed::set<> typed::set<>::universe(const typed::space<> &space)
+{
+  auto res = isl::set::universe(space);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain>::set(const typed::basic_set<Domain> &bset)
+  : isl::set(bset)
+{
+}
+
+template <typename Domain>
+typed::set<Domain>::set(const typed::point<Domain> &pnt)
+  : isl::set(pnt)
+{
+}
+
+template <typename Domain>
+typed::set<Domain>::set(const isl::ctx &ctx, const std::string &str)
+  : isl::set(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<Range> typed::set<Domain>::apply(const typed::map<Domain, Range> &map) const
+{
+  auto res = isl::set::apply(map);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::set<Domain>::apply(const typed::union_map<Domain, Range> &umap) const
+{
+  auto res = isl::set::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<Range> typed::set<Domain>::apply(const typed::basic_map<Domain, Range> &map) const
+{
+  auto res = isl::set::apply(map);
+  return typed::set<Range>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::set<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::set::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::as_set() const
+{
+  auto res = isl::set::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::set<Domain>::bind(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::set::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::coalesce() const
+{
+  auto res = isl::set::coalesce();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::detect_equalities() const
+{
+  auto res = isl::set::detect_equalities();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+bool typed::set<Domain>::every_set(const std::function<bool(typed::set<Domain>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<Domain>(arg0));
+  };
+  return isl::set::every_set(lambda);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::extract_set(const typed::space<Domain> &space) const
+{
+  auto res = isl::set::extract_set(space);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+void typed::set<Domain>::foreach_basic_set(const std::function<void(typed::basic_set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<Domain>(arg0));
+  };
+  return isl::set::foreach_basic_set(lambda);
+}
+
+template <typename Domain>
+void typed::set<Domain>::foreach_point(const std::function<void(typed::point<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<Domain>(arg0));
+  };
+  return isl::set::foreach_point(lambda);
+}
+
+template <typename Domain>
+void typed::set<Domain>::foreach_set(const std::function<void(typed::set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<Domain>(arg0));
+  };
+  return isl::set::foreach_set(lambda);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::set<Domain>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::set<Domain>::identity() const
+{
+  auto res = isl::set::identity();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_aff<Domain, Anonymous> typed::set<Domain>::indicator_function() const
+{
+  auto res = isl::set::indicator_function();
+  return typed::pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::set<Domain>::insert_domain(const typed::space<Arg1> &domain) const
+{
+  auto res = isl::set::insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect(const typed::set<Domain> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::set<Domain>::intersect(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect(const typed::basic_set<Domain> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect(const typed::point<Domain> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::lexmax() const
+{
+  auto res = isl::set::lexmax();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::set<Domain>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::set::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::lexmin() const
+{
+  auto res = isl::set::lexmin();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::set<Domain>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::set::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::lower_bound(const typed::multi_pw_aff<Domain> &lower) const
+{
+  auto res = isl::set::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::lower_bound(const typed::multi_val<Domain> &lower) const
+{
+  auto res = isl::set::lower_bound(lower);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::set<Domain>::max_multi_pw_aff() const
+{
+  auto res = isl::set::max_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::set<Domain>::min_multi_pw_aff() const
+{
+  auto res = isl::set::min_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<> typed::set<Domain>::params() const
+{
+  auto res = isl::set::params();
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::set<Domain>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::set::plain_multi_val_if_fixed();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::set<Domain>::preimage(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::set::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::set<Domain>::preimage(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::set::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::set<Domain2> typed::set<Domain>::preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::set::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::set<Domain>::preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<pair<Domain, Range>> typed::set<Domain>::product(const typed::set<Range> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<pair<Domain, Range>> typed::set<Domain>::product(const typed::basic_set<Range> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::set<pair<Domain, Range>> typed::set<Domain>::product(const typed::point<Range> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::project_out_all_params() const
+{
+  auto res = isl::set::project_out_all_params();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::project_out_param(const std::string &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::set::project_out_param(list);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::pw_multi_aff<Domain, Range> typed::set<Domain>::pw_multi_aff_on_domain(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::set::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::fixed_box<Domain> typed::set<Domain>::simple_fixed_box_hull() const
+{
+  auto res = isl::set::simple_fixed_box_hull();
+  return typed::fixed_box<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::set<Domain>::space() const
+{
+  auto res = isl::set::space();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::subtract(const typed::set<Domain> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::set<Domain>::subtract(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::subtract(const typed::basic_set<Domain> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::subtract(const typed::point<Domain> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::set<Domain>::to_union_set() const
+{
+  auto res = isl::set::to_union_set();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::set<Domain>::translation() const
+{
+  auto res = isl::set::translation();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Arg1>
+typed::map<Arg1, Domain> typed::set<Domain>::unbind_params_insert_domain(const typed::multi_id<Arg1> &domain) const
+{
+  auto res = isl::set::unbind_params_insert_domain(domain);
+  return typed::map<Arg1, Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::unite(const typed::set<Domain> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::set<Domain>::unite(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::unite(const typed::basic_set<Domain> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::unite(const typed::point<Domain> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::universe(const typed::space<Domain> &space)
+{
+  auto res = isl::set::universe(space);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::upper_bound(const typed::multi_pw_aff<Domain> &upper) const
+{
+  auto res = isl::set::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::set<Domain>::upper_bound(const typed::multi_val<Domain> &upper) const
+{
+  auto res = isl::set::upper_bound(upper);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>>::set(const typed::basic_set<pair<Domain, Range>> &bset)
+  : isl::set(bset)
+{
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>>::set(const typed::point<pair<Domain, Range>> &pnt)
+  : isl::set(pnt)
+{
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>>::set(const isl::ctx &ctx, const std::string &str)
+  : isl::set(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<Arg2> typed::set<pair<Domain, Range>>::apply(const typed::map<pair<Domain, Range>, Arg2> &map) const
+{
+  auto res = isl::set::apply(map);
+  return typed::set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::set<pair<Domain, Range>>::apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::set::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<Arg2> typed::set<pair<Domain, Range>>::apply(const typed::basic_map<pair<Domain, Range>, Arg2> &map) const
+{
+  auto res = isl::set::apply(map);
+  return typed::set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::set<pair<Domain, Range>>::as_pw_multi_aff() const
+{
+  auto res = isl::set::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::as_set() const
+{
+  auto res = isl::set::as_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<> typed::set<pair<Domain, Range>>::bind(const typed::multi_id<pair<Domain, Range>> &tuple) const
+{
+  auto res = isl::set::bind(tuple);
+  return typed::set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::coalesce() const
+{
+  auto res = isl::set::coalesce();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::detect_equalities() const
+{
+  auto res = isl::set::detect_equalities();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::set<pair<Domain, Range>>::every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::set::every_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::extract_set(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::set::extract_set(space);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::set<pair<Domain, Range>>::foreach_basic_set(const std::function<void(typed::basic_set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::basic_set arg0) {
+    return fn(typed::basic_set<pair<Domain, Range>>(arg0));
+  };
+  return isl::set::foreach_basic_set(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::set<pair<Domain, Range>>::foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<pair<Domain, Range>>(arg0));
+  };
+  return isl::set::foreach_point(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::set<pair<Domain, Range>>::foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::set::foreach_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::gist(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::gist(const typed::union_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::gist(const typed::basic_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::gist(const typed::point<pair<Domain, Range>> &context) const
+{
+  auto res = isl::set::gist(context);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::set<pair<Domain, Range>>::identity() const
+{
+  auto res = isl::set::identity();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_aff<pair<Domain, Range>, Anonymous> typed::set<pair<Domain, Range>>::indicator_function() const
+{
+  auto res = isl::set::indicator_function();
+  return typed::pw_aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::set<pair<Domain, Range>>::insert_domain(const typed::space<Arg2> &domain) const
+{
+  auto res = isl::set::insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect(const typed::basic_set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect(const typed::point<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::intersect(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect_params(const typed::set<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect_params(const typed::basic_set<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::intersect_params(const typed::point<> &params) const
+{
+  auto res = isl::set::intersect_params(params);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lexmax() const
+{
+  auto res = isl::set::lexmax();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lexmax_pw_multi_aff() const
+{
+  auto res = isl::set::lexmax_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lexmin() const
+{
+  auto res = isl::set::lexmin();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lexmin_pw_multi_aff() const
+{
+  auto res = isl::set::lexmin_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lower_bound(const typed::multi_pw_aff<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::set::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::lower_bound(const typed::multi_val<pair<Domain, Range>> &lower) const
+{
+  auto res = isl::set::lower_bound(lower);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::set<pair<Domain, Range>>::max_multi_pw_aff() const
+{
+  auto res = isl::set::max_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::set<pair<Domain, Range>>::min_multi_pw_aff() const
+{
+  auto res = isl::set::min_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<> typed::set<pair<Domain, Range>>::params() const
+{
+  auto res = isl::set::params();
+  return typed::set<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::set<pair<Domain, Range>>::plain_multi_val_if_fixed() const
+{
+  auto res = isl::set::plain_multi_val_if_fixed();
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::set<pair<Domain, Range>>::preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::set::preimage(ma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::set<pair<Domain, Range>>::preimage(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::set::preimage(mpa);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::set<Domain2> typed::set<pair<Domain, Range>>::preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::set::preimage(pma);
+  return typed::set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::set<pair<Domain, Range>>::preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<pair<pair<Domain, Range>, Arg2>> typed::set<pair<Domain, Range>>::product(const typed::set<Arg2> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<pair<pair<Domain, Range>, Arg2>> typed::set<pair<Domain, Range>>::product(const typed::basic_set<Arg2> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::set<pair<pair<Domain, Range>, Arg2>> typed::set<pair<Domain, Range>>::product(const typed::point<Arg2> &set2) const
+{
+  auto res = isl::set::product(set2);
+  return typed::set<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::project_out_all_params() const
+{
+  auto res = isl::set::project_out_all_params();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::project_out_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::project_out_param(const std::string &id) const
+{
+  auto res = isl::set::project_out_param(id);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::project_out_param(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::set::project_out_param(list);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::pw_multi_aff<pair<Domain, Range>, Arg2> typed::set<pair<Domain, Range>>::pw_multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const
+{
+  auto res = isl::set::pw_multi_aff_on_domain(mv);
+  return typed::pw_multi_aff<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::fixed_box<pair<Domain, Range>> typed::set<pair<Domain, Range>>::simple_fixed_box_hull() const
+{
+  auto res = isl::set::simple_fixed_box_hull();
+  return typed::fixed_box<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::set<pair<Domain, Range>>::space() const
+{
+  auto res = isl::set::space();
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::subtract(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::subtract(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::subtract(const typed::basic_set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::subtract(const typed::point<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::subtract(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::to_union_set() const
+{
+  auto res = isl::set::to_union_set();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<pair<Domain, Range>, pair<Domain, Range>> typed::set<pair<Domain, Range>>::translation() const
+{
+  auto res = isl::set::translation();
+  return typed::map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::map<Arg2, pair<Domain, Range>> typed::set<pair<Domain, Range>>::unbind_params_insert_domain(const typed::multi_id<Arg2> &domain) const
+{
+  auto res = isl::set::unbind_params_insert_domain(domain);
+  return typed::map<Arg2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::unite(const typed::set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::unite(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::unite(const typed::basic_set<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::unite(const typed::point<pair<Domain, Range>> &set2) const
+{
+  auto res = isl::set::unite(set2);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::universe(const typed::space<pair<Domain, Range>> &space)
+{
+  auto res = isl::set::universe(space);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::set<pair<Domain, Range>>::unwrap() const
+{
+  auto res = isl::set::unwrap();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::upper_bound(const typed::multi_pw_aff<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::set::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::set<pair<Domain, Range>>::upper_bound(const typed::multi_val<pair<Domain, Range>> &upper) const
+{
+  auto res = isl::set::upper_bound(upper);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::space<>::add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::space<>::add_named_tuple(const std::string &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<Domain>(res);
+}
+
+typed::space<> typed::space<>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<>(res);
+}
+
+typed::space<> typed::space<>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::space<>::add_unnamed_tuple(unsigned int dim) const
+{
+  auto res = isl::space::add_unnamed_tuple(dim);
+  return typed::space<Domain>(res);
+}
+
+typed::aff<Anonymous> typed::space<>::param_aff_on_domain(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::aff<Anonymous> typed::space<>::param_aff_on_domain(const std::string &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<Anonymous>(res);
+}
+
+typed::space<> typed::space<>::unit(const isl::ctx &ctx)
+{
+  auto res = isl::space::unit(ctx);
+  return typed::space<>(res);
+}
+
+typed::set<> typed::space<>::universe_set() const
+{
+  auto res = isl::space::universe_set();
+  return typed::set<>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::space<Domain, Range> typed::space<Domain>::add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::space<Domain, Range> typed::space<Domain>::add_named_tuple(const std::string &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::space<Domain>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain> typed::space<Domain>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::space<Domain, Range> typed::space<Domain>::add_unnamed_tuple(unsigned int dim) const
+{
+  auto res = isl::space::add_unnamed_tuple(dim);
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::space<Domain>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain, Domain> typed::space<Domain>::identity_multi_aff_on_domain() const
+{
+  auto res = isl::space::identity_multi_aff_on_domain();
+  return typed::multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain, Domain> typed::space<Domain>::identity_multi_pw_aff_on_domain() const
+{
+  auto res = isl::space::identity_multi_pw_aff_on_domain();
+  return typed::multi_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Domain> typed::space<Domain>::identity_pw_multi_aff_on_domain() const
+{
+  auto res = isl::space::identity_pw_multi_aff_on_domain();
+  return typed::pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::space<Domain, Domain> typed::space<Domain>::map_from_set() const
+{
+  auto res = isl::space::map_from_set();
+  return typed::space<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::space<Domain>::multi_aff(const typed::aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::multi_aff<Domain, Range> typed::space<Domain>::multi_aff_on_domain(const typed::multi_val<Range> &mv) const
+{
+  auto res = isl::space::multi_aff_on_domain(mv);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain>
+typed::multi_id<Domain> typed::space<Domain>::multi_id(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_id(list);
+  return typed::multi_id<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::space<Domain>::multi_pw_aff(const typed::pw_aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::space<Domain>::multi_union_pw_aff(const typed::union_pw_aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::space<Domain>::multi_val(const typed::val_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_val(list);
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::space<Domain>::param_aff_on_domain(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::space<Domain>::param_aff_on_domain(const std::string &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::space<Domain>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::space<pair<Domain, Range>> typed::space<Domain>::product(const typed::space<Range> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::space<Domain2> typed::space<Domain>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::space<Domain2> typed::space<Domain>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<Domain2>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::space<Domain>::universe_set() const
+{
+  auto res = isl::space::universe_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::aff<Domain, Anonymous> typed::space<Domain>::zero_aff_on_domain() const
+{
+  auto res = isl::space::zero_aff_on_domain();
+  return typed::aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_aff<Domain> typed::space<Domain>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_pw_aff<Domain> typed::space<Domain>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::space<Domain>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_val<Domain> typed::space<Domain>::zero_multi_val() const
+{
+  auto res = isl::space::zero_multi_val();
+  return typed::multi_val<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::space<Domain, Range>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::space<Domain, Range>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain> typed::space<Domain, Range>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<pair<Domain, Range>, Domain> typed::space<Domain, Range>::domain_map_multi_aff() const
+{
+  auto res = isl::space::domain_map_multi_aff();
+  return typed::multi_aff<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>, Domain> typed::space<Domain, Range>::domain_map_pw_multi_aff() const
+{
+  auto res = isl::space::domain_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::space<Domain, Range>::multi_aff(const typed::aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::space<Domain, Range>::multi_pw_aff(const typed::pw_aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::space<Domain, Range>::multi_union_pw_aff(const typed::union_pw_aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::space<Domain, Range>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::space<pair<Domain, Domain2>, pair<Range, Range2>> typed::space<Domain, Range>::product(const typed::space<Domain2, Range2> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Range> typed::space<Domain, Range>::range() const
+{
+  auto res = isl::space::range();
+  return typed::space<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<pair<Domain, Range>, Range> typed::space<Domain, Range>::range_map_multi_aff() const
+{
+  auto res = isl::space::range_map_multi_aff();
+  return typed::multi_aff<pair<Domain, Range>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>, Range> typed::space<Domain, Range>::range_map_pw_multi_aff() const
+{
+  auto res = isl::space::range_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Range>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Range, Domain> typed::space<Domain, Range>::reverse() const
+{
+  auto res = isl::space::reverse();
+  return typed::space<Range, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::space<Domain2, Range> typed::space<Domain, Range>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::set_domain_tuple(id);
+  return typed::space<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::space<Domain2, Range> typed::space<Domain, Range>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::space::set_domain_tuple(id);
+  return typed::space<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::space<Domain, Range2> typed::space<Domain, Range>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::space<Domain, Range2> typed::space<Domain, Range>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::space<Domain, Range>::universe_map() const
+{
+  auto res = isl::space::universe_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::space<Domain, Range>::wrap() const
+{
+  auto res = isl::space::wrap();
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<Domain, Range> typed::space<Domain, Range>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<Domain, Range> typed::space<Domain, Range>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::space<Domain, Range>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::space<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>>::add_named_tuple(const typed::id<Anonymous> &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::space<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>>::add_named_tuple(const std::string &tuple_id, unsigned int dim) const
+{
+  auto res = isl::space::add_named_tuple(tuple_id, dim);
+  return typed::space<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::space<pair<Domain, Range>>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>> typed::space<pair<Domain, Range>>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::space<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>>::add_unnamed_tuple(unsigned int dim) const
+{
+  auto res = isl::space::add_unnamed_tuple(dim);
+  return typed::space<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::space<pair<Domain, Range>>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<pair<Domain, Range>, pair<Domain, Range>> typed::space<pair<Domain, Range>>::identity_multi_aff_on_domain() const
+{
+  auto res = isl::space::identity_multi_aff_on_domain();
+  return typed::multi_aff<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>, pair<Domain, Range>> typed::space<pair<Domain, Range>>::identity_multi_pw_aff_on_domain() const
+{
+  auto res = isl::space::identity_multi_pw_aff_on_domain();
+  return typed::multi_pw_aff<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<pair<Domain, Range>, pair<Domain, Range>> typed::space<pair<Domain, Range>>::identity_pw_multi_aff_on_domain() const
+{
+  auto res = isl::space::identity_pw_multi_aff_on_domain();
+  return typed::pw_multi_aff<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<pair<Domain, Range>, pair<Domain, Range>> typed::space<pair<Domain, Range>>::map_from_set() const
+{
+  auto res = isl::space::map_from_set();
+  return typed::space<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::multi_aff(const typed::aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::multi_aff<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>>::multi_aff_on_domain(const typed::multi_val<Arg2> &mv) const
+{
+  auto res = isl::space::multi_aff_on_domain(mv);
+  return typed::multi_aff<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_id<pair<Domain, Range>> typed::space<pair<Domain, Range>>::multi_id(const typed::id_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_id(list);
+  return typed::multi_id<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::multi_pw_aff(const typed::pw_aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::multi_union_pw_aff(const typed::union_pw_aff_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::space<pair<Domain, Range>>::multi_val(const typed::val_list<Anonymous> &list) const
+{
+  auto res = isl::space::multi_val(list);
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::aff<pair<Domain, Range>, Anonymous> typed::space<pair<Domain, Range>>::param_aff_on_domain(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::aff<pair<Domain, Range>, Anonymous> typed::space<pair<Domain, Range>>::param_aff_on_domain(const std::string &id) const
+{
+  auto res = isl::space::param_aff_on_domain(id);
+  return typed::aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::space<pair<Domain, Range>>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::space<pair<pair<Domain, Range>, Arg2>> typed::space<pair<Domain, Range>>::product(const typed::space<Arg2> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<pair<Domain, Range>, Arg2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::space<pair<Domain, Range>>::universe_set() const
+{
+  auto res = isl::space::universe_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<Domain, Range> typed::space<pair<Domain, Range>>::unwrap() const
+{
+  auto res = isl::space::unwrap();
+  return typed::space<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::aff<pair<Domain, Range>, Anonymous> typed::space<pair<Domain, Range>>::zero_aff_on_domain() const
+{
+  auto res = isl::space::zero_aff_on_domain();
+  return typed::aff<pair<Domain, Range>, Anonymous>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_pw_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<pair<Domain, Range>> typed::space<pair<Domain, Range>>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_val<pair<Domain, Range>> typed::space<pair<Domain, Range>>::zero_multi_val() const
+{
+  auto res = isl::space::zero_multi_val();
+  return typed::multi_val<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::space<pair<Domain, Range>, Range2>::curry() const
+{
+  auto res = isl::space::curry();
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>> typed::space<pair<Domain, Range>, Range2>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::space<pair<Domain, Range>, Range2>::domain_map_multi_aff() const
+{
+  auto res = isl::space::domain_map_multi_aff();
+  return typed::multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::space<pair<Domain, Range>, Range2>::domain_map_pw_multi_aff() const
+{
+  auto res = isl::space::domain_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Anonymous, Range2> typed::space<pair<Domain, Range>, Range2>::flatten_domain() const
+{
+  auto res = isl::space::flatten_domain();
+  return typed::space<Anonymous, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::multi_aff(const typed::aff_list<pair<Domain, Range>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::multi_pw_aff(const typed::pw_aff_list<pair<Domain, Range>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::multi_union_pw_aff(const typed::union_pw_aff_list<pair<Domain, Range>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<> typed::space<pair<Domain, Range>, Range2>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::space<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::space<pair<Domain, Range>, Range2>::product(const typed::space<Domain2, Arg3> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Range2> typed::space<pair<Domain, Range>, Range2>::range() const
+{
+  auto res = isl::space::range();
+  return typed::space<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<pair<Domain, Range>, Range2>, Range2> typed::space<pair<Domain, Range>, Range2>::range_map_multi_aff() const
+{
+  auto res = isl::space::range_map_multi_aff();
+  return typed::multi_aff<pair<pair<Domain, Range>, Range2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, Range2> typed::space<pair<Domain, Range>, Range2>::range_map_pw_multi_aff() const
+{
+  auto res = isl::space::range_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<pair<Domain, Range>, Range2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Range2, pair<Domain, Range>> typed::space<pair<Domain, Range>, Range2>::reverse() const
+{
+  auto res = isl::space::reverse();
+  return typed::space<Range2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::space<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>, Range2>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg2>
+typed::space<pair<Domain, Range>, Arg2> typed::space<pair<Domain, Range>, Range2>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::space::set_range_tuple(id);
+  return typed::space<pair<Domain, Range>, Arg2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::universe_map() const
+{
+  auto res = isl::space::universe_map();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<pair<Domain, Range>, Range2>> typed::space<pair<Domain, Range>, Range2>::wrap() const
+{
+  auto res = isl::space::wrap();
+  return typed::space<pair<pair<Domain, Range>, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Range>, Range2> typed::space<pair<Domain, Range>, Range2>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain> typed::space<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Domain, pair<Range, Range2>>, Domain> typed::space<Domain, pair<Range, Range2>>::domain_map_multi_aff() const
+{
+  auto res = isl::space::domain_map_multi_aff();
+  return typed::multi_aff<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> typed::space<Domain, pair<Range, Range2>>::domain_map_pw_multi_aff() const
+{
+  auto res = isl::space::domain_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, Anonymous> typed::space<Domain, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::space::flatten_range();
+  return typed::space<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::multi_aff(const typed::aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::multi_pw_aff(const typed::pw_aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::multi_union_pw_aff(const typed::union_pw_aff_list<Domain, Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<> typed::space<Domain, pair<Range, Range2>>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::space<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::space<Domain, pair<Range, Range2>>::product(const typed::space<Domain2, Arg3> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::range() const
+{
+  auto res = isl::space::range();
+  return typed::space<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::range_map_multi_aff() const
+{
+  auto res = isl::space::range_map_multi_aff();
+  return typed::multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::range_map_pw_multi_aff() const
+{
+  auto res = isl::space::range_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<Domain, pair<Range2, Range>> typed::space<Domain, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::space::range_reverse();
+  return typed::space<Domain, pair<Range2, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Range, Range2>, Domain> typed::space<Domain, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::space::reverse();
+  return typed::space<pair<Range, Range2>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::space<Domain2, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::set_domain_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::set_domain_tuple(id);
+  return typed::space<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::space<Domain2, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::set_domain_tuple(const std::string &id) const
+{
+  auto res = isl::space::set_domain_tuple(id);
+  return typed::space<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, Range>, Range2> typed::space<Domain, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::space::uncurry();
+  return typed::space<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::universe_map() const
+{
+  auto res = isl::space::universe_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<pair<Domain, pair<Range, Range2>>> typed::space<Domain, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::space::wrap();
+  return typed::space<pair<Domain, pair<Range, Range2>>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_pw_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::space<Domain, pair<Range, Range2>>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::add_param(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::add_param(const std::string &id) const
+{
+  auto res = isl::space::add_param(id);
+  return typed::space<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<T1, pair<T2, pair<Range, Range2>>> typed::space<pair<T1, T2>, pair<Range, Range2>>::curry() const
+{
+  auto res = isl::space::curry();
+  return typed::space<T1, pair<T2, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::space::domain();
+  return typed::space<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::domain_map_multi_aff() const
+{
+  auto res = isl::space::domain_map_multi_aff();
+  return typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::domain_map_pw_multi_aff() const
+{
+  auto res = isl::space::domain_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<Anonymous, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::flatten_domain() const
+{
+  auto res = isl::space::flatten_domain();
+  return typed::space<Anonymous, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, Anonymous> typed::space<pair<T1, T2>, pair<Range, Range2>>::flatten_range() const
+{
+  auto res = isl::space::flatten_range();
+  return typed::space<pair<T1, T2>, Anonymous>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::multi_aff(const typed::aff_list<pair<T1, T2>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_aff(list);
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::multi_pw_aff(const typed::pw_aff_list<pair<T1, T2>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_pw_aff(list);
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::multi_union_pw_aff(const typed::union_pw_aff_list<pair<T1, T2>, Anonymous> &list) const
+{
+  auto res = isl::space::multi_union_pw_aff(list);
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<> typed::space<pair<T1, T2>, pair<Range, Range2>>::params() const
+{
+  auto res = isl::space::params();
+  return typed::space<>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::space<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::product(const typed::space<Domain2, Arg2> &right) const
+{
+  auto res = isl::space::product(right);
+  return typed::space<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::range() const
+{
+  auto res = isl::space::range();
+  return typed::space<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::range_map_multi_aff() const
+{
+  auto res = isl::space::range_map_multi_aff();
+  return typed::multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::range_map_pw_multi_aff() const
+{
+  auto res = isl::space::range_map_pw_multi_aff();
+  return typed::pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<T1, T2>, pair<Range2, Range>> typed::space<pair<T1, T2>, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::space::range_reverse();
+  return typed::space<pair<T1, T2>, pair<Range2, Range>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<Range, Range2>, pair<T1, T2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::space::reverse();
+  return typed::space<pair<Range, Range2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<pair<T1, T2>, Range>, Range2> typed::space<pair<T1, T2>, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::space::uncurry();
+  return typed::space<pair<pair<T1, T2>, Range>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::universe_map() const
+{
+  auto res = isl::space::universe_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<pair<pair<T1, T2>, pair<Range, Range2>>> typed::space<pair<T1, T2>, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::space::wrap();
+  return typed::space<pair<pair<T1, T2>, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::zero_multi_aff() const
+{
+  auto res = isl::space::zero_multi_aff();
+  return typed::multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::zero_multi_pw_aff() const
+{
+  auto res = isl::space::zero_multi_pw_aff();
+  return typed::multi_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::space<pair<T1, T2>, pair<Range, Range2>>::zero_multi_union_pw_aff() const
+{
+  auto res = isl::space::zero_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range>::union_map(const typed::basic_map<Domain, Range> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range>::union_map(const typed::map<Domain, Range> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::apply_domain(const typed::map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::apply_range(const typed::union_map<Range, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::apply_range(const typed::basic_map<Range, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::apply_range(const typed::map<Range, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::union_map<Domain, Range>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::union_map<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_map<Domain, Range>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Domain> typed::union_map<Domain, Range>::bind_range(const typed::multi_id<Range> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Domain> typed::union_map<Domain, Range>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Domain> typed::union_map<Domain, Range>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Range>, Domain> typed::union_map<Domain, Range>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Range> typed::union_map<Domain, Range>::domain_product(const typed::union_map<Domain2, Range> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Range> typed::union_map<Domain, Range>::domain_product(const typed::basic_map<Domain2, Range> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Range> typed::union_map<Domain, Range>::domain_product(const typed::map<Domain2, Range> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::union_map<Domain, Range>::every_map(const std::function<bool(typed::map<Domain, Range>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Range>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::map<Domain, Range> typed::union_map<Domain, Range>::extract_map(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::union_map<Domain, Range>::foreach_map(const std::function<void(typed::map<Domain, Range>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Range>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist(const typed::union_map<Domain, Range> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist(const typed::basic_map<Domain, Range> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist(const typed::map<Domain, Range> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist_domain(const typed::basic_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist_domain(const typed::point<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::gist_domain(const typed::set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect(const typed::basic_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect(const typed::map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_range(const typed::space<Range> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::intersect_range(const typed::union_set<Range> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::map_list<Domain, Range> typed::union_map<Domain, Range>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_map<Domain2, Range> typed::union_map<Domain, Range>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::preimage_range(const typed::multi_aff<Range2, Range> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::preimage_range(const typed::pw_multi_aff<Range2, Range> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Range>::preimage_range(const typed::union_pw_multi_aff<Range2, Range> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, Range>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, Range>::product(const typed::basic_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, Range>::product(const typed::map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Range> typed::union_map<Domain, Range>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, Range> typed::union_map<Domain, Range>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<Domain, Range>, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, Range>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, Range>::range_product(const typed::basic_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, Range>::range_product(const typed::map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Range, Domain> typed::union_map<Domain, Range>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<Range, Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::union_map<Domain, Range>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract(const typed::basic_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract(const typed::map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_domain(const typed::basic_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_domain(const typed::point<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_domain(const typed::set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_range(const typed::union_set<Range> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_range(const typed::basic_set<Range> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_range(const typed::point<Range> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::subtract_range(const typed::set<Range> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::unite(const typed::union_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::unite(const typed::basic_map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::unite(const typed::map<Domain, Range> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_map<Domain, Range>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_map<Domain, Range>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2>::union_map(const typed::basic_map<pair<Domain, Range>, Range2> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2>::union_map(const typed::map<pair<Domain, Range>, Range2> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::apply_domain(const typed::union_map<pair<Domain, Range>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::apply_domain(const typed::basic_map<pair<Domain, Range>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::apply_domain(const typed::map<pair<Domain, Range>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::apply_range(const typed::union_map<Range2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::apply_range(const typed::basic_map<Range2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::apply_range(const typed::map<Range2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<pair<Domain, Range>> typed::union_map<pair<Domain, Range>, Range2>::bind_range(const typed::multi_id<Range2> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<pair<Domain, Range>, Range2>::curry() const
+{
+  auto res = isl::union_map::curry();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<pair<Domain, Range>> typed::union_map<pair<Domain, Range>, Range2>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<pair<Domain, Range>, Range2>::domain_factor_domain() const
+{
+  auto res = isl::union_map::domain_factor_domain();
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Range, Range2> typed::union_map<pair<Domain, Range>, Range2>::domain_factor_range() const
+{
+  auto res = isl::union_map::domain_factor_range();
+  return typed::union_map<Range, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::union_map<pair<Domain, Range>, Range2>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>> typed::union_map<pair<Domain, Range>, Range2>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<Domain, Range>, Range2>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> typed::union_map<pair<Domain, Range>, Range2>::domain_product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> typed::union_map<pair<Domain, Range>, Range2>::domain_product(const typed::basic_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2> typed::union_map<pair<Domain, Range>, Range2>::domain_product(const typed::map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::union_map<pair<Domain, Range>, Range2>::every_map(const std::function<bool(typed::map<pair<Domain, Range>, Range2>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::extract_map(const typed::space<pair<Domain, Range>, Range2> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::union_map<pair<Domain, Range>, Range2>::foreach_map(const std::function<void(typed::map<pair<Domain, Range>, Range2>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<Domain, Range>, Range2>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist(const typed::union_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist(const typed::basic_map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist(const typed::map<pair<Domain, Range>, Range2> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist_domain(const typed::basic_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist_domain(const typed::point<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::gist_domain(const typed::set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect(const typed::map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_domain(const typed::union_set<pair<Domain, Range>> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_range(const typed::space<Range2> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::intersect_range(const typed::union_set<Range2> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<Domain, Range>> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, Range2> typed::union_map<pair<Domain, Range>, Range2>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::preimage_range(const typed::multi_aff<Arg3, Range2> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::preimage_range(const typed::pw_multi_aff<Arg3, Range2> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, Arg3> typed::union_map<pair<Domain, Range>, Range2>::preimage_range(const typed::union_pw_multi_aff<Arg3, Range2> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<pair<Domain, Range>, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::product(const typed::basic_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::product(const typed::map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<Domain, Range>, Domain2>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<Range2> typed::union_map<pair<Domain, Range>, Range2>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<pair<Domain, Range>, Range2>, Range2> typed::union_map<pair<Domain, Range>, Range2>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<pair<Domain, Range>, Range2>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::range_product(const typed::union_map<pair<Domain, Range>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::range_product(const typed::basic_map<pair<Domain, Range>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>> typed::union_map<pair<Domain, Range>, Range2>::range_product(const typed::map<pair<Domain, Range>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<Domain, Range>, pair<Range2, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Range2, pair<Domain, Range>> typed::union_map<pair<Domain, Range>, Range2>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<Range2, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<> typed::union_map<pair<Domain, Range>, Range2>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract(const typed::map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_domain(const typed::union_set<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_domain(const typed::basic_set<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_domain(const typed::point<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_domain(const typed::set<pair<Domain, Range>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_range(const typed::union_set<Range2> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_range(const typed::basic_set<Range2> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_range(const typed::point<Range2> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::subtract_range(const typed::set<Range2> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::unite(const typed::union_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::unite(const typed::basic_map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::unite(const typed::map<pair<Domain, Range>, Range2> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<pair<Domain, Range>, Range2>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<pair<pair<Domain, Range>, Range2>> typed::union_map<pair<Domain, Range>, Range2>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<pair<Domain, Range>, Range2>>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain>::union_map(const typed::basic_map<Domain, Domain> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain>::union_map(const typed::map<Domain, Domain> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::apply_domain(const typed::map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::apply_range(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::apply_range(const typed::basic_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::apply_range(const typed::map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::union_map<Domain, Domain>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Domain> typed::union_map<Domain, Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Domain> typed::union_map<Domain, Domain>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_map<Domain, Domain>::bind_range(const typed::multi_id<Domain> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_map<Domain, Domain>::deltas() const
+{
+  auto res = isl::union_map::deltas();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_map<Domain, Domain>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::union_map<Domain, Domain>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<pair<Domain, Domain>, Domain> typed::union_map<Domain, Domain>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Domain> typed::union_map<Domain, Domain>::domain_product(const typed::union_map<Domain2, Domain> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Domain> typed::union_map<Domain, Domain>::domain_product(const typed::basic_map<Domain2, Domain> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Domain> typed::union_map<Domain, Domain>::domain_product(const typed::map<Domain2, Domain> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::eq_at(const typed::multi_union_pw_aff<Domain, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::eq_at(const typed::multi_pw_aff<Domain, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::eq_at(const typed::union_pw_aff<Domain, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+bool typed::union_map<Domain, Domain>::every_map(const std::function<bool(typed::map<Domain, Domain>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename Domain>
+typed::map<Domain, Domain> typed::union_map<Domain, Domain>::extract_map(const typed::space<Domain, Domain> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+void typed::union_map<Domain, Domain>::foreach_map(const std::function<void(typed::map<Domain, Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, Domain>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist(const typed::union_map<Domain, Domain> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist(const typed::basic_map<Domain, Domain> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist(const typed::map<Domain, Domain> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist_domain(const typed::basic_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist_domain(const typed::point<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::gist_domain(const typed::set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect(const typed::basic_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect(const typed::map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_range(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::intersect_range(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::map_list<Domain, Domain> typed::union_map<Domain, Domain>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<Domain, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_map<Domain2, Domain> typed::union_map<Domain, Domain>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::preimage_range(const typed::multi_aff<Range2, Domain> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::preimage_range(const typed::pw_multi_aff<Range2, Domain> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, Domain>::preimage_range(const typed::union_pw_multi_aff<Range2, Domain> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::union_map<Domain, Domain>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::union_map<Domain, Domain>::product(const typed::basic_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>> typed::union_map<Domain, Domain>::product(const typed::map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_map<Domain, Domain>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<pair<Domain, Domain>, Domain> typed::union_map<Domain, Domain>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<Domain, Domain>, Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, pair<Domain, Range2>> typed::union_map<Domain, Domain>::range_product(const typed::union_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, pair<Domain, Range2>> typed::union_map<Domain, Domain>::range_product(const typed::basic_map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_map<Domain, pair<Domain, Range2>> typed::union_map<Domain, Domain>::range_product(const typed::map<Domain, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<Domain, Range2>>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::union_map<Domain, Domain>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract(const typed::basic_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract(const typed::map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_domain(const typed::basic_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_domain(const typed::point<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_domain(const typed::set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_range(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_range(const typed::basic_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_range(const typed::point<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::subtract_range(const typed::set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::unite(const typed::union_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::unite(const typed::basic_map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::unite(const typed::map<Domain, Domain> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_map<Domain, Domain>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<pair<Domain, Domain>> typed::union_map<Domain, Domain>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<Domain, Domain>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>>::union_map(const typed::basic_map<Domain, pair<Range, Range2>> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>>::union_map(const typed::map<Domain, pair<Range, Range2>> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::apply_domain(const typed::union_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::apply_domain(const typed::basic_map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::apply_domain(const typed::map<Domain, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg3> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<Domain> typed::union_map<Domain, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<Domain> typed::union_map<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, Domain> typed::union_map<Domain, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain> typed::union_map<Domain, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<Domain, pair<Range, Range2>>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+bool typed::union_map<Domain, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<Domain, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::extract_map(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+void typed::union_map<Domain, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<Domain, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<Domain, pair<Range, Range2>>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist(const typed::union_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist(const typed::basic_map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist(const typed::map<Domain, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist_domain(const typed::basic_set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist_domain(const typed::point<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::gist_domain(const typed::set<Domain> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect(const typed::map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::map_list<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, Domain> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg3, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg3, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, Arg3> typed::union_map<Domain, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg3, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::product(const typed::basic_map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2, typename Arg3>
+typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::product(const typed::map<Domain2, Arg3> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<Domain, Domain2>, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, Range> typed::union_map<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::union_map::range_factor_domain();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, Range2> typed::union_map<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::union_map::range_factor_range();
+  return typed::union_map<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<Domain, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::range_product(const typed::union_map<Domain, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::range_product(const typed::basic_map<Domain, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_map<Domain, pair<Range, Range2>>::range_product(const typed::map<Domain, Arg3> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range2, Range>> typed::union_map<Domain, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::union_map::range_reverse();
+  return typed::union_map<Domain, pair<Range2, Range>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Range, Range2>, Domain> typed::union_map<Domain, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<pair<Range, Range2>, Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<> typed::union_map<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract(const typed::map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_domain(const typed::basic_set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_domain(const typed::point<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_domain(const typed::set<Domain> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_range(const typed::basic_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_range(const typed::point<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::subtract_range(const typed::set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<pair<Domain, Range>, Range2> typed::union_map<Domain, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::union_map::uncurry();
+  return typed::union_map<pair<Domain, Range>, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::unite(const typed::union_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::unite(const typed::basic_map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::unite(const typed::map<Domain, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_map<Domain, pair<Range, Range2>>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<pair<Domain, pair<Range, Range2>>> typed::union_map<Domain, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<Domain, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>>::union_map(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>>::union_map(const typed::map<pair<T1, T2>, pair<T1, T2>> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::basic_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::apply_range(const typed::map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::bind_range(const typed::multi_id<pair<T1, T2>> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<T1, pair<T2, pair<T1, T2>>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::curry() const
+{
+  auto res = isl::union_map::curry();
+  return typed::union_map<T1, pair<T2, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::deltas() const
+{
+  auto res = isl::union_map::deltas();
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<T1, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_factor_domain() const
+{
+  auto res = isl::union_map::domain_factor_domain();
+  return typed::union_map<T1, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<T2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_factor_range() const
+{
+  auto res = isl::union_map::domain_factor_range();
+  return typed::union_map<T2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::union_map<Domain2, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::basic_map<Domain2, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::domain_product(const typed::map<Domain2, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_union_pw_aff<pair<T1, T2>, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::multi_pw_aff<pair<T1, T2>, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::eq_at(const typed::union_pw_aff<pair<T1, T2>, Range> &mupa) const
+{
+  auto res = isl::union_map::eq_at(mupa);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+bool typed::union_map<pair<T1, T2>, pair<T1, T2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<T1, T2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::extract_map(const typed::space<pair<T1, T2>, pair<T1, T2>> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+void typed::union_map<pair<T1, T2>, pair<T1, T2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<T1, T2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<T1, T2>>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist(const typed::map<pair<T1, T2>, pair<T1, T2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::basic_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::point<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::gist_domain(const typed::set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::intersect_range(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::map_list<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::multi_aff<Range2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::pw_multi_aff<Range2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::preimage_range(const typed::union_pw_multi_aff<Range2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::product(const typed::union_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::product(const typed::basic_map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Domain2, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::product(const typed::map<Domain2, Range2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, T1> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_factor_domain() const
+{
+  auto res = isl::union_map::range_factor_domain();
+  return typed::union_map<pair<T1, T2>, T1>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, T2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_factor_range() const
+{
+  auto res = isl::union_map::range_factor_range();
+  return typed::union_map<pair<T1, T2>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<T1, T2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::union_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::basic_map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+template <typename Range2>
+typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_product(const typed::map<pair<T1, T2>, Range2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<T1, T2>, Range2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T2, T1>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::range_reverse() const
+{
+  auto res = isl::union_map::range_reverse();
+  return typed::union_map<pair<T1, T2>, pair<T2, T1>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::space<> typed::union_map<pair<T1, T2>, pair<T1, T2>>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::basic_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::point<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_domain(const typed::set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::basic_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::point<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::subtract_range(const typed::set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<pair<T1, T2>, T1>, T2> typed::union_map<pair<T1, T2>, pair<T1, T2>>::uncurry() const
+{
+  auto res = isl::union_map::uncurry();
+  return typed::union_map<pair<pair<T1, T2>, T1>, T2>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::union_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::basic_map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::unite(const typed::map<pair<T1, T2>, pair<T1, T2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_map<pair<T1, T2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<pair<T1, T2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2>
+typed::union_set<pair<pair<T1, T2>, pair<T1, T2>>> typed::union_map<pair<T1, T2>, pair<T1, T2>>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<pair<T1, T2>, pair<T1, T2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>>::union_map(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &bmap)
+  : isl::union_map(bmap)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>>::union_map(const typed::map<pair<T1, T2>, pair<Range, Range2>> &map)
+  : isl::union_map(map)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>>::union_map(const isl::ctx &ctx, const std::string &str)
+  : isl::union_map(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::union_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::basic_map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_domain(const typed::map<pair<T1, T2>, Domain2> &umap2) const
+{
+  auto res = isl::union_map::apply_domain(umap2);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::union_map<pair<Range, Range2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::basic_map<pair<Range, Range2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::apply_range(const typed::map<pair<Range, Range2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::apply_range(umap2);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::as_map() const
+{
+  auto res = isl::union_map::as_map();
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_map::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::as_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::as_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::bind_range(const typed::multi_id<pair<Range, Range2>> &tuple) const
+{
+  auto res = isl::union_map::bind_range(tuple);
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::union_map::coalesce();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<T1, pair<T2, pair<Range, Range2>>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::curry() const
+{
+  auto res = isl::union_map::curry();
+  return typed::union_map<T1, pair<T2, pair<Range, Range2>>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::detect_equalities() const
+{
+  auto res = isl::union_map::detect_equalities();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_set<pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::union_map::domain();
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<T1, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_domain() const
+{
+  auto res = isl::union_map::domain_factor_domain();
+  return typed::union_map<T1, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<T2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_factor_range() const
+{
+  auto res = isl::union_map::domain_factor_range();
+  return typed::union_map<T2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_map() const
+{
+  auto res = isl::union_map::domain_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_map_union_pw_multi_aff() const
+{
+  auto res = isl::union_map::domain_map_union_pw_multi_aff();
+  return typed::union_pw_multi_aff<pair<pair<T1, T2>, pair<Range, Range2>>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::union_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::basic_map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::domain_product(const typed::map<Domain2, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::domain_product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_map::empty(ctx);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+bool typed::union_map<pair<T1, T2>, pair<Range, Range2>>::every_map(const std::function<bool(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &test) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return test(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::union_map::every_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::extract_map(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_map::extract_map(space);
+  return typed::map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+void typed::union_map<pair<T1, T2>, pair<Range, Range2>>::foreach_map(const std::function<void(typed::map<pair<T1, T2>, pair<Range, Range2>>)> &fn) const
+{
+  auto lambda = [&] (isl::map arg0) {
+    return fn(typed::map<pair<T1, T2>, pair<Range, Range2>>(arg0));
+  };
+  return isl::union_map::foreach_map(lambda);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::map<pair<T1, T2>, pair<Range, Range2>> &context) const
+{
+  auto res = isl::union_map::gist(context);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::basic_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::point<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::gist_domain(const typed::set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::gist_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::intersect(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::union_map::intersect_domain(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_map::intersect_domain(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_map::intersect_params(set);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::space<pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_map::intersect_range(space);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::intersect_range(const typed::union_set<pair<Range, Range2>> &uset) const
+{
+  auto res = isl::union_map::intersect_range(uset);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::lexmax() const
+{
+  auto res = isl::union_map::lexmax();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::lexmin() const
+{
+  auto res = isl::union_map::lexmin();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::map_list<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::map_list() const
+{
+  auto res = isl::union_map::map_list();
+  return typed::map_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_aff<Domain2, pair<T1, T2>> &ma) const
+{
+  auto res = isl::union_map::preimage_domain(ma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::multi_pw_aff<Domain2, pair<T1, T2>> &mpa) const
+{
+  auto res = isl::union_map::preimage_domain(mpa);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &pma) const
+{
+  auto res = isl::union_map::preimage_domain(pma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_map<Domain2, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_domain(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma) const
+{
+  auto res = isl::union_map::preimage_domain(upma);
+  return typed::union_map<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::multi_aff<Arg2, pair<Range, Range2>> &ma) const
+{
+  auto res = isl::union_map::preimage_range(ma);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::pw_multi_aff<Arg2, pair<Range, Range2>> &pma) const
+{
+  auto res = isl::union_map::preimage_range(pma);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, Arg2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::preimage_range(const typed::union_pw_multi_aff<Arg2, pair<Range, Range2>> &upma) const
+{
+  auto res = isl::union_map::preimage_range(upma);
+  return typed::union_map<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::union_map<Domain2, Arg2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::basic_map<Domain2, Arg2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2, typename Arg2>
+typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::product(const typed::map<Domain2, Arg2> &umap2) const
+{
+  auto res = isl::union_map::product(umap2);
+  return typed::union_map<pair<pair<T1, T2>, Domain2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::project_out_all_params() const
+{
+  auto res = isl::union_map::project_out_all_params();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_set<pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range() const
+{
+  auto res = isl::union_map::range();
+  return typed::union_set<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, Range> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::union_map::range_factor_domain();
+  return typed::union_map<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, Range2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::union_map::range_factor_range();
+  return typed::union_map<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_map() const
+{
+  auto res = isl::union_map::range_map();
+  return typed::union_map<pair<pair<T1, T2>, pair<Range, Range2>>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_map<pair<T1, T2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::basic_map<pair<T1, T2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::map<pair<T1, T2>, Arg2> &umap2) const
+{
+  auto res = isl::union_map::range_product(umap2);
+  return typed::union_map<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range2, Range>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::range_reverse() const
+{
+  auto res = isl::union_map::range_reverse();
+  return typed::union_map<pair<T1, T2>, pair<Range2, Range>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<Range, Range2>, pair<T1, T2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::reverse() const
+{
+  auto res = isl::union_map::reverse();
+  return typed::union_map<pair<Range, Range2>, pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::union_map::space();
+  return typed::space<>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::subtract(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::basic_set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::point<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::set<pair<T1, T2>> &dom) const
+{
+  auto res = isl::union_map::subtract_domain(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::union_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::basic_set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::point<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::subtract_range(const typed::set<pair<Range, Range2>> &dom) const
+{
+  auto res = isl::union_map::subtract_range(dom);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<pair<T1, T2>, Range>, Range2> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::uncurry() const
+{
+  auto res = isl::union_map::uncurry();
+  return typed::union_map<pair<pair<T1, T2>, Range>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::union_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::basic_map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::unite(const typed::map<pair<T1, T2>, pair<Range, Range2>> &umap2) const
+{
+  auto res = isl::union_map::unite(umap2);
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::universe() const
+{
+  auto res = isl::union_map::universe();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_set<pair<pair<T1, T2>, pair<Range, Range2>>> typed::union_map<pair<T1, T2>, pair<Range, Range2>>::wrap() const
+{
+  auto res = isl::union_map::wrap();
+  return typed::union_set<pair<pair<T1, T2>, pair<Range, Range2>>>(res);
+}
+
+typed::union_pw_aff<Anonymous>::union_pw_aff(const typed::aff<Anonymous> &aff)
+  : isl::union_pw_aff(aff)
+{
+}
+
+typed::union_pw_aff<Anonymous>::union_pw_aff(const typed::pw_aff<Anonymous> &pa)
+  : isl::union_pw_aff(pa)
+{
+}
+
+typed::union_pw_aff<Anonymous>::union_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_aff(ctx, str)
+{
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::add(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::union_pw_aff<Anonymous>::add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::add(const typed::aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::add(const typed::pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_aff<Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range> &upma2) const
+{
+  auto res = isl::union_pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::union_pw_aff<Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::at(int pos) const
+{
+  auto res = isl::union_pw_aff::at(pos);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_set<> typed::union_pw_aff<Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::union_pw_aff::bind(tuple);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_pw_aff<Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_pw_aff<Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::coalesce() const
+{
+  auto res = isl::union_pw_aff::coalesce();
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_set<> typed::union_pw_aff<Anonymous>::domain() const
+{
+  auto res = isl::union_pw_aff::domain();
+  return typed::union_set<>(res);
+}
+
+typed::pw_multi_aff<Anonymous> typed::union_pw_aff<Anonymous>::extract_pw_multi_aff(const typed::space<Anonymous> &space) const
+{
+  auto res = isl::union_pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::gist(const typed::point<> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::gist(const typed::set<> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff_list<Anonymous> typed::union_pw_aff<Anonymous>::list() const
+{
+  auto res = isl::union_pw_aff::list();
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::neg() const
+{
+  auto res = isl::union_pw_aff::neg();
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::pw_multi_aff_list<Anonymous> typed::union_pw_aff<Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale(mv);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale(long v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale_down(mv);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::scale_down(long v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::set_at(int pos, const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2> typed::union_pw_aff<Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain2>(res);
+}
+
+template <typename Domain2>
+typed::multi_union_pw_aff<Domain2> typed::union_pw_aff<Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain2>(res);
+}
+
+typed::space<> typed::union_pw_aff<Anonymous>::space() const
+{
+  auto res = isl::union_pw_aff::space();
+  return typed::space<>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::sub(const typed::multi_union_pw_aff<Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::sub(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::union_pw_aff<Anonymous>::sub(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::sub(const typed::aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::sub(const typed::pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::multi_union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::union_add(const typed::multi_union_pw_aff<Anonymous> &mupa2) const
+{
+  auto res = isl::union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::union_add(const typed::union_pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_multi_aff<Anonymous> typed::union_pw_aff<Anonymous>::union_add(const typed::union_pw_multi_aff<Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::union_add(const typed::aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Anonymous>::union_add(const typed::pw_aff<Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous>::union_pw_aff(const typed::aff<Domain, Anonymous> &aff)
+  : isl::union_pw_aff(aff)
+{
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous>::union_pw_aff(const typed::pw_aff<Domain, Anonymous> &pa)
+  : isl::union_pw_aff(pa)
+{
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous>::union_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::add(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::add(const typed::pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_aff<Domain, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const
+{
+  auto res = isl::union_pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::as_union_map() const
+{
+  auto res = isl::union_pw_aff::as_union_map();
+  return typed::union_map<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::at(int pos) const
+{
+  auto res = isl::union_pw_aff::at(pos);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_pw_aff<Domain, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::union_pw_aff::bind(tuple);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_pw_aff<Domain, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_pw_aff<Domain, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::coalesce() const
+{
+  auto res = isl::union_pw_aff::coalesce();
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_pw_aff<Domain, Anonymous>::domain() const
+{
+  auto res = isl::union_pw_aff::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::extract_pw_multi_aff(const typed::space<Domain, Anonymous> &space) const
+{
+  auto res = isl::union_pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_aff::intersect_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_aff::intersect_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::list() const
+{
+  auto res = isl::union_pw_aff::list();
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::neg() const
+{
+  auto res = isl::union_pw_aff::neg();
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::multi_aff<Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::pw_multi_aff<Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_pw_aff<Domain2, Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Domain2, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<Domain, Anonymous>::pullback(const typed::union_pw_aff<Domain> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>> typed::union_pw_aff<Domain, Anonymous>::range_product(const typed::multi_union_pw_aff<Domain, Range2> &multi2) const
+{
+  auto res = isl::union_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>> typed::union_pw_aff<Domain, Anonymous>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::union_pw_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale(mv);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale(long v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale_down(mv);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::scale_down(long v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::set_at(int pos, const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, Range2> typed::union_pw_aff<Domain, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+template <typename Range2>
+typed::multi_union_pw_aff<Domain, Range2> typed::union_pw_aff<Domain, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<Domain, Range2>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::union_pw_aff<Domain, Anonymous>::space() const
+{
+  auto res = isl::union_pw_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::sub(const typed::multi_union_pw_aff<Domain, Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::sub(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::sub(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::sub(const typed::aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::sub(const typed::pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_aff::subtract_domain(space);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_aff::subtract_domain(uset);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::union_add(const typed::multi_union_pw_aff<Domain, Anonymous> &mupa2) const
+{
+  auto res = isl::union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::union_add(const typed::union_pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::union_add(const typed::union_pw_multi_aff<Domain, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::union_add(const typed::aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff<Domain, Anonymous>::union_add(const typed::pw_aff<Domain, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_pw_aff(const typed::aff<pair<Domain, Domain2>, Anonymous> &aff)
+  : isl::union_pw_aff(aff)
+{
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_pw_aff(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &pa)
+  : isl::union_pw_aff(pa)
+{
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_pw_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::add(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::add(multi2);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::add(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::add(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::add(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::apply(const typed::union_pw_multi_aff<Anonymous, Range2> &upma2) const
+{
+  auto res = isl::union_pw_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_map<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::as_union_map() const
+{
+  auto res = isl::union_pw_aff::as_union_map();
+  return typed::union_map<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::at(int pos) const
+{
+  auto res = isl::union_pw_aff::at(pos);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_set<pair<Domain, Domain2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::bind(const typed::multi_id<Anonymous> &tuple) const
+{
+  auto res = isl::union_pw_aff::bind(tuple);
+  return typed::union_set<pair<Domain, Domain2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_set<pair<Domain, Domain2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::bind(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<pair<Domain, Domain2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_set<pair<Domain, Domain2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::bind(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::bind(id);
+  return typed::union_set<pair<Domain, Domain2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::coalesce() const
+{
+  auto res = isl::union_pw_aff::coalesce();
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_set<pair<Domain, Domain2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::domain() const
+{
+  auto res = isl::union_pw_aff::domain();
+  return typed::union_set<pair<Domain, Domain2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::extract_pw_multi_aff(const typed::space<pair<Domain, Domain2>, Anonymous> &space) const
+{
+  auto res = isl::union_pw_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::gist(const typed::union_set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::gist(const typed::basic_set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::gist(const typed::point<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::gist(const typed::set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_aff::gist(context);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::intersect_domain(const typed::space<pair<Domain, Domain2>> &space) const
+{
+  auto res = isl::union_pw_aff::intersect_domain(space);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::intersect_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const
+{
+  auto res = isl::union_pw_aff::intersect_domain(uset);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_aff::intersect_params(set);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff_list<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::list() const
+{
+  auto res = isl::union_pw_aff::list();
+  return typed::union_pw_aff_list<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::neg() const
+{
+  auto res = isl::union_pw_aff::neg();
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain> &upma2) const
+{
+  auto res = isl::union_pw_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Arg2>
+typed::union_pw_aff<Arg2, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::union_pw_multi_aff<Arg2, pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Arg2, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::union_pw_multi_aff<pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Arg2>
+typed::union_pw_aff<Arg2, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::multi_aff<Arg2, pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Arg2, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::multi_aff<pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Arg2>
+typed::union_pw_aff<Arg2, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::pw_multi_aff<Arg2, pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Arg2, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::pw_multi_aff<pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Arg2>
+typed::union_pw_aff<Arg2, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::union_pw_aff<Arg2, pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Arg2, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pullback(const typed::union_pw_aff<pair<Domain, Domain2>> &upma) const
+{
+  auto res = isl::union_pw_aff::pullback(upma);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::pw_multi_aff_list<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::range_product(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> &multi2) const
+{
+  auto res = isl::union_pw_aff::range_product(multi2);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::range_product(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const
+{
+  auto res = isl::union_pw_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Anonymous, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale(mv);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale(long v) const
+{
+  auto res = isl::union_pw_aff::scale(v);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale_down(const typed::multi_val<Anonymous> &mv) const
+{
+  auto res = isl::union_pw_aff::scale_down(mv);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale_down(const typed::val<Anonymous> &v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::scale_down(long v) const
+{
+  auto res = isl::union_pw_aff::scale_down(v);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::set_at(int pos, const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff::set_at(pos, el);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::set_range_tuple(const typed::id<Anonymous> &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2>
+template <typename Range2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::set_range_tuple(const std::string &id) const
+{
+  auto res = isl::union_pw_aff::set_range_tuple(id);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::space<> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::space() const
+{
+  auto res = isl::union_pw_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::sub(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &multi2) const
+{
+  auto res = isl::union_pw_aff::sub(multi2);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::sub(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::sub(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::sub(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::sub(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::sub(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::subtract_domain(const typed::space<pair<Domain, Domain2>> &space) const
+{
+  auto res = isl::union_pw_aff::subtract_domain(space);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::subtract_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const
+{
+  auto res = isl::union_pw_aff::subtract_domain(uset);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_add(const typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous> &mupa2) const
+{
+  auto res = isl::union_pw_aff::union_add(mupa2);
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_add(const typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous> &upma2) const
+{
+  auto res = isl::union_pw_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_add(const typed::aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+template <typename Domain, typename Domain2>
+typed::union_pw_aff<pair<Domain, Domain2>, Anonymous> typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>::union_add(const typed::pw_aff<pair<Domain, Domain2>, Anonymous> &upa2) const
+{
+  auto res = isl::union_pw_aff::union_add(upa2);
+  return typed::union_pw_aff<pair<Domain, Domain2>, Anonymous>(res);
+}
+
+typed::union_pw_aff_list<Anonymous>::union_pw_aff_list(const isl::ctx &ctx, int n)
+  : isl::union_pw_aff_list(ctx, n)
+{
+}
+
+typed::union_pw_aff_list<Anonymous>::union_pw_aff_list(const typed::union_pw_aff<Anonymous> &el)
+  : isl::union_pw_aff_list(el)
+{
+}
+
+typed::union_pw_aff_list<Anonymous>::union_pw_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_aff_list(ctx, str)
+{
+}
+
+typed::union_pw_aff_list<Anonymous> typed::union_pw_aff_list<Anonymous>::add(const typed::union_pw_aff<Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+typed::union_pw_aff_list<Anonymous> typed::union_pw_aff_list<Anonymous>::add(const typed::aff<Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+typed::union_pw_aff_list<Anonymous> typed::union_pw_aff_list<Anonymous>::add(const typed::pw_aff<Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+typed::union_pw_aff<Anonymous> typed::union_pw_aff_list<Anonymous>::at(int index) const
+{
+  auto res = isl::union_pw_aff_list::at(index);
+  return typed::union_pw_aff<Anonymous>(res);
+}
+
+typed::union_pw_aff_list<Anonymous> typed::union_pw_aff_list<Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::union_pw_aff_list::drop(first, n);
+  return typed::union_pw_aff_list<Anonymous>(res);
+}
+
+void typed::union_pw_aff_list<Anonymous>::foreach(const std::function<void(typed::union_pw_aff<Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::union_pw_aff arg0) {
+    return fn(typed::union_pw_aff<Anonymous>(arg0));
+  };
+  return isl::union_pw_aff_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous>::union_pw_aff_list(const isl::ctx &ctx, int n)
+  : isl::union_pw_aff_list(ctx, n)
+{
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous>::union_pw_aff_list(const typed::union_pw_aff<Domain, Anonymous> &el)
+  : isl::union_pw_aff_list(el)
+{
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous>::union_pw_aff_list(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_aff_list(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous> typed::union_pw_aff_list<Domain, Anonymous>::add(const typed::union_pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous> typed::union_pw_aff_list<Domain, Anonymous>::add(const typed::aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous> typed::union_pw_aff_list<Domain, Anonymous>::add(const typed::pw_aff<Domain, Anonymous> &el) const
+{
+  auto res = isl::union_pw_aff_list::add(el);
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff<Domain, Anonymous> typed::union_pw_aff_list<Domain, Anonymous>::at(int index) const
+{
+  auto res = isl::union_pw_aff_list::at(index);
+  return typed::union_pw_aff<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+typed::union_pw_aff_list<Domain, Anonymous> typed::union_pw_aff_list<Domain, Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::union_pw_aff_list::drop(first, n);
+  return typed::union_pw_aff_list<Domain, Anonymous>(res);
+}
+
+template <typename Domain>
+void typed::union_pw_aff_list<Domain, Anonymous>::foreach(const std::function<void(typed::union_pw_aff<Domain, Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::union_pw_aff arg0) {
+    return fn(typed::union_pw_aff<Domain, Anonymous>(arg0));
+  };
+  return isl::union_pw_aff_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain>::union_pw_multi_aff(const typed::multi_aff<Domain> &ma)
+  : isl::union_pw_multi_aff(ma)
+{
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain>::union_pw_multi_aff(const typed::pw_multi_aff<Domain> &pma)
+  : isl::union_pw_multi_aff(pma)
+{
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain>::union_pw_multi_aff(const typed::union_pw_aff<Domain> &upa)
+  : isl::union_pw_multi_aff(upa)
+{
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::add(const typed::multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::add(const typed::pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::add(const typed::union_pw_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain>::apply(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain>::apply(const typed::multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain>::apply(const typed::pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain>::apply(const typed::union_pw_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain>
+typed::multi_union_pw_aff<Domain> typed::union_pw_multi_aff<Domain>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::coalesce() const
+{
+  auto res = isl::union_pw_multi_aff::coalesce();
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<> typed::union_pw_multi_aff<Domain>::domain() const
+{
+  auto res = isl::union_pw_multi_aff::domain();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_pw_multi_aff::empty(ctx);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::extract_pw_multi_aff(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::gist(const typed::point<> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::gist(const typed::set<> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::pw_multi_aff_list<Domain> typed::union_pw_multi_aff<Domain>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::union_pw_multi_aff<Domain>::space() const
+{
+  auto res = isl::union_pw_multi_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::sub(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::sub(const typed::multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::sub(const typed::pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::sub(const typed::union_pw_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::union_add(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::union_add(const typed::multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::union_add(const typed::pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_pw_multi_aff<Domain> typed::union_pw_multi_aff<Domain>::union_add(const typed::union_pw_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range>::union_pw_multi_aff(const typed::multi_aff<Domain, Range> &ma)
+  : isl::union_pw_multi_aff(ma)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range>::union_pw_multi_aff(const typed::pw_multi_aff<Domain, Range> &pma)
+  : isl::union_pw_multi_aff(pma)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range>::union_pw_multi_aff(const typed::union_pw_aff<Domain, Range> &upa)
+  : isl::union_pw_multi_aff(upa)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::add(const typed::multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::add(const typed::pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::add(const typed::union_pw_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_multi_aff<Domain, Range>::apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_multi_aff<Domain, Range>::apply(const typed::multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_multi_aff<Domain, Range>::apply(const typed::pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_multi_aff<Domain, Range>::apply(const typed::union_pw_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::multi_union_pw_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::as_union_map() const
+{
+  auto res = isl::union_pw_multi_aff::as_union_map();
+  return typed::union_map<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::coalesce() const
+{
+  auto res = isl::union_pw_multi_aff::coalesce();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<Domain> typed::union_pw_multi_aff<Domain, Range>::domain() const
+{
+  auto res = isl::union_pw_multi_aff::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_pw_multi_aff::empty(ctx);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::extract_pw_multi_aff(const typed::space<Domain, Range> &space) const
+{
+  auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<Domain, Range>::pullback(const typed::union_pw_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::pw_multi_aff_list<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, Range>::range_product(const typed::union_pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, Range>::range_product(const typed::multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, Range>::range_product(const typed::pw_multi_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, Range>::range_product(const typed::union_pw_aff<Domain, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::union_pw_multi_aff<Domain, Range>::space() const
+{
+  auto res = isl::union_pw_multi_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::sub(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::sub(const typed::multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::sub(const typed::pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::sub(const typed::union_pw_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::union_add(const typed::union_pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::union_add(const typed::multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::union_add(const typed::pw_multi_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, Range>::union_add(const typed::union_pw_aff<Domain, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_pw_multi_aff(const typed::multi_aff<pair<Domain, Domain2>, Range> &ma)
+  : isl::union_pw_multi_aff(ma)
+{
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_pw_multi_aff(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &pma)
+  : isl::union_pw_multi_aff(pma)
+{
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_pw_multi_aff(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upa)
+  : isl::union_pw_multi_aff(upa)
+{
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::add(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::add(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::add(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::apply(const typed::union_pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::apply(const typed::multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::apply(const typed::pw_multi_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::apply(const typed::union_pw_aff<Range, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::multi_union_pw_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_map<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::as_union_map() const
+{
+  auto res = isl::union_pw_multi_aff::as_union_map();
+  return typed::union_map<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::coalesce() const
+{
+  auto res = isl::union_pw_multi_aff::coalesce();
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_set<pair<Domain, Domain2>> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::domain() const
+{
+  auto res = isl::union_pw_multi_aff::domain();
+  return typed::union_set<pair<Domain, Domain2>>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_pw_multi_aff::empty(ctx);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::extract_pw_multi_aff(const typed::space<pair<Domain, Domain2>, Range> &space) const
+{
+  auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::gist(const typed::union_set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::gist(const typed::basic_set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::gist(const typed::point<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::gist(const typed::set<pair<Domain, Domain2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::intersect_domain(const typed::space<pair<Domain, Domain2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::intersect_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::preimage_domain_wrapped_domain(const typed::union_pw_aff<Domain3, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Arg3>
+typed::union_pw_multi_aff<Arg3, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::union_pw_multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg3, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::union_pw_multi_aff<pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Arg3>
+typed::union_pw_multi_aff<Arg3, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg3, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::multi_aff<pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Arg3>
+typed::union_pw_multi_aff<Arg3, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::pw_multi_aff<Arg3, pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg3, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::pw_multi_aff<pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Arg3>
+typed::union_pw_multi_aff<Arg3, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::union_pw_aff<Arg3, pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Arg3, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pullback(const typed::union_pw_aff<pair<Domain, Domain2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::pw_multi_aff_list<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::range_product(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::range_product(const typed::multi_aff<pair<Domain, Domain2>, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::range_product(const typed::pw_multi_aff<pair<Domain, Domain2>, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+template <typename Range2>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::range_product(const typed::union_pw_aff<pair<Domain, Domain2>, Range2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::space<> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::space() const
+{
+  auto res = isl::union_pw_multi_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::sub(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::sub(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::sub(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::sub(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::subtract_domain(const typed::space<pair<Domain, Domain2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::subtract_domain(const typed::union_set<pair<Domain, Domain2>> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_add(const typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_add(const typed::multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_add(const typed::pw_multi_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Domain2, typename Range>
+typed::union_pw_multi_aff<pair<Domain, Domain2>, Range> typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>::union_add(const typed::union_pw_aff<pair<Domain, Domain2>, Range> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<Domain, Domain2>, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_pw_multi_aff(const typed::multi_aff<Domain, pair<Range, Range2>> &ma)
+  : isl::union_pw_multi_aff(ma)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_pw_multi_aff(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &pma)
+  : isl::union_pw_multi_aff(pma)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_pw_multi_aff(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upa)
+  : isl::union_pw_multi_aff(upa)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_multi_aff(ctx, str)
+{
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::add(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::apply(const typed::multi_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::apply(const typed::pw_multi_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, Arg3> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::apply(const typed::union_pw_aff<pair<Range, Range2>, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<Domain, Arg3>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::multi_union_pw_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_map<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::union_pw_multi_aff::as_union_map();
+  return typed::union_map<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::union_pw_multi_aff::coalesce();
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_set<Domain> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::union_pw_multi_aff::domain();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_pw_multi_aff::empty(ctx);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<Domain, pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::intersect_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_aff<Domain2, Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pullback(const typed::union_pw_aff<Domain> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::pw_multi_aff_list<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, Range> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::union_pw_multi_aff::range_factor_domain();
+  return typed::union_pw_multi_aff<Domain, Range>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, Range2> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::union_pw_multi_aff::range_factor_range();
+  return typed::union_pw_multi_aff<Domain, Range2>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::multi_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+template <typename Arg3>
+typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::range_product(const typed::union_pw_aff<Domain, Arg3> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<pair<Range, Range2>, Arg3>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::space<> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::space() const
+{
+  auto res = isl::union_pw_multi_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::sub(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::subtract_domain(const typed::union_set<Domain> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename Domain, typename Range, typename Range2>
+typed::union_pw_multi_aff<Domain, pair<Range, Range2>> typed::union_pw_multi_aff<Domain, pair<Range, Range2>>::union_add(const typed::union_pw_aff<Domain, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<Domain, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_pw_multi_aff(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &ma)
+  : isl::union_pw_multi_aff(ma)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_pw_multi_aff(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &pma)
+  : isl::union_pw_multi_aff(pma)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_pw_multi_aff(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upa)
+  : isl::union_pw_multi_aff(upa)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_pw_multi_aff(const isl::ctx &ctx, const std::string &str)
+  : isl::union_pw_multi_aff(ctx, str)
+{
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::add(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::union_pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::multi_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::pw_multi_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, Arg2> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::apply(const typed::union_pw_aff<pair<Range, Range2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::apply(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, Arg2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_multi_union_pw_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_multi_union_pw_aff();
+  return typed::multi_union_pw_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_pw_multi_aff() const
+{
+  auto res = isl::union_pw_multi_aff::as_pw_multi_aff();
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_map<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::as_union_map() const
+{
+  auto res = isl::union_pw_multi_aff::as_union_map();
+  return typed::union_map<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::coalesce() const
+{
+  auto res = isl::union_pw_multi_aff::coalesce();
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_set<pair<T1, T2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::domain() const
+{
+  auto res = isl::union_pw_multi_aff::domain();
+  return typed::union_set<pair<T1, T2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_pw_multi_aff::empty(ctx);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::extract_pw_multi_aff(const typed::space<pair<T1, T2>, pair<Range, Range2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::extract_pw_multi_aff(space);
+  return typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::union_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::basic_set<pair<T1, T2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::point<pair<T1, T2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::gist(const typed::set<pair<T1, T2>> &context) const
+{
+  auto res = isl::union_pw_multi_aff::gist(context);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_pw_multi_aff::intersect_params(set);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::union_pw_multi_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::multi_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::pw_multi_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain3>
+typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::preimage_domain_wrapped_domain(const typed::union_pw_aff<Domain3, T1> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::preimage_domain_wrapped_domain(upma2);
+  return typed::union_pw_multi_aff<pair<Domain3, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_multi_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::multi_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::pw_multi_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Domain2>
+typed::union_pw_multi_aff<Domain2, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_aff<Domain2, pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<Domain2, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pullback(const typed::union_pw_aff<pair<T1, T2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::pullback(upma2);
+  return typed::union_pw_multi_aff<pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::pw_multi_aff_list() const
+{
+  auto res = isl::union_pw_multi_aff::pw_multi_aff_list();
+  return typed::pw_multi_aff_list<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, Range> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_domain() const
+{
+  auto res = isl::union_pw_multi_aff::range_factor_domain();
+  return typed::union_pw_multi_aff<pair<T1, T2>, Range>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, Range2> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_factor_range() const
+{
+  auto res = isl::union_pw_multi_aff::range_factor_range();
+  return typed::union_pw_multi_aff<pair<T1, T2>, Range2>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::multi_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::pw_multi_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+template <typename Arg2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::range_product(const typed::union_pw_aff<pair<T1, T2>, Arg2> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::range_product(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<pair<Range, Range2>, Arg2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::space<> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::space() const
+{
+  auto res = isl::union_pw_multi_aff::space();
+  return typed::space<>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::sub(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::sub(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::space<pair<T1, T2>> &space) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(space);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::subtract_domain(const typed::union_set<pair<T1, T2>> &uset) const
+{
+  auto res = isl::union_pw_multi_aff::subtract_domain(uset);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+template <typename T1, typename T2, typename Range, typename Range2>
+typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>> typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>::union_add(const typed::union_pw_aff<pair<T1, T2>, pair<Range, Range2>> &upma2) const
+{
+  auto res = isl::union_pw_multi_aff::union_add(upma2);
+  return typed::union_pw_multi_aff<pair<T1, T2>, pair<Range, Range2>>(res);
+}
+
+typed::union_set<>::union_set(const typed::basic_set<> &bset)
+  : isl::union_set(bset)
+{
+}
+
+typed::union_set<>::union_set(const typed::point<> &pnt)
+  : isl::union_set(pnt)
+{
+}
+
+typed::union_set<>::union_set(const typed::set<> &set)
+  : isl::union_set(set)
+{
+}
+
+typed::union_set<>::union_set(const isl::ctx &ctx, const std::string &str)
+  : isl::union_set(ctx, str)
+{
+}
+
+typed::union_set<> typed::union_set<>::coalesce() const
+{
+  auto res = isl::union_set::coalesce();
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::detect_equalities() const
+{
+  auto res = isl::union_set::detect_equalities();
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_set::empty(ctx);
+  return typed::union_set<>(res);
+}
+
+bool typed::union_set<>::every_set(const std::function<bool(typed::set<>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<>(arg0));
+  };
+  return isl::union_set::every_set(lambda);
+}
+
+typed::set<> typed::union_set<>::extract_set(const typed::space<> &space) const
+{
+  auto res = isl::union_set::extract_set(space);
+  return typed::set<>(res);
+}
+
+void typed::union_set<>::foreach_point(const std::function<void(typed::point<>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<>(arg0));
+  };
+  return isl::union_set::foreach_point(lambda);
+}
+
+void typed::union_set<>::foreach_set(const std::function<void(typed::set<>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<>(arg0));
+  };
+  return isl::union_set::foreach_set(lambda);
+}
+
+typed::union_set<> typed::union_set<>::gist(const typed::union_set<> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::gist(const typed::basic_set<> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::gist(const typed::point<> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::gist(const typed::set<> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::intersect(const typed::union_set<> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::intersect(const typed::basic_set<> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::intersect(const typed::point<> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::intersect(const typed::set<> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::space<> typed::union_set<>::space() const
+{
+  auto res = isl::union_set::space();
+  return typed::space<>(res);
+}
+
+typed::union_set<> typed::union_set<>::subtract(const typed::union_set<> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::subtract(const typed::basic_set<> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::subtract(const typed::point<> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::subtract(const typed::set<> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::unite(const typed::union_set<> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::unite(const typed::basic_set<> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::unite(const typed::point<> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::unite(const typed::set<> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<>(res);
+}
+
+typed::union_set<> typed::union_set<>::universe() const
+{
+  auto res = isl::union_set::universe();
+  return typed::union_set<>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain>::union_set(const typed::basic_set<Domain> &bset)
+  : isl::union_set(bset)
+{
+}
+
+template <typename Domain>
+typed::union_set<Domain>::union_set(const typed::point<Domain> &pnt)
+  : isl::union_set(pnt)
+{
+}
+
+template <typename Domain>
+typed::union_set<Domain>::union_set(const typed::set<Domain> &set)
+  : isl::union_set(set)
+{
+}
+
+template <typename Domain>
+typed::union_set<Domain>::union_set(const isl::ctx &ctx, const std::string &str)
+  : isl::union_set(ctx, str)
+{
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::union_set<Domain>::apply(const typed::union_map<Domain, Range> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::union_set<Domain>::apply(const typed::basic_map<Domain, Range> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+template <typename Range>
+typed::union_set<Range> typed::union_set<Domain>::apply(const typed::map<Domain, Range> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Range>(res);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::union_set<Domain>::as_set() const
+{
+  auto res = isl::union_set::as_set();
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::coalesce() const
+{
+  auto res = isl::union_set::coalesce();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::detect_equalities() const
+{
+  auto res = isl::union_set::detect_equalities();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_set::empty(ctx);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+bool typed::union_set<Domain>::every_set(const std::function<bool(typed::set<Domain>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<Domain>(arg0));
+  };
+  return isl::union_set::every_set(lambda);
+}
+
+template <typename Domain>
+typed::set<Domain> typed::union_set<Domain>::extract_set(const typed::space<Domain> &space) const
+{
+  auto res = isl::union_set::extract_set(space);
+  return typed::set<Domain>(res);
+}
+
+template <typename Domain>
+void typed::union_set<Domain>::foreach_point(const std::function<void(typed::point<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<Domain>(arg0));
+  };
+  return isl::union_set::foreach_point(lambda);
+}
+
+template <typename Domain>
+void typed::union_set<Domain>::foreach_set(const std::function<void(typed::set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<Domain>(arg0));
+  };
+  return isl::union_set::foreach_set(lambda);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::gist(const typed::union_set<Domain> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::gist(const typed::basic_set<Domain> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::gist(const typed::point<Domain> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::gist(const typed::set<Domain> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_map<Domain, Domain> typed::union_set<Domain>::identity() const
+{
+  auto res = isl::union_set::identity();
+  return typed::union_map<Domain, Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect(const typed::basic_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect(const typed::point<Domain> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect(const typed::set<Domain> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::lexmax() const
+{
+  auto res = isl::union_set::lexmax();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::lexmin() const
+{
+  auto res = isl::union_set::lexmin();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<Domain>::preimage(const typed::multi_aff<Domain2, Domain> &ma) const
+{
+  auto res = isl::union_set::preimage(ma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<Domain>::preimage(const typed::pw_multi_aff<Domain2, Domain> &pma) const
+{
+  auto res = isl::union_set::preimage(pma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<Domain>::preimage(const typed::union_pw_multi_aff<Domain2, Domain> &upma) const
+{
+  auto res = isl::union_set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain>
+typed::space<> typed::union_set<Domain>::space() const
+{
+  auto res = isl::union_set::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::subtract(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::subtract(const typed::basic_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::subtract(const typed::point<Domain> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::subtract(const typed::set<Domain> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::unite(const typed::union_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::unite(const typed::basic_set<Domain> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::unite(const typed::point<Domain> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::unite(const typed::set<Domain> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set<Domain>::universe() const
+{
+  auto res = isl::union_set::universe();
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>>::union_set(const typed::basic_set<pair<Domain, Range>> &bset)
+  : isl::union_set(bset)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>>::union_set(const typed::point<pair<Domain, Range>> &pnt)
+  : isl::union_set(pnt)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>>::union_set(const typed::set<pair<Domain, Range>> &set)
+  : isl::union_set(set)
+{
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>>::union_set(const isl::ctx &ctx, const std::string &str)
+  : isl::union_set(ctx, str)
+{
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::union_set<pair<Domain, Range>>::apply(const typed::union_map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::union_set<pair<Domain, Range>>::apply(const typed::basic_map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Arg2>
+typed::union_set<Arg2> typed::union_set<pair<Domain, Range>>::apply(const typed::map<pair<Domain, Range>, Arg2> &umap) const
+{
+  auto res = isl::union_set::apply(umap);
+  return typed::union_set<Arg2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::as_set() const
+{
+  auto res = isl::union_set::as_set();
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::coalesce() const
+{
+  auto res = isl::union_set::coalesce();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::detect_equalities() const
+{
+  auto res = isl::union_set::detect_equalities();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::empty(const isl::ctx &ctx)
+{
+  auto res = isl::union_set::empty(ctx);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+bool typed::union_set<pair<Domain, Range>>::every_set(const std::function<bool(typed::set<pair<Domain, Range>>)> &test) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return test(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::union_set::every_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::extract_set(const typed::space<pair<Domain, Range>> &space) const
+{
+  auto res = isl::union_set::extract_set(space);
+  return typed::set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+void typed::union_set<pair<Domain, Range>>::foreach_point(const std::function<void(typed::point<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::point arg0) {
+    return fn(typed::point<pair<Domain, Range>>(arg0));
+  };
+  return isl::union_set::foreach_point(lambda);
+}
+
+template <typename Domain, typename Range>
+void typed::union_set<pair<Domain, Range>>::foreach_set(const std::function<void(typed::set<pair<Domain, Range>>)> &fn) const
+{
+  auto lambda = [&] (isl::set arg0) {
+    return fn(typed::set<pair<Domain, Range>>(arg0));
+  };
+  return isl::union_set::foreach_set(lambda);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::gist(const typed::union_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::gist(const typed::basic_set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::gist(const typed::point<pair<Domain, Range>> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::gist(const typed::set<pair<Domain, Range>> &context) const
+{
+  auto res = isl::union_set::gist(context);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<pair<Domain, Range>, pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::identity() const
+{
+  auto res = isl::union_set::identity();
+  return typed::union_map<pair<Domain, Range>, pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect(const typed::basic_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect(const typed::point<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect(const typed::set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::intersect(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect_params(const typed::set<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect_params(const typed::basic_set<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::intersect_params(const typed::point<> &set) const
+{
+  auto res = isl::union_set::intersect_params(set);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::lexmax() const
+{
+  auto res = isl::union_set::lexmax();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::lexmin() const
+{
+  auto res = isl::union_set::lexmin();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<pair<Domain, Range>>::preimage(const typed::multi_aff<Domain2, pair<Domain, Range>> &ma) const
+{
+  auto res = isl::union_set::preimage(ma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<pair<Domain, Range>>::preimage(const typed::pw_multi_aff<Domain2, pair<Domain, Range>> &pma) const
+{
+  auto res = isl::union_set::preimage(pma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+template <typename Domain2>
+typed::union_set<Domain2> typed::union_set<pair<Domain, Range>>::preimage(const typed::union_pw_multi_aff<Domain2, pair<Domain, Range>> &upma) const
+{
+  auto res = isl::union_set::preimage(upma);
+  return typed::union_set<Domain2>(res);
+}
+
+template <typename Domain, typename Range>
+typed::space<> typed::union_set<pair<Domain, Range>>::space() const
+{
+  auto res = isl::union_set::space();
+  return typed::space<>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::subtract(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::subtract(const typed::basic_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::subtract(const typed::point<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::subtract(const typed::set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::subtract(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::unite(const typed::union_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::unite(const typed::basic_set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::unite(const typed::point<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::unite(const typed::set<pair<Domain, Range>> &uset2) const
+{
+  auto res = isl::union_set::unite(uset2);
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_set<pair<Domain, Range>> typed::union_set<pair<Domain, Range>>::universe() const
+{
+  auto res = isl::union_set::universe();
+  return typed::union_set<pair<Domain, Range>>(res);
+}
+
+template <typename Domain, typename Range>
+typed::union_map<Domain, Range> typed::union_set<pair<Domain, Range>>::unwrap() const
+{
+  auto res = isl::union_set::unwrap();
+  return typed::union_map<Domain, Range>(res);
+}
+
+typed::union_set_list<>::union_set_list(const isl::ctx &ctx, int n)
+  : isl::union_set_list(ctx, n)
+{
+}
+
+typed::union_set_list<>::union_set_list(const typed::union_set<> &el)
+  : isl::union_set_list(el)
+{
+}
+
+typed::union_set_list<>::union_set_list(const isl::ctx &ctx, const std::string &str)
+  : isl::union_set_list(ctx, str)
+{
+}
+
+typed::union_set_list<> typed::union_set_list<>::add(const typed::union_set<> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<>(res);
+}
+
+typed::union_set_list<> typed::union_set_list<>::add(const typed::basic_set<> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<>(res);
+}
+
+typed::union_set_list<> typed::union_set_list<>::add(const typed::point<> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<>(res);
+}
+
+typed::union_set_list<> typed::union_set_list<>::add(const typed::set<> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<>(res);
+}
+
+typed::union_set_list<> typed::union_set_list<>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::union_set_list::drop(first, n);
+  return typed::union_set_list<>(res);
+}
+
+void typed::union_set_list<>::foreach(const std::function<void(typed::union_set<>)> &fn) const
+{
+  auto lambda = [&] (isl::union_set arg0) {
+    return fn(typed::union_set<>(arg0));
+  };
+  return isl::union_set_list::foreach(lambda);
+}
+
+template <typename Domain>
+typed::union_set_list<Domain>::union_set_list(const isl::ctx &ctx, int n)
+  : isl::union_set_list(ctx, n)
+{
+}
+
+template <typename Domain>
+typed::union_set_list<Domain>::union_set_list(const typed::union_set<Domain> &el)
+  : isl::union_set_list(el)
+{
+}
+
+template <typename Domain>
+typed::union_set_list<Domain>::union_set_list(const isl::ctx &ctx, const std::string &str)
+  : isl::union_set_list(ctx, str)
+{
+}
+
+template <typename Domain>
+typed::union_set_list<Domain> typed::union_set_list<Domain>::add(const typed::union_set<Domain> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set_list<Domain> typed::union_set_list<Domain>::add(const typed::basic_set<Domain> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set_list<Domain> typed::union_set_list<Domain>::add(const typed::point<Domain> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set_list<Domain> typed::union_set_list<Domain>::add(const typed::set<Domain> &el) const
+{
+  auto res = isl::union_set_list::add(el);
+  return typed::union_set_list<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set<Domain> typed::union_set_list<Domain>::at(int index) const
+{
+  auto res = isl::union_set_list::at(index);
+  return typed::union_set<Domain>(res);
+}
+
+template <typename Domain>
+typed::union_set_list<Domain> typed::union_set_list<Domain>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::union_set_list::drop(first, n);
+  return typed::union_set_list<Domain>(res);
+}
+
+template <typename Domain>
+void typed::union_set_list<Domain>::foreach(const std::function<void(typed::union_set<Domain>)> &fn) const
+{
+  auto lambda = [&] (isl::union_set arg0) {
+    return fn(typed::union_set<Domain>(arg0));
+  };
+  return isl::union_set_list::foreach(lambda);
+}
+
+typed::val<Anonymous>::val(const isl::ctx &ctx, long i)
+  : isl::val(ctx, i)
+{
+}
+
+typed::val<Anonymous>::val(const isl::ctx &ctx, const std::string &str)
+  : isl::val(ctx, str)
+{
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::add(const typed::val<Anonymous> &v2) const
+{
+  auto res = isl::val::add(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::add(long v2) const
+{
+  auto res = isl::val::add(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::ceil() const
+{
+  auto res = isl::val::ceil();
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::floor() const
+{
+  auto res = isl::val::floor();
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::max(const typed::val<Anonymous> &v2) const
+{
+  auto res = isl::val::max(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::max(long v2) const
+{
+  auto res = isl::val::max(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::min(const typed::val<Anonymous> &v2) const
+{
+  auto res = isl::val::min(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::min(long v2) const
+{
+  auto res = isl::val::min(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::mod(const typed::val<Anonymous> &v2) const
+{
+  auto res = isl::val::mod(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::mod(long v2) const
+{
+  auto res = isl::val::mod(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::neg() const
+{
+  auto res = isl::val::neg();
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::sub(const typed::val<Anonymous> &v2) const
+{
+  auto res = isl::val::sub(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val<Anonymous>::sub(long v2) const
+{
+  auto res = isl::val::sub(v2);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val_list<Anonymous>::val_list(const isl::ctx &ctx, int n)
+  : isl::val_list(ctx, n)
+{
+}
+
+typed::val_list<Anonymous>::val_list(const typed::val<Anonymous> &el)
+  : isl::val_list(el)
+{
+}
+
+typed::val_list<Anonymous>::val_list(const isl::ctx &ctx, const std::string &str)
+  : isl::val_list(ctx, str)
+{
+}
+
+typed::val_list<Anonymous> typed::val_list<Anonymous>::add(const typed::val<Anonymous> &el) const
+{
+  auto res = isl::val_list::add(el);
+  return typed::val_list<Anonymous>(res);
+}
+
+typed::val_list<Anonymous> typed::val_list<Anonymous>::add(long el) const
+{
+  auto res = isl::val_list::add(el);
+  return typed::val_list<Anonymous>(res);
+}
+
+typed::val<Anonymous> typed::val_list<Anonymous>::at(int index) const
+{
+  auto res = isl::val_list::at(index);
+  return typed::val<Anonymous>(res);
+}
+
+typed::val_list<Anonymous> typed::val_list<Anonymous>::drop(unsigned int first, unsigned int n) const
+{
+  auto res = isl::val_list::drop(first, n);
+  return typed::val_list<Anonymous>(res);
+}
+
+void typed::val_list<Anonymous>::foreach(const std::function<void(typed::val<Anonymous>)> &fn) const
+{
+  auto lambda = [&] (isl::val arg0) {
+    return fn(typed::val<Anonymous>(arg0));
+  };
+  return isl::val_list::foreach(lambda);
+}
+
+} // namespace typed
+} // namespace isl
+
+#endif /* ISL_TYPED_CPP */
diff --git a/lib/External/isl/include/isl/union_map.h b/lib/External/isl/include/isl/union_map.h
index 4cae611..c630dc0 100644
--- a/lib/External/isl/include/isl/union_map.h
+++ b/lib/External/isl/include/isl/union_map.h
@@ -23,6 +23,8 @@
 __isl_constructor
 __isl_give isl_union_map *isl_union_map_from_basic_map(
 	__isl_take isl_basic_map *bmap);
+__isl_export
+__isl_give isl_union_map *isl_map_to_union_map(__isl_take isl_map *map);
 __isl_constructor
 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map);
 __isl_overload
@@ -276,6 +278,7 @@
 __isl_export
 isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
 	isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user);
+__isl_export
 __isl_give isl_map_list *isl_union_map_get_map_list(
 	__isl_keep isl_union_map *umap);
 __isl_export
@@ -291,6 +294,8 @@
 	__isl_take isl_space *space);
 __isl_export
 isl_bool isl_union_map_isa_map(__isl_keep isl_union_map *umap);
+__isl_export
+__isl_give isl_map *isl_union_map_as_map(__isl_take isl_union_map *umap);
 __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap);
 
 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap);
diff --git a/lib/External/isl/include/isl/union_set.h b/lib/External/isl/include/isl/union_set.h
index 8531da8..35ae11c 100644
--- a/lib/External/isl/include/isl/union_set.h
+++ b/lib/External/isl/include/isl/union_set.h
@@ -14,6 +14,8 @@
 __isl_constructor
 __isl_give isl_union_set *isl_union_set_from_basic_set(
 	__isl_take isl_basic_set *bset);
+__isl_export
+__isl_give isl_union_set *isl_set_to_union_set(__isl_take isl_set *set);
 __isl_constructor
 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set);
 __isl_overload
@@ -142,6 +144,8 @@
 	__isl_take isl_space *space);
 __isl_export
 isl_bool isl_union_set_isa_set(__isl_keep isl_union_set *uset);
+__isl_export
+__isl_give isl_set *isl_union_set_as_set(__isl_take isl_union_set *uset);
 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset);
 __isl_export
 isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
@@ -182,6 +186,7 @@
 void isl_union_set_dump(__isl_keep isl_union_set *uset);
 
 ISL_DECLARE_EXPORTED_LIST_FN(union_set)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(union_set)
 
 __isl_give isl_union_set *isl_union_set_list_union(
 	__isl_take isl_union_set_list *list);
diff --git a/lib/External/isl/include/isl/val.h b/lib/External/isl/include/isl/val.h
index f09252c..942207d 100644
--- a/lib/External/isl/include/isl/val.h
+++ b/lib/External/isl/include/isl/val.h
@@ -170,6 +170,7 @@
 __isl_give char *isl_multi_val_to_str(__isl_keep isl_multi_val *mv);
 
 ISL_DECLARE_EXPORTED_LIST_FN(val)
+ISL_DECLARE_EXPORTED_LIST_FN_READ(val)
 
 #if defined(__cplusplus)
 }
diff --git a/lib/External/isl/install-sh b/lib/External/isl/install-sh
index 8175c64..ec298b5 100755
--- a/lib/External/isl/install-sh
+++ b/lib/External/isl/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2018-03-11.20; # UTC
+scriptversion=2020-11-14.01; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@
 # Desired mode of installed file.
 mode=0755
 
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
 chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
@@ -99,18 +104,28 @@
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
+  -C            install only if different (preserve data modification time)
   -d            create directories instead of installing files.
   -g GROUP      $chgrpprog installed files to GROUP.
   -m MODE       $chmodprog installed files to MODE.
   -o USER       $chownprog installed files to USER.
+  -p            pass -p to $cpprog.
   -s            $stripprog installed files.
+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
   -t DIRECTORY  install into DIRECTORY.
   -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
   CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
   RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@
     -o) chowncmd="$chownprog $2"
         shift;;
 
+    -p) cpprog="$cpprog -p";;
+
     -s) stripcmd=$stripprog;;
 
+    -S) backupsuffix="$2"
+        shift;;
+
     -t)
         is_target_a_directory=always
         dst_arg=$2
@@ -255,6 +275,10 @@
     dstdir=$dst
     test -d "$dstdir"
     dstdir_status=$?
+    # Don't chown directories that already exist.
+    if test $dstdir_status = 0; then
+      chowncmd=""
+    fi
   else
 
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
         # With -d, create the new directory with the user-specified mode.
         # Otherwise, rely on $mkdir_umask.
         if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@
         fi
 
         posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
-            # here however when possible just to lower collision chance.
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	# The $RANDOM variable is not portable (e.g., dash).  Use it
+	# here however when possible just to lower collision chance.
+	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
 
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+	trap '
+	  ret=$?
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+	  exit $ret
+	' 0
 
-            # Because "mkdir -p" follows existing symlinks and we likely work
-            # directly in world-writeable /tmp, make sure that the '$tmpdir'
-            # directory is successfully created first before we actually test
-            # 'mkdir -p' feature.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Because "mkdir -p" follows existing symlinks and we likely work
+	# directly in world-writeable /tmp, make sure that the '$tmpdir'
+	# directory is successfully created first before we actually test
+	# 'mkdir -p'.
+	if (umask $mkdir_umask &&
+	    $mkdirprog $mkdir_mode "$tmpdir" &&
+	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+	then
+	  if test -z "$dir_arg" || {
+	       # Check for POSIX incompatibilities with -m.
+	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+	       # other-writable bit of parent directory when it shouldn't.
+	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+	       test_tmpdir="$tmpdir/a"
+	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+	       case $ls_ld_tmpdir in
+		 d????-?r-*) different_mode=700;;
+		 d????-?--*) different_mode=755;;
+		 *) false;;
+	       esac &&
+	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+	       }
+	     }
+	  then posix_mkdir=:
+	  fi
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+	else
+	  # Remove any dirs left behind by ancient mkdir implementations.
+	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+	fi
+	trap '' 0;;
     esac
 
     if
@@ -382,7 +387,7 @@
     then :
     else
 
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # mkdir does not conform to POSIX,
       # or it failed possibly due to a race condition.  Create the
       # directory the slow way, step by step, checking for races as we go.
 
@@ -411,7 +416,7 @@
           prefixes=
         else
           if $posix_mkdir; then
-            (umask=$mkdir_umask &&
+            (umask $mkdir_umask &&
              $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
             # Don't fail if two instances are running concurrently.
             test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+	 # Create $dsttmp read-write so that cp doesn't create it read-only,
+	 # which would cause strip to fail.
+	 if test -z "$doit"; then
+	   : >"$dsttmp" # No need to fork-exec 'touch'.
+	 else
+	   $doit touch "$dsttmp"
+	 fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -477,6 +493,13 @@
     then
       rm -f "$dsttmp"
     else
+      # If $backupsuffix is set, and the file being installed
+      # already exists, attempt a backup.  Don't worry if it fails,
+      # e.g., if mv doesn't support -f.
+      if test -n "$backupsuffix" && test -f "$dst"; then
+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+      fi
+
       # Rename the file to the real destination.
       $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
 
@@ -491,9 +514,9 @@
         # file should still install successfully.
         {
           test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          $doit $rmcmd "$dst" 2>/dev/null ||
           { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
           } ||
           { echo "$0: cannot unlink or rename $dst" >&2
             (exit 1); exit 1
diff --git a/lib/External/isl/interface/Makefile.am b/lib/External/isl/interface/Makefile.am
index 58bd0e6..702f9a4 100644
--- a/lib/External/isl/interface/Makefile.am
+++ b/lib/External/isl/interface/Makefile.am
@@ -17,6 +17,11 @@
 	cpp.cc \
 	cpp_conversion.h \
 	cpp_conversion.cc \
+	plain_cpp.h \
+	plain_cpp.cc \
+	set_lang_defaults_arg4.h \
+	template_cpp.h \
+	template_cpp.cc \
 	extract_interface.h \
 	extract_interface.cc
 extract_interface_LDFLAGS = $(CLANG_LDFLAGS) $(CLANG_RFLAG)
diff --git a/lib/External/isl/interface/Makefile.in b/lib/External/isl/interface/Makefile.in
index 4b4ce99..93c6371 100644
--- a/lib/External/isl/interface/Makefile.in
+++ b/lib/External/isl/interface/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -91,7 +91,10 @@
 noinst_PROGRAMS = extract_interface$(EXEEXT)
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_detect_clang.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_cxx_compile_stdcxx.m4 \
+	$(top_srcdir)/../m4/ax_cxx_compile_stdcxx_11.m4 \
+	$(top_srcdir)/../m4/ax_cxx_compile_stdcxx_11_no_override.m4 \
+	$(top_srcdir)/../m4/ax_detect_clang.m4 \
 	$(top_srcdir)/../m4/ax_prog_cc_for_build.m4 \
 	$(top_srcdir)/../m4/ax_prog_cxx_for_build.m4 \
 	$(top_srcdir)/../m4/libtool.m4 \
@@ -114,6 +117,8 @@
 	extract_interface-python.$(OBJEXT) \
 	extract_interface-cpp.$(OBJEXT) \
 	extract_interface-cpp_conversion.$(OBJEXT) \
+	extract_interface-plain_cpp.$(OBJEXT) \
+	extract_interface-template_cpp.$(OBJEXT) \
 	extract_interface-extract_interface.$(OBJEXT)
 extract_interface_OBJECTS = $(am_extract_interface_OBJECTS)
 am__DEPENDENCIES_1 =
@@ -146,7 +151,9 @@
 	./$(DEPDIR)/extract_interface-cpp_conversion.Po \
 	./$(DEPDIR)/extract_interface-extract_interface.Po \
 	./$(DEPDIR)/extract_interface-generator.Po \
-	./$(DEPDIR)/extract_interface-python.Po
+	./$(DEPDIR)/extract_interface-plain_cpp.Po \
+	./$(DEPDIR)/extract_interface-python.Po \
+	./$(DEPDIR)/extract_interface-template_cpp.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -191,8 +198,8 @@
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-	$(LISP)isl_config.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+	isl_config.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -229,6 +236,8 @@
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -278,6 +287,7 @@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
+HAVE_CXX11 = @HAVE_CXX11@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -365,7 +375,6 @@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -390,6 +399,11 @@
 	cpp.cc \
 	cpp_conversion.h \
 	cpp_conversion.cc \
+	plain_cpp.h \
+	plain_cpp.cc \
+	set_lang_defaults_arg4.h \
+	template_cpp.h \
+	template_cpp.cc \
 	extract_interface.h \
 	extract_interface.cc
 
@@ -472,7 +486,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-cpp_conversion.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-extract_interface.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-generator.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-plain_cpp.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-python.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_interface-template_cpp.Po@am__quote@ # am--include-marker
 
 $(am__depfiles_remade):
 	@$(MKDIR_P) $(@D)
@@ -557,6 +573,34 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-cpp_conversion.obj `if test -f 'cpp_conversion.cc'; then $(CYGPATH_W) 'cpp_conversion.cc'; else $(CYGPATH_W) '$(srcdir)/cpp_conversion.cc'; fi`
 
+extract_interface-plain_cpp.o: plain_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-plain_cpp.o -MD -MP -MF $(DEPDIR)/extract_interface-plain_cpp.Tpo -c -o extract_interface-plain_cpp.o `test -f 'plain_cpp.cc' || echo '$(srcdir)/'`plain_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-plain_cpp.o `test -f 'plain_cpp.cc' || echo '$(srcdir)/'`plain_cpp.cc
+
+extract_interface-plain_cpp.obj: plain_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-plain_cpp.obj -MD -MP -MF $(DEPDIR)/extract_interface-plain_cpp.Tpo -c -o extract_interface-plain_cpp.obj `if test -f 'plain_cpp.cc'; then $(CYGPATH_W) 'plain_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/plain_cpp.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-plain_cpp.Tpo $(DEPDIR)/extract_interface-plain_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='plain_cpp.cc' object='extract_interface-plain_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-plain_cpp.obj `if test -f 'plain_cpp.cc'; then $(CYGPATH_W) 'plain_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/plain_cpp.cc'; fi`
+
+extract_interface-template_cpp.o: template_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-template_cpp.o -MD -MP -MF $(DEPDIR)/extract_interface-template_cpp.Tpo -c -o extract_interface-template_cpp.o `test -f 'template_cpp.cc' || echo '$(srcdir)/'`template_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-template_cpp.o `test -f 'template_cpp.cc' || echo '$(srcdir)/'`template_cpp.cc
+
+extract_interface-template_cpp.obj: template_cpp.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-template_cpp.obj -MD -MP -MF $(DEPDIR)/extract_interface-template_cpp.Tpo -c -o extract_interface-template_cpp.obj `if test -f 'template_cpp.cc'; then $(CYGPATH_W) 'template_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/template_cpp.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-template_cpp.Tpo $(DEPDIR)/extract_interface-template_cpp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='template_cpp.cc' object='extract_interface-template_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -c -o extract_interface-template_cpp.obj `if test -f 'template_cpp.cc'; then $(CYGPATH_W) 'template_cpp.cc'; else $(CYGPATH_W) '$(srcdir)/template_cpp.cc'; fi`
+
 extract_interface-extract_interface.o: extract_interface.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(extract_interface_CPPFLAGS) $(CPPFLAGS) $(extract_interface_CXXFLAGS) $(CXXFLAGS) -MT extract_interface-extract_interface.o -MD -MP -MF $(DEPDIR)/extract_interface-extract_interface.Tpo -c -o extract_interface-extract_interface.o `test -f 'extract_interface.cc' || echo '$(srcdir)/'`extract_interface.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/extract_interface-extract_interface.Tpo $(DEPDIR)/extract_interface-extract_interface.Po
@@ -697,6 +741,10 @@
 	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__post_remove_distdir)
 
+dist-zstd: distdir
+	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+	$(am__post_remove_distdir)
+
 dist-tarZ: distdir
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
@@ -739,6 +787,8 @@
 	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
+	*.tar.zst*) \
+	  zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
@@ -754,7 +804,7 @@
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
 	    --srcdir=../.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
-	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
 	  && $(MAKE) $(AM_MAKEFLAGS) install \
 	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -850,7 +900,9 @@
 	-rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po
 	-rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po
 	-rm -f ./$(DEPDIR)/extract_interface-generator.Po
+	-rm -f ./$(DEPDIR)/extract_interface-plain_cpp.Po
 	-rm -f ./$(DEPDIR)/extract_interface-python.Po
+	-rm -f ./$(DEPDIR)/extract_interface-template_cpp.Po
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
@@ -902,7 +954,9 @@
 	-rm -f ./$(DEPDIR)/extract_interface-cpp_conversion.Po
 	-rm -f ./$(DEPDIR)/extract_interface-extract_interface.Po
 	-rm -f ./$(DEPDIR)/extract_interface-generator.Po
+	-rm -f ./$(DEPDIR)/extract_interface-plain_cpp.Po
 	-rm -f ./$(DEPDIR)/extract_interface-python.Po
+	-rm -f ./$(DEPDIR)/extract_interface-template_cpp.Po
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -927,18 +981,18 @@
 	check-am clean clean-cscope clean-generic clean-libtool \
 	clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \
 	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-	dist-xz dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-libtool \
-	distclean-tags distcleancheck distdir distuninstallcheck dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am
+	dist-xz dist-zip dist-zstd distcheck distclean \
+	distclean-compile distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am
 
 .PRECIOUS: Makefile
 
diff --git a/lib/External/isl/interface/aclocal.m4 b/lib/External/isl/interface/aclocal.m4
index e3797c0..f7f49e4 100644
--- a/lib/External/isl/interface/aclocal.m4
+++ b/lib/External/isl/interface/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,45 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+#   AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+#   been defined and thus are available for use.  This avoids random issues
+#   where a macro isn't expanded.  Instead the configure script emits a
+#   non-fatal:
+#
+#     ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+#   It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+#   Here's an example:
+#
+#     AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+#   Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+  m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
+
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -35,7 +73,7 @@
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.3], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +89,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.3])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +148,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +179,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,7 +370,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -371,7 +409,9 @@
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -398,7 +438,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -595,7 +635,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -616,7 +656,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -637,7 +677,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -680,7 +720,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -701,12 +741,7 @@
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -719,7 +754,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -748,7 +783,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -795,7 +830,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -814,7 +849,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -895,7 +930,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -955,7 +990,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -983,7 +1018,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1002,7 +1037,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1133,6 +1168,9 @@
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
+m4_include([../m4/ax_cxx_compile_stdcxx.m4])
+m4_include([../m4/ax_cxx_compile_stdcxx_11.m4])
+m4_include([../m4/ax_cxx_compile_stdcxx_11_no_override.m4])
 m4_include([../m4/ax_detect_clang.m4])
 m4_include([../m4/ax_prog_cc_for_build.m4])
 m4_include([../m4/ax_prog_cxx_for_build.m4])
diff --git a/lib/External/isl/interface/compile b/lib/External/isl/interface/compile
old mode 100644
new mode 100755
index 99e5052..23fcba0
--- a/lib/External/isl/interface/compile
+++ b/lib/External/isl/interface/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
 	  MINGW*)
 	    file_conv=mingw
 	    ;;
-	  CYGWIN*)
+	  CYGWIN* | MSYS*)
 	    file_conv=cygwin
 	    ;;
 	  *)
@@ -67,7 +67,7 @@
 	mingw/*)
 	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
 	  ;;
-	cygwin/*)
+	cygwin/* | msys/*)
 	  file=`cygpath -m "$file" || echo "$file"`
 	  ;;
 	wine/*)
diff --git a/lib/External/isl/interface/config.guess b/lib/External/isl/interface/config.guess
old mode 100644
new mode 100755
index f50dcdb..0fc11ed
--- a/lib/External/isl/interface/config.guess
+++ b/lib/External/isl/interface/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2018-02-24'
+timestamp='2020-11-07'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 # Please send patches to <config-patches@gnu.org>.
 
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION]
@@ -50,7 +50,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,8 +84,6 @@
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
-
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
 # temporary files to be created and, as you can see below, it is a
@@ -96,41 +94,47 @@
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > "$dummy.c" ;
-	for c in cc gcc c89 c99 ; do
-	  if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
-	     CC_FOR_BUILD="$c"; break ;
-	  fi ;
-	done ;
-	if test x"$CC_FOR_BUILD" = x ; then
-	  CC_FOR_BUILD=no_compiler_found ;
-	fi
-	;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+    # prevent multiple calls if $tmp is already set
+    test "$tmp" && return 0
+    : "${TMPDIR=/tmp}"
+    # shellcheck disable=SC2039
+    { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
+	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+    dummy=$tmp/dummy
+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+	,,)    echo "int x;" > "$dummy.c"
+	       for driver in cc gcc c89 c99 ; do
+		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+		       CC_FOR_BUILD="$driver"
+		       break
+		   fi
+	       done
+	       if test x"$CC_FOR_BUILD" = x ; then
+		   CC_FOR_BUILD=no_compiler_found
+	       fi
+	       ;;
+	,,*)   CC_FOR_BUILD=$CC ;;
+	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+    esac
+}
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
+UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
+UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
+UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
 
 case "$UNAME_SYSTEM" in
 Linux|GNU|GNU/*)
@@ -138,7 +142,7 @@
 	# We could probably try harder.
 	LIBC=gnu
 
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	cat <<-EOF > "$dummy.c"
 	#include <features.h>
 	#if defined(__UCLIBC__)
@@ -146,17 +150,15 @@
 	#elif defined(__dietlibc__)
 	LIBC=dietlibc
 	#else
+	#include <stdarg.h>
+	#ifdef __DEFINED_va_list
+	LIBC=musl
+	#else
 	LIBC=gnu
 	#endif
+	#endif
 	EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
-
-	# If ldd exists, use it to detect musl libc.
-	if command -v ldd >/dev/null && \
-		ldd --version 2>&1 | grep -q ^musl
-	then
-	    LIBC=musl
-	fi
+	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
 	;;
 esac
 
@@ -175,19 +177,20 @@
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
 	    "/sbin/$sysctl" 2>/dev/null || \
 	    "/usr/sbin/$sysctl" 2>/dev/null || \
-	    echo unknown)`
+	    echo unknown))
 	case "$UNAME_MACHINE_ARCH" in
+	    aarch64eb) machine=aarch64_be-unknown ;;
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
 	    earmv*)
-		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+		arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
+		endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
 		machine="${arch}${endian}"-unknown
 		;;
 	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
@@ -199,7 +202,7 @@
 		os=netbsdelf
 		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
 		then
@@ -218,7 +221,7 @@
 	case "$UNAME_MACHINE_ARCH" in
 	    earm*)
 		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+		abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
 		;;
 	esac
 	# The OS release
@@ -231,24 +234,24 @@
 		release='-gnu'
 		;;
 	    *)
-		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "$machine-${os}${release}${abi}"
+	echo "$machine-${os}${release}${abi-}"
 	exit ;;
     *:Bitrig:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
 	exit ;;
     *:OpenBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
 	exit ;;
     *:LibertyBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
 	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
 	exit ;;
     *:MidnightBSD:*:*)
@@ -260,6 +263,9 @@
     *:SolidBSD:*:*)
 	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
 	exit ;;
+    *:OS108:*:*)
+	echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
+	exit ;;
     macppc:MirBSD:*:*)
 	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
 	exit ;;
@@ -269,26 +275,29 @@
     *:Sortix:*:*)
 	echo "$UNAME_MACHINE"-unknown-sortix
 	exit ;;
+    *:Twizzler:*:*)
+	echo "$UNAME_MACHINE"-unknown-twizzler
+	exit ;;
     *:Redox:*:*)
 	echo "$UNAME_MACHINE"-unknown-redox
 	exit ;;
     mips:OSF1:*.*)
-        echo mips-dec-osf1
-        exit ;;
+	echo mips-dec-osf1
+	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
 		;;
 	*5.*)
-		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
 		;;
 	esac
 	# According to Compaq, /usr/sbin/psrinfo has been available on
 	# OSF/1 and Tru64 systems produced since 1995.  I hope that
 	# covers most systems running today.  This code pipes the CPU
 	# types through head -n 1, so we only detect the type of CPU 0.
-	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1)
 	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
 		UNAME_MACHINE=alpha ;;
@@ -326,7 +335,7 @@
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
+	echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"
 	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 	exitcode=$?
 	trap '' 0
@@ -360,7 +369,7 @@
 	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+	if test "$( (/bin/universe) 2>/dev/null)" = att ; then
 		echo pyramid-pyramid-sysv3
 	else
 		echo pyramid-pyramid-bsd
@@ -373,28 +382,28 @@
 	echo sparc-icl-nx6
 	exit ;;
     DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
-	case `/usr/bin/uname -p` in
+	case $(/usr/bin/uname -p) in
 	    sparc) echo sparc-icl-nx7; exit ;;
 	esac ;;
     s390x:SunOS:*:*)
-	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
 	exit ;;
     sun4H:SunOS:5.*:*)
-	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+	echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
 	exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
 	echo i386-pc-auroraux"$UNAME_RELEASE"
 	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
 		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
@@ -402,30 +411,30 @@
 		SUN_ARCH=x86_64
 	    fi
 	fi
-	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
-	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     sun4*:SunOS:*:*)
-	case "`/usr/bin/arch -k`" in
+	case "$(/usr/bin/arch -k)" in
 	    Series*|S4*)
-		UNAME_RELEASE=`uname -v`
+		UNAME_RELEASE=$(uname -v)
 		;;
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
-	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
+	echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
 	exit ;;
     sun3*:SunOS:*:*)
 	echo m68k-sun-sunos"$UNAME_RELEASE"
 	exit ;;
     sun*:*:4.2BSD:*)
-	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
 	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
-	case "`/bin/arch`" in
+	case "$(/bin/arch)" in
 	    sun3)
 		echo m68k-sun-sunos"$UNAME_RELEASE"
 		;;
@@ -482,7 +491,7 @@
 	echo clipper-intergraph-clix"$UNAME_RELEASE"
 	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -505,8 +514,8 @@
 	}
 EOF
 	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
-	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
+	  dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
+	  SYSTEM_NAME=$("$dummy" "$dummyarg") &&
 	    { echo "$SYSTEM_NAME"; exit; }
 	echo mips-mips-riscos"$UNAME_RELEASE"
 	exit ;;
@@ -533,11 +542,11 @@
 	exit ;;
     AViiON:dgux:*:*)
 	# DG/UX returns AViiON for all architectures
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+	UNAME_PROCESSOR=$(/usr/bin/uname -p)
+	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
 	then
-	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
-	       [ "$TARGET_BINARY_INTERFACE"x = x ]
+	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+	       test "$TARGET_BINARY_INTERFACE"x = x
 	    then
 		echo m88k-dg-dgux"$UNAME_RELEASE"
 	    else
@@ -561,17 +570,17 @@
 	echo m68k-tektronix-bsd
 	exit ;;
     *:IRIX*:*:*)
-	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
+	echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
 	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
 	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+	exit ;;               # Note that: echo "'$(uname -s)'" gives 'AIX '
     i*86:AIX:*:*)
 	echo i386-ibm-aix
 	exit ;;
     ia64:AIX:*:*)
-	if [ -x /usr/bin/oslevel ] ; then
-		IBM_REV=`/usr/bin/oslevel`
+	if test -x /usr/bin/oslevel ; then
+		IBM_REV=$(/usr/bin/oslevel)
 	else
 		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
@@ -579,7 +588,7 @@
 	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 
@@ -591,7 +600,7 @@
 			exit(0);
 			}
 EOF
-		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
+		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
 		then
 			echo "$SYSTEM_NAME"
 		else
@@ -604,15 +613,15 @@
 	fi
 	exit ;;
     *:AIX:*:[4567])
-	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')
 	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if test -x /usr/bin/lslpp ; then
+		IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
 	else
 		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
 	fi
@@ -640,14 +649,14 @@
 	echo m68k-hp-bsd4.4
 	exit ;;
     9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
 	case "$UNAME_MACHINE" in
 	    9000/31?)            HP_ARCH=m68000 ;;
 	    9000/[34]??)         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-		if [ -x /usr/bin/getconf ]; then
-		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		if test -x /usr/bin/getconf; then
+		    sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
+		    sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
 		    case "$sc_cpu_version" in
 		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
 		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
@@ -659,8 +668,8 @@
 			esac ;;
 		    esac
 		fi
-		if [ "$HP_ARCH" = "" ]; then
-		    eval "$set_cc_for_build"
+		if test "$HP_ARCH" = ""; then
+		    set_cc_for_build
 		    sed 's/^		//' << EOF > "$dummy.c"
 
 		#define _HPUX_SOURCE
@@ -694,13 +703,13 @@
 		    exit (0);
 		}
 EOF
-		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
+		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ "$HP_ARCH" = hppa2.0w ]
+	if test "$HP_ARCH" = hppa2.0w
 	then
-	    eval "$set_cc_for_build"
+	    set_cc_for_build
 
 	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
 	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -722,11 +731,11 @@
 	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
 	exit ;;
     ia64:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
 	echo ia64-hp-hpux"$HPUX_REV"
 	exit ;;
     3050*:HI-UX:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 	#include <unistd.h>
 	int
@@ -752,7 +761,7 @@
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
 		{ echo "$SYSTEM_NAME"; exit; }
 	echo unknown-hitachi-hiuxwe2
 	exit ;;
@@ -772,7 +781,7 @@
 	echo hppa1.0-hp-osf
 	exit ;;
     i*86:OSF1:*:*)
-	if [ -x /usr/sbin/sysversion ] ; then
+	if test -x /usr/sbin/sysversion ; then
 	    echo "$UNAME_MACHINE"-unknown-osf1mk
 	else
 	    echo "$UNAME_MACHINE"-unknown-osf1
@@ -821,14 +830,14 @@
 	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
+	FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
+	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+	FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
 	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
-	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
+	FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
 	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -840,15 +849,26 @@
     *:BSD/OS:*:*)
 	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
 	exit ;;
+    arm:FreeBSD:*:*)
+	UNAME_PROCESSOR=$(uname -p)
+	set_cc_for_build
+	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_PCS_VFP
+	then
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
+	else
+	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
+	fi
+	exit ;;
     *:FreeBSD:*:*)
-	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	UNAME_PROCESSOR=$(/usr/bin/uname -p)
 	case "$UNAME_PROCESSOR" in
 	    amd64)
 		UNAME_PROCESSOR=x86_64 ;;
 	    i386)
 		UNAME_PROCESSOR=i586 ;;
 	esac
-	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
 	exit ;;
     i*:CYGWIN*:*)
 	echo "$UNAME_MACHINE"-pc-cygwin
@@ -881,21 +901,21 @@
 	echo "$UNAME_MACHINE"-pc-uwin
 	exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
+	echo x86_64-pc-cygwin
 	exit ;;
     prep*:SunOS:5.*:*)
-	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+	echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
 	exit ;;
     *:GNU:*:*)
 	# the GNU system
-	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
+	echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
 	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
+	echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
 	exit ;;
-    i*86:Minix:*:*)
-	echo "$UNAME_MACHINE"-pc-minix
+    *:Minix:*:*)
+	echo "$UNAME_MACHINE"-unknown-minix
 	exit ;;
     aarch64:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -905,7 +925,7 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
 	  EV56)  UNAME_MACHINE=alphaev56 ;;
 	  PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -922,7 +942,7 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     arm*:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 	    | grep -q __ARM_EABI__
 	then
@@ -971,23 +991,51 @@
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
 	exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
+	IS_GLIBC=0
+	test x"${LIBC}" = xgnu && IS_GLIBC=1
 	sed 's/^	//' << EOF > "$dummy.c"
 	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
+	#undef mips
+	#undef mipsel
+	#undef mips64
+	#undef mips64el
+	#if ${IS_GLIBC} && defined(_ABI64)
+	LIBCABI=gnuabi64
+	#else
+	#if ${IS_GLIBC} && defined(_ABIN32)
+	LIBCABI=gnuabin32
+	#else
+	LIBCABI=${LIBC}
+	#endif
+	#endif
+
+	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa64r6
+	#else
+	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa32r6
+	#else
+	#if defined(__mips64)
+	CPU=mips64
+	#else
+	CPU=mips
+	#endif
+	#endif
+	#endif
+
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
+	MIPS_ENDIAN=el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
+	MIPS_ENDIAN=
 	#else
-	CPU=
+	MIPS_ENDIAN=
 	#endif
 	#endif
 EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
-	test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
+	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
+	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
 	;;
     mips64el:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1006,7 +1054,7 @@
 	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
-	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
 	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
 	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
 	  *)    echo hppa-unknown-linux-"$LIBC" ;;
@@ -1046,11 +1094,17 @@
 	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
 	exit ;;
     x86_64:Linux:*:*)
-	if objdump -f /bin/sh | grep -q elf32-x86-64; then
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32
-	else
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+	set_cc_for_build
+	LIBCABI=$LIBC
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_X32 >/dev/null
+	    then
+		LIBCABI="$LIBC"x32
+	    fi
 	fi
+	echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"
 	exit ;;
     xtensa*:Linux:*:*)
 	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1090,7 +1144,7 @@
 	echo "$UNAME_MACHINE"-pc-msdosdjgpp
 	exit ;;
     i*86:*:4.*:*)
-	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
+	UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
 		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
 	else
@@ -1099,19 +1153,19 @@
 	exit ;;
     i*86:*:5:[678]*)
 	# UnixWare 7.x, OpenUNIX and OpenServer 6.
-	case `/bin/uname -X | grep "^Machine"` in
+	case $(/bin/uname -X | grep "^Machine") in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
-	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
+	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
 	exit ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
-		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
 		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
 		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
 		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 			&& UNAME_MACHINE=i586
@@ -1161,7 +1215,7 @@
     3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
-	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	&& OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1172,7 +1226,7 @@
     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
 	OS_REL='.3'
 	test -r /etc/.relid \
-	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	    && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@@ -1205,7 +1259,7 @@
 	exit ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
-		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		UNAME_MACHINE=$( (uname -p) 2>/dev/null)
 		echo "$UNAME_MACHINE"-sni-sysv4
 	else
 		echo ns32k-sni-sysv
@@ -1239,7 +1293,7 @@
 	echo mips-sony-newsos6
 	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-	if [ -d /usr/nec ]; then
+	if test -d /usr/nec; then
 		echo mips-nec-sysv"$UNAME_RELEASE"
 	else
 		echo mips-unknown-sysv"$UNAME_RELEASE"
@@ -1287,44 +1341,48 @@
     *:Rhapsody:*:*)
 	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
 	exit ;;
+    arm64:Darwin:*:*)
+	echo aarch64-apple-darwin"$UNAME_RELEASE"
+	exit ;;
     *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	eval "$set_cc_for_build"
-	if test "$UNAME_PROCESSOR" = unknown ; then
-	    UNAME_PROCESSOR=powerpc
+	UNAME_PROCESSOR=$(uname -p)
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	if command -v xcode-select > /dev/null 2> /dev/null && \
+		! xcode-select --print-path > /dev/null 2> /dev/null ; then
+	    # Avoid executing cc if there is no toolchain installed as
+	    # cc will be a stub that puts up a graphical alert
+	    # prompting the user to install developer tools.
+	    CC_FOR_BUILD=no_compiler_found
+	else
+	    set_cc_for_build
 	fi
-	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
-		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
-		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_PPC >/dev/null
-		then
-		    UNAME_PROCESSOR=powerpc
-		fi
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
+	    fi
+	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_PPC >/dev/null
+	    then
+		UNAME_PROCESSOR=powerpc
 	    fi
 	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
+	    # uname -m returns i386 or x86_64
+	    UNAME_PROCESSOR=$UNAME_MACHINE
 	fi
 	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
 	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
-	UNAME_PROCESSOR=`uname -p`
+	UNAME_PROCESSOR=$(uname -p)
 	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
@@ -1362,6 +1420,7 @@
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
+	# shellcheck disable=SC2154
 	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
 	else
@@ -1391,10 +1450,10 @@
 	echo mips-sei-seiux"$UNAME_RELEASE"
 	exit ;;
     *:DragonFly:*:*)
-	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
+	echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
 	exit ;;
     *:*VMS:*:*)
-	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	UNAME_MACHINE=$( (uname -p) 2>/dev/null)
 	case "$UNAME_MACHINE" in
 	    A*) echo alpha-dec-vms ; exit ;;
 	    I*) echo ia64-dec-vms ; exit ;;
@@ -1404,7 +1463,7 @@
 	echo i386-pc-xenix
 	exit ;;
     i*86:skyos:*:*)
-	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
+	echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
 	exit ;;
     i*86:rdos:*:*)
 	echo "$UNAME_MACHINE"-pc-rdos
@@ -1418,8 +1477,148 @@
     amd64:Isilon\ OneFS:*:*)
 	echo x86_64-unknown-onefs
 	exit ;;
+    *:Unleashed:*:*)
+	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
+	exit ;;
 esac
 
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+  "4"
+#else
+  ""
+#endif
+  ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+  struct utsname un;
+
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname un;
+  uname (&un);
+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname *un;
+  uname (&un);
+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
 echo "$0: unable to guess system type" >&2
 
 case "$UNAME_MACHINE:$UNAME_SYSTEM" in
@@ -1442,6 +1641,12 @@
   https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
   https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+EOF
+
+year=$(echo $timestamp | sed 's,-.*,,')
+# shellcheck disable=SC2003
+if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
+   cat >&2 <<EOF
 
 If $0 has already been updated, send the following data and any
 information you think might be pertinent to config-patches@gnu.org to
@@ -1449,31 +1654,32 @@
 
 config.guess timestamp = $timestamp
 
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
+uname -m = $( (uname -m) 2>/dev/null || echo unknown)
+uname -r = $( (uname -r) 2>/dev/null || echo unknown)
+uname -s = $( (uname -s) 2>/dev/null || echo unknown)
+uname -v = $( (uname -v) 2>/dev/null || echo unknown)
 
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
+/bin/uname -X     = $( (/bin/uname -X) 2>/dev/null)
 
-hostinfo               = `(hostinfo) 2>/dev/null`
-/bin/universe          = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch              = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+hostinfo               = $( (hostinfo) 2>/dev/null)
+/bin/universe          = $( (/bin/universe) 2>/dev/null)
+/usr/bin/arch -k       = $( (/usr/bin/arch -k) 2>/dev/null)
+/bin/arch              = $( (/bin/arch) 2>/dev/null)
+/usr/bin/oslevel       = $( (/usr/bin/oslevel) 2>/dev/null)
+/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
 
 UNAME_MACHINE = "$UNAME_MACHINE"
 UNAME_RELEASE = "$UNAME_RELEASE"
 UNAME_SYSTEM  = "$UNAME_SYSTEM"
 UNAME_VERSION = "$UNAME_VERSION"
 EOF
+fi
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/lib/External/isl/interface/config.sub b/lib/External/isl/interface/config.sub
old mode 100644
new mode 100755
index 1d8e98b..c874b7a
--- a/lib/External/isl/interface/config.sub
+++ b/lib/External/isl/interface/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2020 Free Software Foundation, Inc.
 
-timestamp='2018-02-22'
+timestamp='2020-11-07'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@
 #	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 # It is wrong to echo any other type of specification.
 
-me=`echo "$0" | sed -e 's,.*/,,'`
+me=$(echo "$0" | sed -e 's,.*/,,')
 
 usage="\
 Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@@ -67,7 +67,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2020 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -89,7 +89,7 @@
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -110,1223 +110,1167 @@
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		basic_os=$field3-$field4
 		;;
-	-bluegene*)
-		os=-cnk
+	*-*-*)
+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+		# parts
+		maybe_os=$field2-$field3
+		case $maybe_os in
+			nto-qnx* | linux-* | uclinux-uclibc* \
+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+			| storm-chaos* | os2-emx* | rtmk-nova*)
+				basic_machine=$field1
+				basic_os=$maybe_os
+				;;
+			android-linux)
+				basic_machine=$field1-unknown
+				basic_os=linux-android
+				;;
+			*)
+				basic_machine=$field1-$field2
+				basic_os=$field3
+				;;
+		esac
 		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
+	*-*)
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						basic_os=
+						;;
+					*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+				esac
+			;;
+		esac
 		;;
-	-scout)
-		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
-		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	*)
+		# Convert single-component short-hands not valid as part of
+		# multi-component configurations.
+		case $field1 in
+			386bsd)
+				basic_machine=i386-pc
+				basic_os=bsd
+				;;
+			a29khif)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			adobe68k)
+				basic_machine=m68010-adobe
+				basic_os=scout
+				;;
+			alliant)
+				basic_machine=fx80-alliant
+				basic_os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				basic_os=
+				;;
+			am29k)
+				basic_machine=a29k-none
+				basic_os=bsd
+				;;
+			amdahl)
+				basic_machine=580-amdahl
+				basic_os=sysv
+				;;
+			amiga)
+				basic_machine=m68k-unknown
+				basic_os=
+				;;
+			amigaos | amigados)
+				basic_machine=m68k-unknown
+				basic_os=amigaos
+				;;
+			amigaunix | amix)
+				basic_machine=m68k-unknown
+				basic_os=sysv4
+				;;
+			apollo68)
+				basic_machine=m68k-apollo
+				basic_os=sysv
+				;;
+			apollo68bsd)
+				basic_machine=m68k-apollo
+				basic_os=bsd
+				;;
+			aros)
+				basic_machine=i386-pc
+				basic_os=aros
+				;;
+			aux)
+				basic_machine=m68k-apple
+				basic_os=aux
+				;;
+			balance)
+				basic_machine=ns32k-sequent
+				basic_os=dynix
+				;;
+			blackfin)
+				basic_machine=bfin-unknown
+				basic_os=linux
+				;;
+			cegcc)
+				basic_machine=arm-unknown
+				basic_os=cegcc
+				;;
+			convex-c1)
+				basic_machine=c1-convex
+				basic_os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				basic_os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				basic_os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				basic_os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				basic_os=bsd
+				;;
+			cray)
+				basic_machine=j90-cray
+				basic_os=unicos
+				;;
+			crds | unos)
+				basic_machine=m68k-crds
+				basic_os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				basic_os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			delta88)
+				basic_machine=m88k-motorola
+				basic_os=sysv3
+				;;
+			dicos)
+				basic_machine=i686-pc
+				basic_os=dicos
+				;;
+			djgpp)
+				basic_machine=i586-pc
+				basic_os=msdosdjgpp
+				;;
+			ebmon29k)
+				basic_machine=a29k-amd
+				basic_os=ebmon
+				;;
+			es1800 | OSE68k | ose68k | ose | OSE)
+				basic_machine=m68k-ericsson
+				basic_os=ose
+				;;
+			gmicro)
+				basic_machine=tron-gmicro
+				basic_os=sysv
+				;;
+			go32)
+				basic_machine=i386-pc
+				basic_os=go32
+				;;
+			h8300hms)
+				basic_machine=h8300-hitachi
+				basic_os=hms
+				;;
+			h8300xray)
+				basic_machine=h8300-hitachi
+				basic_os=xray
+				;;
+			h8500hms)
+				basic_machine=h8500-hitachi
+				basic_os=hms
+				;;
+			harris)
+				basic_machine=m88k-harris
+				basic_os=sysv3
+				;;
+			hp300 | hp300hpux)
+				basic_machine=m68k-hp
+				basic_os=hpux
+				;;
+			hp300bsd)
+				basic_machine=m68k-hp
+				basic_os=bsd
+				;;
+			hppaosf)
+				basic_machine=hppa1.1-hp
+				basic_os=osf
+				;;
+			hppro)
+				basic_machine=hppa1.1-hp
+				basic_os=proelf
+				;;
+			i386mach)
+				basic_machine=i386-mach
+				basic_os=mach
+				;;
+			isi68 | isi)
+				basic_machine=m68k-isi
+				basic_os=sysv
+				;;
+			m68knommu)
+				basic_machine=m68k-unknown
+				basic_os=linux
+				;;
+			magnum | m3230)
+				basic_machine=mips-mips
+				basic_os=sysv
+				;;
+			merlin)
+				basic_machine=ns32k-utek
+				basic_os=sysv
+				;;
+			mingw64)
+				basic_machine=x86_64-pc
+				basic_os=mingw64
+				;;
+			mingw32)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			mingw32ce)
+				basic_machine=arm-unknown
+				basic_os=mingw32ce
+				;;
+			monitor)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			morphos)
+				basic_machine=powerpc-unknown
+				basic_os=morphos
+				;;
+			moxiebox)
+				basic_machine=moxie-unknown
+				basic_os=moxiebox
+				;;
+			msdos)
+				basic_machine=i386-pc
+				basic_os=msdos
+				;;
+			msys)
+				basic_machine=i686-pc
+				basic_os=msys
+				;;
+			mvs)
+				basic_machine=i370-ibm
+				basic_os=mvs
+				;;
+			nacl)
+				basic_machine=le32-unknown
+				basic_os=nacl
+				;;
+			ncr3000)
+				basic_machine=i486-ncr
+				basic_os=sysv4
+				;;
+			netbsd386)
+				basic_machine=i386-pc
+				basic_os=netbsd
+				;;
+			netwinder)
+				basic_machine=armv4l-rebel
+				basic_os=linux
+				;;
+			news | news700 | news800 | news900)
+				basic_machine=m68k-sony
+				basic_os=newsos
+				;;
+			news1000)
+				basic_machine=m68030-sony
+				basic_os=newsos
+				;;
+			necv70)
+				basic_machine=v70-nec
+				basic_os=sysv
+				;;
+			nh3000)
+				basic_machine=m68k-harris
+				basic_os=cxux
+				;;
+			nh[45]000)
+				basic_machine=m88k-harris
+				basic_os=cxux
+				;;
+			nindy960)
+				basic_machine=i960-intel
+				basic_os=nindy
+				;;
+			mon960)
+				basic_machine=i960-intel
+				basic_os=mon960
+				;;
+			nonstopux)
+				basic_machine=mips-compaq
+				basic_os=nonstopux
+				;;
+			os400)
+				basic_machine=powerpc-ibm
+				basic_os=os400
+				;;
+			OSE68000 | ose68000)
+				basic_machine=m68000-ericsson
+				basic_os=ose
+				;;
+			os68k)
+				basic_machine=m68k-none
+				basic_os=os68k
+				;;
+			paragon)
+				basic_machine=i860-intel
+				basic_os=osf
+				;;
+			parisc)
+				basic_machine=hppa-unknown
+				basic_os=linux
+				;;
+			psp)
+				basic_machine=mipsallegrexel-sony
+				basic_os=psp
+				;;
+			pw32)
+				basic_machine=i586-unknown
+				basic_os=pw32
+				;;
+			rdos | rdos64)
+				basic_machine=x86_64-pc
+				basic_os=rdos
+				;;
+			rdos32)
+				basic_machine=i386-pc
+				basic_os=rdos
+				;;
+			rom68k)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			sa29200)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			sei)
+				basic_machine=mips-sei
+				basic_os=seiux
+				;;
+			sequent)
+				basic_machine=i386-sequent
+				basic_os=
+				;;
+			sps7)
+				basic_machine=m68k-bull
+				basic_os=sysv2
+				;;
+			st2000)
+				basic_machine=m68k-tandem
+				basic_os=
+				;;
+			stratus)
+				basic_machine=i860-stratus
+				basic_os=sysv4
+				;;
+			sun2)
+				basic_machine=m68000-sun
+				basic_os=
+				;;
+			sun2os3)
+				basic_machine=m68000-sun
+				basic_os=sunos3
+				;;
+			sun2os4)
+				basic_machine=m68000-sun
+				basic_os=sunos4
+				;;
+			sun3)
+				basic_machine=m68k-sun
+				basic_os=
+				;;
+			sun3os3)
+				basic_machine=m68k-sun
+				basic_os=sunos3
+				;;
+			sun3os4)
+				basic_machine=m68k-sun
+				basic_os=sunos4
+				;;
+			sun4)
+				basic_machine=sparc-sun
+				basic_os=
+				;;
+			sun4os3)
+				basic_machine=sparc-sun
+				basic_os=sunos3
+				;;
+			sun4os4)
+				basic_machine=sparc-sun
+				basic_os=sunos4
+				;;
+			sun4sol2)
+				basic_machine=sparc-sun
+				basic_os=solaris2
+				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				basic_os=
+				;;
+			sv1)
+				basic_machine=sv1-cray
+				basic_os=unicos
+				;;
+			symmetry)
+				basic_machine=i386-sequent
+				basic_os=dynix
+				;;
+			t3e)
+				basic_machine=alphaev5-cray
+				basic_os=unicos
+				;;
+			t90)
+				basic_machine=t90-cray
+				basic_os=unicos
+				;;
+			toad1)
+				basic_machine=pdp10-xkl
+				basic_os=tops20
+				;;
+			tpf)
+				basic_machine=s390x-ibm
+				basic_os=tpf
+				;;
+			udi29k)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			ultra3)
+				basic_machine=a29k-nyu
+				basic_os=sym1
+				;;
+			v810 | necv810)
+				basic_machine=v810-nec
+				basic_os=none
+				;;
+			vaxv)
+				basic_machine=vax-dec
+				basic_os=sysv
+				;;
+			vms)
+				basic_machine=vax-dec
+				basic_os=vms
+				;;
+			vsta)
+				basic_machine=i386-pc
+				basic_os=vsta
+				;;
+			vxworks960)
+				basic_machine=i960-wrs
+				basic_os=vxworks
+				;;
+			vxworks68)
+				basic_machine=m68k-wrs
+				basic_os=vxworks
+				;;
+			vxworks29k)
+				basic_machine=a29k-wrs
+				basic_os=vxworks
+				;;
+			xbox)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			ymp)
+				basic_machine=ymp-cray
+				basic_os=unicos
+				;;
+			*)
+				basic_machine=$1
+				basic_os=
+				;;
+		esac
 		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
 		;;
-	c54x)
-		basic_machine=tic54x-unknown
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c55x)
-		basic_machine=tic55x-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c6x)
-		basic_machine=tic6x-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
+		;;
+	orion105)
+		cpu=clipper
+		vendor=highlevel
+		;;
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
+		;;
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
+		;;
+
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		cpu=m68000
+		vendor=att
+		;;
+	3b*)
+		cpu=we32k
+		vendor=att
+		;;
+	bluegene*)
+		cpu=powerpc
+		vendor=ibm
+		basic_os=cnk
+		;;
+	decsystem10* | dec10*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops10
+		;;
+	decsystem20* | dec20*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		cpu=m68k
+		vendor=motorola
+		;;
+	dpx2*)
+		cpu=m68k
+		vendor=bull
+		basic_os=sysv3
+		;;
+	encore | umax | mmax)
+		cpu=ns32k
+		vendor=encore
+		;;
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		basic_os=${basic_os:-bsd}
+		;;
+	fx2800)
+		cpu=i860
+		vendor=alliant
+		;;
+	genix)
+		cpu=ns32k
+		vendor=ns
+		;;
+	h3050r* | hiux*)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		cpu=m68000
+		vendor=hp
+		;;
+	hp9k3[2-9][0-9])
+		cpu=m68k
+		vendor=hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	i*86v32)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv32
+		;;
+	i*86v4*)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv4
+		;;
+	i*86v)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=sysv
+		;;
+	i*86sol2)
+		cpu=$(echo "$1" | sed -e 's/86.*/86/')
+		vendor=pc
+		basic_os=solaris2
+		;;
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		basic_os=${basic_os:-unicos}
+		;;
+	iris | iris4d)
+		cpu=mips
+		vendor=sgi
+		case $basic_os in
+		    irix*)
+			;;
+		    *)
+			basic_os=irix4
+			;;
+		esac
+		;;
+	miniframe)
+		cpu=m68000
+		vendor=convergent
+		;;
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		basic_os=mint
+		;;
+	news-3600 | risc-news)
+		cpu=mips
+		vendor=sony
+		basic_os=newsos
+		;;
+	next | m*-next)
+		cpu=m68k
+		vendor=next
+		case $basic_os in
+		    openstep*)
+		        ;;
+		    nextstep*)
+			;;
+		    ns2*)
+		      basic_os=nextstep2
+			;;
+		    *)
+		      basic_os=nextstep3
+			;;
+		esac
+		;;
+	np1)
+		cpu=np1
+		vendor=gould
+		;;
+	op50n-* | op60c-*)
+		cpu=hppa1.1
+		vendor=oki
+		basic_os=proelf
+		;;
+	pa-hitachi)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	pbd)
+		cpu=sparc
+		vendor=tti
+		;;
+	pbb)
+		cpu=m68k
+		vendor=tti
+		;;
+	pc532)
+		cpu=ns32k
+		vendor=pc532
+		;;
+	pn)
+		cpu=pn
+		vendor=gould
+		;;
+	power)
+		cpu=power
+		vendor=ibm
+		;;
+	ps2)
+		cpu=i386
+		vendor=ibm
+		;;
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
+		;;
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
+		;;
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		basic_os=${basic_os:-elf}
+		;;
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		basic_os=vxworks
+		;;
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
+		;;
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
+		;;
+	w65)
+		cpu=w65
+		vendor=wdc
+		;;
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		basic_os=proelf
+		;;
+	none)
+		cpu=none
+		vendor=none
 		;;
 	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
-		;;
-	ms1)
-		basic_machine=mt-unknown
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=$(echo "$basic_machine" | sed 's/-.*//')
 		;;
 
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
-		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
-		;;
-
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
 	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
-	# Recognize the various machine names and aliases which stand
-	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-pc
-		os=-bsd
-		;;
-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
-		;;
-	3b*)
-		basic_machine=we32k-att
-		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
-		;;
-	c54x-*)
-		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
-	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
-		;;
-	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
-		;;
-	delta | 3300 | motorola-3300 | motorola-delta \
-	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
-	dpx2*)
-		basic_machine=m68k-bull
-		os=-sysv3
-		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
-		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
-	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
-		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
-	fx2800)
-		basic_machine=i860-alliant
-		;;
-	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
-	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
-		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
-	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
-		;;
-	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
-		;;
-	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k78[0-9] | hp78[0-9])
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
-	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
-		;;
-	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
-		;;
-	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
-		;;
-	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
-		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
-	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
-			;;
-		    *)
-			os=-irix4
-			;;
-		esac
-		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
-	miniframe)
-		basic_machine=m68000-convergent
-		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
-	mips3*-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
-		;;
-	ms1-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
-		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
-	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
-	next | m*-next)
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
-			;;
-		    -ns2*)
-		      os=-nextstep2
-			;;
-		    *)
-		      os=-nextstep3
-			;;
-		esac
-		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
-		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
-	np1)
-		basic_machine=np1-gould
-		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
-		;;
-	nsv-tandem)
-		basic_machine=nsv-tandem
-		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
-		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
-		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	pbd)
-		basic_machine=sparc-tti
-		;;
-	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
 	pc98)
-		basic_machine=i386-pc
+		cpu=i386
+		vendor=pc
 		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		basic_os=${basic_os:-unicosmp}
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
+	c90-unknown | c90-cray)
+		vendor=cray
+		basic_os=${Basic_os:-unicos}
 		;;
-	pentium4)
-		basic_machine=i786-pc
+	fx80-unknown)
+		vendor=alliant
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	romp-unknown)
+		vendor=ibm
 		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	mmix-unknown)
+		vendor=knuth
 		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	pn)
-		basic_machine=pn-gould
+	vax-unknown)
+		vendor=dec
 		;;
-	power)	basic_machine=power-ibm
+	pdp11-unknown)
+		vendor=dec
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	we32k-unknown)
+		vendor=att
 		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
+	i370-ibm*)
+		vendor=ibm
 		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	orion-unknown)
+		vendor=highlevel
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
-		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
-		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ps2)
-		basic_machine=i386-ibm
-		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
-		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
-		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	rm[46]00)
-		basic_machine=mips-siemens
-		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
-		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
-		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
-		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
-	sequent)
-		basic_machine=i386-sequent
-		;;
-	sh5el)
-		basic_machine=sh5le-unknown
-		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
-		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
-		;;
-	spur)
-		basic_machine=spur-unknown
-		;;
-	st2000)
-		basic_machine=m68k-tandem
-		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
-		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	sun2)
-		basic_machine=m68000-sun
-		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
-		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
-		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
-		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
-		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
-		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
-		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
-		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
-		;;
-	sun4)
-		basic_machine=sparc-sun
-		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
-		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
-		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
-		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
-		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
-		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
-		;;
-	tx39)
-		basic_machine=mipstx39-unknown
-		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
-		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
-		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
-		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
-		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
-		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
-		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
-		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
-		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
-		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
-		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
-		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
-		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	x64)
-		basic_machine=x86_64-pc
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
-		;;
-	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
-		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
+	# Here we normalize CPU types with a missing or matching vendor
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		basic_os=${basic_os:-bosx}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+	blackfin-*)
+		cpu=bfin
+		basic_os=linux
 		;;
-	romp)
-		basic_machine=romp-ibm
+	c54x-*)
+		cpu=tic54x
 		;;
-	mmix)
-		basic_machine=mmix-knuth
+	c55x-*)
+		cpu=tic55x
 		;;
-	rs6000)
-		basic_machine=rs6000-ibm
+	c6x-*)
+		cpu=tic6x
 		;;
-	vax)
-		basic_machine=vax-dec
+	e500v[12]-*)
+		cpu=powerpc
+		basic_os=${basic_os}"spe"
 		;;
-	pdp11)
-		basic_machine=pdp11-dec
+	mips3*-*)
+		cpu=mips64
 		;;
-	we32k)
-		basic_machine=we32k-att
+	ms1-*)
+		cpu=mt
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	m68knommu-*)
+		cpu=m68k
+		basic_os=linux
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	openrisc-*)
+		cpu=or32
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	parisc-*)
+		cpu=hppa
+		basic_os=linux
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
 		;;
+	pentium4-*)
+		cpu=i786
+		;;
+	pc98-*)
+		cpu=i386
+		;;
+	ppc-* | ppcbe-*)
+		cpu=powerpc
+		;;
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
+		;;
+	ppc64-*)
+		cpu=powerpc64
+		;;
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
+		;;
+	sb1-*)
+		cpu=mipsisa64sb1
+		;;
+	sb1el-*)
+		cpu=mipsisa64sb1el
+		;;
+	sh5e[lb]-*)
+		cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
+		;;
+	spur-*)
+		cpu=spur
+		;;
+	strongarm-* | thumb-*)
+		cpu=arm
+		;;
+	tx39-*)
+		cpu=mipstx39
+		;;
+	tx39el-*)
+		cpu=mipstx39el
+		;;
+	x64-*)
+		cpu=x86_64
+		;;
+	xscale-* | xscalee[bl]-*)
+		cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
+		;;
+	arm64-*)
+		cpu=aarch64
+		;;
+
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		basic_os=${basic_os:-elf}
+		;;
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
+		;;
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
+		;;
+	crx-*)
+		basic_os=${basic_os:-elf}
+		;;
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
+		;;
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
+		;;
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
+		;;
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
+		;;
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
+		;;
+	mipsallegrexel-sony)
+		cpu=mipsallegrexel
+		vendor=sony
+		;;
+	tile*-*)
+		basic_os=${basic_os:-linux-gnu}
+		;;
+
 	*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb \
+			| arm | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bpf | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64eb | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k | nvptx \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| picochip \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv64 \
+			| rl78 | romp | rs6000 | rx \
+			| s390 | s390x \
+			| score \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| w65 \
+			| wasm32 | wasm64 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1334,203 +1278,213 @@
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if test x$basic_os != x
 then
+
+# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+	gnu/linux*)
+		kernel=linux
+		os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
+		;;
+	os2-emx)
+		kernel=os2
+		os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
+		;;
+	nto-qnx*)
+		kernel=nto
+		os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
+		;;
+	*-*)
+		# shellcheck disable=SC2162
+		IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+		;;
+	# Default OS when just kernel was specified
+	nto*)
+		kernel=nto
+		os=$(echo $basic_os | sed -e 's|nto|qnx|')
+		;;
+	linux*)
+		kernel=linux
+		os=$(echo $basic_os | sed -e 's|linux|gnu|')
+		;;
+	*)
+		kernel=
+		os=$basic_os
+		;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
 case $os in
 	# First match some system type aliases that might get confused
 	# with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
+	# solaris* is a basic system type, with this one exception.
+	auroraux)
+		os=auroraux
 		;;
-	-solaris1 | -solaris1.*)
-		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+	bluegene*)
+		os=cnk
 		;;
-	-solaris)
-		os=-solaris2
+	solaris1 | solaris1.*)
+		os=$(echo $os | sed -e 's|solaris1|sunos4|')
 		;;
-	-unixware*)
-		os=-sysv4.2uw
+	solaris)
+		os=solaris2
 		;;
-	-gnu/linux*)
-		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+	unixware*)
+		os=sysv4.2uw
 		;;
 	# es1800 is here to avoid being matched by es* (a different OS)
-	-es1800*)
-		os=-ose
+	es1800*)
+		os=ose
 		;;
-	# Now accept the basic system types.
-	# The portable systems comes first.
-	# Each alternative MUST end in a * to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
-	      | -midnightbsd*)
-	# Remember, each alternative MUST END IN *, to match a version number.
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
 		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
+	isc)
+		os=isc2.2
 		;;
-	-nto-qnx*)
+	sco6)
+		os=sco5v6
 		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+	sco5)
+		os=sco3.2v5
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sco4)
+		os=sco3.2v4
 		;;
-	-mac*)
-		os=`echo "$os" | sed -e 's|mac|macos|'`
+	sco3.2.[4-9]*)
+		os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	sco*v* | scout)
+		# Don't match below
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	sco*)
+		os=sco3.2v2
 		;;
-	-sunos5*)
-		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+	psos*)
+		os=psos
 		;;
-	-sunos6*)
-		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+	qnx*)
+		os=qnx
 		;;
-	-opened*)
-		os=-openedition
+	hiux*)
+		os=hiuxwe2
 		;;
-	-os400*)
-		os=-os400
+	lynx*178)
+		os=lynxos178
 		;;
-	-wince*)
-		os=-wince
+	lynx*5)
+		os=lynxos5
 		;;
-	-utek*)
-		os=-bsd
+	lynxos*)
+		# don't get caught up in next wildcard
 		;;
-	-dynix*)
-		os=-bsd
+	lynx*)
+		os=lynxos
 		;;
-	-acis*)
-		os=-aos
+	mac[0-9]*)
+		os=$(echo "$os" | sed -e 's|mac|macos|')
 		;;
-	-atheos*)
-		os=-atheos
+	opened*)
+		os=openedition
 		;;
-	-syllable*)
-		os=-syllable
+	os400*)
+		os=os400
 		;;
-	-386bsd)
-		os=-bsd
+	sunos5*)
+		os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
 		;;
-	-ctix* | -uts*)
-		os=-sysv
+	sunos6*)
+		os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
 		;;
-	-nova*)
-		os=-rtmk-nova
+	wince*)
+		os=wince
 		;;
-	-ns2)
-		os=-nextstep2
+	utek*)
+		os=bsd
 		;;
-	-nsk*)
-		os=-nsk
+	dynix*)
+		os=bsd
+		;;
+	acis*)
+		os=aos
+		;;
+	atheos*)
+		os=atheos
+		;;
+	syllable*)
+		os=syllable
+		;;
+	386bsd)
+		os=bsd
+		;;
+	ctix* | uts*)
+		os=sysv
+		;;
+	nova*)
+		os=rtmk-nova
+		;;
+	ns2)
+		os=nextstep2
 		;;
 	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
+	sinix5.*)
+		os=$(echo $os | sed -e 's|sinix|sysv|')
 		;;
-	-sinix*)
-		os=-sysv4
+	sinix*)
+		os=sysv4
 		;;
-	-tpf*)
-		os=-tpf
+	tpf*)
+		os=tpf
 		;;
-	-triton*)
-		os=-sysv3
+	triton*)
+		os=sysv3
 		;;
-	-oss*)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-svr4*)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	-svr3)
-		os=-sysv3
+	svr3)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	sysvr4)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	ose*)
+		os=ose
 		;;
-	-ose*)
-		os=-ose
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	dicos*)
+		os=dicos
 		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
-	-dicos*)
-		os=-dicos
-		;;
-	-pikeos*)
+	pikeos*)
 		# Until real need of OS specific support for
 		# particular features comes up, bare metal
 		# configurations are quite functional.
-		case $basic_machine in
+		case $cpu in
 		    arm*)
-			os=-eabi
+			os=eabi
 			;;
 		    *)
-			os=-elf
+			os=elf
 			;;
 		esac
 		;;
-	-nacl*)
-		;;
-	-ios)
-		;;
-	-none)
-		;;
 	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
-		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
-		exit 1
+		# No normalization, but not necessarily accepted, that comes below.
 		;;
 esac
+
 else
 
 # Here we handle the default operating systems that come with various machines.
@@ -1543,258 +1497,356 @@
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+kernel=
+case $cpu-$vendor in
 	score-*)
-		os=-elf
+		os=elf
 		;;
 	spu-*)
-		os=-elf
+		os=elf
 		;;
 	*-acorn)
-		os=-riscix1.2
+		os=riscix1.2
 		;;
 	arm*-rebel)
-		os=-linux
+		kernel=linux
+		os=gnu
 		;;
 	arm*-semi)
-		os=-aout
+		os=aout
 		;;
 	c4x-* | tic4x-*)
-		os=-coff
+		os=coff
 		;;
 	c8051-*)
-		os=-elf
+		os=elf
+		;;
+	clipper-intergraph)
+		os=clix
 		;;
 	hexagon-*)
-		os=-elf
+		os=elf
 		;;
 	tic54x-*)
-		os=-coff
+		os=coff
 		;;
 	tic55x-*)
-		os=-coff
+		os=coff
 		;;
 	tic6x-*)
-		os=-coff
+		os=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
-		os=-tops20
+		os=tops20
 		;;
 	pdp11-*)
-		os=-none
+		os=none
 		;;
 	*-dec | vax-*)
-		os=-ultrix4.2
+		os=ultrix4.2
 		;;
 	m68*-apollo)
-		os=-domain
+		os=domain
 		;;
 	i386-sun)
-		os=-sunos4.0.2
+		os=sunos4.0.2
 		;;
 	m68000-sun)
-		os=-sunos3
+		os=sunos3
 		;;
 	m68*-cisco)
-		os=-aout
+		os=aout
 		;;
 	mep-*)
-		os=-elf
+		os=elf
 		;;
 	mips*-cisco)
-		os=-elf
+		os=elf
 		;;
 	mips*-*)
-		os=-elf
+		os=elf
 		;;
 	or32-*)
-		os=-coff
+		os=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
+		os=sysv3
 		;;
 	sparc-* | *-sun)
-		os=-sunos4.1.1
+		os=sunos4.1.1
 		;;
 	pru-*)
-		os=-elf
+		os=elf
 		;;
 	*-be)
-		os=-beos
+		os=beos
 		;;
 	*-ibm)
-		os=-aix
+		os=aix
 		;;
 	*-knuth)
-		os=-mmixware
+		os=mmixware
 		;;
 	*-wec)
-		os=-proelf
+		os=proelf
 		;;
 	*-winbond)
-		os=-proelf
+		os=proelf
 		;;
 	*-oki)
-		os=-proelf
+		os=proelf
 		;;
 	*-hp)
-		os=-hpux
+		os=hpux
 		;;
 	*-hitachi)
-		os=-hiux
+		os=hiux
 		;;
 	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
+		os=sysv
 		;;
 	*-cbm)
-		os=-amigaos
+		os=amigaos
 		;;
 	*-dg)
-		os=-dgux
+		os=dgux
 		;;
 	*-dolphin)
-		os=-sysv3
+		os=sysv3
 		;;
 	m68k-ccur)
-		os=-rtu
+		os=rtu
 		;;
 	m88k-omron*)
-		os=-luna
+		os=luna
 		;;
 	*-next)
-		os=-nextstep
+		os=nextstep
 		;;
 	*-sequent)
-		os=-ptx
+		os=ptx
 		;;
 	*-crds)
-		os=-unos
+		os=unos
 		;;
 	*-ns)
-		os=-genix
+		os=genix
 		;;
 	i370-*)
-		os=-mvs
+		os=mvs
 		;;
 	*-gould)
-		os=-sysv
+		os=sysv
 		;;
 	*-highlevel)
-		os=-bsd
+		os=bsd
 		;;
 	*-encore)
-		os=-bsd
+		os=bsd
 		;;
 	*-sgi)
-		os=-irix
+		os=irix
 		;;
 	*-siemens)
-		os=-sysv4
+		os=sysv4
 		;;
 	*-masscomp)
-		os=-rtu
+		os=rtu
 		;;
 	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
+		os=uxpv
 		;;
 	*-rom68k)
-		os=-coff
+		os=coff
 		;;
 	*-*bug)
-		os=-coff
+		os=coff
 		;;
 	*-apple)
-		os=-macos
+		os=macos
 		;;
 	*-atari*)
-		os=-mint
+		os=mint
+		;;
+	*-wrs)
+		os=vxworks
 		;;
 	*)
-		os=-none
+		os=none
 		;;
 esac
+
 fi
 
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+	# Sometimes we do "kernel-abi", so those need to count as OSes.
+	musl* | newlib* | uclibc*)
+		;;
+	# Likewise for "kernel-libc"
+	eabi | eabihf | gnueabi | gnueabihf)
+		;;
+	# Now accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST end in a * to match a version number.
+	gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+	     | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \
+	     | hiux* | abug | nacl* | netware* | windows* \
+	     | os9* | macos* | osx* | ios* \
+	     | mpw* | magic* | mmixware* | mon960* | lnews* \
+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+	     | aos* | aros* | cloudabi* | sortix* | twizzler* \
+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+	     | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
+	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | udi* | lites* | ieee* | go32* | aux* | hcos* \
+	     | chorusrdb* | cegcc* | glidix* \
+	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | midipix* | mingw32* | mingw64* | mint* \
+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+	     | interix* | uwin* | mks* | rhapsody* | darwin* \
+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
+	     | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+	     | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+	     | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
+		;;
+	# This one is extra strict with allowed versions
+	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		;;
+	none)
+		;;
+	*)
+		echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+	linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
+		;;
+	uclinux-uclibc* )
+		;;
+	-dietlibc* | -newlib* | -musl* | -uclibc* )
+		# These are just libc implementations, not actual OSes, and thus
+		# require a kernel.
+		echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+		exit 1
+		;;
+	kfreebsd*-gnu* | kopensolaris*-gnu*)
+		;;
+	nto-qnx*)
+		;;
+	os2-emx)
+		;;
+	*-eabi* | *-gnueabi*)
+		;;
+	-*)
+		# Blank kernel with real OS is always fine.
+		;;
+	*-*)
+		echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+		exit 1
+		;;
+esac
+
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
-		case $os in
-			-riscix*)
+case $vendor in
+	unknown)
+		case $cpu-$os in
+			*-riscix*)
 				vendor=acorn
 				;;
-			-sunos*)
+			*-sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			*-cnk* | *-aix*)
 				vendor=ibm
 				;;
-			-beos*)
+			*-beos*)
 				vendor=be
 				;;
-			-hpux*)
+			*-hpux*)
 				vendor=hp
 				;;
-			-mpeix*)
+			*-mpeix*)
 				vendor=hp
 				;;
-			-hiux*)
+			*-hiux*)
 				vendor=hitachi
 				;;
-			-unos*)
+			*-unos*)
 				vendor=crds
 				;;
-			-dgux*)
+			*-dgux*)
 				vendor=dg
 				;;
-			-luna*)
+			*-luna*)
 				vendor=omron
 				;;
-			-genix*)
+			*-genix*)
 				vendor=ns
 				;;
-			-mvs* | -opened*)
+			*-clix*)
+				vendor=intergraph
+				;;
+			*-mvs* | *-opened*)
 				vendor=ibm
 				;;
-			-os400*)
+			*-os400*)
 				vendor=ibm
 				;;
-			-ptx*)
+			s390-* | s390x-*)
+				vendor=ibm
+				;;
+			*-ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
+			*-tpf*)
 				vendor=ibm
 				;;
-			-vxsim* | -vxworks* | -windiss*)
+			*-vxsim* | *-vxworks* | *-windiss*)
 				vendor=wrs
 				;;
-			-aux*)
+			*-aux*)
 				vendor=apple
 				;;
-			-hms*)
+			*-hms*)
 				vendor=hitachi
 				;;
-			-mpw* | -macos*)
+			*-mpw* | *-macos*)
 				vendor=apple
 				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
 				vendor=atari
 				;;
-			-vos*)
+			*-vos*)
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo "$basic_machine$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/lib/External/isl/interface/configure b/lib/External/isl/interface/configure
old mode 100644
new mode 100755
index 30e35b1..e63e13e
--- a/lib/External/isl/interface/configure
+++ b/lib/External/isl/interface/configure
@@ -198,6 +198,7 @@
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
 
   test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
     ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
@@ -205,8 +206,7 @@
     ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
     PATH=/empty FPATH=/empty; export PATH FPATH
     test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
-      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
   if (eval "$as_required") 2>/dev/null; then :
   as_have_required=yes
 else
@@ -661,9 +661,10 @@
 LD
 FGREP
 EGREP
-GREP
 SED
 LIBTOOL
+HAVE_CXX11
+GREP
 CXXCPPFLAGS_FOR_BUILD
 CXXFLAGS_FOR_BUILD
 CXXCPP_FOR_BUILD
@@ -755,7 +756,6 @@
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -842,7 +842,6 @@
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1095,15 +1094,6 @@
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1241,7 +1231,7 @@
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1394,7 +1384,6 @@
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -2613,12 +2602,7 @@
 am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -6505,6 +6489,1069 @@
 EXEEXT="$BUILD_EXEEXT"
 OBJEXT="$BUILD_OBJEXT"
 
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+	echo $CXX | $GREP -e "-std=" > /dev/null 2> /dev/null
+	if test $? -eq 0; then
+		  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_cxx_compile_cxx11=yes
+else
+  ax_cv_cxx_compile_cxx11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
+$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ac_success = xno; then
+    HAVE_CXX11=0
+  else
+    HAVE_CXX11=1
+
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
+
+  fi
+
+
+	else
+		  ax_cxx_compile_alternatives="11 0x"    ax_cxx_compile_cxx11_required=false
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_cxx_compile_cxx11=yes
+else
+  ax_cv_cxx_compile_cxx11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
+$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+
+
+    if test x$ac_success = xno; then
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval \${$cachevar+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval $cachevar=yes
+else
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX11=0
+    { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5
+$as_echo "$as_me: No compiler with C++11 support was found" >&6;}
+  else
+    HAVE_CXX11=1
+
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
+
+  fi
+
+
+
+	fi
+
+
 # Check whether --enable-shared was given.
 if test "${enable_shared+set}" = set; then :
   enableval=$enable_shared; p=${PACKAGE-default}
@@ -6544,8 +7591,8 @@
 
 
 
-macro_version='2.4.6'
-macro_revision='2.4.6'
+macro_version='2.4.6.42-b88ce-dirty'
+macro_revision='2.4.6.42'
 
 
 
@@ -6712,69 +7759,6 @@
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
 if ${ac_cv_path_EGREP+:} false; then :
@@ -7774,7 +8758,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd* | netbsdelf*-gnu)
+netbsd*)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
   else
@@ -8137,13 +9121,29 @@
 fi
 
 : ${AR=ar}
-: ${AR_FLAGS=cr}
 
 
 
 
 
 
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because thats what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+
+
+
+
+
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+
 
 
 
@@ -8592,7 +9592,7 @@
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++,
+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
@@ -8638,8 +9638,11 @@
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
-    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -9858,8 +10861,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR cr libconftest.a conftest.o" >&5
-      $AR cr libconftest.a conftest.o 2>&5
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -10096,7 +11099,6 @@
 
 
 
-
 func_stripname_cnf ()
 {
   case $2 in
@@ -10366,8 +11368,8 @@
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
-# which needs '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC and
+# ICC, which need '.lib').
 libext=a
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -10832,12 +11834,6 @@
 	lt_prog_compiler_pic='-KPIC'
 	lt_prog_compiler_static='-static'
         ;;
-      # flang / f18. f95 an alias for gfortran or flang on Debian
-      flang* | f18* | f95*)
-	lt_prog_compiler_wl='-Wl,'
-	lt_prog_compiler_pic='-fPIC'
-	lt_prog_compiler_static='-static'
-        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -11300,23 +12296,20 @@
 
   case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
+    # Microsoft Visual C++ or Intel C++ Compiler.
     if test yes != "$GCC"; then
       with_gnu_ld=no
     fi
     ;;
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     ;;
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs=no
-    ;;
   esac
 
   ld_shlibs=yes
@@ -11475,6 +12468,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     interix[3-9]*)
@@ -11571,7 +12565,7 @@
       fi
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
@@ -11692,7 +12686,7 @@
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
 	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
 	else
-	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
@@ -11959,12 +12953,12 @@
 
     cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
+      # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       case $cc_basename in
-      cl*)
-	# Native MSVC
+      cl* | icl*)
+	# Native MSVC or ICC
 	hardcode_libdir_flag_spec=' '
 	allow_undefined_flag=unsupported
 	always_export_symbols=yes
@@ -12005,7 +12999,7 @@
           fi'
 	;;
       *)
-	# Assume MSVC wrapper
+	# Assume MSVC and ICC wrapper
 	hardcode_libdir_flag_spec=' '
 	allow_undefined_flag=unsupported
 	# Tell ltmain to make .lib files, not .a files.
@@ -12241,7 +13235,6 @@
 	if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
 	fi
-	link_all_deplibs=no
       else
 	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
 	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -12263,7 +13256,7 @@
       esac
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
@@ -12330,6 +13323,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
+      file_list_spec='@'
       ;;
 
     osf3*)
@@ -13037,8 +14031,8 @@
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -13094,7 +14088,7 @@
     ;;
 
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -13378,18 +14372,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -14285,30 +15267,41 @@
 old_striplib=
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
 $as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if test -z "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-  darwin*)
-    if test -n "$STRIP"; then
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-    else
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+      fi
+      ;;
+    *)
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-    fi
-    ;;
-  *)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 
 
@@ -14780,7 +15773,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -15076,8 +16069,8 @@
 
       cygwin* | mingw* | pw32* | cegcc*)
 	case $GXX,$cc_basename in
-	,cl* | no,cl*)
-	  # Native MSVC
+	,cl* | no,cl* | ,icl* | no,icl*)
+	  # Native MSVC or ICC
 	  # hardcode_libdir_flag_spec is actually meaningless, as there is
 	  # no search path for DLLs.
 	  hardcode_libdir_flag_spec_CXX=' '
@@ -15207,6 +16200,7 @@
 	  emximp -o $lib $output_objdir/$libname.def'
 	old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
 	enable_shared_with_static_runtimes_CXX=yes
+	file_list_spec_CXX='@'
 	;;
 
       dgux*)
@@ -15272,7 +16266,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -15337,7 +16331,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -15676,7 +16670,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -15760,7 +16754,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -15771,7 +16765,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
 	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -16284,7 +17278,7 @@
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -16642,7 +17636,7 @@
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -16650,7 +17644,7 @@
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -16659,9 +17653,6 @@
       ;;
     esac
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs_CXX=no
-    ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -17015,8 +18006,8 @@
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -17072,7 +18063,7 @@
     ;;
 
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -17355,18 +18346,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -18040,7 +19019,7 @@
 
 
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CLANG_CXXFLAGS $CPPFLAGS"
+CPPFLAGS="$CLANG_CXXFLAGS -I$srcdir $CPPFLAGS"
 ac_fn_cxx_check_header_mongrel "$LINENO" "clang/Basic/SourceLocation.h" "ac_cv_header_clang_Basic_SourceLocation_h" "$ac_includes_default"
 if test "x$ac_cv_header_clang_Basic_SourceLocation_h" = xyes; then :
 
@@ -18435,6 +19414,8 @@
 	#include <clang/Lex/PreprocessorOptions.h>
 	#include <clang/Frontend/CompilerInstance.h>
 
+	#include "set_lang_defaults_arg4.h"
+
 int
 main ()
 {
@@ -18445,7 +19426,8 @@
 	llvm::Triple T(TO.Triple);
 	PreprocessorOptions PO;
 	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
-			T, PO, LangStandard::lang_unspecified);
+			T, setLangDefaultsArg4(PO),
+			LangStandard::lang_unspecified);
 
   ;
   return 0;
@@ -19374,6 +20356,7 @@
 DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
 archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
 STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
@@ -19556,7 +20539,6 @@
 DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
-AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -20394,7 +21376,9 @@
     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
@@ -20564,8 +21548,11 @@
 # The archiver.
 AR=$lt_AR
 
+# Flags to create an archive (by configure).
+lt_ar_flags=$lt_ar_flags
+
 # Flags to create an archive.
-AR_FLAGS=$lt_AR_FLAGS
+AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
 
 # How to feed a file listing to the archiver.
 archiver_list_spec=$lt_archiver_list_spec
diff --git a/lib/External/isl/interface/configure.ac b/lib/External/isl/interface/configure.ac
index 9399b0a..357eb60 100644
--- a/lib/External/isl/interface/configure.ac
+++ b/lib/External/isl/interface/configure.ac
@@ -17,6 +17,8 @@
 EXEEXT="$BUILD_EXEEXT"
 OBJEXT="$BUILD_OBJEXT"
 
+AX_CXX_COMPILE_STDCXX_11_NO_OVERRIDE
+
 AC_DISABLE_SHARED
 AC_PROG_LIBTOOL
 
diff --git a/lib/External/isl/interface/cpp.cc b/lib/External/isl/interface/cpp.cc
index 1295b9c..23e2281 100644
--- a/lib/External/isl/interface/cpp.cc
+++ b/lib/External/isl/interface/cpp.cc
@@ -16,7 +16,7 @@
  * THIS SOFTWARE IS PROVIDED BY TOBIAS GROSSER ''AS IS'' AND ANY
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TOBIAS GROSSER OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
@@ -31,702 +31,285 @@
  * Tobias Grosser.
  */
 
-#include <cstdarg>
-#include <cstdio>
 #include <iostream>
-#include <map>
-#include <sstream>
 #include <string>
 #include <vector>
 
 #include "cpp.h"
 #include "isl_config.h"
 
-/* Print string formatted according to "fmt" to ostream "os".
+/* Determine the isl types from which the given class can be implicitly
+ * constructed using a unary constructor.
  *
- * This osprintf method allows us to use printf style formatting constructs when
- * writing to an ostream.
+ * Look through all constructors for implicit conversion constructors that take
+ * an isl type and add those types, along with the corresponding
+ * constructor argument.
  */
-static void osprintf(ostream &os, const char *format, va_list arguments)
+void cpp_generator::set_class_construction_types(isl_class &clazz)
 {
-	va_list copy;
-	char *string_pointer;
-	size_t size;
+	for (const auto &cons : clazz.constructors) {
+		ParmVarDecl *param;
+		QualType type;
+		std::string arg_type;
 
-	va_copy(copy, arguments);
-	size = vsnprintf(NULL, 0, format, copy);
-	string_pointer = new char[size + 1];
-	va_end(copy);
-	vsnprintf(string_pointer, size + 1, format, arguments);
-	os << string_pointer;
-	delete[] string_pointer;
-}
+		if (!is_implicit_conversion(Method(clazz, cons)))
+			continue;
 
-/* Print string formatted according to "fmt" to ostream "os".
- *
- * This osprintf method allows us to use printf style formatting constructs when
- * writing to an ostream.
- */
-static void osprintf(ostream &os, const char *format, ...)
-{
-	va_list arguments;
-
-	va_start(arguments, format);
-	osprintf(os, format, arguments);
-	va_end(arguments);
-}
-
-/* Print string formatted according to "fmt" to ostream "os"
- * with the given indentation.
- *
- * This osprintf method allows us to use printf style formatting constructs when
- * writing to an ostream.
- */
-static void osprintf(ostream &os, int indent, const char *format, ...)
-{
-	va_list arguments;
-
-	osprintf(os, "%*s", indent, " ");
-	va_start(arguments, format);
-	osprintf(os, format, arguments);
-	va_end(arguments);
-}
-
-/* Convert "l" to a string.
- */
-static std::string to_string(long l)
-{
-	std::ostringstream strm;
-	strm << l;
-	return strm.str();
-}
-
-/* Generate a cpp interface based on the extracted types and functions.
- *
- * Print first a set of forward declarations for all isl wrapper
- * classes, then the declarations of the classes, and at the end all
- * implementations.
- *
- * If checked C++ bindings are being generated,
- * then wrap them in a namespace to avoid conflicts
- * with the default C++ bindings (with automatic checks using exceptions).
- */
-void cpp_generator::generate()
-{
-	ostream &os = cout;
-
-	osprintf(os, "\n");
-	osprintf(os, "namespace isl {\n\n");
-	if (checked)
-		osprintf(os, "namespace checked {\n\n");
-
-	print_forward_declarations(os);
-	osprintf(os, "\n");
-	print_declarations(os);
-	osprintf(os, "\n");
-	print_implementations(os);
-
-	if (checked)
-		osprintf(os, "} // namespace checked\n");
-	osprintf(os, "} // namespace isl\n");
-}
-
-/* Print forward declarations for all classes to "os".
-*/
-void cpp_generator::print_forward_declarations(ostream &os)
-{
-	map<string, isl_class>::iterator ci;
-
-	osprintf(os, "// forward declarations\n");
-
-	for (ci = classes.begin(); ci != classes.end(); ++ci)
-		print_class_forward_decl(os, ci->second);
-}
-
-/* Print all declarations to "os".
- */
-void cpp_generator::print_declarations(ostream &os)
-{
-	map<string, isl_class>::iterator ci;
-	bool first = true;
-
-	for (ci = classes.begin(); ci != classes.end(); ++ci) {
-		if (first)
-			first = false;
-		else
-			osprintf(os, "\n");
-
-		print_class(os, ci->second);
+		param = cons->getParamDecl(0);
+		type = param->getOriginalType();
+		arg_type = extract_type(type);
+		clazz.construction_types.emplace(arg_type, param);
 	}
 }
 
-/* Print all implementations to "os".
+/* Determine the isl types from which any (proper) class can be constructed
+ * using a unary constructor.
  */
-void cpp_generator::print_implementations(ostream &os)
+void cpp_generator::set_construction_types()
 {
-	map<string, isl_class>::iterator ci;
-	bool first = true;
-
-	for (ci = classes.begin(); ci != classes.end(); ++ci) {
-		if (first)
-			first = false;
-		else
-			osprintf(os, "\n");
-
-		print_class_impl(os, ci->second);
+	for (auto &kvp : classes) {
+		auto &clazz = kvp.second;
+		set_class_construction_types(clazz);
 	}
 }
 
-/* If "clazz" is a subclass that is based on a type function,
- * then introduce a "type" field that holds the value of the type
- * corresponding to the subclass and make the fields of the class
- * accessible to the "isa" and "as" methods of the (immediate) superclass.
- * In particular, "isa" needs access to the type field itself,
- * while "as" needs access to the private constructor.
- * In case of the "isa" method, all instances are made friends
- * to avoid access right confusion.
+/* Construct a generator for C++ bindings.
+ *
+ * The classes and methods are extracted by the constructor
+ * of the generator superclass.
+ *
+ * Additionally extract information about types
+ * that can be converted to a class and copy all methods
+ * from superclasses that can be converted to a given class
+ * to that class.
  */
-void cpp_generator::print_subclass_type(ostream &os, const isl_class &clazz)
+cpp_generator::cpp_generator(SourceManager &SM,
+	set<RecordDecl *> &exported_types,
+	set<FunctionDecl *> exported_functions, set<FunctionDecl *> functions) :
+		generator(SM, exported_types, exported_functions, functions)
 {
-	std::string cppstring = type2cpp(clazz);
-	std::string super;
-	const char *cppname = cppstring.c_str();
-	const char *supername;
-
-	if (!clazz.is_type_subclass())
-		return;
-
-	super = type2cpp(clazz.superclass_name);
-	supername = super.c_str();
-	osprintf(os, "  template <class T>\n");
-	osprintf(os, "  friend %s %s::isa() const;\n",
-		isl_bool2cpp().c_str(), supername);
-	osprintf(os, "  friend %s %s::as<%s>() const;\n",
-		cppname, supername, cppname);
-	osprintf(os, "  static const auto type = %s;\n",
-		clazz.subclass_name.c_str());
+	set_construction_types();
+	copy_super_methods();
 }
 
-/* Print declarations for class "clazz" to "os".
+/* Copy the method called "name" described by "fd" from "super" to "clazz"
+ * with the distance to the original ancestor given by "depth".
  *
- * If "clazz" is a subclass based on a type function,
- * then it is made to inherit from the (immediate) superclass and
- * a "type" attribute is added for use in the "as" and "isa"
- * methods of the superclass.
- *
- * Conversely, if "clazz" is a superclass with a type function,
- * then declare those "as" and "isa" methods.
- *
- * The pointer to the isl object is only added for classes that
- * are not subclasses, since subclasses refer to the same isl object.
+ * In particular, keep track of "fd" as well as the superclass
+ * from which it was copied and the distance to the original ancestor.
  */
-void cpp_generator::print_class(ostream &os, const isl_class &clazz)
+static void copy_method(isl_class &clazz, const isl_class &super,
+	const std::string &name, FunctionDecl *fd, int depth)
 {
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
+	clazz.methods[name].insert(fd);
+	clazz.copied_from.emplace(fd, super);
+	clazz.copy_depth.emplace(fd, depth);
+}
 
-	osprintf(os, "// declarations for isl::%s\n", cppname);
+/* Do "fd1" and "fd2" have the same signature (ignoring the first argument
+ * which represents the object class on which the corresponding method
+ * gets called).
+ */
+static bool same_signature(FunctionDecl *fd1, FunctionDecl *fd2)
+{
+	int n1 = fd1->getNumParams();
+	int n2 = fd2->getNumParams();
 
-	print_class_factory_decl(os, clazz);
-	osprintf(os, "\n");
-	osprintf(os, "class %s ", cppname);
-	if (clazz.is_type_subclass())
-		osprintf(os, ": public %s ",
-			type2cpp(clazz.superclass_name).c_str());
-	osprintf(os, "{\n");
-	print_subclass_type(os, clazz);
-	print_class_factory_decl(os, clazz, "  friend ");
-	osprintf(os, "\n");
-	osprintf(os, "protected:\n");
-	if (!clazz.is_type_subclass()) {
-		osprintf(os, "  %s *ptr = nullptr;\n", name);
-		osprintf(os, "\n");
+	if (n1 != n2)
+		return false;
+
+	for (int i = 1; i < n1; ++i) {
+		ParmVarDecl *p1 = fd1->getParamDecl(i);
+		ParmVarDecl *p2 = fd2->getParamDecl(i);
+
+		if (p1->getOriginalType() != p2->getOriginalType())
+			return false;
 	}
-	print_protected_constructors_decl(os, clazz);
-	osprintf(os, "\n");
-	osprintf(os, "public:\n");
-	print_public_constructors_decl(os, clazz);
-	print_constructors_decl(os, clazz);
-	print_copy_assignment_decl(os, clazz);
-	print_destructor_decl(os, clazz);
-	print_ptr_decl(os, clazz);
-	print_downcast_decl(os, clazz);
-	print_ctx_decl(os);
-	osprintf(os, "\n");
-	print_persistent_callbacks_decl(os, clazz);
-	print_methods_decl(os, clazz);
-	print_set_enums_decl(os, clazz);
 
-	osprintf(os, "};\n");
+	return true;
 }
 
-/* Print forward declaration of class "clazz" to "os".
+/* Return the distance between "clazz" and the ancestor
+ * from which "fd" got copied.
+ * If no distance was recorded, then the method has not been copied
+ * but appears in "clazz" itself and so the distance is zero.
  */
-void cpp_generator::print_class_forward_decl(ostream &os,
-	const isl_class &clazz)
+static int copy_depth(const isl_class &clazz, FunctionDecl *fd)
 {
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	osprintf(os, "class %s;\n", cppname);
+	if (clazz.copy_depth.count(fd) == 0)
+		return 0;
+	return clazz.copy_depth.at(fd);
 }
 
-/* Print global factory functions to "os".
+/* Is the method derived from "fd", with method name "name" and
+ * with distance to the original ancestor "depth",
+ * overridden by a method already in "clazz"?
  *
- * Each class has two global factory functions:
+ * A method is considered to have been overridden if there
+ * is a method with the same name in "clazz" that has the same signature and
+ * that comes from an ancestor closer to "clazz",
+ * where an ancestor is closer if the distance in the class hierarchy
+ * is smaller or the distance is the same and the ancestor appears
+ * closer in the declaration of the type (in which case it gets added first).
  *
- * 	set manage(__isl_take isl_set *ptr);
- * 	set manage_copy(__isl_keep isl_set *ptr);
- *
- * A user can construct isl C++ objects from a raw pointer and indicate whether
- * they intend to take the ownership of the object or not through these global
- * factory functions. This ensures isl object creation is very explicit and
- * pointers are not converted by accident. Thanks to overloading, manage() and
- * manage_copy() can be called on any isl raw pointer and the corresponding
- * object is automatically created, without the user having to choose the right
- * isl object type.
- *
- * For a subclass based on a type function, no factory functions
- * are introduced because they share the C object type with
- * the superclass.
+ * If a method with the same signature has already been added,
+ * but it does not override the method derived from "fd",
+ * then this method is removed since it is overridden by "fd".
  */
-void cpp_generator::print_class_factory_decl(ostream &os,
-	const isl_class &clazz, const std::string &prefix)
+static bool is_overridden(FunctionDecl *fd, isl_class &clazz,
+	const std::string &name, int depth)
 {
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
+	if (clazz.methods.count(name) == 0)
+		return false;
 
-	if (clazz.is_type_subclass())
-		return;
-
-	os << prefix;
-	osprintf(os, "inline %s manage(__isl_take %s *ptr);\n", cppname, name);
-	os << prefix;
-	osprintf(os, "inline %s manage_copy(__isl_keep %s *ptr);\n",
-		cppname, name);
+	for (const auto &m : clazz.methods.at(name)) {
+		if (!same_signature(fd, m))
+			continue;
+		if (copy_depth(clazz, m) <= depth)
+			return true;
+		clazz.methods[name].erase(m);
+		return false;
+	}
+	return false;
 }
 
-/* Print declarations of protected constructors for class "clazz" to "os".
+/* Add the methods "methods" with method name "name" from "super" to "clazz"
+ * provided they have not been overridden by a method already in "clazz".
  *
- * Each class has currently one protected constructor:
- *
- * 	1) Constructor from a plain isl_* C pointer
- *
- * Example:
- *
- * 	set(__isl_take isl_set *ptr);
- *
- * The raw pointer constructor is kept protected. Object creation is only
- * possible through manage() or manage_copy().
+ * Methods that are static in their original class are not copied.
  */
-void cpp_generator::print_protected_constructors_decl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::copy_methods(isl_class &clazz, const std::string &name,
+	const isl_class &super, const function_set &methods)
 {
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
+	for (auto fd : methods) {
+		int depth;
 
-	osprintf(os, "  inline explicit %s(__isl_take %s *ptr);\n", cppname,
-		 name);
+		if (method2class(fd)->is_static(fd))
+			continue;
+		depth = copy_depth(super, fd) + 1;
+		if (is_overridden(fd, clazz, name, depth))
+			continue;
+		copy_method(clazz, super, name, fd, depth);
+	}
 }
 
-/* Print declarations of public constructors for class "clazz" to "os".
+/* Add all methods from "super" to "clazz" that have not been overridden
+ * by a method already in "clazz".
  *
- * Each class currently has two public constructors:
- *
- * 	1) A default constructor
- * 	2) A copy constructor
- *
- * Example:
- *
- *	set();
- *	set(const set &set);
+ * Look through all groups of methods with the same name.
  */
-void cpp_generator::print_public_constructors_decl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::copy_super_methods(isl_class &clazz, const isl_class &super)
 {
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	osprintf(os, "  inline /* implicit */ %s();\n", cppname);
+	for (const auto &kvp : super.methods) {
+		const auto &name = kvp.first;
+		const auto &methods = kvp.second;
 
-	osprintf(os, "  inline /* implicit */ %s(const %s &obj);\n",
-		 cppname, cppname);
+		copy_methods(clazz, name, super, methods);
+	}
 }
 
-/* Print declarations for "method" in class "clazz" to "os".
+/* Copy methods from the superclasses of "clazz"
+ * if an object of this class can be implicitly converted to an object
+ * from the superclass, keeping track
+ * of the classes that have already been handled in "done".
  *
- * "kind" specifies the kind of method that should be generated.
+ * Make sure the superclasses have copied methods from their superclasses first
+ * since those methods could be copied further down to this class.
  *
- * "convert" specifies which of the method arguments should
- * be automatically converted.
+ * Consider the superclass that appears closest to the subclass first.
  */
-template <>
-void cpp_generator::print_method<cpp_generator::decl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind,
-	const std::vector<bool> &convert)
+void cpp_generator::copy_super_methods(isl_class &clazz, set<string> &done)
 {
-	string name = clazz.method_name(method);
+	auto supers = find_superclasses(clazz.type);
 
-	print_named_method_decl(os, clazz, method, name, kind, convert);
+	for (const auto &super : supers)
+		if (done.count(super) == 0)
+			copy_super_methods(classes[super], done);
+	done.insert(clazz.name);
+
+	for (const auto &super_name : supers) {
+		const auto &super = classes[super_name];
+
+		if (super.construction_types.count(clazz.name) == 0)
+			continue;
+		copy_super_methods(clazz, super);
+	}
 }
 
-/* Print declarations for "method" in class "clazz" to "os",
- * without any argument conversions.
+/* For each (proper) class, copy methods from its superclasses,
+ * if an object from the class can be converted to an object
+ * from the superclass.
  *
- * "kind" specifies the kind of method that should be generated.
+ * Type based subclasses are not considered for now since
+ * they do not have any explicit superclasses.
+ *
+ * Iterate through all (proper) classes and copy methods
+ * from their superclasses,
+ * unless they have already been determined by a recursive call.
  */
-template <>
-void cpp_generator::print_method<cpp_generator::decl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind)
+void cpp_generator::copy_super_methods()
 {
-	print_method<decl>(os, clazz,method, kind, {});
+	set<string> done;
+
+	for (auto &kvp : classes) {
+		auto &clazz = kvp.second;
+
+		if (clazz.is_type_subclass())
+			continue;
+		if (done.count(clazz.name) != 0)
+			continue;
+		copy_super_methods(clazz, done);
+	}
 }
 
-/* Print declarations for constructors for class "class" to "os".
+/* Print declarations or implementations of constructors.
  *
  * For each isl function that is marked as __isl_constructor,
  * add a corresponding C++ constructor.
  *
- * Example:
+ * Example of declarations:
  *
  * 	inline /\* implicit *\/ union_set(basic_set bset);
  * 	inline /\* implicit *\/ union_set(set set);
  * 	inline explicit val(ctx ctx, long i);
  * 	inline explicit val(ctx ctx, const std::string &str);
  */
-void cpp_generator::print_constructors_decl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::class_printer::print_constructors()
 {
-	function_set::const_iterator in;
-	const function_set &constructors = clazz.constructors;
-
-	for (in = constructors.begin(); in != constructors.end(); ++in) {
-		FunctionDecl *cons = *in;
-
-		print_method<decl>(os, clazz, cons, function_kind_constructor);
-	}
+	for (const auto &cons : clazz.constructors)
+		print_method(Method(clazz, cons));
 }
 
-/* Print declarations of copy assignment operator for class "clazz"
- * to "os".
- *
- * Each class has one assignment operator.
- *
- * 	isl:set &set::operator=(set obj)
- *
+/* Print declarations or definitions for methods in the class.
  */
-void cpp_generator::print_copy_assignment_decl(ostream &os,
-	const isl_class &clazz)
+void cpp_generator::class_printer::print_methods()
 {
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	osprintf(os, "  inline %s &operator=(%s obj);\n", cppname, cppname);
+	for (const auto &kvp : clazz.methods)
+		print_method_group(kvp.second, kvp.first);
 }
 
-/* Print declaration of destructor for class "clazz" to "os".
- *
- * No explicit destructor is needed for type based subclasses.
- */
-void cpp_generator::print_destructor_decl(ostream &os, const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (clazz.is_type_subclass())
-		return;
-
-	osprintf(os, "  inline ~%s();\n", cppname);
-}
-
-/* Print declaration of pointer functions for class "clazz" to "os".
- * Since type based subclasses share the pointer with their superclass,
- * they can also reuse these functions from the superclass.
- *
- * To obtain a raw pointer three functions are provided:
- *
- * 	1) __isl_give isl_set *copy()
- *
- * 	  Returns a pointer to a _copy_ of the internal object
- *
- * 	2) __isl_keep isl_set *get()
- *
- * 	  Returns a pointer to the internal object
- *
- * 	3) __isl_give isl_set *release()
- *
- * 	  Returns a pointer to the internal object and resets the
- * 	  internal pointer to nullptr.
- *
- * We also provide functionality to explicitly check if a pointer is
- * currently managed by this object.
- *
- * 	4) bool is_null()
- *
- * 	  Check if the current object is a null pointer.
- *
- * The functions get() and release() model the value_ptr proposed in
- * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf.
- * The copy() function is an extension to allow the user to explicitly
- * copy the underlying object.
- *
- * Also generate a declaration to delete copy() for r-values, for
- * r-values release() should be used to avoid unnecessary copies.
- */
-void cpp_generator::print_ptr_decl(ostream &os, const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-
-	if (clazz.is_type_subclass())
-		return;
-
-	osprintf(os, "  inline __isl_give %s *copy() const &;\n", name);
-	osprintf(os, "  inline __isl_give %s *copy() && = delete;\n", name);
-	osprintf(os, "  inline __isl_keep %s *get() const;\n", name);
-	osprintf(os, "  inline __isl_give %s *release();\n", name);
-	osprintf(os, "  inline bool is_null() const;\n");
-}
-
-/* Print a template declaration with given indentation
- * for the "isa_type" method that ensures it is only enabled
- * when called with a template argument
- * that represents a type that is equal to that
- * of the return type of the type function of "super".
- * In particular, "isa_type" gets called from "isa"
- * with as template argument the type of the "type" field
- * of the subclass.
- * The check ensures that this subclass is in fact a direct subclass
- * of "super".
- */
-void cpp_generator::print_isa_type_template(ostream &os, int indent,
-	const isl_class &super)
-{
-	osprintf(os, indent,
-		"template <typename T,\n");
-	osprintf(os, indent,
-		"        typename = typename std::enable_if<std::is_same<\n");
-	osprintf(os, indent,
-		"                const decltype(%s(NULL)),\n",
-		super.fn_type->getNameAsString().c_str());
-	osprintf(os, indent,
-		"                const T>::value>::type>\n");
-}
-
-/* Print declarations for the "as" and "isa" methods, if "clazz"
- * is a superclass with a type function.
- *
- * "isa" checks whether an object is of a given subclass type.
- * "isa_type" does the same, but gets passed the value of the type field
- * of the subclass as a function argument and the type of this field
- * as a template argument.
- * "as" tries to cast an object to a given subclass type, returning
- * an invalid object if the object is not of the given type.
- */
-void cpp_generator::print_downcast_decl(ostream &os, const isl_class &clazz)
-{
-	if (!clazz.fn_type)
-		return;
-
-	osprintf(os, "private:\n");
-	print_isa_type_template(os, 2, clazz);
-	osprintf(os, "  inline %s isa_type(T subtype) const;\n",
-		isl_bool2cpp().c_str());
-	osprintf(os, "public:\n");
-	osprintf(os, "  template <class T> inline %s isa() const;\n",
-		isl_bool2cpp().c_str());
-	osprintf(os, "  template <class T> inline T as() const;\n");
-}
-
-/* Print the declaration of the ctx method.
- */
-void cpp_generator::print_ctx_decl(ostream &os)
-{
-	std::string ns = isl_namespace();
-
-	osprintf(os, "  inline %sctx ctx() const;\n", ns.c_str());
-}
-
-/* Add a space to the return type "type" if needed,
- * i.e., if it is not the type of a pointer.
- */
-static string add_space_to_return_type(const string &type)
-{
-	if (type[type.size() - 1] == '*')
-		return type;
-	return type + " ";
-}
-
-/* Print the prototype of the static inline method that is used
- * as the C callback of "clazz" set by "method" to "os".
- */
-void cpp_generator::print_persistent_callback_prototype(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, bool is_declaration)
-{
-	string callback_name, rettype, c_args;
-	ParmVarDecl *param = persistent_callback_arg(method);
-	const FunctionProtoType *callback;
-	QualType ptype;
-	string classname;
-
-	ptype = param->getType();
-	callback = extract_prototype(ptype);
-
-	rettype = callback->getReturnType().getAsString();
-	rettype = add_space_to_return_type(rettype);
-	callback_name = clazz.persistent_callback_name(method);
-	c_args = generate_callback_args(ptype, false);
-
-	if (!is_declaration)
-		classname = type2cpp(clazz) + "::";
-
-	osprintf(os, "%s%s%s(%s)",
-		 rettype.c_str(), classname.c_str(),
-		 callback_name.c_str(), c_args.c_str());
-}
-
-/* Print the prototype of the method for setting the callback function
- * of "clazz" set by "method" to "os".
- */
-void cpp_generator::print_persistent_callback_setter_prototype(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, bool is_declaration)
-{
-	string classname, callback_name, cpptype;
-	ParmVarDecl *param = persistent_callback_arg(method);
-
-	if (!is_declaration)
-		classname = type2cpp(clazz) + "::";
-
-	cpptype = type2cpp(param->getOriginalType());
-	callback_name = clazz.persistent_callback_name(method);
-	osprintf(os, "void %sset_%s_data(const %s &%s)",
-		classname.c_str(), callback_name.c_str(), cpptype.c_str(),
-		param->getName().str().c_str());
-}
-
-/* Given a function "method" for setting a "clazz" persistent callback,
- * print the fields that are needed for marshalling the callback to "os".
- *
- * In particular, print
- * - the declaration of a data structure for storing the C++ callback function
- * - a shared pointer to such a data structure
- * - the declaration of a static inline method
- *   for use as the C callback function
- * - the declaration of a private method for setting the callback function
- */
-void cpp_generator::print_persistent_callback_data(ostream &os,
-	const isl_class &clazz, FunctionDecl *method)
-{
-	string callback_name;
-	ParmVarDecl *param = persistent_callback_arg(method);
-
-	callback_name = clazz.persistent_callback_name(method);
-	print_callback_data_decl(os, param, callback_name);
-	osprintf(os, ";\n");
-	osprintf(os, "  std::shared_ptr<%s_data> %s_data;\n",
-		callback_name.c_str(), callback_name.c_str());
-	osprintf(os, "  static inline ");
-	print_persistent_callback_prototype(os, clazz, method, true);
-	osprintf(os, ";\n");
-	osprintf(os, "  inline ");
-	print_persistent_callback_setter_prototype(os, clazz, method, true);
-	osprintf(os, ";\n");
-}
-
-/* Print declarations needed for the persistent callbacks of "clazz".
- *
- * In particular, if there are any persistent callbacks, then
- * print a private method for copying callback data from
- * one object to another,
- * private data for keeping track of the persistent callbacks and
- * public methods for setting the persistent callbacks.
- */
-void cpp_generator::print_persistent_callbacks_decl(ostream &os,
-	const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	set<FunctionDecl *>::const_iterator in;
-	const set<FunctionDecl *> &callbacks = clazz.persistent_callbacks;
-
-	if (!clazz.has_persistent_callbacks())
-		return;
-
-	osprintf(os, "private:\n");
-	osprintf(os, "  inline %s &copy_callbacks(const %s &obj);\n",
-		cppname, cppname);
-	for (in = callbacks.begin(); in != callbacks.end(); ++in)
-		print_persistent_callback_data(os, clazz, *in);
-
-	osprintf(os, "public:\n");
-	for (in = callbacks.begin(); in != callbacks.end(); ++in)
-		print_method<decl>(os, clazz, *in, function_kind_member_method);
-}
-
-/* Print declarations for methods in class "clazz" to "os".
- */
-void cpp_generator::print_methods_decl(ostream &os, const isl_class &clazz)
-{
-	map<string, function_set >::const_iterator it;
-
-	for (it = clazz.methods.begin(); it != clazz.methods.end(); ++it)
-		print_method_group_decl(os, clazz, it->second);
-}
-
-/* Print a declaration for a method "name" in "clazz" derived
- * from "fd", which sets an enum, to "os".
- *
- * The last argument is removed because it is replaced by
- * a break-up into several methods.
- */
-void cpp_generator::print_set_enum_decl(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd, const string &name)
-{
-	int n = fd->getNumParams();
-
-	print_method_header(os, clazz, fd, name, n - 1, true,
-				function_kind_member_method);
-}
-
-/* Print declarations for the methods in "clazz" derived from "fd",
- * which sets an enum, to "os".
+/* Print declarations or implementations for the methods derived from "fd",
+ * which sets an enum.
  *
  * A method is generated for each value in the enum, setting
  * the enum to that value.
  */
-void cpp_generator::print_set_enums_decl(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd)
+void cpp_generator::class_printer::print_set_enums(FunctionDecl *fd)
 {
-	vector<set_enum>::const_iterator it;
-	const vector<set_enum> &set_enums = clazz.set_enums.at(fd);
+	for (const auto &set : clazz.set_enums.at(fd)) {
+		EnumMethod method(clazz, fd, set.method_name, set.name);
 
-	for (it = set_enums.begin(); it != set_enums.end(); ++it)
-		print_set_enum_decl(os, clazz, fd, it->method_name);
+		print_method(method);
+	}
 }
 
-/* Print declarations for methods in "clazz" derived from functions
- * that set an enum, to "os".
+/* Print declarations or implementations for methods derived from functions
+ * that set an enum.
  */
-void cpp_generator::print_set_enums_decl(ostream &os, const isl_class &clazz)
+void cpp_generator::class_printer::print_set_enums()
 {
-	map<FunctionDecl *, vector<set_enum> >::const_iterator it;
-
-	for (it = clazz.set_enums.begin(); it != clazz.set_enums.end(); ++it)
-		print_set_enums_decl(os, clazz, it->first);
-}
-
-/* Print a declaration for the "get" method "fd" in class "clazz",
- * using a name that includes the "get_" prefix, to "os".
- */
-template<>
-void cpp_generator::print_get_method<cpp_generator::decl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *fd)
-{
-	function_kind kind = function_kind_member_method;
-	string base = clazz.base_method_name(fd);
-
-	print_named_method_decl(os, clazz, fd, base, kind);
+	for (const auto &kvp : clazz.set_enums)
+		print_set_enums(kvp.first);
 }
 
 /* Update "convert" to reflect the next combination of automatic conversions
@@ -745,7 +328,8 @@
  * for automatic conversion since this is the argument
  * from which the isl_ctx used in the conversion is extracted.
  */
-bool cpp_generator::next_variant(FunctionDecl *fd, std::vector<bool> &convert)
+bool cpp_generator::class_printer::next_variant(FunctionDecl *fd,
+	std::vector<bool> &convert)
 {
 	size_t n = convert.size();
 
@@ -753,7 +337,7 @@
 		ParmVarDecl *param = fd->getParamDecl(i);
 		const Type *type = param->getOriginalType().getTypePtr();
 
-		if (conversions.count(type) == 0)
+		if (generator.conversions.count(type) == 0)
 			continue;
 		if (convert[i])
 			continue;
@@ -766,10 +350,12 @@
 	return false;
 }
 
-/* Print a declaration or definition for method "fd" in class "clazz"
- * to "os".
+/* Print a declaration or definition for a method called "name"
+ * derived from "fd".
  *
- * For methods that are identified as "get" methods, also
+ * If the method was copied from a superclass, then print a definition
+ * that calls the corresponding method in the superclass.
+ * Otherwise, for methods that are identified as "get" methods, also
  * print a declaration or definition for the method
  * using a name that includes the "get_" prefix.
  *
@@ -777,795 +363,133 @@
  * whether any of its arguments can be automatically converted
  * from something else, and, if so, generate a method
  * for each combination of converted arguments.
+ * Do so by constructing a ConversionMethod that changes the converted arguments
+ * to those of the sources of the conversions.
+ *
+ * Note that a method may be both copied from a superclass and
+ * have arguments that can be automatically converted.
+ * In this case, the conversion methods for the arguments
+ * call the corresponding method in this class, which
+ * in turn will call the method in the superclass.
  */
-template <enum cpp_generator::method_part part>
-void cpp_generator::print_method_variants(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd)
+void cpp_generator::class_printer::print_method_variants(FunctionDecl *fd,
+	const std::string &name)
 {
-	function_kind kind = get_method_kind(clazz, fd);
-	std::vector<bool> convert(fd->getNumParams());
+	Method method(clazz, fd, name);
+	std::vector<bool> convert(method.num_params());
 
-	print_method<part>(os, clazz, fd, kind);
-	if (clazz.is_get_method(fd))
-		print_get_method<part>(os, clazz, fd);
-	if (kind == function_kind_member_method)
-		while (next_variant(fd, convert))
-			print_method<part>(os, clazz, fd, kind, convert);
-}
-
-/* Print declarations for methods "methods" in class "clazz" to "os".
- */
-void cpp_generator::print_method_group_decl(ostream &os, const isl_class &clazz,
-	const function_set &methods)
-{
-	function_set::const_iterator it;
-
-	for (it = methods.begin(); it != methods.end(); ++it)
-		print_method_variants<decl>(os, clazz, *it);
-}
-
-/* Print a declaration for a method called "name" in class "clazz"
- * derived from "fd" to "os".
- *
- * "kind" specifies the kind of method that should be generated.
- *
- * "convert" specifies which of the method arguments should
- * be automatically converted.
- */
-void cpp_generator::print_named_method_decl(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd, const string &name, function_kind kind,
-	const std::vector<bool> &convert)
-{
-	print_named_method_header(os, clazz, fd, name, true, kind, convert);
-}
-
-/* Print implementations for class "clazz" to "os".
- */
-void cpp_generator::print_class_impl(ostream &os, const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	osprintf(os, "// implementations for isl::%s", cppname);
-
-	print_class_factory_impl(os, clazz);
-	print_public_constructors_impl(os, clazz);
-	print_protected_constructors_impl(os, clazz);
-	print_constructors_impl(os, clazz);
-	print_copy_assignment_impl(os, clazz);
-	print_destructor_impl(os, clazz);
-	print_ptr_impl(os, clazz);
-	print_downcast_impl(os, clazz);
-	print_ctx_impl(os, clazz);
-	print_persistent_callbacks_impl(os, clazz);
-	print_methods_impl(os, clazz);
-	print_set_enums_impl(os, clazz);
-	print_stream_insertion(os, clazz);
-}
-
-/* Print code for throwing an exception corresponding to the last error
- * that occurred on "saved_ctx".
- * This assumes that a valid isl::ctx is available in the "saved_ctx" variable,
- * e.g., through a prior call to print_save_ctx.
- */
-static void print_throw_last_error(ostream &os)
-{
-	osprintf(os, "    exception::throw_last_error(saved_ctx);\n");
-}
-
-/* Print code with the given indentation
- * for throwing an exception_invalid with the given message.
- */
-static void print_throw_invalid(ostream &os, int indent, const char *msg)
-{
-	osprintf(os, indent,
-		"exception::throw_invalid(\"%s\", __FILE__, __LINE__);\n", msg);
-}
-
-/* Print code for throwing an exception on NULL input.
- */
-static void print_throw_NULL_input(ostream &os)
-{
-	print_throw_invalid(os, 4, "NULL input");
-}
-
-/* Print code with the given indentation
- * for acting on an invalid error with message "msg".
- * In particular, throw an exception_invalid.
- * In the checked C++ bindings, isl_die is called instead with the code
- * in "checked_code".
- */
-void cpp_generator::print_invalid(ostream &os, int indent, const char *msg,
-	const char *checked_code)
-{
-	if (checked)
-		osprintf(os, indent,
-			"isl_die(ctx().get(), isl_error_invalid, "
-			"\"%s\", %s);\n", msg, checked_code);
-	else
-		print_throw_invalid(os, indent, msg);
-}
-
-/* Print an operator for inserting objects of "class"
- * into an output stream.
- *
- * Unless checked C++ bindings are being generated,
- * the operator requires its argument to be non-NULL.
- * An exception is thrown if anything went wrong during the printing.
- * During this printing, isl is made not to print any error message
- * because the error message is included in the exception.
- *
- * If checked C++ bindings are being generated and anything went wrong,
- * then record this failure in the output stream.
- */
-void cpp_generator::print_stream_insertion(ostream &os, const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (!clazz.fn_to_str)
-		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "inline std::ostream &operator<<(std::ostream &os, ");
-	osprintf(os, "const %s &obj)\n", cppname);
-	osprintf(os, "{\n");
-	print_check_ptr_start(os, clazz, "obj.get()");
-	osprintf(os, "  char *str = %s_to_str(obj.get());\n", name);
-	print_check_ptr_end(os, "str");
-	if (checked) {
-		osprintf(os, "  if (!str) {\n");
-		osprintf(os, "    os.setstate(std::ios_base::badbit);\n");
-		osprintf(os, "    return os;\n");
-		osprintf(os, "  }\n");
-	}
-	osprintf(os, "  os << str;\n");
-	osprintf(os, "  free(str);\n");
-	osprintf(os, "  return os;\n");
-	osprintf(os, "}\n");
-}
-
-/* Print code that checks that "ptr" is not NULL at input.
- *
- * Omit the check if checked C++ bindings are being generated.
- */
-void cpp_generator::print_check_ptr(ostream &os, const char *ptr)
-{
-	if (checked)
-		return;
-
-	osprintf(os, "  if (!%s)\n", ptr);
-	print_throw_NULL_input(os);
-}
-
-/* Print code that checks that "ptr" is not NULL at input and
- * that saves a copy of the isl_ctx of "ptr" for a later check.
- *
- * Omit the check if checked C++ bindings are being generated.
- */
-void cpp_generator::print_check_ptr_start(ostream &os, const isl_class &clazz,
-	const char *ptr)
-{
-	if (checked)
-		return;
-
-	print_check_ptr(os, ptr);
-	osprintf(os, "  auto saved_ctx = %s_get_ctx(%s);\n",
-		clazz.name.c_str(), ptr);
-	print_on_error_continue(os);
-}
-
-/* Print code that checks that "ptr" is not NULL at the end.
- * A copy of the isl_ctx is expected to have been saved by
- * code generated by print_check_ptr_start.
- *
- * Omit the check if checked C++ bindings are being generated.
- */
-void cpp_generator::print_check_ptr_end(ostream &os, const char *ptr)
-{
-	if (checked)
-		return;
-
-	osprintf(os, "  if (!%s)\n", ptr);
-	print_throw_last_error(os);
-}
-
-/* Print implementation of global factory functions to "os".
- *
- * Each class has two global factory functions:
- *
- * 	set manage(__isl_take isl_set *ptr);
- * 	set manage_copy(__isl_keep isl_set *ptr);
- *
- * Unless checked C++ bindings are being generated,
- * both functions require the argument to be non-NULL.
- * An exception is thrown if anything went wrong during the copying
- * in manage_copy.
- * During the copying, isl is made not to print any error message
- * because the error message is included in the exception.
- *
- * For a subclass based on a type function, no factory functions
- * are introduced because they share the C object type with
- * the superclass.
- */
-void cpp_generator::print_class_factory_impl(ostream &os,
-	const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (clazz.is_type_subclass())
-		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "%s manage(__isl_take %s *ptr) {\n", cppname, name);
-	print_check_ptr(os, "ptr");
-	osprintf(os, "  return %s(ptr);\n", cppname);
-	osprintf(os, "}\n");
-
-	osprintf(os, "%s manage_copy(__isl_keep %s *ptr) {\n", cppname,
-		name);
-	print_check_ptr_start(os, clazz, "ptr");
-	osprintf(os, "  ptr = %s_copy(ptr);\n", name);
-	print_check_ptr_end(os, "ptr");
-	osprintf(os, "  return %s(ptr);\n", cppname);
-	osprintf(os, "}\n");
-}
-
-/* Print implementations of protected constructors for class "clazz" to "os".
- *
- * The pointer to the isl object is either initialized directly or
- * through the (immediate) superclass.
- */
-void cpp_generator::print_protected_constructors_impl(ostream &os,
-	const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	bool subclass = clazz.is_type_subclass();
-
-	osprintf(os, "\n");
-	osprintf(os, "%s::%s(__isl_take %s *ptr)\n", cppname, cppname, name);
-	if (subclass)
-		osprintf(os, "    : %s(ptr) {}\n",
-			type2cpp(clazz.superclass_name).c_str());
-	else
-		osprintf(os, "    : ptr(ptr) {}\n");
-}
-
-/* Print implementations of public constructors for class "clazz" to "os".
- *
- * The pointer to the isl object is either initialized directly or
- * through the (immediate) superclass.
- *
- * If the class has any persistent callbacks, then copy them
- * from the original object in the copy constructor.
- * If the class is a subclass, then the persistent callbacks
- * are assumed to be copied by the copy constructor of the superclass.
- *
- * Throw an exception from the copy constructor if anything went wrong
- * during the copying or if the input is NULL, if any copying is performed.
- * During the copying, isl is made not to print any error message
- * because the error message is included in the exception.
- * No exceptions are thrown if checked C++ bindings
- * are being generated,
- */
-void cpp_generator::print_public_constructors_impl(ostream &os,
-	const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	std::string super;
-	const char *cppname = cppstring.c_str();
-	bool subclass = clazz.is_type_subclass();
-
-	osprintf(os, "\n");
-	if (subclass)
-		super = type2cpp(clazz.superclass_name);
-	osprintf(os, "%s::%s()\n", cppname, cppname);
-	if (subclass)
-		osprintf(os, "    : %s() {}\n\n", super.c_str());
-	else
-		osprintf(os, "    : ptr(nullptr) {}\n\n");
-	osprintf(os, "%s::%s(const %s &obj)\n", cppname, cppname, cppname);
-	if (subclass)
-		osprintf(os, "    : %s(obj)\n", super.c_str());
-	else
-		osprintf(os, "    : ptr(nullptr)\n");
-	osprintf(os, "{\n");
-	if (!subclass) {
-		print_check_ptr_start(os, clazz, "obj.ptr");
-		osprintf(os, "  ptr = obj.copy();\n");
-		if (clazz.has_persistent_callbacks())
-			osprintf(os, "  copy_callbacks(obj);\n");
-		print_check_ptr_end(os, "ptr");
-	}
-	osprintf(os, "}\n");
-}
-
-/* Print definition for "method" in class "clazz" to "os",
- * without any automatic type conversions.
- *
- * "kind" specifies the kind of method that should be generated.
- *
- * This method distinguishes three kinds of methods: member methods, static
- * methods, and constructors.
- *
- * Member methods call "method" by passing to the underlying isl function the
- * isl object belonging to "this" as first argument and the remaining arguments
- * as subsequent arguments.
- *
- * Static methods call "method" by passing all arguments to the underlying isl
- * function, as no this-pointer is available. The result is a newly managed
- * isl C++ object.
- *
- * Constructors create a new object from a given set of input parameters. They
- * do not return a value, but instead update the pointer stored inside the
- * newly created object.
- *
- * If the method has a callback argument, we reduce the number of parameters
- * that are exposed by one to hide the user pointer from the interface. On
- * the C++ side no user pointer is needed, as arguments can be forwarded
- * as part of the std::function argument which specifies the callback function.
- *
- * Unless checked C++ bindings are being generated,
- * the inputs of the method are first checked for being valid isl objects and
- * a copy of the associated isl::ctx is saved (if needed).
- * If any failure occurs, either during the check for the inputs or
- * during the isl function call, an exception is thrown.
- * During the function call, isl is made not to print any error message
- * because the error message is included in the exception.
- */
-template<>
-void cpp_generator::print_method<cpp_generator::impl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind)
-{
-	string methodname = method->getName().str();
-	int num_params = method->getNumParams();
-
-	osprintf(os, "\n");
-	print_method_header(os, clazz, method, false, kind);
-	osprintf(os, "{\n");
-	print_argument_validity_check(os, method, kind);
-	print_save_ctx(os, method, kind);
-	print_on_error_continue(os);
-
-	for (int i = 0; i < num_params; ++i) {
-		ParmVarDecl *param = method->getParamDecl(i);
-		if (is_callback(param->getType())) {
-			num_params -= 1;
-			print_callback_local(os, param);
-		}
-	}
-
-	osprintf(os, "  auto res = %s(", methodname.c_str());
-
-	for (int i = 0; i < num_params; ++i) {
-		ParmVarDecl *param = method->getParamDecl(i);
-		bool load_from_this_ptr = false;
-
-		if (i == 0 && kind == function_kind_member_method)
-			load_from_this_ptr = true;
-
-		print_method_param_use(os, param, load_from_this_ptr);
-
-		if (i != num_params - 1)
-			osprintf(os, ", ");
-	}
-	osprintf(os, ");\n");
-
-	print_exceptional_execution_check(os, clazz, method, kind);
-	if (kind == function_kind_constructor) {
-		osprintf(os, "  ptr = res;\n");
+	if (method.clazz.copied_from.count(method.fd) == 0) {
+		print_method(method);
+		if (clazz.is_get_method(fd))
+			print_get_method(fd);
 	} else {
-		print_method_return(os, clazz, method);
+		auto super = method.clazz.copied_from.at(method.fd);
+		print_method(ConversionMethod(method, super.name));
 	}
-
-	osprintf(os, "}\n");
-}
-
-/* Print a definition for "method" in class "clazz" to "os",
- * where at least one of the argument types needs to be converted,
- * as specified by "convert".
- *
- * "kind" specifies the kind of method that should be generated and
- * is assumed to be set to function_kind_member_method.
- *
- * The generated method performs the required conversion(s) and
- * calls the method generated without conversions.
- *
- * Each conversion is performed by calling the conversion function
- * with as arguments the isl_ctx of the object and the argument
- * to the generated method.
- * In order to be able to use this isl_ctx, the current object needs
- * to valid.  The validity of other arguments is checked
- * by the called method.
- */
-template<>
-void cpp_generator::print_method<cpp_generator::impl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind,
-	const std::vector<bool> &convert)
-{
-	string name = clazz.method_name(method);
-	int num_params = method->getNumParams();
-
-	if (kind != function_kind_member_method)
-		die("Automatic conversion currently only supported "
-		    "for object methods");
-
-	osprintf(os, "\n");
-	print_named_method_header(os, clazz, method, name, false,
-				  kind, convert);
-	osprintf(os, "{\n");
-	print_check_ptr(os, "ptr");
-	osprintf(os, "  return this->%s(", name.c_str());
-	for (int i = 1; i < num_params; ++i) {
-		ParmVarDecl *param = method->getParamDecl(i);
-		std::string name = param->getName().str();
-
-		if (i != 1)
-			osprintf(os, ", ");
-		if (convert[i]) {
-			QualType type = param->getOriginalType();
-			string cpptype = type2cpp(type);
-			osprintf(os, "%s(ctx(), %s)",
-				cpptype.c_str(), name.c_str());
-		} else {
-			osprintf(os, "%s", name.c_str());
-		}
-	}
-	osprintf(os, ");\n");
-	osprintf(os, "}\n");
-}
-
-/* Print implementations of constructors for class "clazz" to "os".
- */
-void cpp_generator::print_constructors_impl(ostream &os,
-	const isl_class &clazz)
-{
-	function_set::const_iterator in;
-	const function_set constructors = clazz.constructors;
-
-	for (in = constructors.begin(); in != constructors.end(); ++in) {
-		FunctionDecl *cons = *in;
-
-		print_method<impl>(os, clazz, cons, function_kind_constructor);
-	}
-}
-
-/* Print implementation of copy assignment operator for class "clazz" to "os".
- *
- * If the class has any persistent callbacks, then copy them
- * from the original object.
- */
-void cpp_generator::print_copy_assignment_impl(ostream &os,
-	const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	osprintf(os, "\n");
-	osprintf(os, "%s &%s::operator=(%s obj) {\n", cppname,
-		 cppname, cppname);
-	osprintf(os, "  std::swap(this->ptr, obj.ptr);\n", name);
-	if (clazz.has_persistent_callbacks())
-		osprintf(os, "  copy_callbacks(obj);\n");
-	osprintf(os, "  return *this;\n");
-	osprintf(os, "}\n");
-}
-
-/* Print implementation of destructor for class "clazz" to "os".
- *
- * No explicit destructor is needed for type based subclasses.
- */
-void cpp_generator::print_destructor_impl(ostream &os,
-	const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (clazz.is_type_subclass())
+	if (method.kind != Method::Kind::member_method)
 		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "%s::~%s() {\n", cppname, cppname);
-	osprintf(os, "  if (ptr)\n");
-	osprintf(os, "    %s_free(ptr);\n", name);
-	osprintf(os, "}\n");
-}
-
-/* Print a check that the persistent callback corresponding to "fd"
- * is not set, throwing an exception (or printing an error message
- * and returning nullptr) if it is set.
- */
-void cpp_generator::print_check_no_persistent_callback(ostream &os,
-	const isl_class &clazz, FunctionDecl *fd)
-{
-	string callback_name = clazz.persistent_callback_name(fd);
-
-	osprintf(os, "  if (%s_data)\n", callback_name.c_str());
-	print_invalid(os, 4, "cannot release object with persistent callbacks",
-			    "return nullptr");
-}
-
-/* Print implementation of ptr() functions for class "clazz" to "os".
- * Since type based subclasses share the pointer with their superclass,
- * they can also reuse these functions from the superclass.
- *
- * If an object has persistent callbacks set, then the underlying
- * C object pointer cannot be released because it references data
- * in the C++ object.
- */
-void cpp_generator::print_ptr_impl(ostream &os, const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	set<FunctionDecl *>::const_iterator in;
-	const set<FunctionDecl *> &callbacks = clazz.persistent_callbacks;
-
-	if (clazz.is_type_subclass())
-		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "__isl_give %s *%s::copy() const & {\n", name, cppname);
-	osprintf(os, "  return %s_copy(ptr);\n", name);
-	osprintf(os, "}\n\n");
-	osprintf(os, "__isl_keep %s *%s::get() const {\n", name, cppname);
-	osprintf(os, "  return ptr;\n");
-	osprintf(os, "}\n\n");
-	osprintf(os, "__isl_give %s *%s::release() {\n", name, cppname);
-	for (in = callbacks.begin(); in != callbacks.end(); ++in)
-		print_check_no_persistent_callback(os, clazz, *in);
-	osprintf(os, "  %s *tmp = ptr;\n", name);
-	osprintf(os, "  ptr = nullptr;\n");
-	osprintf(os, "  return tmp;\n");
-	osprintf(os, "}\n\n");
-	osprintf(os, "bool %s::is_null() const {\n", cppname);
-	osprintf(os, "  return ptr == nullptr;\n");
-	osprintf(os, "}\n");
-}
-
-/* Print implementations for the "as" and "isa" methods, if "clazz"
- * is a superclass with a type function.
- *
- * "isa" checks whether an object is of a given subclass type.
- * "isa_type" does the same, but gets passed the value of the type field
- * of the subclass as a function argument and the type of this field
- * as a template argument.
- * "as" casts an object to a given subclass type, erroring out
- * if the object is not of the given type.
- *
- * If the input is an invalid object, then these methods raise
- * an exception.
- * If checked bindings are being generated,
- * then an invalid boolean or object is returned instead.
- */
-void cpp_generator::print_downcast_impl(ostream &os, const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-
-	if (!clazz.fn_type)
-		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "template <typename T, typename>\n");
-	osprintf(os, "%s %s::isa_type(T subtype) const\n",
-		isl_bool2cpp().c_str(), cppname);
-	osprintf(os, "{\n");
-	osprintf(os, "  if (is_null())\n");
-	if (checked)
-		osprintf(os, "    return boolean();\n");
-	else
-		print_throw_NULL_input(os);
-	osprintf(os, "  return %s(get()) == subtype;\n",
-		clazz.fn_type->getNameAsString().c_str());
-	osprintf(os, "}\n");
-
-	osprintf(os, "template <class T>\n");
-	osprintf(os, "%s %s::isa() const\n", isl_bool2cpp().c_str(), cppname);
-	osprintf(os, "{\n");
-	osprintf(os, "  return isa_type<decltype(T::type)>(T::type);\n");
-	osprintf(os, "}\n");
-
-	osprintf(os, "template <class T>\n");
-	osprintf(os, "T %s::as() const\n", cppname);
-	osprintf(os, "{\n");
-	if (checked)
-		osprintf(os, " if (isa<T>().is_false())\n");
-	else
-		osprintf(os, " if (!isa<T>())\n");
-	print_invalid(os, 4, "not an object of the requested subtype",
-		    "return T()");
-	osprintf(os, "  return T(copy());\n");
-	osprintf(os, "}\n");
-}
-
-/* Print the implementation of the ctx method.
- */
-void cpp_generator::print_ctx_impl(ostream &os, const isl_class &clazz)
-{
-	const char *name = clazz.name.c_str();
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	std::string ns = isl_namespace();
-
-	osprintf(os, "\n");
-	osprintf(os, "%sctx %s::ctx() const {\n", ns.c_str(), cppname);
-	osprintf(os, "  return %sctx(%s_get_ctx(ptr));\n", ns.c_str(), name);
-	osprintf(os, "}\n");
-}
-
-/* Print the implementations of the methods needed for the persistent callbacks
- * of "clazz".
- */
-void cpp_generator::print_persistent_callbacks_impl(ostream &os,
-	const isl_class &clazz)
-{
-	std::string cppstring = type2cpp(clazz);
-	const char *cppname = cppstring.c_str();
-	string classname = type2cpp(clazz);
-	set<FunctionDecl *>::const_iterator in;
-	const set<FunctionDecl *> &callbacks = clazz.persistent_callbacks;
-
-	if (!clazz.has_persistent_callbacks())
-		return;
-
-	osprintf(os, "\n");
-	osprintf(os, "%s &%s::copy_callbacks(const %s &obj)\n",
-		cppname, classname.c_str(), cppname);
-	osprintf(os, "{\n");
-	for (in = callbacks.begin(); in != callbacks.end(); ++in) {
-		string callback_name = clazz.persistent_callback_name(*in);
-
-		osprintf(os, "  %s_data = obj.%s_data;\n",
-			callback_name.c_str(), callback_name.c_str());
-	}
-	osprintf(os, "  return *this;\n");
-	osprintf(os, "}\n");
-
-	for (in = callbacks.begin(); in != callbacks.end(); ++in) {
-		function_kind kind = function_kind_member_method;
-
-		print_set_persistent_callback(os, clazz, *in, kind);
+	while (next_variant(fd, convert)) {
+		print_method(ConversionMethod(method, [&] (int pos) {
+			return get_param(fd, pos, convert);
+		}));
 	}
 }
 
-/* Print definitions for methods of class "clazz" to "os".
+/* Given a function declaration representing a method,
+ * does this method have a single argument (beyond the object
+ * on which the method is called) that corresponds to
+ * an isl object?
  */
-void cpp_generator::print_methods_impl(ostream &os, const isl_class &clazz)
+static bool has_single_isl_argument(FunctionDecl *fd)
 {
-	map<string, function_set>::const_iterator it;
+	ParmVarDecl *param;
 
-	for (it = clazz.methods.begin(); it != clazz.methods.end(); ++it)
-		print_method_group_impl(os, clazz, it->second);
+	if (fd->getNumParams() != 2)
+		return false;
+
+	param = fd->getParamDecl(1);
+	return generator::is_isl_type(param->getOriginalType());
 }
 
-/* Print the definition for a method "method_name" in "clazz" derived
- * from "fd", which sets an enum, to "os".
- * In particular, the method "method_name" sets the enum to "enum_name".
- *
- * The last argument of the C function does not appear in the method call,
- * but is fixed to "enum_name" instead.
- * Other than that, the method printed here is similar to one
- * printed by cpp_generator::print_method_impl, except that
- * some of the special cases do not occur.
+/* Does the set "methods" contain exactly one function declaration
+ * that corresponds to a method of "clazz" itself (i.e., that
+ * was not copied from an ancestor)?
  */
-void cpp_generator::print_set_enum_impl(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd, const string &enum_name, const string &method_name)
-{
-	string c_name = fd->getName().str();
-	int n = fd->getNumParams();
-	function_kind kind = function_kind_member_method;
-
-	osprintf(os, "\n");
-	print_method_header(os, clazz, fd, method_name, n - 1, false, kind);
-	osprintf(os, "{\n");
-
-	print_argument_validity_check(os, fd, kind);
-	print_save_ctx(os, fd, kind);
-	print_on_error_continue(os);
-
-	osprintf(os, "  auto res = %s(", c_name.c_str());
-
-	for (int i = 0; i < n - 1; ++i) {
-		ParmVarDecl *param = fd->getParamDecl(i);
-
-		if (i > 0)
-			osprintf(os, ", ");
-		print_method_param_use(os, param, i == 0);
-	}
-	osprintf(os, ", %s", enum_name.c_str());
-	osprintf(os, ");\n");
-
-	print_exceptional_execution_check(os, clazz, fd, kind);
-	print_method_return(os, clazz, fd);
-
-	osprintf(os, "}\n");
-}
-
-/* Print definitions for the methods in "clazz" derived from "fd",
- * which sets an enum, to "os".
- *
- * A method is generated for each value in the enum, setting
- * the enum to that value.
- */
-void cpp_generator::print_set_enums_impl(ostream &os, const isl_class &clazz,
-	FunctionDecl *fd)
-{
-	vector<set_enum>::const_iterator it;
-	const vector<set_enum> &set_enums = clazz.set_enums.at(fd);
-
-	for (it = set_enums.begin(); it != set_enums.end(); ++it) {
-		print_set_enum_impl(os, clazz, fd, it->name, it->method_name);
-	}
-}
-
-/* Print definitions for methods in "clazz" derived from functions
- * that set an enum, to "os".
- */
-void cpp_generator::print_set_enums_impl(ostream &os, const isl_class &clazz)
-{
-	map<FunctionDecl *, vector<set_enum> >::const_iterator it;
-
-	for (it = clazz.set_enums.begin(); it != clazz.set_enums.end(); ++it)
-		print_set_enums_impl(os, clazz, it->first);
-}
-
-/* Print a definition for the "get" method "fd" in class "clazz",
- * using a name that includes the "get_" prefix, to "os".
- *
- * This definition simply calls the variant without the "get_" prefix and
- * returns its result.
- * Note that static methods are not considered to be "get" methods.
- */
-template<>
-void cpp_generator::print_get_method<cpp_generator::impl>(ostream &os,
-	const isl_class &clazz, FunctionDecl *fd)
-{
-	string get_name = clazz.base_method_name(fd);
-	string name = clazz.method_name(fd);
-	function_kind kind = function_kind_member_method;
-	int num_params = fd->getNumParams();
-
-	osprintf(os, "\n");
-	print_named_method_header(os, clazz, fd, get_name, false, kind);
-	osprintf(os, "{\n");
-	osprintf(os, "  return %s(", name.c_str());
-	for (int i = 1; i < num_params; ++i) {
-		ParmVarDecl *param = fd->getParamDecl(i);
-
-		if (i != 1)
-			osprintf(os, ", ");
-		osprintf(os, "%s", param->getName().str().c_str());
-	}
-	osprintf(os, ");\n");
-	osprintf(os, "}\n");
-}
-
-/* Print definitions for methods "methods" in class "clazz" to "os".
- */
-void cpp_generator::print_method_group_impl(ostream &os, const isl_class &clazz,
+static FunctionDecl *single_local(const isl_class &clazz,
 	const function_set &methods)
 {
-	function_set::const_iterator it;
+	int count = 0;
+	FunctionDecl *local;
 
-	for (it = methods.begin(); it != methods.end(); ++it)
-		print_method_variants<impl>(os, clazz, *it);
+	for (const auto &fn : methods) {
+		if (!clazz.first_arg_matches_class(fn))
+			continue;
+		++count;
+		local = fn;
+	}
+
+	return count == 1 ? local : NULL;
 }
 
-/* Print the use of "param" to "os".
+/* Given a function declaration "fd" for a method called "name"
+ * with a single argument representing an isl object,
+ * generate declarations or definitions for methods with the same name,
+ * but with as argument an isl object of a class that can be implicitly
+ * converted to that of the original argument.
+ * In particular, generate methods for converting this argument.
+ */
+void cpp_generator::class_printer::print_descendent_overloads(
+	FunctionDecl *fd, const std::string &name)
+{
+	Method method(clazz, fd, name);
+	ParmVarDecl *param = fd->getParamDecl(1);
+	QualType type = param->getOriginalType();
+	std::string arg = type->getPointeeType().getAsString();
+
+	for (const auto &kvp : generator.classes[arg].construction_types) {
+		const auto sub = kvp.second;
+		print_method(ConversionMethod(method, [&] (int pos) {
+			return sub;
+		}));
+	}
+}
+
+/* Print declarations or definitions for methods called "name"
+ * derived from "methods".
  *
- * "load_from_this_ptr" specifies whether the parameter should be loaded from
- * the this-ptr.  In case a value is loaded from a this pointer, the original
+ * If want_descendent_overloads signals that variants should be added that take
+ * as arguments those types that can be converted to the original argument type
+ * through a unary constructor and if only one of the methods in the group
+ * was originally defined in "clazz", then effectively add those variants.
+ * Only do this for methods with a single (isl object) argument.
+ */
+void cpp_generator::class_printer::print_method_group(
+	const function_set &methods, const std::string &name)
+{
+	FunctionDecl *local;
+
+	for (const auto &fd : methods)
+		print_method_variants(fd, name);
+	if (!want_descendent_overloads(methods))
+		return;
+	local = single_local(clazz, methods);
+	if (!local)
+		return;
+	if (!has_single_isl_argument(local))
+		return;
+	print_descendent_overloads(local, name);
+}
+
+/* Print the use of the argument at position "pos" to "os".
+ *
+ * Member methods pass the isl object corresponding to "this"
+ * as first argument (at position 0).
+ * Any other arguments are passed along from the method arguments.
+ *
+ * If the argument value is loaded from a this pointer, the original
  * value must be preserved and must consequently be copied.  Values that are
- * loaded from parameters do not need to be preserved, as such values will
- * already be copies of the actual parameters.  It is consequently possible
+ * loaded from method parameters do not need to be preserved, as such values
+ * will already be copies of the actual parameters.  It is consequently possible
  * to directly take the pointer from these values, which saves
  * an unnecessary copy.
  *
@@ -1577,390 +501,84 @@
  * in a structure called <name>_data.
  * The caller of this function must ensure that these variables exist.
  */
-void cpp_generator::print_method_param_use(ostream &os, ParmVarDecl *param,
-	bool load_from_this_ptr)
+void Method::print_param_use(ostream &os, int pos) const
 {
+	ParmVarDecl *param = fd->getParamDecl(pos);
+	bool load_from_this_ptr = pos == 0 && kind == member_method;
 	string name = param->getName().str();
-	const char *name_str = name.c_str();
 	QualType type = param->getOriginalType();
 
 	if (type->isIntegerType()) {
-		osprintf(os, "%s", name_str);
+		os << name;
 		return;
 	}
 
-	if (is_string(type)) {
-		osprintf(os, "%s.c_str()", name_str);
+	if (generator::is_string(type)) {
+		os << name << ".c_str()";
 		return;
 	}
 
-	if (is_callback(type)) {
-		osprintf(os, "%s_lambda, ", name_str);
-		osprintf(os, "&%s_data", name_str);
+	if (generator::is_callback(type)) {
+		os << name << "_lambda, ";
+		os << "&" << name << "_data";
 		return;
 	}
 
 	if (!load_from_this_ptr)
-		osprintf(os, "%s.", name_str);
+		os << name << ".";
 
-	if (keeps(param)) {
-		osprintf(os, "get()");
+	if (generator::keeps(param)) {
+		os << "get()";
 	} else {
 		if (load_from_this_ptr)
-			osprintf(os, "copy()");
+			os << "copy()";
 		else
-			osprintf(os, "release()");
+			os << "release()";
 	}
 }
 
-/* Print code that checks that all isl object arguments to "method" are valid
- * (not NULL) and throws an exception if they are not.
- * "kind" specifies the kind of method that is being generated.
- *
- * If checked bindings are being generated,
- * then no such check is performed.
+/* Does the isl function from which this method is derived
+ * modify an object of a subclass based on a type function?
  */
-void cpp_generator::print_argument_validity_check(ostream &os,
-	FunctionDecl *method, function_kind kind)
-{
-	int n;
-	bool first = true;
-
-	if (checked)
-		return;
-
-	n = method->getNumParams();
-	for (int i = 0; i < n; ++i) {
-		bool is_this;
-		ParmVarDecl *param = method->getParamDecl(i);
-		string name = param->getName().str();
-		const char *name_str = name.c_str();
-		QualType type = param->getOriginalType();
-
-		is_this = i == 0 && kind == function_kind_member_method;
-		if (!is_this && (is_isl_ctx(type) || !is_isl_type(type)))
-			continue;
-
-		if (first)
-			osprintf(os, "  if (");
-		else
-			osprintf(os, " || ");
-
-		if (is_this)
-			osprintf(os, "!ptr");
-		else
-			osprintf(os, "%s.is_null()", name_str);
-
-		first = false;
-	}
-	if (first)
-		return;
-	osprintf(os, ")\n");
-	print_throw_NULL_input(os);
-}
-
-/* Print code for saving a copy of the isl::ctx available at the start
- * of the method "method" in a "saved_ctx" variable,
- * for use in exception handling.
- * "kind" specifies what kind of method "method" is.
- *
- * If checked bindings are being generated,
- * then the "saved_ctx" variable is not needed.
- * If "method" is a member function, then obtain the isl_ctx from
- * the "this" object.
- * If the first argument of the method is an isl::ctx, then use that one.
- * Otherwise, save a copy of the isl::ctx associated to the first argument
- * of isl object type.
- */
-void cpp_generator::print_save_ctx(ostream &os, FunctionDecl *method,
-	function_kind kind)
-{
-	int n;
-	ParmVarDecl *param = method->getParamDecl(0);
-	QualType type = param->getOriginalType();
-
-	if (checked)
-		return;
-	if (kind == function_kind_member_method) {
-		osprintf(os, "  auto saved_ctx = ctx();\n");
-		return;
-	}
-	if (is_isl_ctx(type)) {
-		const char *name;
-
-		name = param->getName().str().c_str();
-		osprintf(os, "  auto saved_ctx = %s;\n", name);
-		return;
-	}
-	n = method->getNumParams();
-	for (int i = 0; i < n; ++i) {
-		ParmVarDecl *param = method->getParamDecl(i);
-		QualType type = param->getOriginalType();
-
-		if (!is_isl_type(type))
-			continue;
-		osprintf(os, "  auto saved_ctx = %s.ctx();\n",
-			param->getName().str().c_str());
-		return;
-	}
-}
-
-/* Print code to make isl not print an error message when an error occurs
- * within the current scope (if exceptions are available),
- * since the error message will be included in the exception.
- * If exceptions are not available, then exception::on_error
- * is set to ISL_ON_ERROR_ABORT and isl is therefore made to abort instead.
- *
- * If checked bindings are being generated,
- * then leave it to the user to decide what isl should do on error.
- * Otherwise, assume that a valid isl::ctx is available
- * in the "saved_ctx" variable,
- * e.g., through a prior call to print_save_ctx.
- */
-void cpp_generator::print_on_error_continue(ostream &os)
-{
-	if (checked)
-		return;
-	osprintf(os, "  options_scoped_set_on_error saved_on_error(saved_ctx, "
-		     "exception::on_error);\n");
-}
-
-/* Print code to "os" that checks whether any of the persistent callbacks
- * of "clazz" is set and if it failed with an exception.  If so, the "eptr"
- * in the corresponding data structure contains the exception
- * that was caught and that needs to be rethrown.
- * This field is cleared because the callback and its data may get reused.
- *
- * The check only needs to be generated for member methods since
- * an object is needed for any of the persistent callbacks to be set.
- */
-static void print_persistent_callback_exceptional_execution_check(ostream &os,
-	const isl_class &clazz, cpp_generator::function_kind kind)
-{
-	const set<FunctionDecl *> &callbacks = clazz.persistent_callbacks;
-	set<FunctionDecl *>::const_iterator in;
-
-	if (kind != cpp_generator::function_kind_member_method)
-		return;
-
-	for (in = callbacks.begin(); in != callbacks.end(); ++in) {
-		string callback_name = clazz.persistent_callback_name(*in);
-
-		osprintf(os, "  if (%s_data && %s_data->eptr) {\n",
-			callback_name.c_str(), callback_name.c_str());
-		osprintf(os, "    std::exception_ptr eptr = %s_data->eptr;\n",
-			callback_name.c_str());
-		osprintf(os, "    %s_data->eptr = nullptr;\n",
-			callback_name.c_str());
-		osprintf(os, "    std::rethrow_exception(eptr);\n");
-		osprintf(os, "  }\n");
-	}
-}
-
-/* Print code that checks whether the execution of the core of "method"
- * of class "clazz" was successful.
- * "kind" specifies what kind of method "method" is.
- *
- * If checked bindings are being generated,
- * then no checks are performed.
- *
- * Otherwise, first check if any of the callbacks failed with
- * an exception.  If so, the "eptr" in the corresponding data structure
- * contains the exception that was caught and that needs to be rethrown.
- * Then check if the function call failed in any other way and throw
- * the appropriate exception.
- * In particular, if the return type is isl_stat, isl_bool or isl_size,
- * then a negative value indicates a failure.  If the return type
- * is an isl type, then a NULL value indicates a failure.
- * Assume print_save_ctx has made sure that a valid isl::ctx
- * is available in the "ctx" variable.
- */
-void cpp_generator::print_exceptional_execution_check(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, function_kind kind)
-{
-	int n;
-	bool check_null, check_neg;
-	QualType return_type = method->getReturnType();
-
-	if (checked)
-		return;
-
-	print_persistent_callback_exceptional_execution_check(os, clazz, kind);
-
-	n = method->getNumParams();
-	for (int i = 0; i < n; ++i) {
-		ParmVarDecl *param = method->getParamDecl(i);
-		const char *name;
-
-		if (!is_callback(param->getOriginalType()))
-			continue;
-		name = param->getName().str().c_str();
-		osprintf(os, "  if (%s_data.eptr)\n", name);
-		osprintf(os, "    std::rethrow_exception(%s_data.eptr);\n",
-			name);
-	}
-
-	check_neg = is_isl_neg_error(return_type);
-	check_null = is_isl_type(return_type);
-	if (!check_null && !check_neg)
-		return;
-
-	if (check_neg)
-		osprintf(os, "  if (res < 0)\n");
-	else
-		osprintf(os, "  if (!res)\n");
-	print_throw_last_error(os);
-}
-
-/* Does "fd" modify an object of a subclass based on a type function?
- */
-static bool is_subclass_mutator(const isl_class &clazz, FunctionDecl *fd)
+bool Method::is_subclass_mutator() const
 {
 	return clazz.is_type_subclass() && generator::is_mutator(clazz, fd);
 }
 
-/* Return the C++ return type of the method corresponding to "fd" in "clazz".
+/* Return the C++ return type of the method "method".
  *
- * If "fd" modifies an object of a subclass, then return
+ * If the corresponding function modifies an object of a subclass, then return
  * the type of this subclass.
  * Otherwise, return the C++ counterpart of the actual return type.
  */
-std::string cpp_generator::get_return_type(const isl_class &clazz,
-	FunctionDecl *fd)
+std::string cpp_type_printer::return_type(const Method &method) const
 {
-	if (is_subclass_mutator(clazz, fd))
-		return type2cpp(clazz);
+	if (method.is_subclass_mutator())
+		return cpp_generator::type2cpp(method.clazz);
 	else
-		return type2cpp(fd->getReturnType());
-}
-
-/* Given a function "method" for setting a "clazz" persistent callback,
- * print the implementations of the methods needed for that callback.
- *
- * In particular, print
- * - the implementation of a static inline method
- *   for use as the C callback function
- * - the definition of a private method for setting the callback function
- * - the public method for constructing a new object with the callback set.
- */
-void cpp_generator::print_set_persistent_callback(ostream &os,
-	const isl_class &clazz, FunctionDecl *method,
-	function_kind kind)
-{
-	string fullname = method->getName().str();
-	ParmVarDecl *param = persistent_callback_arg(method);
-	string classname = type2cpp(clazz);
-	string pname;
-	string callback_name = clazz.persistent_callback_name(method);
-
-	osprintf(os, "\n");
-	print_persistent_callback_prototype(os, clazz, method, false);
-	osprintf(os, "\n");
-	osprintf(os, "{\n");
-	print_callback_body(os, 2, param, callback_name);
-	osprintf(os, "}\n\n");
-
-	pname = param->getName().str();
-	print_persistent_callback_setter_prototype(os, clazz, method, false);
-	osprintf(os, "\n");
-	osprintf(os, "{\n");
-	print_check_ptr_start(os, clazz, "ptr");
-	osprintf(os, "  %s_data = std::make_shared<struct %s_data>();\n",
-		callback_name.c_str(), callback_name.c_str());
-	osprintf(os, "  %s_data->func = %s;\n",
-		callback_name.c_str(), pname.c_str());
-	osprintf(os, "  ptr = %s(ptr, &%s, %s_data.get());\n",
-		fullname.c_str(), callback_name.c_str(), callback_name.c_str());
-	print_check_ptr_end(os, "ptr");
-	osprintf(os, "}\n\n");
-
-	print_method_header(os, clazz, method, false, kind);
-	osprintf(os, "{\n");
-	osprintf(os, "  auto copy = *this;\n");
-	osprintf(os, "  copy.set_%s_data(%s);\n",
-		callback_name.c_str(), pname.c_str());
-	osprintf(os, "  return copy;\n");
-	osprintf(os, "}\n");
-}
-
-/* Print the return statement of the C++ method corresponding
- * to the C function "method" in class "clazz" to "os".
- *
- * The result of the isl function is returned as a new
- * object if the underlying isl function returns an isl_* ptr, as a bool
- * if the isl function returns an isl_bool, as void if the isl functions
- * returns an isl_stat,
- * as std::string if the isl function returns 'const char *', and as
- * unmodified return value otherwise.
- * If checked C++ bindings are being generated,
- * then an isl_bool return type is transformed into a boolean and
- * an isl_stat into a stat since no exceptions can be generated
- * on negative results from the isl function.
- * If the method returns a new instance of the same object type and
- * if the class has any persistent callbacks, then the data
- * for these callbacks are copied from the original to the new object.
- * If "clazz" is a subclass that is based on a type function and
- * if the return type corresponds to the superclass data type,
- * then it is replaced by the subclass data type.
- */
-void cpp_generator::print_method_return(ostream &os, const isl_class &clazz,
-	FunctionDecl *method)
-{
-	QualType return_type = method->getReturnType();
-	string rettype_str = get_return_type(clazz, method);
-	bool returns_super = is_subclass_mutator(clazz, method);
-
-	if (is_isl_type(return_type) ||
-		    (checked && is_isl_neg_error(return_type))) {
-		osprintf(os, "  return manage(res)");
-		if (is_mutator(clazz, method) &&
-		    clazz.has_persistent_callbacks())
-			osprintf(os, ".copy_callbacks(*this)");
-		if (returns_super)
-			osprintf(os, ".as<%s>()", rettype_str.c_str());
-		osprintf(os, ";\n");
-	} else if (is_isl_stat(return_type)) {
-		osprintf(os, "  return;\n");
-	} else if (is_string(return_type)) {
-		osprintf(os, "  std::string tmp(res);\n");
-		if (gives(method))
-			osprintf(os, "  free(res);\n");
-		osprintf(os, "  return tmp;\n");
-	} else {
-		osprintf(os, "  return res;\n");
-	}
+		return param(-1, method.fd->getReturnType());
 }
 
 /* Return the formal parameter at position "pos" of "fd".
  * However, if this parameter should be converted, as indicated
  * by "convert", then return the second formal parameter
  * of the conversion function instead.
- *
- * If "convert" is empty, then it is assumed that
- * none of the arguments should be converted.
  */
-ParmVarDecl *cpp_generator::get_param(FunctionDecl *fd, int pos,
-	const std::vector<bool> &convert)
+ParmVarDecl *cpp_generator::class_printer::get_param(FunctionDecl *fd,
+	int pos, const std::vector<bool> &convert)
 {
 	ParmVarDecl *param = fd->getParamDecl(pos);
 
-	if (convert.size() == 0)
-		return param;
 	if (!convert[pos])
 		return param;
-	return conversions[param->getOriginalType().getTypePtr()];
+	return generator.conversions[param->getOriginalType().getTypePtr()];
 }
 
-/* Print the header for "method" in class "clazz", with name "cname" and
- * "num_params" number of arguments, to "os".
+/* Print the header for "method", without newline or semicolon,
+ * using "type_printer" to print argument and return types.
  *
- * Print the header of a declaration if "is_declaration" is set, otherwise print
- * the header of a method definition.
- *
- * "kind" specifies the kind of method that should be generated.
- *
- * "convert" specifies which of the method arguments should
- * be automatically converted.
+ * Print the header of a declaration if this->declarations is set,
+ * otherwise print the header of a method definition.
  *
  * This function prints headers for member methods, static methods, and
  * constructors, either for their declaration or definition.
@@ -1978,13 +596,12 @@
  *
  * is translated into:
  *
- * 	inline set intersect(set set2) const;
+ * 	inline set intersect(set set2) const
  *
  * For static functions and constructors all parameters of the original isl
  * function are exposed.
  *
- * Parameters that are defined as __isl_keep, are of type string or
- * are callbacks, are passed
+ * Parameters of which no copy is required, are passed
  * as const reference, which allows the compiler to optimize the parameter
  * transfer.
  *
@@ -1995,123 +612,62 @@
  * for these constructors, whereas without a comment not every user would
  * know that implicit construction is allowed in absence of an explicit keyword.
  *
- * If any of the arguments needs to be converted, then the argument
- * of the method is changed to that of the source of the conversion.
+ * Note that in case "method" is a ConversionMethod, the argument returned
+ * by Method::get_param may be different from the original argument.
  * The name of the argument is, however, derived from the original
  * function argument.
  */
-void cpp_generator::print_method_header(ostream &os, const isl_class &clazz,
-	FunctionDecl *method, const string &cname, int num_params,
-	bool is_declaration, function_kind kind,
-	const std::vector<bool> &convert)
+void cpp_generator::class_printer::print_method_header(
+	const Method &method, const cpp_type_printer &type_printer)
 {
-	string rettype_str = get_return_type(clazz, method);
-	string classname = type2cpp(clazz);
-	int first_param = 0;
+	string rettype_str = type_printer.return_type(method);
 
-	if (kind == function_kind_member_method)
-		first_param = 1;
+	if (declarations) {
+		os << "  ";
 
-	if (is_declaration) {
-		osprintf(os, "  ");
+		if (method.kind == Method::Kind::static_method)
+			os << "static ";
 
-		if (kind == function_kind_static_method)
-			osprintf(os, "static ");
+		os << "inline ";
 
-		osprintf(os, "inline ");
-
-		if (kind == function_kind_constructor) {
-			if (is_implicit_conversion(clazz, method))
-				osprintf(os, "/* implicit */ ");
+		if (method.kind == Method::Kind::constructor) {
+			if (generator.is_implicit_conversion(method))
+				os << "/* implicit */ ";
 			else
-				osprintf(os, "explicit ");
+				os << "explicit ";
 		}
 	}
 
-	if (kind != function_kind_constructor)
-		osprintf(os, "%s ", rettype_str.c_str());
+	if (method.kind != Method::Kind::constructor)
+		os << rettype_str << " ";
 
-	if (!is_declaration)
-		osprintf(os, "%s::", classname.c_str());
+	if (!declarations)
+		os << type_printer.class_type(cppstring) << "::";
 
-	if (kind != function_kind_constructor)
-		osprintf(os, "%s", cname.c_str());
+	if (method.kind != Method::Kind::constructor)
+		os << method.name;
 	else
-		osprintf(os, "%s", classname.c_str());
+		os << cppstring;
 
-	osprintf(os, "(");
-
-	for (int i = first_param; i < num_params; ++i) {
-		std::string name = method->getParamDecl(i)->getName().str();
-		ParmVarDecl *param = get_param(method, i, convert);
+	method.print_cpp_arg_list(os, [&] (int i) {
+		std::string name = method.fd->getParamDecl(i)->getName().str();
+		ParmVarDecl *param = method.get_param(i);
 		QualType type = param->getOriginalType();
-		string cpptype = type2cpp(type);
+		string cpptype = type_printer.param(i, type);
 
-		if (is_callback(type))
-			num_params--;
-
-		if (keeps(param) || is_string(type) || is_callback(type))
-			osprintf(os, "const %s &%s", cpptype.c_str(),
-				 name.c_str());
+		if (!method.param_needs_copy(i))
+			os << "const " << cpptype << " &" << name;
 		else
-			osprintf(os, "%s %s", cpptype.c_str(), name.c_str());
+			os << cpptype << " " << name;
+	});
 
-		if (i != num_params - 1)
-			osprintf(os, ", ");
-	}
-
-	osprintf(os, ")");
-
-	if (kind == function_kind_member_method)
-		osprintf(os, " const");
-
-	if (is_declaration)
-		osprintf(os, ";");
-	osprintf(os, "\n");
-}
-
-/* Print the header for a method called "name" in class "clazz"
- * derived from "method" to "os".
- *
- * Print the header of a declaration if "is_declaration" is set, otherwise print
- * the header of a method definition.
- *
- * "kind" specifies the kind of method that should be generated.
- *
- * "convert" specifies which of the method arguments should
- * be automatically converted.
- */
-void cpp_generator::print_named_method_header(ostream &os,
-	const isl_class &clazz, FunctionDecl *method, string name,
-	bool is_declaration, function_kind kind,
-	const std::vector<bool> &convert)
-{
-	int num_params = method->getNumParams();
-
-	name = rename_method(name);
-	print_method_header(os, clazz, method, name, num_params,
-			    is_declaration, kind, convert);
-}
-
-/* Print the header for "method" in class "clazz" to "os"
- * using its default name.
- *
- * Print the header of a declaration if "is_declaration" is set, otherwise print
- * the header of a method definition.
- *
- * "kind" specifies the kind of method that should be generated.
- */
-void cpp_generator::print_method_header(ostream &os, const isl_class &clazz,
-	FunctionDecl *method, bool is_declaration, function_kind kind)
-{
-	string name = clazz.method_name(method);
-
-	print_named_method_header(os, clazz, method, name, is_declaration,
-				  kind);
+	if (method.kind == Method::Kind::member_method)
+		os << " const";
 }
 
 /* Generate the list of argument types for a callback function of
- * type "type".  If "cpp" is set, then generate the C++ type list, otherwise
+ * type "type", appearing in argument position "arg".
+ * If "cpp" is set, then generate the C++ type list, otherwise
  * the C type list.
  *
  * For a callback of type
@@ -2121,14 +677,18 @@
  * the following C++ argument list is generated:
  *
  *      map
+ *
+ * The arguments of the callback are considered to appear
+ * after the position of the callback itself.
  */
-string cpp_generator::generate_callback_args(QualType type, bool cpp)
+std::string cpp_type_printer::generate_callback_args(int arg, QualType type,
+	bool cpp) const
 {
 	std::string type_str;
 	const FunctionProtoType *callback;
 	int num_params;
 
-	callback = extract_prototype(type);
+	callback = generator::extract_prototype(type);
 	num_params = callback->getNumArgs();
 	if (cpp)
 		num_params--;
@@ -2137,7 +697,7 @@
 		QualType type = callback->getArgType(i);
 
 		if (cpp)
-			type_str += type2cpp(type);
+			type_str += param(arg + 1 + i, type);
 		else
 			type_str += type.getAsString();
 
@@ -2151,7 +711,8 @@
 	return type_str;
 }
 
-/* Generate the full cpp type of a callback function of type "type".
+/* Generate the full cpp type of a callback function of type "type",
+ * appearing in argument position "arg".
  *
  * For a callback of type
  *
@@ -2161,278 +722,23 @@
  *
  *      std::function<stat(map)>
  */
-string cpp_generator::generate_callback_type(QualType type)
+std::string cpp_type_printer::generate_callback_type(int arg, QualType type)
+	const
 {
 	std::string type_str;
-	const FunctionProtoType *callback = extract_prototype(type);
+	const FunctionProtoType *callback = generator::extract_prototype(type);
 	QualType return_type = callback->getReturnType();
-	string rettype_str = type2cpp(return_type);
+	string rettype_str = param(arg, return_type);
 
 	type_str = "std::function<";
 	type_str += rettype_str;
 	type_str += "(";
-	type_str += generate_callback_args(type, true);
+	type_str += generate_callback_args(arg, type, true);
 	type_str += ")>";
 
 	return type_str;
 }
 
-/* Print the call to the C++ callback function "call",
- * with the given indentation, wrapped
- * for use inside the lambda function that is used as the C callback function,
- * in the case where checked C++ bindings are being generated.
- *
- * In particular, print
- *
- *        auto ret = @call@;
- *        return ret.release();
- */
-void cpp_generator::print_wrapped_call_checked(ostream &os, int indent,
-	const string &call)
-{
-	osprintf(os, indent, "auto ret = %s;\n", call.c_str());
-	osprintf(os, indent, "return ret.release();\n");
-}
-
-/* Print the call to the C++ callback function "call",
- * with the given indentation and with return type "rtype", wrapped
- * for use inside the lambda function that is used as the C callback function.
- *
- * In particular, print
- *
- *        ISL_CPP_TRY {
- *          @call@;
- *          return isl_stat_ok;
- *        } ISL_CPP_CATCH_ALL {
- *          data->eptr = std::current_exception();
- *          return isl_stat_error;
- *        }
- * or
- *        ISL_CPP_TRY {
- *          auto ret = @call@;
- *          return ret ? isl_bool_true : isl_bool_false;
- *        } ISL_CPP_CATCH_ALL {
- *          data->eptr = std::current_exception();
- *          return isl_bool_error;
- *        }
- * or
- *        ISL_CPP_TRY {
- *          auto ret = @call@;
- *          return ret.release();
- *        } ISL_CPP_CATCH_ALL {
- *          data->eptr = std::current_exception();
- *          return NULL;
- *        }
- *
- * depending on the return type.
- *
- * where ISL_CPP_TRY is defined to "try" and ISL_CPP_CATCH_ALL to "catch (...)"
- * (if exceptions are available).
- *
- * If checked C++ bindings are being generated, then
- * the call is wrapped differently.
- */
-void cpp_generator::print_wrapped_call(ostream &os, int indent,
-	const string &call, QualType rtype)
-{
-	if (checked)
-		return print_wrapped_call_checked(os, indent, call);
-
-	osprintf(os, indent, "ISL_CPP_TRY {\n");
-	if (is_isl_stat(rtype))
-		osprintf(os, indent, "  %s;\n", call.c_str());
-	else
-		osprintf(os, indent, "  auto ret = %s;\n", call.c_str());
-	if (is_isl_stat(rtype))
-		osprintf(os, indent, "  return isl_stat_ok;\n");
-	else if (is_isl_bool(rtype))
-		osprintf(os, indent,
-			"  return ret ? isl_bool_true : isl_bool_false;\n");
-	else
-		osprintf(os, indent, "  return ret.release();\n");
-	osprintf(os, indent, "} ISL_CPP_CATCH_ALL {\n");
-	osprintf(os, indent, "  data->eptr = std::current_exception();\n");
-	if (is_isl_stat(rtype))
-		osprintf(os, indent, "  return isl_stat_error;\n");
-	else if (is_isl_bool(rtype))
-		osprintf(os, indent, "  return isl_bool_error;\n");
-	else
-		osprintf(os, indent, "  return NULL;\n");
-	osprintf(os, indent, "}\n");
-}
-
-/* Print the declaration for a "prefix"_data data structure
- * that can be used for passing to a C callback function
- * containing a copy of the C++ callback function "param",
- * along with an std::exception_ptr that is used to store any
- * exceptions thrown in the C++ callback.
- *
- * If the C callback is of the form
- *
- *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
- *
- * then the following declaration is printed:
- *
- *      struct <prefix>_data {
- *        std::function<stat(map)> func;
- *        std::exception_ptr eptr;
- *      }
- *
- * (without a newline or a semicolon).
- *
- * The std::exception_ptr object is not added to "prefix"_data
- * if checked C++ bindings are being generated.
- */
-void cpp_generator::print_callback_data_decl(ostream &os, ParmVarDecl *param,
-	const string &prefix)
-{
-	string cpp_args;
-
-	cpp_args = generate_callback_type(param->getType());
-
-	osprintf(os, "  struct %s_data {\n", prefix.c_str());
-	osprintf(os, "    %s func;\n", cpp_args.c_str());
-	if (!checked)
-		osprintf(os, "    std::exception_ptr eptr;\n");
-	osprintf(os, "  }");
-}
-
-/* Print the body of C function callback with the given indentation
- * that can be use as an argument to "param" for marshalling
- * the corresponding C++ callback.
- * The data structure that contains the C++ callback is of type
- * "prefix"_data.
- *
- * For a callback of the form
- *
- *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
- *
- * the following code is generated:
- *
- *        auto *data = static_cast<struct <prefix>_data *>(arg_1);
- *        ISL_CPP_TRY {
- *          stat ret = (data->func)(manage(arg_0));
- *          return isl_stat_ok;
- *        } ISL_CPP_CATCH_ALL {
- *          data->eptr = std::current_exception();
- *          return isl_stat_error;
- *        }
- *
- * If checked C++ bindings are being generated, then
- * generate the following code:
- *
- *        auto *data = static_cast<struct <prefix>_data *>(arg_1);
- *        stat ret = (data->func)(manage(arg_0));
- *        return isl_stat(ret);
- */
-void cpp_generator::print_callback_body(ostream &os, int indent,
-	ParmVarDecl *param, const string &prefix)
-{
-	QualType ptype, rtype;
-	string call, last_idx;
-	const FunctionProtoType *callback;
-	int num_params;
-
-	ptype = param->getType();
-
-	callback = extract_prototype(ptype);
-	rtype = callback->getReturnType();
-	num_params = callback->getNumArgs();
-
-	last_idx = ::to_string(num_params - 1);
-
-	call = "(data->func)(";
-	for (long i = 0; i < num_params - 1; i++) {
-		if (!callback_takes_argument(param, i))
-			call += "manage_copy";
-		else
-			call += "manage";
-		call += "(arg_" + ::to_string(i) + ")";
-		if (i != num_params - 2)
-			call += ", ";
-	}
-	call += ")";
-
-	osprintf(os, indent,
-		 "auto *data = static_cast<struct %s_data *>(arg_%s);\n",
-		 prefix.c_str(), last_idx.c_str());
-	print_wrapped_call(os, indent, call, rtype);
-}
-
-/* Print the local variables that are needed for a callback argument,
- * in particular, print a lambda function that wraps the callback and
- * a pointer to the actual C++ callback function.
- *
- * For a callback of the form
- *
- *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
- *
- * the following lambda function is generated:
- *
- *      auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat {
- *        auto *data = static_cast<struct fn_data *>(arg_1);
- *        try {
- *          stat ret = (data->func)(manage(arg_0));
- *          return isl_stat_ok;
- *        } catch (...) {
- *          data->eptr = std::current_exception();
- *          return isl_stat_error;
- *        }
- *      };
- *
- * A copy of the std::function C++ callback function is stored in
- * a fn_data data structure for passing to the C callback function,
- * along with an std::exception_ptr that is used to store any
- * exceptions thrown in the C++ callback.
- *
- *      struct fn_data {
- *        std::function<stat(map)> func;
- *        std::exception_ptr eptr;
- *      } fn_data = { fn };
- *
- * This std::function object represents the actual user
- * callback function together with the locally captured state at the caller.
- *
- * The lambda function is expected to be used as a C callback function
- * where the lambda itself is provided as the function pointer and
- * where the user void pointer is a pointer to fn_data.
- * The std::function object is extracted from the pointer to fn_data
- * inside the lambda function.
- *
- * The std::exception_ptr object is not added to fn_data
- * if checked C++ bindings are being generated.
- * The body of the generated lambda function then is as follows:
- *
- *        stat ret = (data->func)(manage(arg_0));
- *        return isl_stat(ret);
- *
- * If the C callback does not take its arguments, then
- * manage_copy is used instead of manage.
- */
-void cpp_generator::print_callback_local(ostream &os, ParmVarDecl *param)
-{
-	string pname;
-	QualType ptype, rtype;
-	string c_args, cpp_args, rettype;
-	const FunctionProtoType *callback;
-
-	pname = param->getName().str();
-	ptype = param->getType();
-
-	c_args = generate_callback_args(ptype, false);
-
-	callback = extract_prototype(ptype);
-	rtype = callback->getReturnType();
-	rettype = rtype.getAsString();
-
-	print_callback_data_decl(os, param, pname);
-	osprintf(os, " %s_data = { %s };\n", pname.c_str(), pname.c_str());
-	osprintf(os, "  auto %s_lambda = [](%s) -> %s {\n",
-		 pname.c_str(), c_args.c_str(), rettype.c_str());
-	print_callback_body(os, 4, param, pname);
-	osprintf(os, "  };\n");
-}
-
 /* An array listing functions that must be renamed and the function name they
  * should be renamed to. We currently rename functions in case their name would
  * match a reserved C++ keyword, which is not allowed in C++.
@@ -2445,7 +751,7 @@
  * match the name in the C bindings. We do this for example to avoid
  * C++ keywords.
  */
-std::string cpp_generator::rename_method(std::string name)
+static std::string rename_method(std::string name)
 {
 	for (size_t i = 0; i < sizeof(rename_map) / sizeof(rename_map[0]); i++)
 		if (name.compare(rename_map[i][0]) == 0)
@@ -2470,55 +776,102 @@
 }
 
 /* Return the C++ counterpart to the isl_bool type.
- * If checked C++ bindings are being generated,
- * then this is "boolean".  Otherwise, it is simply "bool".
+ *
+ * By default, this is simply "bool" since
+ * the exceptional case is handled through exceptions.
  */
-string cpp_generator::isl_bool2cpp()
+std::string cpp_type_printer::isl_bool() const
 {
-	return checked ? "boolean" : "bool";
+	return "bool";
+}
+
+/* Return the C++ counterpart to the isl_stat type.
+ *
+ * By default, this is simply "void" since
+ * the exceptional case is handled through exceptions.
+ */
+string cpp_type_printer::isl_stat() const
+{
+	return "void";
+}
+
+/* Return the C++ counterpart to the isl_size type.
+ *
+ * By default, this is simply "unsigned" since
+ * the exceptional case is handled through exceptions.
+ */
+string cpp_type_printer::isl_size() const
+{
+	return "unsigned";
 }
 
 /* Return the namespace of the generated C++ bindings.
+ *
+ * By default, this is "isl::".
  */
-string cpp_generator::isl_namespace()
+std::string cpp_type_printer::isl_namespace() const
 {
-	return checked ? "isl::checked::" : "isl::";
+	return "isl::";
 }
 
-/* Translate QualType "type" to its C++ name counterpart.
+/* Return the class type given the C++ name.
  *
- * An isl_bool return type is translated into "bool",
- * while an isl_stat is translated into "void" and
- * an isl_size is translated to "unsigned".
- * The exceptional cases are handled through exceptions.
- * If checked C++ bindings are being generated, then
- * C++ counterparts of isl_bool, isl_stat and isl_size need to be used instead.
+ * By default, directly use the C++ name.
  */
-string cpp_generator::type2cpp(QualType type)
+std::string cpp_type_printer::class_type(const std::string &cpp_name) const
 {
-	if (is_isl_type(type))
-		return isl_namespace() +
-				type2cpp(type->getPointeeType().getAsString());
+	return cpp_name;
+}
 
-	if (is_isl_bool(type))
-		return isl_bool2cpp();
+/* Return the qualified form of the given C++ isl type name appearing
+ * in argument position "arg" (-1 for return type).
+ *
+ * By default, the argument position is ignored.
+ */
+std::string cpp_type_printer::qualified(int arg, const std::string &cpp_type)
+	const
+{
+	return isl_namespace() + cpp_type;
+}
 
-	if (is_isl_stat(type))
-		return checked ? "stat" : "void";
+/* Return the C++ counterpart to the given isl type appearing
+ * in argument position "arg" (-1 for return type).
+ */
+std::string cpp_type_printer::isl_type(int arg, QualType type) const
+{
+	auto name = type->getPointeeType().getAsString();
+	return qualified(arg, cpp_generator::type2cpp(name));
+}
 
-	if (is_isl_size(type))
-		return checked ? "class size" : "unsigned";
+/* Translate parameter or return type "type" to its C++ name counterpart.
+ * "arg" is the position of the argument, or -1 in case of the return type.
+ * If any callback is involved, then the return type and arguments types
+ * of the callback are considered to start at the position of the callback.
+ */
+std::string cpp_type_printer::param(int arg, QualType type) const
+{
+	if (cpp_generator::is_isl_type(type))
+		return isl_type(arg, type);
+
+	if (cpp_generator::is_isl_bool(type))
+		return isl_bool();
+
+	if (cpp_generator::is_isl_stat(type))
+		return isl_stat();
+
+	if (cpp_generator::is_isl_size(type))
+		return isl_size();
 
 	if (type->isIntegerType())
 		return type.getAsString();
 
-	if (is_string(type))
+	if (cpp_generator::is_string(type))
 		return "std::string";
 
-	if (is_callback(type))
-		return generate_callback_type(type);
+	if (cpp_generator::is_callback(type))
+		return generate_callback_type(arg, type);
 
-	die("Cannot convert type to C++ type");
+	generator::die("Cannot convert type to C++ type");
 }
 
 /* Check if "subclass_type" is a subclass of "class_type".
@@ -2559,13 +912,13 @@
  * parameter, where the parameter type is a subclass of the class that is
  * currently being generated.
  */
-bool cpp_generator::is_implicit_conversion(const isl_class &clazz,
-	FunctionDecl *cons)
+bool cpp_generator::is_implicit_conversion(const Method &cons)
 {
-	ParmVarDecl *param = cons->getParamDecl(0);
+	const auto &clazz = cons.clazz;
+	ParmVarDecl *param = cons.fd->getParamDecl(0);
 	QualType type = param->getOriginalType();
 
-	int num_params = cons->getNumParams();
+	int num_params = cons.fd->getNumParams();
 	if (num_params != 1)
 		return false;
 
@@ -2579,11 +932,270 @@
  *
  * Given the declaration of a static or member method, returns its kind.
  */
-cpp_generator::function_kind cpp_generator::get_method_kind(
-	const isl_class &clazz, FunctionDecl *method)
+static Method::Kind get_kind(const isl_class &clazz, FunctionDecl *method)
 {
-	if (is_static(clazz, method))
-		return function_kind_static_method;
+	if (generator::is_constructor(method))
+		return Method::Kind::constructor;
+	else if (generator::is_static(clazz, method))
+		return Method::Kind::static_method;
 	else
-		return function_kind_member_method;
+		return Method::Kind::member_method;
+}
+
+/* Return the callback argument of "fd", if there is any.
+ * Return NULL otherwise.
+ */
+static ParmVarDecl *find_callback_arg(FunctionDecl *fd)
+{
+	int num_params = fd->getNumParams();
+
+	for (int i = 0; i < num_params; ++i) {
+		ParmVarDecl *param = fd->getParamDecl(i);
+		if (generator::is_callback(param->getType()))
+			return param;
+	}
+
+	return NULL;
+}
+
+/* Construct a C++ method object from the class to which is belongs,
+ * the isl function from which it is derived and the method name.
+ *
+ * Perform any renaming of the method that may be required and
+ * determine the type of the method.
+ */
+Method::Method(const isl_class &clazz, FunctionDecl *fd,
+	const std::string &name) :
+		clazz(clazz), fd(fd), name(rename_method(name)),
+		kind(get_kind(clazz, fd)),
+		callback(find_callback_arg(fd))
+{
+}
+
+/* Construct a C++ method object from the class to which is belongs and
+ * the isl function from which it is derived.
+ *
+ * Obtain the default method name and continue
+ * with the generic constructor.
+ */
+Method::Method(const isl_class &clazz, FunctionDecl *fd) :
+	Method(clazz, fd, clazz.method_name(fd))
+{
+}
+
+/* Return the number of parameters of the corresponding C function.
+ *
+ * If the method has a callback argument, we reduce the number of parameters
+ * that are exposed by one to hide the user pointer from the interface. On
+ * the C++ side no user pointer is needed, as arguments can be forwarded
+ * as part of the std::function argument which specifies the callback function.
+ *
+ * The user pointer is also removed from the number of parameters
+ * of the C function because the pair of callback and user pointer
+ * is considered as a single argument that is printed as a whole
+ * by Method::print_param_use.
+ */
+int Method::c_num_params() const
+{
+	return fd->getNumParams() - (callback != NULL);
+}
+
+/* Return the number of parameters of the method
+ * (including the implicit "this").
+ *
+ * By default, it is the same as the number of parameters
+ * of the corresponding C function.
+ */
+int Method::num_params() const
+{
+	return c_num_params();
+}
+
+/* Print the arguments from "start" (inclusive) to "end" (exclusive)
+ * as arguments to a method of C function call, using "print_arg"
+ * to print each individual argument.
+ */
+void Method::print_arg_list(std::ostream &os, int start, int end,
+	const std::function<void(int i)> &print_arg)
+{
+	os << "(";
+	for (int i = start; i < end; ++i) {
+		if (i != start)
+			os << ", ";
+		print_arg(i);
+	}
+	os << ")";
+}
+
+/* Print the arguments to the method call, using "print_arg"
+ * to print each individual argument.
+ */
+void Method::print_cpp_arg_list(std::ostream &os,
+	const std::function<void(int i)> &print_arg) const
+{
+	int first_param = kind == member_method ? 1 : 0;
+	print_arg_list(os, first_param, num_params(), print_arg);
+}
+
+/* Should the parameter at position "pos" be a copy (rather than
+ * a const reference)?
+ *
+ * Strictly speaking, a copy is only needed on isl types that are
+ * not marked __isl_keep, since those will be release()'d
+ * by code printed by Method::print_param_use.
+ *
+ * However, there may be other arguments such as integer types
+ * that are more naturally passed as a copy.
+ * The default is therefore to require a copy, except for
+ * arguments marked __isl_keep, string arguments or callback arguments.
+ */
+bool Method::param_needs_copy(int pos) const
+{
+	ParmVarDecl *param = get_param(pos);
+	QualType type = param->getOriginalType();
+
+	if (generator::keeps(param))
+		return false;
+	if (generator::is_string(type) || generator::is_callback(type))
+		return false;
+	return true;
+}
+
+/* Return the method argument at position "pos".
+ */
+clang::ParmVarDecl *Method::get_param(int pos) const
+{
+	return fd->getParamDecl(pos);
+}
+
+/* Construct a method that performs one or more conversions
+ * from the original Method (without conversions),
+ * the name of the type to which "this" should be converted and
+ * a function for determining the arguments of the constructed method.
+ */
+ConversionMethod::ConversionMethod(const Method &method,
+	const std::string &this_type,
+	const std::function<clang::ParmVarDecl *(int pos)> &get_param) :
+		NoCopyMethod(method), this_type(this_type),
+		get_param_fn(get_param)
+{
+}
+
+/* Construct a method that only performs a conversion on "this"
+ * from the original Method (without conversions) and
+ * the name of the type to which "this" should be converted.
+ *
+ * Call the generic constructor with
+ * a function for determining the arguments of the constructed method
+ * that performs no conversion.
+ */
+ConversionMethod::ConversionMethod(const Method &method,
+	const std::string &this_type) :
+		ConversionMethod(method, this_type, [this] (int pos) {
+			return Method::get_param(pos);
+		})
+{
+}
+
+/* Construct a method that performs one or more argument conversions
+ * from the original Method (without conversions) and
+ * a function for determining the arguments of the constructed method.
+ *
+ * Call the generic constructor with method.clazz.name as "this" type,
+ * indicating that "this" should not be converted.
+ */
+ConversionMethod::ConversionMethod(const Method &method,
+	const std::function<clang::ParmVarDecl *(int pos)> &get_param) :
+		ConversionMethod(method, method.clazz.name, get_param)
+{
+}
+
+/* Should the parameter at position "pos" be a copy (rather than
+ * a const reference)?
+ *
+ * Parameters of isl type do not need to be a copy.
+ * For other types, use the same defaults as Method.
+ */
+bool NoCopyMethod::param_needs_copy(int pos) const
+{
+	ParmVarDecl *param = get_param(pos);
+	QualType type = param->getOriginalType();
+
+	if (generator::is_isl_type(type))
+		return false;
+
+	return Method::param_needs_copy(pos);
+}
+
+/* Return the method argument at position "pos".
+ *
+ * Call get_param_fn to determine this argument.
+ */
+clang::ParmVarDecl *ConversionMethod::get_param(int pos) const
+{
+	return get_param_fn(pos);
+}
+
+/* Print a call to the method (without the arguments),
+ * with "ns" the namespace of the generated C++ bindings.
+ *
+ * If "this_type" is different from the name of the class of the method,
+ * then "this" needs to be converted to that type before
+ * the call is performed.
+ */
+void ConversionMethod::print_call(std::ostream &os, const std::string &ns) const
+{
+	if (clazz.name == this_type) {
+		os << "this->";
+	} else {
+		auto cpp_type = ns + cpp_generator::type2cpp(this_type);
+		os << cpp_type << "(*this).";
+	}
+	os << name;
+}
+
+/* Construct an object representing a C++ method for setting an enum
+ * from the class to which is belongs,
+ * the isl function from which it is derived and the method and enum names.
+ */
+EnumMethod::EnumMethod(const isl_class &clazz, FunctionDecl *fd,
+	const std::string &method_name, const std::string &enum_name) :
+		Method(clazz, fd, method_name), enum_name(enum_name)
+{
+}
+
+/* Print the use of the argument at position "pos" to "os".
+ *
+ * If the position is beyond the number of method arguments,
+ * then it corresponds to the enum value corresponding to this EnumMethod.
+ * Otherwise, delegate to Method::print_param_use.
+ */
+void EnumMethod::print_param_use(ostream &os, int pos) const
+{
+	if (pos == num_params())
+		os << enum_name;
+	else
+		Method::print_param_use(os, pos);
+}
+
+/* Return the number of parameters of the method
+ * (including the implicit "this").
+ *
+ * The last argument of the C function does not appear in the method call,
+ * because it is replaced by a break-up into several methods.
+ */
+int EnumMethod::num_params() const
+{
+	return Method::num_params() - 1;
+}
+
+/* Initialize a class method printer from the stream onto which the methods
+ * are printed, the class method description and the C++ interface generator.
+ */
+cpp_generator::class_printer::class_printer(std::ostream &os,
+		const isl_class &clazz, cpp_generator &generator,
+		bool declarations) :
+	os(os), clazz(clazz), cppstring(type2cpp(clazz)), generator(generator),
+	declarations(declarations)
+{
 }
diff --git a/lib/External/isl/interface/cpp.h b/lib/External/isl/interface/cpp.h
index c207af1..837cdee 100644
--- a/lib/External/isl/interface/cpp.h
+++ b/lib/External/isl/interface/cpp.h
@@ -1,169 +1,183 @@
+#ifndef ISL_INTERFACE_CPP_H
+#define ISL_INTERFACE_CPP_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+
 #include "generator.h"
 
-using namespace std;
-using namespace clang;
+/* A generated C++ method derived from an isl function.
+ *
+ * "clazz" is the class to which the method belongs.
+ * "fd" is the original isl function.
+ * "name" is the name of the method, which may be different
+ * from the default name derived from "fd".
+ * "kind" is the type of the method.
+ * "callback" stores the callback argument, if any, or NULL.
+ */
+struct Method {
+	enum Kind {
+		static_method,
+		member_method,
+		constructor,
+	};
+
+	Method(const isl_class &clazz, FunctionDecl *fd,
+		const std::string &name);
+	Method(const isl_class &clazz, FunctionDecl *fd);
+
+	int c_num_params() const;
+	virtual int num_params() const;
+	virtual bool param_needs_copy(int pos) const;
+	virtual clang::ParmVarDecl *get_param(int pos) const;
+	virtual void print_param_use(ostream &os, int pos) const;
+	bool is_subclass_mutator() const;
+	static void print_arg_list(std::ostream &os, int start, int end,
+		const std::function<void(int i)> &print_arg);
+	void print_cpp_arg_list(std::ostream &os,
+		const std::function<void(int i)> &print_arg) const;
+
+	const isl_class &clazz;
+	FunctionDecl *const fd;
+	const std::string name;
+	const enum Kind kind;
+	ParmVarDecl *const callback;
+};
+
+/* A method that does not require its isl type parameters to be a copy.
+ */
+struct NoCopyMethod : Method {
+	NoCopyMethod(const Method &method) : Method(method) {}
+
+	virtual bool param_needs_copy(int pos) const override;
+};
+
+/* A generated method that performs one or more argument conversions and
+ * then calls the original method.
+ *
+ * A ConversionMethod inherits from a NoCopyMethod, because
+ * unlike methods that call an isl C function,
+ * a conversion method never calls release() on an isl type argument,
+ * so they can all be passed as const references.
+ *
+ * "this_type" is the name of the type to which "this" should be converted
+ * (if different from clazz.name).
+ * "get_param_fn" returns the method argument at position "pos".
+ */
+struct ConversionMethod : NoCopyMethod {
+	ConversionMethod(const Method &method, const std::string &this_type,
+		const std::function<clang::ParmVarDecl *(int pos)> &get_param);
+	ConversionMethod(const Method &method, const std::string &this_type);
+	ConversionMethod(const Method &method,
+		const std::function<clang::ParmVarDecl *(int pos)> &get_param);
+	virtual clang::ParmVarDecl *get_param(int pos) const override;
+
+	void print_call(std::ostream &os, const std::string &ns) const;
+
+	const std::string this_type;
+	const std::function<clang::ParmVarDecl *(int pos)> get_param_fn;
+};
+
+/* A specialized generated C++ method for setting an enum.
+ *
+ * "enum_name" is a string representation of the enum value
+ * set by this method.
+ */
+struct EnumMethod : public Method {
+	EnumMethod(const isl_class &clazz, FunctionDecl *fd,
+		const std::string &method_name, const std::string &enum_name);
+
+	virtual int num_params() const override;
+	virtual void print_param_use(ostream &os, int pos) const override;
+
+	std::string enum_name;
+};
+
+/* A type printer for converting argument and return types,
+ * as well as the class type,
+ * to string representations of the corresponding types
+ * in the C++ interface.
+ */
+struct cpp_type_printer {
+	cpp_type_printer() {}
+
+	virtual std::string isl_bool() const;
+	virtual std::string isl_stat() const;
+	virtual std::string isl_size() const;
+	virtual std::string isl_namespace() const;
+	virtual std::string class_type(const std::string &cpp_name) const;
+	virtual std::string qualified(int arg, const std::string &cpp_type)
+		const;
+	std::string isl_type(int arg, QualType type) const;
+	std::string generate_callback_args(int arg, QualType type, bool cpp)
+		const;
+	std::string generate_callback_type(int arg, QualType type) const;
+	std::string param(int arg, QualType type) const;
+	std::string return_type(const Method &method) const;
+};
 
 /* Generator for C++ bindings.
- *
- * "checked" is set if C++ bindings should be generated
- * that rely on the user to check for error conditions.
  */
 class cpp_generator : public generator {
 protected:
-	bool checked;
+	struct class_printer;
 public:
 	cpp_generator(SourceManager &SM, set<RecordDecl *> &exported_types,
 		set<FunctionDecl *> exported_functions,
-		set<FunctionDecl *> functions,
-		bool checked = false) :
-		generator(SM, exported_types, exported_functions, functions),
-		checked(checked) {}
-
-	enum function_kind {
-		function_kind_static_method,
-		function_kind_member_method,
-		function_kind_constructor,
-	};
-	enum method_part {
-		decl,
-		impl,
-	};
-
-	virtual void generate();
+		set<FunctionDecl *> functions);
 private:
-	void print_forward_declarations(ostream &os);
-	void print_declarations(ostream &os);
-	void print_class(ostream &os, const isl_class &clazz);
-	void print_subclass_type(ostream &os, const isl_class &clazz);
-	void print_class_forward_decl(ostream &os, const isl_class &clazz);
-	void print_class_factory_decl(ostream &os, const isl_class &clazz,
-		const std::string &prefix = std::string());
-	void print_protected_constructors_decl(ostream &os,
-		const isl_class &clazz);
-	void print_copy_assignment_decl(ostream &os, const isl_class &clazz);
-	void print_public_constructors_decl(ostream &os,
-		const isl_class &clazz);
-	void print_constructors_decl(ostream &os, const isl_class &clazz);
-	void print_destructor_decl(ostream &os, const isl_class &clazz);
-	void print_ptr_decl(ostream &os, const isl_class &clazz);
-	void print_isa_type_template(ostream &os, int indent,
-		const isl_class &super);
-	void print_downcast_decl(ostream &os, const isl_class &clazz);
-	void print_ctx_decl(ostream &os);
-	void print_persistent_callback_prototype(ostream &os,
-		const isl_class &clazz, FunctionDecl *method,
-		bool is_declaration);
-	void print_persistent_callback_setter_prototype(ostream &os,
-		const isl_class &clazz, FunctionDecl *method,
-		bool is_declaration);
-	void print_persistent_callback_data(ostream &os, const isl_class &clazz,
-		FunctionDecl *method);
-	void print_persistent_callbacks_decl(ostream &os,
-		const isl_class &clazz);
-	void print_methods_decl(ostream &os, const isl_class &clazz);
-	bool next_variant(FunctionDecl *fd, std::vector<bool> &convert);
-	template <enum method_part>
-	void print_method_variants(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd);
-	void print_method_group_decl(ostream &os, const isl_class &clazz,
-		const function_set &methods);
-	void print_named_method_decl(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd, const string &name, function_kind kind,
-		const std::vector<bool> &convert = {});
-	template <enum method_part>
-	void print_method(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, function_kind kind);
-	template <enum method_part>
-	void print_method(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, function_kind kind,
-		const std::vector<bool> &convert);
-	void print_set_enum_decl(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd, const string &name);
-	void print_set_enums_decl(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd);
-	void print_set_enums_decl(ostream &os, const isl_class &clazz);
-	void print_implementations(ostream &os);
-	void print_class_impl(ostream &os, const isl_class &clazz);
-	void print_check_ptr(ostream &os, const char *ptr);
-	void print_check_ptr_start(ostream &os, const isl_class &clazz,
-		const char *ptr);
-	void print_check_ptr_end(ostream &os, const char *ptr);
-	void print_class_factory_impl(ostream &os, const isl_class &clazz);
-	void print_protected_constructors_impl(ostream &os,
-		const isl_class &clazz);
-	void print_public_constructors_impl(ostream &os,
-		const isl_class &clazz);
-	void print_constructors_impl(ostream &os, const isl_class &clazz);
-	void print_copy_assignment_impl(ostream &os, const isl_class &clazz);
-	void print_destructor_impl(ostream &os, const isl_class &clazz);
-	void print_check_no_persistent_callback(ostream &os,
-		const isl_class &clazz, FunctionDecl *fd);
-	void print_ptr_impl(ostream &os, const isl_class &clazz);
-	void print_downcast_impl(ostream &os, const isl_class &clazz);
-	void print_ctx_impl(ostream &os, const isl_class &clazz);
-	void print_persistent_callbacks_impl(ostream &os,
-		const isl_class &clazz);
-	void print_methods_impl(ostream &os, const isl_class &clazz);
-	void print_method_group_impl(ostream &os, const isl_class &clazz,
-		const function_set &methods);
-	void print_argument_validity_check(ostream &os, FunctionDecl *method,
-		function_kind kind);
-	void print_save_ctx(ostream &os, FunctionDecl *method,
-		function_kind kind);
-	void print_on_error_continue(ostream &os);
-	void print_exceptional_execution_check(ostream &os,
-		const isl_class &clazz, FunctionDecl *method,
-		function_kind kind);
-	void print_set_persistent_callback(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, function_kind kind);
-	void print_method_return(ostream &os, const isl_class &clazz,
-		FunctionDecl *method);
-	void print_set_enum_impl(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd, const string &enum_name,
-		const string &method_name);
-	void print_set_enums_impl(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd);
-	void print_set_enums_impl(ostream &os, const isl_class &clazz);
-	template <enum method_part>
-	void print_get_method(ostream &os, const isl_class &clazz,
-		FunctionDecl *fd);
-	void print_invalid(ostream &os, int indent, const char *msg,
-		const char *checked_code);
-	void print_stream_insertion(ostream &os, const isl_class &clazz);
-	void print_method_param_use(ostream &os, ParmVarDecl *param,
-		bool load_from_this_ptr);
-	std::string get_return_type(const isl_class &clazz, FunctionDecl *fd);
-	ParmVarDecl *get_param(FunctionDecl *fd, int pos,
-		const std::vector<bool> &convert);
-	void print_method_header(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, const string &cname, int num_params,
-		bool is_declaration, function_kind kind,
-		const std::vector<bool> &convert = {});
-	void print_named_method_header(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, string name, bool is_declaration,
-		function_kind kind, const std::vector<bool> &convert = {});
-	void print_method_header(ostream &os, const isl_class &clazz,
-		FunctionDecl *method, bool is_declaration, function_kind kind);
-	string generate_callback_args(QualType type, bool cpp);
-	string generate_callback_type(QualType type);
-	void print_wrapped_call_checked(std::ostream &os, int indent,
-		const std::string &call);
-	void print_wrapped_call(std::ostream &os, int indent,
-		const std::string &call, QualType rtype);
-	void print_callback_data_decl(ostream &os, ParmVarDecl *param,
-		const string &name);
-	void print_callback_body(ostream &os, int indent, ParmVarDecl *param,
-		const string &name);
-	void print_callback_local(ostream &os, ParmVarDecl *param);
-	std::string rename_method(std::string name);
-	string isl_bool2cpp();
-	string isl_namespace();
-	string type2cpp(QualType type);
-	bool is_implicit_conversion(const isl_class &clazz, FunctionDecl *cons);
+	void set_class_construction_types(isl_class &clazz);
+	void set_construction_types();
+	void copy_methods(isl_class &clazz, const std::string &name,
+		const isl_class &super, const function_set &methods);
+	void copy_super_methods(isl_class &clazz, const isl_class &super);
+	void copy_super_methods(isl_class &clazz, set<string> &done);
+	void copy_super_methods();
+	bool is_implicit_conversion(const Method &cons);
 	bool is_subclass(QualType subclass_type, const isl_class &class_type);
-	function_kind get_method_kind(const isl_class &clazz,
-		FunctionDecl *method);
 public:
 	static string type2cpp(const isl_class &clazz);
 	static string type2cpp(string type_string);
 };
+
+/* A helper class for printing method declarations and definitions
+ * of a class.
+ *
+ * "os" is the stream onto which the methods are printed.
+ * "clazz" describes the methods of the class.
+ * "cppstring" is the C++ name of the class.
+ * "generator" is the C++ interface generator printing the classes.
+ * "declarations" is set if this object is used to print declarations.
+ */
+struct cpp_generator::class_printer {
+	std::ostream &os;
+	const isl_class &clazz;
+	const std::string cppstring;
+	cpp_generator &generator;
+	const bool declarations;
+
+	class_printer(std::ostream &os, const isl_class &clazz,
+			cpp_generator &generator, bool declarations);
+
+	void print_constructors();
+	void print_methods();
+	bool next_variant(FunctionDecl *fd, std::vector<bool> &convert);
+	void print_method_variants(FunctionDecl *fd, const std::string &name);
+	virtual bool want_descendent_overloads(const function_set &methods) = 0;
+	void print_descendent_overloads(FunctionDecl *fd,
+		const std::string &name);
+	void print_method_group(const function_set &methods,
+		const std::string &name);
+	virtual void print_method(const Method &method) = 0;
+	virtual void print_method(const ConversionMethod &method) = 0;
+	virtual void print_get_method(FunctionDecl *fd) = 0;
+	void print_set_enums(FunctionDecl *fd);
+	void print_set_enums();
+	ParmVarDecl *get_param(FunctionDecl *fd, int pos,
+		const std::vector<bool> &convert);
+	void print_method_header(const Method &method,
+		const cpp_type_printer &type_printer);
+};
+
+#endif
diff --git a/lib/External/isl/interface/depcomp b/lib/External/isl/interface/depcomp
old mode 100644
new mode 100755
index 65cbf70..6b39162
--- a/lib/External/isl/interface/depcomp
+++ b/lib/External/isl/interface/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/lib/External/isl/interface/extract_interface.cc b/lib/External/isl/interface/extract_interface.cc
index 2602750..55d4e34 100644
--- a/lib/External/isl/interface/extract_interface.cc
+++ b/lib/External/isl/interface/extract_interface.cc
@@ -82,8 +82,9 @@
 #include "extract_interface.h"
 #include "generator.h"
 #include "python.h"
-#include "cpp.h"
+#include "plain_cpp.h"
 #include "cpp_conversion.h"
+#include "template_cpp.h"
 
 using namespace std;
 using namespace clang;
@@ -420,12 +421,15 @@
 
 #ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
 
+#include "set_lang_defaults_arg4.h"
+
 static void set_lang_defaults(CompilerInstance *Clang)
 {
 	PreprocessorOptions &PO = Clang->getPreprocessorOpts();
 	TargetOptions &TO = Clang->getTargetOpts();
 	llvm::Triple T(TO.Triple);
-	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C, T, PO,
+	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C, T,
+					    setLangDefaultsArg4(PO),
 					    LangStandard::lang_unspecified);
 }
 
@@ -506,14 +510,17 @@
 		gen = new python_generator(SM, consumer.exported_types,
 			consumer.exported_functions, consumer.functions);
 	} else if (OutputLanguage.compare("cpp") == 0) {
-		gen = new cpp_generator(SM, consumer.exported_types,
+		gen = new plain_cpp_generator(SM, consumer.exported_types,
 			consumer.exported_functions, consumer.functions);
 	} else if (OutputLanguage.compare("cpp-checked") == 0) {
-		gen = new cpp_generator(SM, consumer.exported_types,
+		gen = new plain_cpp_generator(SM, consumer.exported_types,
 			consumer.exported_functions, consumer.functions, true);
 	} else if (OutputLanguage.compare("cpp-checked-conversion") == 0) {
 		gen = new cpp_conversion_generator(SM, consumer.exported_types,
 			consumer.exported_functions, consumer.functions);
+	} else if (OutputLanguage.compare("template-cpp") == 0) {
+		gen = new template_cpp_generator(SM, consumer.exported_types,
+			consumer.exported_functions, consumer.functions);
 	} else {
 		cerr << "Language '" << OutputLanguage
 		     << "' not recognized." << endl
diff --git a/lib/External/isl/interface/generator.cc b/lib/External/isl/interface/generator.cc
index dc6ebea..eacbc36 100644
--- a/lib/External/isl/interface/generator.cc
+++ b/lib/External/isl/interface/generator.cc
@@ -46,23 +46,35 @@
 const char *isl_class::get_prefix = "get_";
 const char *isl_class::set_callback_prefix = "set_";
 
-/* Should "method" be considered to be a static method?
- * That is, is the first argument something other than
- * an instance of the class?
+/* Is the first argument an instance of the class?
  */
-bool isl_class::is_static(FunctionDecl *method) const
+bool isl_class::first_arg_matches_class(FunctionDecl *method) const
 {
 	ParmVarDecl *param;
 	QualType type;
 
 	if (method->getNumParams() < 1)
-		return true;
+		return false;
 
 	param = method->getParamDecl(0);
 	type = param->getOriginalType();
 	if (!generator::is_isl_type(type))
-		return true;
-	return generator::extract_type(type) != name;
+		return false;
+	return generator::extract_type(type) == name;
+}
+
+/* Should "method" be considered to be a static method?
+ * That is, is the first argument something other than
+ * an instance of the class?
+ *
+ * If this method was copied from a superclass, then check
+ * whether the method is static with respect to this superclass.
+ */
+bool isl_class::is_static(FunctionDecl *method) const
+{
+	if (copied_from.count(method) != 0)
+		return copied_from.at(method).is_static(method);
+	return !first_arg_matches_class(method);
 }
 
 /* Should "method" be considered to be a static method?
@@ -417,8 +429,8 @@
 			std::string name = method->getName().str();
 			die(name + " has unhandled enum argument");
 		} else {
-			string fullname = c->name_without_type_suffixes(method);
-			c->methods[fullname].insert(method);
+			string name = c->method_name(method);
+			c->methods[name].insert(method);
 		}
 	}
 
@@ -791,7 +803,8 @@
 /* If "suffix" is a suffix of "s", then return "s" with the suffix removed.
  * Otherwise, simply return "s".
  */
-static std::string drop_suffix(const std::string &s, const std::string &suffix)
+std::string generator::drop_suffix(const std::string &s,
+	const std::string &suffix)
 {
 	size_t len, suffix_len;
 
@@ -828,7 +841,7 @@
 		param = method->getParamDecl(i);
 		type = type_suffix(param);
 
-		name = drop_suffix(name, type);
+		name = generator::drop_suffix(name, type);
 	}
 
 	return name;
diff --git a/lib/External/isl/interface/generator.h b/lib/External/isl/interface/generator.h
index 6cd0928..29faaaa 100644
--- a/lib/External/isl/interface/generator.h
+++ b/lib/External/isl/interface/generator.h
@@ -64,6 +64,18 @@
  * "fn_type" is a reference to a function that described subclasses, if any.
  * If "fn_type" is set, then "type_subclasses" maps the values returned
  * by that function to the names of the corresponding subclasses.
+ *
+ * The following fields are only used for the C++ bindings.
+ * For methods that are not derived from a function that applies
+ * directly to this class, but are rather copied from some ancestor,
+ * "copied_from" records the direct superclass from which the method
+ * was copied (where it may have been copied from a further ancestor) and
+ * "copy_depth" records the distance to the ancestor to which
+ * the function applies.
+ * "construction_types" contains the set of isl classes that can be
+ * implicitly converted to this class through a unary constructor,
+ * mapped to the single argument
+ * of this unary constructor.
  */
 struct isl_class {
 	string name;
@@ -80,6 +92,12 @@
 	FunctionDecl *fn_copy;
 	FunctionDecl *fn_free;
 
+	std::map<clang::FunctionDecl *, const isl_class &> copied_from;
+	std::map<clang::FunctionDecl *, int> copy_depth;
+	std::map<std::string, clang::ParmVarDecl *> construction_types;
+
+	/* Is the first argument an instance of the class? */
+	bool first_arg_matches_class(FunctionDecl *method) const;
 	/* Does "method" correspond to a static method? */
 	bool is_static(FunctionDecl *method) const;
 	/* Is this class a subclass based on a type function? */
@@ -152,6 +170,8 @@
 	void extract_class_automatic_conversions(const isl_class &clazz);
 	void extract_automatic_conversions();
 public:
+	static std::string drop_suffix(const std::string &s,
+		const std::string &suffix);
 	static void die(const char *msg) __attribute__((noreturn));
 	static void die(string msg) __attribute__((noreturn));
 	static vector<string> find_superclasses(Decl *decl);
diff --git a/lib/External/isl/interface/install-sh b/lib/External/isl/interface/install-sh
old mode 100644
new mode 100755
index 8175c64..ec298b5
--- a/lib/External/isl/interface/install-sh
+++ b/lib/External/isl/interface/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2018-03-11.20; # UTC
+scriptversion=2020-11-14.01; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@
 # Desired mode of installed file.
 mode=0755
 
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
 chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
@@ -99,18 +104,28 @@
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
+  -C            install only if different (preserve data modification time)
   -d            create directories instead of installing files.
   -g GROUP      $chgrpprog installed files to GROUP.
   -m MODE       $chmodprog installed files to MODE.
   -o USER       $chownprog installed files to USER.
+  -p            pass -p to $cpprog.
   -s            $stripprog installed files.
+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
   -t DIRECTORY  install into DIRECTORY.
   -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
   CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
   RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@
     -o) chowncmd="$chownprog $2"
         shift;;
 
+    -p) cpprog="$cpprog -p";;
+
     -s) stripcmd=$stripprog;;
 
+    -S) backupsuffix="$2"
+        shift;;
+
     -t)
         is_target_a_directory=always
         dst_arg=$2
@@ -255,6 +275,10 @@
     dstdir=$dst
     test -d "$dstdir"
     dstdir_status=$?
+    # Don't chown directories that already exist.
+    if test $dstdir_status = 0; then
+      chowncmd=""
+    fi
   else
 
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
         # With -d, create the new directory with the user-specified mode.
         # Otherwise, rely on $mkdir_umask.
         if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@
         fi
 
         posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
-            # here however when possible just to lower collision chance.
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	# The $RANDOM variable is not portable (e.g., dash).  Use it
+	# here however when possible just to lower collision chance.
+	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
 
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+	trap '
+	  ret=$?
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+	  exit $ret
+	' 0
 
-            # Because "mkdir -p" follows existing symlinks and we likely work
-            # directly in world-writeable /tmp, make sure that the '$tmpdir'
-            # directory is successfully created first before we actually test
-            # 'mkdir -p' feature.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Because "mkdir -p" follows existing symlinks and we likely work
+	# directly in world-writeable /tmp, make sure that the '$tmpdir'
+	# directory is successfully created first before we actually test
+	# 'mkdir -p'.
+	if (umask $mkdir_umask &&
+	    $mkdirprog $mkdir_mode "$tmpdir" &&
+	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+	then
+	  if test -z "$dir_arg" || {
+	       # Check for POSIX incompatibilities with -m.
+	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+	       # other-writable bit of parent directory when it shouldn't.
+	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+	       test_tmpdir="$tmpdir/a"
+	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+	       case $ls_ld_tmpdir in
+		 d????-?r-*) different_mode=700;;
+		 d????-?--*) different_mode=755;;
+		 *) false;;
+	       esac &&
+	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+	       }
+	     }
+	  then posix_mkdir=:
+	  fi
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+	else
+	  # Remove any dirs left behind by ancient mkdir implementations.
+	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+	fi
+	trap '' 0;;
     esac
 
     if
@@ -382,7 +387,7 @@
     then :
     else
 
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # mkdir does not conform to POSIX,
       # or it failed possibly due to a race condition.  Create the
       # directory the slow way, step by step, checking for races as we go.
 
@@ -411,7 +416,7 @@
           prefixes=
         else
           if $posix_mkdir; then
-            (umask=$mkdir_umask &&
+            (umask $mkdir_umask &&
              $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
             # Don't fail if two instances are running concurrently.
             test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+	 # Create $dsttmp read-write so that cp doesn't create it read-only,
+	 # which would cause strip to fail.
+	 if test -z "$doit"; then
+	   : >"$dsttmp" # No need to fork-exec 'touch'.
+	 else
+	   $doit touch "$dsttmp"
+	 fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -477,6 +493,13 @@
     then
       rm -f "$dsttmp"
     else
+      # If $backupsuffix is set, and the file being installed
+      # already exists, attempt a backup.  Don't worry if it fails,
+      # e.g., if mv doesn't support -f.
+      if test -n "$backupsuffix" && test -f "$dst"; then
+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+      fi
+
       # Rename the file to the real destination.
       $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
 
@@ -491,9 +514,9 @@
         # file should still install successfully.
         {
           test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          $doit $rmcmd "$dst" 2>/dev/null ||
           { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
           } ||
           { echo "$0: cannot unlink or rename $dst" >&2
             (exit 1); exit 1
diff --git a/lib/External/isl/interface/isl.py b/lib/External/isl/interface/isl.py
index 9196cf4..9e747ed 100644
--- a/lib/External/isl/interface/isl.py
+++ b/lib/External/isl/interface/isl.py
@@ -101,6 +101,16 @@
             obj = union_pw_multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def as_multi_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is union_pw_multi_aff:
+                arg0 = union_pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_multi_aff_as_multi_union_pw_aff(isl.isl_union_pw_multi_aff_copy(arg0.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
     def as_pw_multi_aff(arg0):
         try:
             if not arg0.__class__ is union_pw_multi_aff:
@@ -111,6 +121,16 @@
         res = isl.isl_union_pw_multi_aff_as_pw_multi_aff(isl.isl_union_pw_multi_aff_copy(arg0.ptr))
         obj = pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    def as_union_map(arg0):
+        try:
+            if not arg0.__class__ is union_pw_multi_aff:
+                arg0 = union_pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_multi_aff_as_union_map(isl.isl_union_pw_multi_aff_copy(arg0.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
     def coalesce(arg0):
         try:
             if not arg0.__class__ is union_pw_multi_aff:
@@ -169,18 +189,6 @@
         res = isl.isl_union_pw_multi_aff_flat_range_product(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr))
         obj = union_pw_multi_aff(ctx=ctx, ptr=res)
         return obj
-    def space(arg0):
-        try:
-            if not arg0.__class__ is union_pw_multi_aff:
-                arg0 = union_pw_multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_pw_multi_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is union_pw_multi_aff:
@@ -300,6 +308,18 @@
             obj = union_pw_multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def pw_multi_aff_list(arg0):
+        try:
+            if not arg0.__class__ is union_pw_multi_aff:
+                arg0 = union_pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_multi_aff_get_pw_multi_aff_list(arg0.ptr)
+        obj = pw_multi_aff_list(ctx=ctx, ptr=res)
+        return obj
+    def get_pw_multi_aff_list(arg0):
+        return arg0.pw_multi_aff_list()
     def range_factor_domain(arg0):
         try:
             if not arg0.__class__ is union_pw_multi_aff:
@@ -335,6 +355,18 @@
         res = isl.isl_union_pw_multi_aff_range_product(isl.isl_union_pw_multi_aff_copy(arg0.ptr), isl.isl_union_pw_multi_aff_copy(arg1.ptr))
         obj = union_pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    def space(arg0):
+        try:
+            if not arg0.__class__ is union_pw_multi_aff:
+                arg0 = union_pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_multi_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is union_pw_multi_aff:
@@ -390,8 +422,12 @@
 isl.isl_union_pw_multi_aff_add.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_apply_union_pw_multi_aff.restype = c_void_p
 isl.isl_union_pw_multi_aff_apply_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_multi_aff_as_multi_union_pw_aff.restype = c_void_p
+isl.isl_union_pw_multi_aff_as_multi_union_pw_aff.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_as_pw_multi_aff.restype = c_void_p
 isl.isl_union_pw_multi_aff_as_pw_multi_aff.argtypes = [c_void_p]
+isl.isl_union_pw_multi_aff_as_union_map.restype = c_void_p
+isl.isl_union_pw_multi_aff_as_union_map.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_coalesce.restype = c_void_p
 isl.isl_union_pw_multi_aff_coalesce.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_domain.restype = c_void_p
@@ -402,8 +438,6 @@
 isl.isl_union_pw_multi_aff_extract_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_flat_range_product.restype = c_void_p
 isl.isl_union_pw_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p]
-isl.isl_union_pw_multi_aff_get_space.restype = c_void_p
-isl.isl_union_pw_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_gist.restype = c_void_p
 isl.isl_union_pw_multi_aff_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_intersect_domain_space.restype = c_void_p
@@ -423,12 +457,16 @@
 isl.isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.restype = c_void_p
 isl.isl_union_pw_multi_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_multi_aff_get_pw_multi_aff_list.restype = c_void_p
+isl.isl_union_pw_multi_aff_get_pw_multi_aff_list.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_range_factor_domain.restype = c_void_p
 isl.isl_union_pw_multi_aff_range_factor_domain.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_range_factor_range.restype = c_void_p
 isl.isl_union_pw_multi_aff_range_factor_range.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_range_product.restype = c_void_p
 isl.isl_union_pw_multi_aff_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_multi_aff_get_space.restype = c_void_p
+isl.isl_union_pw_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_union_pw_multi_aff_sub.restype = c_void_p
 isl.isl_union_pw_multi_aff_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_multi_aff_subtract_domain_space.restype = c_void_p
@@ -501,6 +539,18 @@
         res = isl.isl_multi_union_pw_aff_add(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_get_at(arg0.ptr, arg1)
+        obj = union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def bind(arg0, arg1):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -551,42 +601,6 @@
         res = isl.isl_multi_union_pw_aff_flat_range_product(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is multi_union_pw_aff:
-                arg0 = multi_union_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_union_pw_aff_get_at(arg0.ptr, arg1)
-        obj = union_pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
-    def list(arg0):
-        try:
-            if not arg0.__class__ is multi_union_pw_aff:
-                arg0 = multi_union_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_union_pw_aff_get_list(arg0.ptr)
-        obj = union_pw_aff_list(ctx=ctx, ptr=res)
-        return obj
-    def get_list(arg0):
-        return arg0.list()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is multi_union_pw_aff:
-                arg0 = multi_union_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_union_pw_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -602,6 +616,17 @@
         res = isl.isl_multi_union_pw_aff_gist(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def intersect_domain(arg0, arg1):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -643,6 +668,18 @@
         if res < 0:
             raise
         return bool(res)
+    def list(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_get_list(arg0.ptr)
+        obj = union_pw_aff_list(ctx=ctx, ptr=res)
+        return obj
+    def get_list(arg0):
+        return arg0.list()
     def neg(arg0):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -691,6 +728,28 @@
         res = isl.isl_multi_union_pw_aff_range_product(isl.isl_multi_union_pw_aff_copy(arg0.ptr), isl.isl_multi_union_pw_aff_copy(arg1.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
+    def reset_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_reset_range_tuple_id(isl.isl_multi_union_pw_aff_copy(arg0.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
     def scale(*args):
         if len(args) == 2 and args[1].__class__ is multi_val:
             ctx = args[0].ctx
@@ -742,6 +801,19 @@
         res = isl.isl_multi_union_pw_aff_set_at(isl.isl_multi_union_pw_aff_copy(arg0.ptr), arg1, isl.isl_union_pw_aff_copy(arg2.ptr))
         obj = multi_union_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_multi_union_pw_aff_set_range_tuple_id(isl.isl_multi_union_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def size(arg0):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -753,6 +825,18 @@
         if res < 0:
             raise
         return int(res)
+    def space(arg0):
+        try:
+            if not arg0.__class__ is multi_union_pw_aff:
+                arg0 = multi_union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_union_pw_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is multi_union_pw_aff:
@@ -805,6 +889,8 @@
 isl.isl_multi_union_pw_aff_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_multi_union_pw_aff_add.restype = c_void_p
 isl.isl_multi_union_pw_aff_add.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_union_pw_aff_get_at.restype = c_void_p
+isl.isl_multi_union_pw_aff_get_at.argtypes = [c_void_p, c_int]
 isl.isl_multi_union_pw_aff_bind.restype = c_void_p
 isl.isl_multi_union_pw_aff_bind.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_coalesce.restype = c_void_p
@@ -813,19 +899,16 @@
 isl.isl_multi_union_pw_aff_domain.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_flat_range_product.restype = c_void_p
 isl.isl_multi_union_pw_aff_flat_range_product.argtypes = [c_void_p, c_void_p]
-isl.isl_multi_union_pw_aff_get_at.restype = c_void_p
-isl.isl_multi_union_pw_aff_get_at.argtypes = [c_void_p, c_int]
-isl.isl_multi_union_pw_aff_get_list.restype = c_void_p
-isl.isl_multi_union_pw_aff_get_list.argtypes = [c_void_p]
-isl.isl_multi_union_pw_aff_get_space.restype = c_void_p
-isl.isl_multi_union_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_gist.restype = c_void_p
 isl.isl_multi_union_pw_aff_gist.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_union_pw_aff_has_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_intersect_domain.restype = c_void_p
 isl.isl_multi_union_pw_aff_intersect_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_intersect_params.restype = c_void_p
 isl.isl_multi_union_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_involves_nan.argtypes = [c_void_p]
+isl.isl_multi_union_pw_aff_get_list.restype = c_void_p
+isl.isl_multi_union_pw_aff_get_list.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_neg.restype = c_void_p
 isl.isl_multi_union_pw_aff_neg.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_plain_is_equal.argtypes = [c_void_p, c_void_p]
@@ -833,6 +916,10 @@
 isl.isl_multi_union_pw_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_range_product.restype = c_void_p
 isl.isl_multi_union_pw_aff_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_union_pw_aff_get_range_tuple_id.restype = c_void_p
+isl.isl_multi_union_pw_aff_get_range_tuple_id.argtypes = [c_void_p]
+isl.isl_multi_union_pw_aff_reset_range_tuple_id.restype = c_void_p
+isl.isl_multi_union_pw_aff_reset_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_scale_multi_val.restype = c_void_p
 isl.isl_multi_union_pw_aff_scale_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_scale_val.restype = c_void_p
@@ -843,7 +930,11 @@
 isl.isl_multi_union_pw_aff_scale_down_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_set_at.restype = c_void_p
 isl.isl_multi_union_pw_aff_set_at.argtypes = [c_void_p, c_int, c_void_p]
+isl.isl_multi_union_pw_aff_set_range_tuple_id.restype = c_void_p
+isl.isl_multi_union_pw_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_size.argtypes = [c_void_p]
+isl.isl_multi_union_pw_aff_get_space.restype = c_void_p
+isl.isl_multi_union_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_union_pw_aff_sub.restype = c_void_p
 isl.isl_multi_union_pw_aff_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_union_pw_aff_union_add.restype = c_void_p
@@ -943,18 +1034,6 @@
         res = isl.isl_union_pw_aff_domain(isl.isl_union_pw_aff_copy(arg0.ptr))
         obj = union_set(ctx=ctx, ptr=res)
         return obj
-    def space(arg0):
-        try:
-            if not arg0.__class__ is union_pw_aff:
-                arg0 = union_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_pw_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is union_pw_aff:
@@ -1034,6 +1113,18 @@
             obj = union_pw_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def space(arg0):
+        try:
+            if not arg0.__class__ is union_pw_aff:
+                arg0 = union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is union_pw_aff:
@@ -1061,6 +1152,16 @@
             obj = union_pw_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is union_pw_aff:
+                arg0 = union_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_aff_to_list(isl.isl_union_pw_aff_copy(arg0.ptr))
+        obj = union_pw_aff_list(ctx=ctx, ptr=res)
+        return obj
     def union_add(arg0, arg1):
         try:
             if not arg0.__class__ is union_pw_aff:
@@ -1091,8 +1192,6 @@
 isl.isl_union_pw_aff_coalesce.argtypes = [c_void_p]
 isl.isl_union_pw_aff_domain.restype = c_void_p
 isl.isl_union_pw_aff_domain.argtypes = [c_void_p]
-isl.isl_union_pw_aff_get_space.restype = c_void_p
-isl.isl_union_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_union_pw_aff_gist.restype = c_void_p
 isl.isl_union_pw_aff_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_aff_intersect_domain_space.restype = c_void_p
@@ -1107,12 +1206,16 @@
 isl.isl_union_pw_aff_intersect_params.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_aff_pullback_union_pw_multi_aff.restype = c_void_p
 isl.isl_union_pw_aff_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_aff_get_space.restype = c_void_p
+isl.isl_union_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_union_pw_aff_sub.restype = c_void_p
 isl.isl_union_pw_aff_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_aff_subtract_domain_space.restype = c_void_p
 isl.isl_union_pw_aff_subtract_domain_space.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_aff_subtract_domain_union_set.restype = c_void_p
 isl.isl_union_pw_aff_subtract_domain_union_set.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_aff_to_list.restype = c_void_p
+isl.isl_union_pw_aff_to_list.argtypes = [c_void_p]
 isl.isl_union_pw_aff_union_add.restype = c_void_p
 isl.isl_union_pw_aff_union_add.argtypes = [c_void_p, c_void_p]
 isl.isl_union_pw_aff_copy.restype = c_void_p
@@ -1205,6 +1308,48 @@
             obj = multi_pw_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def as_map(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_as_map(isl.isl_multi_pw_aff_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def as_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_as_multi_aff(isl.isl_multi_pw_aff_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def as_set(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_as_set(isl.isl_multi_pw_aff_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_get_at(arg0.ptr, arg1)
+        obj = pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def bind(arg0, arg1):
         try:
             if not arg0.__class__ is multi_pw_aff:
@@ -1285,42 +1430,6 @@
         res = isl.isl_multi_pw_aff_flat_range_product(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr))
         obj = multi_pw_aff(ctx=ctx, ptr=res)
         return obj
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is multi_pw_aff:
-                arg0 = multi_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_pw_aff_get_at(arg0.ptr, arg1)
-        obj = pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
-    def list(arg0):
-        try:
-            if not arg0.__class__ is multi_pw_aff:
-                arg0 = multi_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_pw_aff_get_list(arg0.ptr)
-        obj = pw_aff_list(ctx=ctx, ptr=res)
-        return obj
-    def get_list(arg0):
-        return arg0.list()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is multi_pw_aff:
-                arg0 = multi_pw_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_pw_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is multi_pw_aff:
@@ -1336,6 +1445,17 @@
         res = isl.isl_multi_pw_aff_gist(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = multi_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def identity(*args):
         if len(args) == 1:
             ctx = args[0].ctx
@@ -1427,6 +1547,29 @@
                 raise
             return bool(res)
         raise Error
+    def isa_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_isa_multi_aff(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def list(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_get_list(arg0.ptr)
+        obj = pw_aff_list(ctx=ctx, ptr=res)
+        return obj
+    def get_list(arg0):
+        return arg0.list()
     def max(arg0, arg1):
         try:
             if not arg0.__class__ is multi_pw_aff:
@@ -1550,6 +1693,28 @@
         res = isl.isl_multi_pw_aff_range_product(isl.isl_multi_pw_aff_copy(arg0.ptr), isl.isl_multi_pw_aff_copy(arg1.ptr))
         obj = multi_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
+    def reset_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_reset_range_tuple_id(isl.isl_multi_pw_aff_copy(arg0.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
     def scale(*args):
         if len(args) == 2 and args[1].__class__ is multi_val:
             ctx = args[0].ctx
@@ -1601,6 +1766,19 @@
         res = isl.isl_multi_pw_aff_set_at(isl.isl_multi_pw_aff_copy(arg0.ptr), arg1, isl.isl_pw_aff_copy(arg2.ptr))
         obj = multi_pw_aff(ctx=ctx, ptr=res)
         return obj
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_multi_pw_aff_set_range_tuple_id(isl.isl_multi_pw_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = multi_pw_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def size(arg0):
         try:
             if not arg0.__class__ is multi_pw_aff:
@@ -1612,6 +1790,18 @@
         if res < 0:
             raise
         return int(res)
+    def space(arg0):
+        try:
+            if not arg0.__class__ is multi_pw_aff:
+                arg0 = multi_pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_pw_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is multi_pw_aff:
@@ -1687,6 +1877,14 @@
 isl.isl_multi_pw_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_add_constant_val.restype = c_void_p
 isl.isl_multi_pw_aff_add_constant_val.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_pw_aff_as_map.restype = c_void_p
+isl.isl_multi_pw_aff_as_map.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_as_multi_aff.restype = c_void_p
+isl.isl_multi_pw_aff_as_multi_aff.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_as_set.restype = c_void_p
+isl.isl_multi_pw_aff_as_set.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_get_at.restype = c_void_p
+isl.isl_multi_pw_aff_get_at.argtypes = [c_void_p, c_int]
 isl.isl_multi_pw_aff_bind.restype = c_void_p
 isl.isl_multi_pw_aff_bind.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_bind_domain.restype = c_void_p
@@ -1699,14 +1897,9 @@
 isl.isl_multi_pw_aff_domain.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_flat_range_product.restype = c_void_p
 isl.isl_multi_pw_aff_flat_range_product.argtypes = [c_void_p, c_void_p]
-isl.isl_multi_pw_aff_get_at.restype = c_void_p
-isl.isl_multi_pw_aff_get_at.argtypes = [c_void_p, c_int]
-isl.isl_multi_pw_aff_get_list.restype = c_void_p
-isl.isl_multi_pw_aff_get_list.argtypes = [c_void_p]
-isl.isl_multi_pw_aff_get_space.restype = c_void_p
-isl.isl_multi_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_gist.restype = c_void_p
 isl.isl_multi_pw_aff_gist.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_pw_aff_has_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_identity_multi_pw_aff.restype = c_void_p
 isl.isl_multi_pw_aff_identity_multi_pw_aff.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_identity_on_domain_space.restype = c_void_p
@@ -1720,6 +1913,9 @@
 isl.isl_multi_pw_aff_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_involves_param_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_involves_param_id_list.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_pw_aff_isa_multi_aff.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_get_list.restype = c_void_p
+isl.isl_multi_pw_aff_get_list.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_max.restype = c_void_p
 isl.isl_multi_pw_aff_max.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_max_multi_val.restype = c_void_p
@@ -1741,6 +1937,10 @@
 isl.isl_multi_pw_aff_pullback_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_range_product.restype = c_void_p
 isl.isl_multi_pw_aff_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_pw_aff_get_range_tuple_id.restype = c_void_p
+isl.isl_multi_pw_aff_get_range_tuple_id.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_reset_range_tuple_id.restype = c_void_p
+isl.isl_multi_pw_aff_reset_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_scale_multi_val.restype = c_void_p
 isl.isl_multi_pw_aff_scale_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_scale_val.restype = c_void_p
@@ -1751,7 +1951,11 @@
 isl.isl_multi_pw_aff_scale_down_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_set_at.restype = c_void_p
 isl.isl_multi_pw_aff_set_at.argtypes = [c_void_p, c_int, c_void_p]
+isl.isl_multi_pw_aff_set_range_tuple_id.restype = c_void_p
+isl.isl_multi_pw_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_size.argtypes = [c_void_p]
+isl.isl_multi_pw_aff_get_space.restype = c_void_p
+isl.isl_multi_pw_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_pw_aff_sub.restype = c_void_p
 isl.isl_multi_pw_aff_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_pw_aff_unbind_params_insert_domain.restype = c_void_p
@@ -1838,6 +2042,16 @@
             obj = pw_multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def as_map(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_as_map(isl.isl_pw_multi_aff_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def as_multi_aff(arg0):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -1848,6 +2062,28 @@
         res = isl.isl_pw_multi_aff_as_multi_aff(isl.isl_pw_multi_aff_copy(arg0.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def as_set(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_as_set(isl.isl_pw_multi_aff_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_get_at(arg0.ptr, arg1)
+        obj = pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def bind_domain(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -1937,30 +2173,17 @@
             cb_arg1 = multi_aff(ctx=arg0.ctx, ptr=(cb_arg1))
             try:
                 arg1(cb_arg0, cb_arg1)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_pw_multi_aff_foreach_piece(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def space(arg0):
-        try:
-            if not arg0.__class__ is pw_multi_aff:
-                arg0 = pw_multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_pw_multi_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -1976,6 +2199,17 @@
         res = isl.isl_pw_multi_aff_gist(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     @staticmethod
     def identity_on_domain(*args):
         if len(args) == 1 and args[0].__class__ is space:
@@ -2071,6 +2305,22 @@
         res = isl.isl_pw_multi_aff_min_multi_val(isl.isl_pw_multi_aff_copy(arg0.ptr))
         obj = multi_val(ctx=ctx, ptr=res)
         return obj
+    @staticmethod
+    def multi_val_on_domain(arg0, arg1):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is multi_val:
+                arg1 = multi_val(arg1)
+        except:
+            return union_pw_multi_aff(arg0).multi_val_on_domain(arg1)
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_multi_val_on_domain(isl.isl_set_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def n_piece(arg0):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -2162,6 +2412,18 @@
         res = isl.isl_pw_multi_aff_range_product(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr))
         obj = pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
     def scale(*args):
         if len(args) == 2 and (args[1].__class__ is val or type(args[1]) == int):
             args = list(args)
@@ -2188,6 +2450,31 @@
             obj = pw_multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_pw_multi_aff_set_range_tuple_id(isl.isl_pw_multi_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = pw_multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
+    def space(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -2218,6 +2505,36 @@
         res = isl.isl_pw_multi_aff_subtract_domain(isl.isl_pw_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = pw_multi_aff(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_to_list(isl.isl_pw_multi_aff_copy(arg0.ptr))
+        obj = pw_multi_aff_list(ctx=ctx, ptr=res)
+        return obj
+    def to_multi_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_to_multi_pw_aff(isl.isl_pw_multi_aff_copy(arg0.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def to_union_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is pw_multi_aff:
+                arg0 = pw_multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_to_union_pw_multi_aff(isl.isl_pw_multi_aff_copy(arg0.ptr))
+        obj = union_pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def union_add(arg0, arg1):
         try:
             if not arg0.__class__ is pw_multi_aff:
@@ -2257,8 +2574,14 @@
 isl.isl_pw_multi_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_add_constant_val.restype = c_void_p
 isl.isl_pw_multi_aff_add_constant_val.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_as_map.restype = c_void_p
+isl.isl_pw_multi_aff_as_map.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_as_multi_aff.restype = c_void_p
 isl.isl_pw_multi_aff_as_multi_aff.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_as_set.restype = c_void_p
+isl.isl_pw_multi_aff_as_set.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_get_at.restype = c_void_p
+isl.isl_pw_multi_aff_get_at.argtypes = [c_void_p, c_int]
 isl.isl_pw_multi_aff_bind_domain.restype = c_void_p
 isl.isl_pw_multi_aff_bind_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_bind_domain_wrapped_domain.restype = c_void_p
@@ -2272,10 +2595,9 @@
 isl.isl_pw_multi_aff_flat_range_product.restype = c_void_p
 isl.isl_pw_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_foreach_piece.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_pw_multi_aff_get_space.restype = c_void_p
-isl.isl_pw_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_gist.restype = c_void_p
 isl.isl_pw_multi_aff_gist.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_has_range_tuple_id.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_identity_on_domain_space.restype = c_void_p
 isl.isl_pw_multi_aff_identity_on_domain_space.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_insert_domain.restype = c_void_p
@@ -2290,6 +2612,8 @@
 isl.isl_pw_multi_aff_max_multi_val.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_min_multi_val.restype = c_void_p
 isl.isl_pw_multi_aff_min_multi_val.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_multi_val_on_domain.restype = c_void_p
+isl.isl_pw_multi_aff_multi_val_on_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_n_piece.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.restype = c_void_p
 isl.isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff.argtypes = [c_void_p, c_void_p]
@@ -2307,14 +2631,26 @@
 isl.isl_pw_multi_aff_range_map.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_range_product.restype = c_void_p
 isl.isl_pw_multi_aff_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_get_range_tuple_id.restype = c_void_p
+isl.isl_pw_multi_aff_get_range_tuple_id.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_scale_val.restype = c_void_p
 isl.isl_pw_multi_aff_scale_val.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_scale_down_val.restype = c_void_p
 isl.isl_pw_multi_aff_scale_down_val.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_set_range_tuple_id.restype = c_void_p
+isl.isl_pw_multi_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_get_space.restype = c_void_p
+isl.isl_pw_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_sub.restype = c_void_p
 isl.isl_pw_multi_aff_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_subtract_domain.restype = c_void_p
 isl.isl_pw_multi_aff_subtract_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_to_list.restype = c_void_p
+isl.isl_pw_multi_aff_to_list.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_to_multi_pw_aff.restype = c_void_p
+isl.isl_pw_multi_aff_to_multi_pw_aff.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_to_union_pw_multi_aff.restype = c_void_p
+isl.isl_pw_multi_aff_to_union_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_union_add.restype = c_void_p
 isl.isl_pw_multi_aff_union_add.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_multi_aff_zero.restype = c_void_p
@@ -2398,6 +2734,16 @@
         res = isl.isl_pw_aff_as_aff(isl.isl_pw_aff_copy(arg0.ptr))
         obj = aff(ctx=ctx, ptr=res)
         return obj
+    def as_map(arg0):
+        try:
+            if not arg0.__class__ is pw_aff:
+                arg0 = pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_aff_as_map(isl.isl_pw_aff_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
     def bind(*args):
         if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
             args = list(args)
@@ -2877,6 +3223,26 @@
         res = isl.isl_pw_aff_tdiv_r(isl.isl_pw_aff_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr))
         obj = pw_aff(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is pw_aff:
+                arg0 = pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_aff_to_list(isl.isl_pw_aff_copy(arg0.ptr))
+        obj = pw_aff_list(ctx=ctx, ptr=res)
+        return obj
+    def to_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is pw_aff:
+                arg0 = pw_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_aff_to_union_pw_aff(isl.isl_pw_aff_copy(arg0.ptr))
+        obj = union_pw_aff(ctx=ctx, ptr=res)
+        return obj
     def union_add(arg0, arg1):
         try:
             if not arg0.__class__ is pw_aff:
@@ -2903,6 +3269,8 @@
 isl.isl_pw_aff_add_constant_val.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_aff_as_aff.restype = c_void_p
 isl.isl_pw_aff_as_aff.argtypes = [c_void_p]
+isl.isl_pw_aff_as_map.restype = c_void_p
+isl.isl_pw_aff_as_map.argtypes = [c_void_p]
 isl.isl_pw_aff_bind_id.restype = c_void_p
 isl.isl_pw_aff_bind_id.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_aff_bind_domain.restype = c_void_p
@@ -2974,6 +3342,10 @@
 isl.isl_pw_aff_tdiv_q.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_aff_tdiv_r.restype = c_void_p
 isl.isl_pw_aff_tdiv_r.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_aff_to_list.restype = c_void_p
+isl.isl_pw_aff_to_list.argtypes = [c_void_p]
+isl.isl_pw_aff_to_union_pw_aff.restype = c_void_p
+isl.isl_pw_aff_to_union_pw_aff.argtypes = [c_void_p]
 isl.isl_pw_aff_union_add.restype = c_void_p
 isl.isl_pw_aff_union_add.argtypes = [c_void_p, c_void_p]
 isl.isl_pw_aff_copy.restype = c_void_p
@@ -3054,6 +3426,38 @@
             obj = multi_aff(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def as_map(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_as_map(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def as_set(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_as_set(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_get_at(arg0.ptr, arg1)
+        obj = aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def bind(arg0, arg1):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3099,6 +3503,18 @@
         res = isl.isl_multi_aff_bind_domain_wrapped_domain(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def constant_multi_val(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_get_constant_multi_val(arg0.ptr)
+        obj = multi_val(ctx=ctx, ptr=res)
+        return obj
+    def get_constant_multi_val(arg0):
+        return arg0.constant_multi_val()
     @staticmethod
     def domain_map(arg0):
         try:
@@ -3135,54 +3551,6 @@
         res = isl.isl_multi_aff_floor(isl.isl_multi_aff_copy(arg0.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is multi_aff:
-                arg0 = multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_aff_get_at(arg0.ptr, arg1)
-        obj = aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
-    def constant_multi_val(arg0):
-        try:
-            if not arg0.__class__ is multi_aff:
-                arg0 = multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_aff_get_constant_multi_val(arg0.ptr)
-        obj = multi_val(ctx=ctx, ptr=res)
-        return obj
-    def get_constant_multi_val(arg0):
-        return arg0.constant_multi_val()
-    def list(arg0):
-        try:
-            if not arg0.__class__ is multi_aff:
-                arg0 = multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_aff_get_list(arg0.ptr)
-        obj = aff_list(ctx=ctx, ptr=res)
-        return obj
-    def get_list(arg0):
-        return arg0.list()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is multi_aff:
-                arg0 = multi_aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_aff_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3198,6 +3566,17 @@
         res = isl.isl_multi_aff_gist(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def identity(*args):
         if len(args) == 1:
             ctx = args[0].ctx
@@ -3250,6 +3629,26 @@
         if res < 0:
             raise
         return bool(res)
+    def list(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_get_list(arg0.ptr)
+        obj = aff_list(ctx=ctx, ptr=res)
+        return obj
+    def get_list(arg0):
+        return arg0.list()
+    @staticmethod
+    def multi_val_on_domain(*args):
+        if len(args) == 2 and args[0].__class__ is space and args[1].__class__ is multi_val:
+            ctx = args[0].ctx
+            res = isl.isl_multi_aff_multi_val_on_domain_space(isl.isl_space_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr))
+            obj = multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def neg(arg0):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3324,6 +3723,28 @@
         res = isl.isl_multi_aff_range_product(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
+    def reset_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_reset_range_tuple_id(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
     def scale(*args):
         if len(args) == 2 and args[1].__class__ is multi_val:
             ctx = args[0].ctx
@@ -3375,6 +3796,19 @@
         res = isl.isl_multi_aff_set_at(isl.isl_multi_aff_copy(arg0.ptr), arg1, isl.isl_aff_copy(arg2.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_multi_aff_set_range_tuple_id(isl.isl_multi_aff_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def size(arg0):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3386,6 +3820,18 @@
         if res < 0:
             raise
         return int(res)
+    def space(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3401,6 +3847,36 @@
         res = isl.isl_multi_aff_sub(isl.isl_multi_aff_copy(arg0.ptr), isl.isl_multi_aff_copy(arg1.ptr))
         obj = multi_aff(ctx=ctx, ptr=res)
         return obj
+    def to_multi_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_to_multi_pw_aff(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def to_multi_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_to_multi_union_pw_aff(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def to_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is multi_aff:
+                arg0 = multi_aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_aff_to_pw_multi_aff(isl.isl_multi_aff_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def unbind_params_insert_domain(arg0, arg1):
         try:
             if not arg0.__class__ is multi_aff:
@@ -3440,28 +3916,29 @@
 isl.isl_multi_aff_add_constant_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_add_constant_val.restype = c_void_p
 isl.isl_multi_aff_add_constant_val.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_aff_as_map.restype = c_void_p
+isl.isl_multi_aff_as_map.argtypes = [c_void_p]
+isl.isl_multi_aff_as_set.restype = c_void_p
+isl.isl_multi_aff_as_set.argtypes = [c_void_p]
+isl.isl_multi_aff_get_at.restype = c_void_p
+isl.isl_multi_aff_get_at.argtypes = [c_void_p, c_int]
 isl.isl_multi_aff_bind.restype = c_void_p
 isl.isl_multi_aff_bind.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_bind_domain.restype = c_void_p
 isl.isl_multi_aff_bind_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_bind_domain_wrapped_domain.restype = c_void_p
 isl.isl_multi_aff_bind_domain_wrapped_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_aff_get_constant_multi_val.restype = c_void_p
+isl.isl_multi_aff_get_constant_multi_val.argtypes = [c_void_p]
 isl.isl_multi_aff_domain_map.restype = c_void_p
 isl.isl_multi_aff_domain_map.argtypes = [c_void_p]
 isl.isl_multi_aff_flat_range_product.restype = c_void_p
 isl.isl_multi_aff_flat_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_floor.restype = c_void_p
 isl.isl_multi_aff_floor.argtypes = [c_void_p]
-isl.isl_multi_aff_get_at.restype = c_void_p
-isl.isl_multi_aff_get_at.argtypes = [c_void_p, c_int]
-isl.isl_multi_aff_get_constant_multi_val.restype = c_void_p
-isl.isl_multi_aff_get_constant_multi_val.argtypes = [c_void_p]
-isl.isl_multi_aff_get_list.restype = c_void_p
-isl.isl_multi_aff_get_list.argtypes = [c_void_p]
-isl.isl_multi_aff_get_space.restype = c_void_p
-isl.isl_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_aff_gist.restype = c_void_p
 isl.isl_multi_aff_gist.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_aff_has_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_aff_identity_multi_aff.restype = c_void_p
 isl.isl_multi_aff_identity_multi_aff.argtypes = [c_void_p]
 isl.isl_multi_aff_identity_on_domain_space.restype = c_void_p
@@ -3470,6 +3947,10 @@
 isl.isl_multi_aff_insert_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_involves_locals.argtypes = [c_void_p]
 isl.isl_multi_aff_involves_nan.argtypes = [c_void_p]
+isl.isl_multi_aff_get_list.restype = c_void_p
+isl.isl_multi_aff_get_list.argtypes = [c_void_p]
+isl.isl_multi_aff_multi_val_on_domain_space.restype = c_void_p
+isl.isl_multi_aff_multi_val_on_domain_space.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_neg.restype = c_void_p
 isl.isl_multi_aff_neg.argtypes = [c_void_p]
 isl.isl_multi_aff_plain_is_equal.argtypes = [c_void_p, c_void_p]
@@ -3481,6 +3962,10 @@
 isl.isl_multi_aff_range_map.argtypes = [c_void_p]
 isl.isl_multi_aff_range_product.restype = c_void_p
 isl.isl_multi_aff_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_aff_get_range_tuple_id.restype = c_void_p
+isl.isl_multi_aff_get_range_tuple_id.argtypes = [c_void_p]
+isl.isl_multi_aff_reset_range_tuple_id.restype = c_void_p
+isl.isl_multi_aff_reset_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_aff_scale_multi_val.restype = c_void_p
 isl.isl_multi_aff_scale_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_scale_val.restype = c_void_p
@@ -3491,9 +3976,19 @@
 isl.isl_multi_aff_scale_down_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_set_at.restype = c_void_p
 isl.isl_multi_aff_set_at.argtypes = [c_void_p, c_int, c_void_p]
+isl.isl_multi_aff_set_range_tuple_id.restype = c_void_p
+isl.isl_multi_aff_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_size.argtypes = [c_void_p]
+isl.isl_multi_aff_get_space.restype = c_void_p
+isl.isl_multi_aff_get_space.argtypes = [c_void_p]
 isl.isl_multi_aff_sub.restype = c_void_p
 isl.isl_multi_aff_sub.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_aff_to_multi_pw_aff.restype = c_void_p
+isl.isl_multi_aff_to_multi_pw_aff.argtypes = [c_void_p]
+isl.isl_multi_aff_to_multi_union_pw_aff.restype = c_void_p
+isl.isl_multi_aff_to_multi_union_pw_aff.argtypes = [c_void_p]
+isl.isl_multi_aff_to_pw_multi_aff.restype = c_void_p
+isl.isl_multi_aff_to_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_multi_aff_unbind_params_insert_domain.restype = c_void_p
 isl.isl_multi_aff_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_aff_zero.restype = c_void_p
@@ -3586,6 +4081,18 @@
         res = isl.isl_aff_ceil(isl.isl_aff_copy(arg0.ptr))
         obj = aff(ctx=ctx, ptr=res)
         return obj
+    def constant_val(arg0):
+        try:
+            if not arg0.__class__ is aff:
+                arg0 = aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_aff_get_constant_val(arg0.ptr)
+        obj = val(ctx=ctx, ptr=res)
+        return obj
+    def get_constant_val(arg0):
+        return arg0.constant_val()
     def div(arg0, arg1):
         try:
             if not arg0.__class__ is aff:
@@ -3656,18 +4163,6 @@
         res = isl.isl_aff_ge_set(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
-    def constant_val(arg0):
-        try:
-            if not arg0.__class__ is aff:
-                arg0 = aff(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_aff_get_constant_val(arg0.ptr)
-        obj = val(ctx=ctx, ptr=res)
-        return obj
-    def get_constant_val(arg0):
-        return arg0.constant_val()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is aff:
@@ -3840,6 +4335,16 @@
         res = isl.isl_aff_sub(isl.isl_aff_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr))
         obj = aff(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is aff:
+                arg0 = aff(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_aff_to_list(isl.isl_aff_copy(arg0.ptr))
+        obj = aff_list(ctx=ctx, ptr=res)
+        return obj
     def unbind_params_insert_domain(arg0, arg1):
         try:
             if not arg0.__class__ is aff:
@@ -3874,6 +4379,8 @@
 isl.isl_aff_bind_id.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_ceil.restype = c_void_p
 isl.isl_aff_ceil.argtypes = [c_void_p]
+isl.isl_aff_get_constant_val.restype = c_void_p
+isl.isl_aff_get_constant_val.argtypes = [c_void_p]
 isl.isl_aff_div.restype = c_void_p
 isl.isl_aff_div.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_eq_set.restype = c_void_p
@@ -3884,8 +4391,6 @@
 isl.isl_aff_floor.argtypes = [c_void_p]
 isl.isl_aff_ge_set.restype = c_void_p
 isl.isl_aff_ge_set.argtypes = [c_void_p, c_void_p]
-isl.isl_aff_get_constant_val.restype = c_void_p
-isl.isl_aff_get_constant_val.argtypes = [c_void_p]
 isl.isl_aff_gist.restype = c_void_p
 isl.isl_aff_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_gt_set.restype = c_void_p
@@ -3911,6 +4416,8 @@
 isl.isl_aff_scale_down_val.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_sub.restype = c_void_p
 isl.isl_aff_sub.argtypes = [c_void_p, c_void_p]
+isl.isl_aff_to_list.restype = c_void_p
+isl.isl_aff_to_list.argtypes = [c_void_p]
 isl.isl_aff_unbind_params_insert_domain.restype = c_void_p
 isl.isl_aff_unbind_params_insert_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_aff_zero_on_domain_space.restype = c_void_p
@@ -3936,6 +4443,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_aff_list_from_aff(isl.isl_aff_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_aff_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -3971,6 +4482,18 @@
         res = isl.isl_aff_list_add(isl.isl_aff_list_copy(arg0.ptr), isl.isl_aff_copy(arg1.ptr))
         obj = aff_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is aff_list:
+                arg0 = aff_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_aff_list_get_at(arg0.ptr, arg1)
+        obj = aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is aff_list:
@@ -4018,30 +4541,17 @@
             cb_arg0 = aff(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_aff_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is aff_list:
-                arg0 = aff_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_aff_list_get_at(arg0.ptr, arg1)
-        obj = aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is aff_list:
@@ -4073,8 +4583,12 @@
 isl.isl_aff_list_alloc.argtypes = [Context, c_int]
 isl.isl_aff_list_from_aff.restype = c_void_p
 isl.isl_aff_list_from_aff.argtypes = [c_void_p]
+isl.isl_aff_list_read_from_str.restype = c_void_p
+isl.isl_aff_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_aff_list_add.restype = c_void_p
 isl.isl_aff_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_aff_list_get_at.restype = c_void_p
+isl.isl_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_aff_list_clear.restype = c_void_p
 isl.isl_aff_list_clear.argtypes = [c_void_p]
 isl.isl_aff_list_concat.restype = c_void_p
@@ -4082,8 +4596,6 @@
 isl.isl_aff_list_drop.restype = c_void_p
 isl.isl_aff_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_aff_list_get_at.restype = c_void_p
-isl.isl_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_aff_list_insert.restype = c_void_p
 isl.isl_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_aff_list_size.argtypes = [c_void_p]
@@ -4124,21 +4636,20 @@
             cb_arg1 = ast_build(ctx=arg0.ctx, ptr=isl.isl_ast_build_copy(cb_arg1))
             try:
                 res = arg1(cb_arg0, cb_arg1)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return None
             return isl.isl_ast_node_copy(res.ptr)
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_ast_build_set_at_each_domain(isl.isl_ast_build_copy(arg0.ptr), cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None:
             exc_info = arg0.at_each_domain['exc_info'][0]
             arg0.at_each_domain['exc_info'][0] = None
-            if exc_info != None:
-                raise (exc_info[0], exc_info[1], exc_info[2])
+            if exc_info is not None:
+                raise exc_info
         obj = ast_build(ctx=ctx, ptr=res)
         obj.copy_callbacks(arg0)
         obj.at_each_domain = { 'func': cb, 'exc_info': exc_info }
@@ -4150,8 +4661,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         if len(args) == 2 and args[1].__class__ is pw_multi_aff:
@@ -4160,8 +4671,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         raise Error
@@ -4172,8 +4683,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         if len(args) == 2 and args[1].__class__ is pw_multi_aff:
@@ -4182,8 +4693,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         raise Error
@@ -4194,8 +4705,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         if len(args) == 2 and args[1].__class__ is set:
@@ -4204,8 +4715,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_expr(ctx=ctx, ptr=res)
             return obj
         raise Error
@@ -4220,23 +4731,6 @@
         res = isl.isl_ast_build_from_context(isl.isl_set_copy(arg0.ptr))
         obj = ast_build(ctx=ctx, ptr=res)
         return obj
-    def schedule(arg0):
-        try:
-            if not arg0.__class__ is ast_build:
-                arg0 = ast_build(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_ast_build_get_schedule(arg0.ptr)
-        if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None:
-            exc_info = arg0.at_each_domain['exc_info'][0]
-            arg0.at_each_domain['exc_info'][0] = None
-            if exc_info != None:
-                raise (exc_info[0], exc_info[1], exc_info[2])
-        obj = union_map(ctx=ctx, ptr=res)
-        return obj
-    def get_schedule(arg0):
-        return arg0.schedule()
     def node_from(*args):
         if len(args) == 2 and args[1].__class__ is schedule:
             ctx = args[0].ctx
@@ -4244,8 +4738,8 @@
             if hasattr(args[0], 'at_each_domain') and args[0].at_each_domain['exc_info'] != None:
                 exc_info = args[0].at_each_domain['exc_info'][0]
                 args[0].at_each_domain['exc_info'][0] = None
-                if exc_info != None:
-                    raise (exc_info[0], exc_info[1], exc_info[2])
+                if exc_info is not None:
+                    raise exc_info
             obj = ast_node(ctx=ctx, ptr=res)
             return obj
         raise Error
@@ -4265,10 +4759,27 @@
         if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None:
             exc_info = arg0.at_each_domain['exc_info'][0]
             arg0.at_each_domain['exc_info'][0] = None
-            if exc_info != None:
-                raise (exc_info[0], exc_info[1], exc_info[2])
+            if exc_info is not None:
+                raise exc_info
         obj = ast_node(ctx=ctx, ptr=res)
         return obj
+    def schedule(arg0):
+        try:
+            if not arg0.__class__ is ast_build:
+                arg0 = ast_build(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_ast_build_get_schedule(arg0.ptr)
+        if hasattr(arg0, 'at_each_domain') and arg0.at_each_domain['exc_info'] != None:
+            exc_info = arg0.at_each_domain['exc_info'][0]
+            arg0.at_each_domain['exc_info'][0] = None
+            if exc_info is not None:
+                raise exc_info
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
+    def get_schedule(arg0):
+        return arg0.schedule()
 
 isl.isl_ast_build_alloc.restype = c_void_p
 isl.isl_ast_build_alloc.argtypes = [Context]
@@ -4288,12 +4799,12 @@
 isl.isl_ast_build_expr_from_set.argtypes = [c_void_p, c_void_p]
 isl.isl_ast_build_from_context.restype = c_void_p
 isl.isl_ast_build_from_context.argtypes = [c_void_p]
-isl.isl_ast_build_get_schedule.restype = c_void_p
-isl.isl_ast_build_get_schedule.argtypes = [c_void_p]
 isl.isl_ast_build_node_from_schedule.restype = c_void_p
 isl.isl_ast_build_node_from_schedule.argtypes = [c_void_p, c_void_p]
 isl.isl_ast_build_node_from_schedule_map.restype = c_void_p
 isl.isl_ast_build_node_from_schedule_map.argtypes = [c_void_p, c_void_p]
+isl.isl_ast_build_get_schedule.restype = c_void_p
+isl.isl_ast_build_get_schedule.argtypes = [c_void_p]
 isl.isl_ast_build_copy.restype = c_void_p
 isl.isl_ast_build_copy.argtypes = [c_void_p]
 isl.isl_ast_build_free.restype = c_void_p
@@ -5706,9 +6217,21 @@
         string = cast(res, c_char_p).value.decode('ascii')
         libc.free(res)
         return string
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is ast_node:
+                arg0 = ast_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_ast_node_to_list(isl.isl_ast_node_copy(arg0.ptr))
+        obj = ast_node_list(ctx=ctx, ptr=res)
+        return obj
 
 isl.isl_ast_node_to_C_str.restype = POINTER(c_char)
 isl.isl_ast_node_to_C_str.argtypes = [c_void_p]
+isl.isl_ast_node_to_list.restype = c_void_p
+isl.isl_ast_node_to_list.argtypes = [c_void_p]
 isl.isl_ast_node_copy.restype = c_void_p
 isl.isl_ast_node_copy.argtypes = [c_void_p]
 isl.isl_ast_node_free.restype = c_void_p
@@ -5843,6 +6366,17 @@
         return obj
     def get_init(arg0):
         return arg0.init()
+    def is_degenerate(arg0):
+        try:
+            if not arg0.__class__ is ast_node:
+                arg0 = ast_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_ast_node_for_is_degenerate(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def iterator(arg0):
         try:
             if not arg0.__class__ is ast_node:
@@ -5855,17 +6389,6 @@
         return obj
     def get_iterator(arg0):
         return arg0.iterator()
-    def is_degenerate(arg0):
-        try:
-            if not arg0.__class__ is ast_node:
-                arg0 = ast_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_ast_node_for_is_degenerate(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
 
 isl.isl_ast_node_for_get_body.restype = c_void_p
 isl.isl_ast_node_for_get_body.argtypes = [c_void_p]
@@ -5875,9 +6398,9 @@
 isl.isl_ast_node_for_get_inc.argtypes = [c_void_p]
 isl.isl_ast_node_for_get_init.restype = c_void_p
 isl.isl_ast_node_for_get_init.argtypes = [c_void_p]
+isl.isl_ast_node_for_is_degenerate.argtypes = [c_void_p]
 isl.isl_ast_node_for_get_iterator.restype = c_void_p
 isl.isl_ast_node_for_get_iterator.argtypes = [c_void_p]
-isl.isl_ast_node_for_is_degenerate.argtypes = [c_void_p]
 isl.isl_ast_node_copy.restype = c_void_p
 isl.isl_ast_node_copy.argtypes = [c_void_p]
 isl.isl_ast_node_free.restype = c_void_p
@@ -5937,6 +6460,17 @@
         return obj
     def get_else_node(arg0):
         return arg0.else_node()
+    def has_else_node(arg0):
+        try:
+            if not arg0.__class__ is ast_node:
+                arg0 = ast_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_ast_node_if_has_else_node(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def then_node(arg0):
         try:
             if not arg0.__class__ is ast_node:
@@ -5949,25 +6483,14 @@
         return obj
     def get_then_node(arg0):
         return arg0.then_node()
-    def has_else_node(arg0):
-        try:
-            if not arg0.__class__ is ast_node:
-                arg0 = ast_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_ast_node_if_has_else_node(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
 
 isl.isl_ast_node_if_get_cond.restype = c_void_p
 isl.isl_ast_node_if_get_cond.argtypes = [c_void_p]
 isl.isl_ast_node_if_get_else_node.restype = c_void_p
 isl.isl_ast_node_if_get_else_node.argtypes = [c_void_p]
+isl.isl_ast_node_if_has_else_node.argtypes = [c_void_p]
 isl.isl_ast_node_if_get_then_node.restype = c_void_p
 isl.isl_ast_node_if_get_then_node.argtypes = [c_void_p]
-isl.isl_ast_node_if_has_else_node.argtypes = [c_void_p]
 isl.isl_ast_node_copy.restype = c_void_p
 isl.isl_ast_node_copy.argtypes = [c_void_p]
 isl.isl_ast_node_free.restype = c_void_p
@@ -6024,6 +6547,18 @@
         res = isl.isl_ast_node_list_add(isl.isl_ast_node_list_copy(arg0.ptr), isl.isl_ast_node_copy(arg1.ptr))
         obj = ast_node_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is ast_node_list:
+                arg0 = ast_node_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_ast_node_list_get_at(arg0.ptr, arg1)
+        obj = ast_node(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is ast_node_list:
@@ -6071,30 +6606,17 @@
             cb_arg0 = ast_node(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_ast_node_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is ast_node_list:
-                arg0 = ast_node_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_ast_node_list_get_at(arg0.ptr, arg1)
-        obj = ast_node(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is ast_node_list:
@@ -6128,6 +6650,8 @@
 isl.isl_ast_node_list_from_ast_node.argtypes = [c_void_p]
 isl.isl_ast_node_list_add.restype = c_void_p
 isl.isl_ast_node_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_ast_node_list_get_at.restype = c_void_p
+isl.isl_ast_node_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_ast_node_list_clear.restype = c_void_p
 isl.isl_ast_node_list_clear.argtypes = [c_void_p]
 isl.isl_ast_node_list_concat.restype = c_void_p
@@ -6135,8 +6659,6 @@
 isl.isl_ast_node_list_drop.restype = c_void_p
 isl.isl_ast_node_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_ast_node_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_ast_node_list_get_at.restype = c_void_p
-isl.isl_ast_node_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_ast_node_list_insert.restype = c_void_p
 isl.isl_ast_node_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_ast_node_list_size.argtypes = [c_void_p]
@@ -6339,6 +6861,36 @@
         res = isl.isl_union_map_apply_range(isl.isl_union_map_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
         obj = union_map(ctx=ctx, ptr=res)
         return obj
+    def as_map(arg0):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_as_map(isl.isl_union_map_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def as_multi_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_as_multi_union_pw_aff(isl.isl_union_map_copy(arg0.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def as_union_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_as_union_pw_multi_aff(isl.isl_union_map_copy(arg0.ptr))
+        obj = union_pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def bind_range(arg0, arg1):
         try:
             if not arg0.__class__ is union_map:
@@ -6496,16 +7048,15 @@
             cb_arg0 = map(ctx=arg0.ctx, ptr=isl.isl_map_copy(cb_arg0))
             try:
                 res = arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 1 if res else 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_map_every_map(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
         return bool(res)
@@ -6569,16 +7120,15 @@
             cb_arg0 = map(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_map_foreach_map(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
     @staticmethod
@@ -6632,18 +7182,6 @@
         res = isl.isl_union_map_from_range(isl.isl_union_set_copy(arg0.ptr))
         obj = union_map(ctx=ctx, ptr=res)
         return obj
-    def space(arg0):
-        try:
-            if not arg0.__class__ is union_map:
-                arg0 = union_map(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_map_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is union_map:
@@ -6957,6 +7495,18 @@
         res = isl.isl_union_map_lexmin(isl.isl_union_map_copy(arg0.ptr))
         obj = union_map(ctx=ctx, ptr=res)
         return obj
+    def map_list(arg0):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_get_map_list(arg0.ptr)
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def get_map_list(arg0):
+        return arg0.map_list()
     def polyhedral_hull(arg0):
         try:
             if not arg0.__class__ is union_map:
@@ -7106,6 +7656,18 @@
         res = isl.isl_union_map_reverse(isl.isl_union_map_copy(arg0.ptr))
         obj = union_map(ctx=ctx, ptr=res)
         return obj
+    def space(arg0):
+        try:
+            if not arg0.__class__ is union_map:
+                arg0 = union_map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_map_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def subtract(arg0, arg1):
         try:
             if not arg0.__class__ is union_map:
@@ -7219,6 +7781,12 @@
 isl.isl_union_map_apply_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_apply_range.restype = c_void_p
 isl.isl_union_map_apply_range.argtypes = [c_void_p, c_void_p]
+isl.isl_union_map_as_map.restype = c_void_p
+isl.isl_union_map_as_map.argtypes = [c_void_p]
+isl.isl_union_map_as_multi_union_pw_aff.restype = c_void_p
+isl.isl_union_map_as_multi_union_pw_aff.argtypes = [c_void_p]
+isl.isl_union_map_as_union_pw_multi_aff.restype = c_void_p
+isl.isl_union_map_as_union_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_union_map_bind_range.restype = c_void_p
 isl.isl_union_map_bind_range.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_coalesce.restype = c_void_p
@@ -7267,8 +7835,6 @@
 isl.isl_union_map_from_domain_and_range.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_from_range.restype = c_void_p
 isl.isl_union_map_from_range.argtypes = [c_void_p]
-isl.isl_union_map_get_space.restype = c_void_p
-isl.isl_union_map_get_space.argtypes = [c_void_p]
 isl.isl_union_map_gist.restype = c_void_p
 isl.isl_union_map_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_gist_domain.restype = c_void_p
@@ -7310,6 +7876,8 @@
 isl.isl_union_map_lexmax.argtypes = [c_void_p]
 isl.isl_union_map_lexmin.restype = c_void_p
 isl.isl_union_map_lexmin.argtypes = [c_void_p]
+isl.isl_union_map_get_map_list.restype = c_void_p
+isl.isl_union_map_get_map_list.argtypes = [c_void_p]
 isl.isl_union_map_polyhedral_hull.restype = c_void_p
 isl.isl_union_map_polyhedral_hull.argtypes = [c_void_p]
 isl.isl_union_map_preimage_domain_multi_aff.restype = c_void_p
@@ -7344,6 +7912,8 @@
 isl.isl_union_map_range_reverse.argtypes = [c_void_p]
 isl.isl_union_map_reverse.restype = c_void_p
 isl.isl_union_map_reverse.argtypes = [c_void_p]
+isl.isl_union_map_get_space.restype = c_void_p
+isl.isl_union_map_get_space.argtypes = [c_void_p]
 isl.isl_union_map_subtract.restype = c_void_p
 isl.isl_union_map_subtract.argtypes = [c_void_p, c_void_p]
 isl.isl_union_map_subtract_domain.restype = c_void_p
@@ -7441,6 +8011,16 @@
         res = isl.isl_map_apply_range(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def as_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_as_pw_multi_aff(isl.isl_map_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def bind_domain(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -7566,6 +8146,29 @@
         res = isl.isl_map_domain_product(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def domain_tuple_dim(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_domain_tuple_dim(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
+    def domain_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_get_domain_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_domain_tuple_id(arg0):
+        return arg0.domain_tuple_id()
     @staticmethod
     def empty(arg0):
         try:
@@ -7646,42 +8249,17 @@
             cb_arg0 = basic_map(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_map_foreach_basic_map(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def range_simple_fixed_box_hull(arg0):
-        try:
-            if not arg0.__class__ is map:
-                arg0 = map(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_map_get_range_simple_fixed_box_hull(arg0.ptr)
-        obj = fixed_box(ctx=ctx, ptr=res)
-        return obj
-    def get_range_simple_fixed_box_hull(arg0):
-        return arg0.range_simple_fixed_box_hull()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is map:
-                arg0 = map(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_map_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -7712,6 +8290,28 @@
         res = isl.isl_map_gist_domain(isl.isl_map_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def has_domain_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_has_domain_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def intersect(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -8129,6 +8729,18 @@
         res = isl.isl_map_range_factor_range(isl.isl_map_copy(arg0.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def range_lattice_tile(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_get_range_lattice_tile(arg0.ptr)
+        obj = fixed_box(ctx=ctx, ptr=res)
+        return obj
+    def get_range_lattice_tile(arg0):
+        return arg0.range_lattice_tile()
     def range_product(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -8154,6 +8766,41 @@
         res = isl.isl_map_range_reverse(isl.isl_map_copy(arg0.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def range_simple_fixed_box_hull(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_get_range_simple_fixed_box_hull(arg0.ptr)
+        obj = fixed_box(ctx=ctx, ptr=res)
+        return obj
+    def get_range_simple_fixed_box_hull(arg0):
+        return arg0.range_simple_fixed_box_hull()
+    def range_tuple_dim(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_range_tuple_dim(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
     def reverse(arg0):
         try:
             if not arg0.__class__ is map:
@@ -8174,6 +8821,44 @@
         res = isl.isl_map_sample(isl.isl_map_copy(arg0.ptr))
         obj = basic_map(ctx=ctx, ptr=res)
         return obj
+    def set_domain_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_map_set_domain_tuple_id(isl.isl_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = map(ctx=ctx, ptr=res)
+            return obj
+        raise Error
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_map_set_range_tuple_id(isl.isl_map_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = map(ctx=ctx, ptr=res)
+            return obj
+        raise Error
+    def space(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def subtract(arg0, arg1):
         try:
             if not arg0.__class__ is map:
@@ -8189,6 +8874,26 @@
         res = isl.isl_map_subtract(isl.isl_map_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_to_list(isl.isl_map_copy(arg0.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def to_union_map(arg0):
+        try:
+            if not arg0.__class__ is map:
+                arg0 = map(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_to_union_map(isl.isl_map_copy(arg0.ptr))
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
     def uncurry(arg0):
         try:
             if not arg0.__class__ is map:
@@ -8273,6 +8978,8 @@
 isl.isl_map_apply_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_map_apply_range.restype = c_void_p
 isl.isl_map_apply_range.argtypes = [c_void_p, c_void_p]
+isl.isl_map_as_pw_multi_aff.restype = c_void_p
+isl.isl_map_as_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_map_bind_domain.restype = c_void_p
 isl.isl_map_bind_domain.argtypes = [c_void_p, c_void_p]
 isl.isl_map_bind_range.restype = c_void_p
@@ -8295,6 +9002,9 @@
 isl.isl_map_domain_factor_range.argtypes = [c_void_p]
 isl.isl_map_domain_product.restype = c_void_p
 isl.isl_map_domain_product.argtypes = [c_void_p, c_void_p]
+isl.isl_map_domain_tuple_dim.argtypes = [c_void_p]
+isl.isl_map_get_domain_tuple_id.restype = c_void_p
+isl.isl_map_get_domain_tuple_id.argtypes = [c_void_p]
 isl.isl_map_empty.restype = c_void_p
 isl.isl_map_empty.argtypes = [c_void_p]
 isl.isl_map_eq_at_multi_pw_aff.restype = c_void_p
@@ -8310,14 +9020,12 @@
 isl.isl_map_flatten_range.restype = c_void_p
 isl.isl_map_flatten_range.argtypes = [c_void_p]
 isl.isl_map_foreach_basic_map.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_map_get_range_simple_fixed_box_hull.restype = c_void_p
-isl.isl_map_get_range_simple_fixed_box_hull.argtypes = [c_void_p]
-isl.isl_map_get_space.restype = c_void_p
-isl.isl_map_get_space.argtypes = [c_void_p]
 isl.isl_map_gist.restype = c_void_p
 isl.isl_map_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_map_gist_domain.restype = c_void_p
 isl.isl_map_gist_domain.argtypes = [c_void_p, c_void_p]
+isl.isl_map_has_domain_tuple_id.argtypes = [c_void_p]
+isl.isl_map_has_range_tuple_id.argtypes = [c_void_p]
 isl.isl_map_intersect.restype = c_void_p
 isl.isl_map_intersect.argtypes = [c_void_p, c_void_p]
 isl.isl_map_intersect_domain.restype = c_void_p
@@ -8386,16 +9094,33 @@
 isl.isl_map_range_factor_domain.argtypes = [c_void_p]
 isl.isl_map_range_factor_range.restype = c_void_p
 isl.isl_map_range_factor_range.argtypes = [c_void_p]
+isl.isl_map_get_range_lattice_tile.restype = c_void_p
+isl.isl_map_get_range_lattice_tile.argtypes = [c_void_p]
 isl.isl_map_range_product.restype = c_void_p
 isl.isl_map_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_map_range_reverse.restype = c_void_p
 isl.isl_map_range_reverse.argtypes = [c_void_p]
+isl.isl_map_get_range_simple_fixed_box_hull.restype = c_void_p
+isl.isl_map_get_range_simple_fixed_box_hull.argtypes = [c_void_p]
+isl.isl_map_range_tuple_dim.argtypes = [c_void_p]
+isl.isl_map_get_range_tuple_id.restype = c_void_p
+isl.isl_map_get_range_tuple_id.argtypes = [c_void_p]
 isl.isl_map_reverse.restype = c_void_p
 isl.isl_map_reverse.argtypes = [c_void_p]
 isl.isl_map_sample.restype = c_void_p
 isl.isl_map_sample.argtypes = [c_void_p]
+isl.isl_map_set_domain_tuple_id.restype = c_void_p
+isl.isl_map_set_domain_tuple_id.argtypes = [c_void_p, c_void_p]
+isl.isl_map_set_range_tuple_id.restype = c_void_p
+isl.isl_map_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
+isl.isl_map_get_space.restype = c_void_p
+isl.isl_map_get_space.argtypes = [c_void_p]
 isl.isl_map_subtract.restype = c_void_p
 isl.isl_map_subtract.argtypes = [c_void_p, c_void_p]
+isl.isl_map_to_list.restype = c_void_p
+isl.isl_map_to_list.argtypes = [c_void_p]
+isl.isl_map_to_union_map.restype = c_void_p
+isl.isl_map_to_union_map.argtypes = [c_void_p]
 isl.isl_map_uncurry.restype = c_void_p
 isl.isl_map_uncurry.argtypes = [c_void_p]
 isl.isl_map_union.restype = c_void_p
@@ -8809,6 +9534,16 @@
         res = isl.isl_union_set_apply(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
         obj = union_set(ctx=ctx, ptr=res)
         return obj
+    def as_set(arg0):
+        try:
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_set_as_set(isl.isl_union_set_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
     def coalesce(arg0):
         try:
             if not arg0.__class__ is union_set:
@@ -8859,16 +9594,15 @@
             cb_arg0 = set(ctx=arg0.ctx, ptr=isl.isl_set_copy(cb_arg0))
             try:
                 res = arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 1 if res else 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_set_every_set(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
         return bool(res)
@@ -8899,16 +9633,15 @@
             cb_arg0 = point(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_set_foreach_point(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
     def foreach_set(arg0, arg1):
@@ -8923,30 +9656,17 @@
             cb_arg0 = set(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_set_foreach_set(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def space(arg0):
-        try:
-            if not arg0.__class__ is union_set:
-                arg0 = union_set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_set_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is union_set:
@@ -9160,6 +9880,18 @@
         res = isl.isl_union_set_sample_point(isl.isl_union_set_copy(arg0.ptr))
         obj = point(ctx=ctx, ptr=res)
         return obj
+    def space(arg0):
+        try:
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_set_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def subtract(arg0, arg1):
         try:
             if not arg0.__class__ is union_set:
@@ -9175,6 +9907,16 @@
         res = isl.isl_union_set_subtract(isl.isl_union_set_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr))
         obj = union_set(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_set_to_list(isl.isl_union_set_copy(arg0.ptr))
+        obj = union_set_list(ctx=ctx, ptr=res)
+        return obj
     def union(arg0, arg1):
         try:
             if not arg0.__class__ is union_set:
@@ -9223,6 +9965,8 @@
 isl.isl_union_set_affine_hull.argtypes = [c_void_p]
 isl.isl_union_set_apply.restype = c_void_p
 isl.isl_union_set_apply.argtypes = [c_void_p, c_void_p]
+isl.isl_union_set_as_set.restype = c_void_p
+isl.isl_union_set_as_set.argtypes = [c_void_p]
 isl.isl_union_set_coalesce.restype = c_void_p
 isl.isl_union_set_coalesce.argtypes = [c_void_p]
 isl.isl_union_set_compute_divs.restype = c_void_p
@@ -9236,8 +9980,6 @@
 isl.isl_union_set_extract_set.argtypes = [c_void_p, c_void_p]
 isl.isl_union_set_foreach_point.argtypes = [c_void_p, c_void_p, c_void_p]
 isl.isl_union_set_foreach_set.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_union_set_get_space.restype = c_void_p
-isl.isl_union_set_get_space.argtypes = [c_void_p]
 isl.isl_union_set_gist.restype = c_void_p
 isl.isl_union_set_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_union_set_gist_params.restype = c_void_p
@@ -9268,8 +10010,12 @@
 isl.isl_union_set_preimage_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
 isl.isl_union_set_sample_point.restype = c_void_p
 isl.isl_union_set_sample_point.argtypes = [c_void_p]
+isl.isl_union_set_get_space.restype = c_void_p
+isl.isl_union_set_get_space.argtypes = [c_void_p]
 isl.isl_union_set_subtract.restype = c_void_p
 isl.isl_union_set_subtract.argtypes = [c_void_p, c_void_p]
+isl.isl_union_set_to_list.restype = c_void_p
+isl.isl_union_set_to_list.argtypes = [c_void_p]
 isl.isl_union_set_union.restype = c_void_p
 isl.isl_union_set_union.argtypes = [c_void_p, c_void_p]
 isl.isl_union_set_universe.restype = c_void_p
@@ -9346,6 +10092,16 @@
         res = isl.isl_set_apply(isl.isl_set_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def as_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_as_pw_multi_aff(isl.isl_set_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def bind(arg0, arg1):
         try:
             if not arg0.__class__ is set:
@@ -9444,16 +10200,15 @@
             cb_arg0 = basic_set(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_set_foreach_basic_set(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
     def foreach_point(arg0, arg1):
@@ -9468,66 +10223,17 @@
             cb_arg0 = point(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_set_foreach_point(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def plain_multi_val_if_fixed(arg0):
-        try:
-            if not arg0.__class__ is set:
-                arg0 = set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_set_get_plain_multi_val_if_fixed(arg0.ptr)
-        obj = multi_val(ctx=ctx, ptr=res)
-        return obj
-    def get_plain_multi_val_if_fixed(arg0):
-        return arg0.plain_multi_val_if_fixed()
-    def simple_fixed_box_hull(arg0):
-        try:
-            if not arg0.__class__ is set:
-                arg0 = set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_set_get_simple_fixed_box_hull(arg0.ptr)
-        obj = fixed_box(ctx=ctx, ptr=res)
-        return obj
-    def get_simple_fixed_box_hull(arg0):
-        return arg0.simple_fixed_box_hull()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is set:
-                arg0 = set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_set_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
-    def stride(arg0, arg1):
-        try:
-            if not arg0.__class__ is set:
-                arg0 = set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_set_get_stride(arg0.ptr, arg1)
-        obj = val(ctx=ctx, ptr=res)
-        return obj
-    def get_stride(arg0, arg1):
-        return arg0.stride(arg1)
     def gist(arg0, arg1):
         try:
             if not arg0.__class__ is set:
@@ -9828,6 +10534,18 @@
         res = isl.isl_set_params(isl.isl_set_copy(arg0.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def plain_multi_val_if_fixed(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_get_plain_multi_val_if_fixed(arg0.ptr)
+        obj = multi_val(ctx=ctx, ptr=res)
+        return obj
+    def get_plain_multi_val_if_fixed(arg0):
+        return arg0.plain_multi_val_if_fixed()
     def polyhedral_hull(arg0):
         try:
             if not arg0.__class__ is set:
@@ -9898,6 +10616,13 @@
             obj = set(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def pw_multi_aff_on_domain(*args):
+        if len(args) == 2 and args[1].__class__ is multi_val:
+            ctx = args[0].ctx
+            res = isl.isl_set_pw_multi_aff_on_domain_multi_val(isl.isl_set_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr))
+            obj = pw_multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def sample(arg0):
         try:
             if not arg0.__class__ is set:
@@ -9918,6 +10643,42 @@
         res = isl.isl_set_sample_point(isl.isl_set_copy(arg0.ptr))
         obj = point(ctx=ctx, ptr=res)
         return obj
+    def simple_fixed_box_hull(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_get_simple_fixed_box_hull(arg0.ptr)
+        obj = fixed_box(ctx=ctx, ptr=res)
+        return obj
+    def get_simple_fixed_box_hull(arg0):
+        return arg0.simple_fixed_box_hull()
+    def space(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
+    def stride(arg0, arg1):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_get_stride(arg0.ptr, arg1)
+        obj = val(ctx=ctx, ptr=res)
+        return obj
+    def get_stride(arg0, arg1):
+        return arg0.stride(arg1)
     def subtract(arg0, arg1):
         try:
             if not arg0.__class__ is set:
@@ -9933,6 +10694,16 @@
         res = isl.isl_set_subtract(isl.isl_set_copy(arg0.ptr), isl.isl_set_copy(arg1.ptr))
         obj = set(ctx=ctx, ptr=res)
         return obj
+    def to_union_set(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_to_union_set(isl.isl_set_copy(arg0.ptr))
+        obj = union_set(ctx=ctx, ptr=res)
+        return obj
     def translation(arg0):
         try:
             if not arg0.__class__ is set:
@@ -9943,6 +10714,17 @@
         res = isl.isl_set_translation(isl.isl_set_copy(arg0.ptr))
         obj = map(ctx=ctx, ptr=res)
         return obj
+    def tuple_dim(arg0):
+        try:
+            if not arg0.__class__ is set:
+                arg0 = set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_set_tuple_dim(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
     def unbind_params(arg0, arg1):
         try:
             if not arg0.__class__ is set:
@@ -10042,6 +10824,8 @@
 isl.isl_set_affine_hull.argtypes = [c_void_p]
 isl.isl_set_apply.restype = c_void_p
 isl.isl_set_apply.argtypes = [c_void_p, c_void_p]
+isl.isl_set_as_pw_multi_aff.restype = c_void_p
+isl.isl_set_as_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_set_bind.restype = c_void_p
 isl.isl_set_bind.argtypes = [c_void_p, c_void_p]
 isl.isl_set_coalesce.restype = c_void_p
@@ -10060,14 +10844,6 @@
 isl.isl_set_flatten.argtypes = [c_void_p]
 isl.isl_set_foreach_basic_set.argtypes = [c_void_p, c_void_p, c_void_p]
 isl.isl_set_foreach_point.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_set_get_plain_multi_val_if_fixed.restype = c_void_p
-isl.isl_set_get_plain_multi_val_if_fixed.argtypes = [c_void_p]
-isl.isl_set_get_simple_fixed_box_hull.restype = c_void_p
-isl.isl_set_get_simple_fixed_box_hull.argtypes = [c_void_p]
-isl.isl_set_get_space.restype = c_void_p
-isl.isl_set_get_space.argtypes = [c_void_p]
-isl.isl_set_get_stride.restype = c_void_p
-isl.isl_set_get_stride.argtypes = [c_void_p, c_int]
 isl.isl_set_gist.restype = c_void_p
 isl.isl_set_gist.argtypes = [c_void_p, c_void_p]
 isl.isl_set_identity.restype = c_void_p
@@ -10110,6 +10886,8 @@
 isl.isl_set_min_val.argtypes = [c_void_p, c_void_p]
 isl.isl_set_params.restype = c_void_p
 isl.isl_set_params.argtypes = [c_void_p]
+isl.isl_set_get_plain_multi_val_if_fixed.restype = c_void_p
+isl.isl_set_get_plain_multi_val_if_fixed.argtypes = [c_void_p]
 isl.isl_set_polyhedral_hull.restype = c_void_p
 isl.isl_set_polyhedral_hull.argtypes = [c_void_p]
 isl.isl_set_preimage_multi_aff.restype = c_void_p
@@ -10126,14 +10904,25 @@
 isl.isl_set_project_out_param_id.argtypes = [c_void_p, c_void_p]
 isl.isl_set_project_out_param_id_list.restype = c_void_p
 isl.isl_set_project_out_param_id_list.argtypes = [c_void_p, c_void_p]
+isl.isl_set_pw_multi_aff_on_domain_multi_val.restype = c_void_p
+isl.isl_set_pw_multi_aff_on_domain_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_set_sample.restype = c_void_p
 isl.isl_set_sample.argtypes = [c_void_p]
 isl.isl_set_sample_point.restype = c_void_p
 isl.isl_set_sample_point.argtypes = [c_void_p]
+isl.isl_set_get_simple_fixed_box_hull.restype = c_void_p
+isl.isl_set_get_simple_fixed_box_hull.argtypes = [c_void_p]
+isl.isl_set_get_space.restype = c_void_p
+isl.isl_set_get_space.argtypes = [c_void_p]
+isl.isl_set_get_stride.restype = c_void_p
+isl.isl_set_get_stride.argtypes = [c_void_p, c_int]
 isl.isl_set_subtract.restype = c_void_p
 isl.isl_set_subtract.argtypes = [c_void_p, c_void_p]
+isl.isl_set_to_union_set.restype = c_void_p
+isl.isl_set_to_union_set.argtypes = [c_void_p]
 isl.isl_set_translation.restype = c_void_p
 isl.isl_set_translation.argtypes = [c_void_p]
+isl.isl_set_tuple_dim.argtypes = [c_void_p]
 isl.isl_set_unbind_params.restype = c_void_p
 isl.isl_set_unbind_params.argtypes = [c_void_p, c_void_p]
 isl.isl_set_unbind_params_insert_domain.restype = c_void_p
@@ -10395,6 +11184,16 @@
         res = isl.isl_basic_set_sample_point(isl.isl_basic_set_copy(arg0.ptr))
         obj = point(ctx=ctx, ptr=res)
         return obj
+    def to_set(arg0):
+        try:
+            if not arg0.__class__ is basic_set:
+                arg0 = basic_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_basic_set_to_set(isl.isl_basic_set_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
     def union(arg0, arg1):
         try:
             if not arg0.__class__ is basic_set:
@@ -10445,6 +11244,8 @@
 isl.isl_basic_set_sample.argtypes = [c_void_p]
 isl.isl_basic_set_sample_point.restype = c_void_p
 isl.isl_basic_set_sample_point.argtypes = [c_void_p]
+isl.isl_basic_set_to_set.restype = c_void_p
+isl.isl_basic_set_to_set.argtypes = [c_void_p]
 isl.isl_basic_set_union.restype = c_void_p
 isl.isl_basic_set_union.argtypes = [c_void_p, c_void_p]
 isl.isl_basic_set_copy.restype = c_void_p
@@ -10480,6 +11281,17 @@
             return 'isl.fixed_box("""%s""")' % s
         else:
             return 'isl.fixed_box("%s")' % s
+    def is_valid(arg0):
+        try:
+            if not arg0.__class__ is fixed_box:
+                arg0 = fixed_box(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_fixed_box_is_valid(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def offset(arg0):
         try:
             if not arg0.__class__ is fixed_box:
@@ -10516,25 +11328,14 @@
         return obj
     def get_space(arg0):
         return arg0.space()
-    def is_valid(arg0):
-        try:
-            if not arg0.__class__ is fixed_box:
-                arg0 = fixed_box(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_fixed_box_is_valid(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
 
+isl.isl_fixed_box_is_valid.argtypes = [c_void_p]
 isl.isl_fixed_box_get_offset.restype = c_void_p
 isl.isl_fixed_box_get_offset.argtypes = [c_void_p]
 isl.isl_fixed_box_get_size.restype = c_void_p
 isl.isl_fixed_box_get_size.argtypes = [c_void_p]
 isl.isl_fixed_box_get_space.restype = c_void_p
 isl.isl_fixed_box_get_space.argtypes = [c_void_p]
-isl.isl_fixed_box_is_valid.argtypes = [c_void_p]
 isl.isl_fixed_box_copy.restype = c_void_p
 isl.isl_fixed_box_copy.argtypes = [c_void_p]
 isl.isl_fixed_box_free.restype = c_void_p
@@ -10586,11 +11387,23 @@
         return string
     def get_name(arg0):
         return arg0.name()
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is id:
+                arg0 = id(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_id_to_list(isl.isl_id_copy(arg0.ptr))
+        obj = id_list(ctx=ctx, ptr=res)
+        return obj
 
 isl.isl_id_read_from_str.restype = c_void_p
 isl.isl_id_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_id_get_name.restype = POINTER(c_char)
 isl.isl_id_get_name.argtypes = [c_void_p]
+isl.isl_id_to_list.restype = c_void_p
+isl.isl_id_to_list.argtypes = [c_void_p]
 isl.isl_id_copy.restype = c_void_p
 isl.isl_id_copy.argtypes = [c_void_p]
 isl.isl_id_free.restype = c_void_p
@@ -10618,6 +11431,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_id_list_from_id(isl.isl_id_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_id_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -10653,6 +11470,18 @@
         res = isl.isl_id_list_add(isl.isl_id_list_copy(arg0.ptr), isl.isl_id_copy(arg1.ptr))
         obj = id_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is id_list:
+                arg0 = id_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_id_list_get_at(arg0.ptr, arg1)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is id_list:
@@ -10700,30 +11529,17 @@
             cb_arg0 = id(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_id_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is id_list:
-                arg0 = id_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_id_list_get_at(arg0.ptr, arg1)
-        obj = id(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is id_list:
@@ -10755,8 +11571,12 @@
 isl.isl_id_list_alloc.argtypes = [Context, c_int]
 isl.isl_id_list_from_id.restype = c_void_p
 isl.isl_id_list_from_id.argtypes = [c_void_p]
+isl.isl_id_list_read_from_str.restype = c_void_p
+isl.isl_id_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_id_list_add.restype = c_void_p
 isl.isl_id_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_id_list_get_at.restype = c_void_p
+isl.isl_id_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_id_list_clear.restype = c_void_p
 isl.isl_id_list_clear.argtypes = [c_void_p]
 isl.isl_id_list_concat.restype = c_void_p
@@ -10764,8 +11584,6 @@
 isl.isl_id_list_drop.restype = c_void_p
 isl.isl_id_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_id_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_id_list_get_at.restype = c_void_p
-isl.isl_id_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_id_list_insert.restype = c_void_p
 isl.isl_id_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_id_list_size.argtypes = [c_void_p]
@@ -10776,6 +11594,183 @@
 isl.isl_id_list_to_str.restype = POINTER(c_char)
 isl.isl_id_list_to_str.argtypes = [c_void_p]
 
+class map_list(object):
+    def __init__(self, *args, **keywords):
+        if "ptr" in keywords:
+            self.ctx = keywords["ctx"]
+            self.ptr = keywords["ptr"]
+            return
+        if len(args) == 1 and type(args[0]) == int:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_map_list_alloc(self.ctx, args[0])
+            return
+        if len(args) == 1 and args[0].__class__ is map:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_map_list_from_map(isl.isl_map_copy(args[0].ptr))
+            return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_map_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
+        raise Error
+    def __del__(self):
+        if hasattr(self, 'ptr'):
+            isl.isl_map_list_free(self.ptr)
+    def __str__(arg0):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        ptr = isl.isl_map_list_to_str(arg0.ptr)
+        res = cast(ptr, c_char_p).value.decode('ascii')
+        libc.free(ptr)
+        return res
+    def __repr__(self):
+        s = str(self)
+        if '"' in s:
+            return 'isl.map_list("""%s""")' % s
+        else:
+            return 'isl.map_list("%s")' % s
+    def add(arg0, arg1):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map:
+                arg1 = map(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_add(isl.isl_map_list_copy(arg0.ptr), isl.isl_map_copy(arg1.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_get_at(arg0.ptr, arg1)
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
+    def clear(arg0):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_clear(isl.isl_map_list_copy(arg0.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def concat(arg0, arg1):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is map_list:
+                arg1 = map_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_concat(isl.isl_map_list_copy(arg0.ptr), isl.isl_map_list_copy(arg1.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def drop(arg0, arg1, arg2):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_drop(isl.isl_map_list_copy(arg0.ptr), arg1, arg2)
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def foreach(arg0, arg1):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        exc_info = [None]
+        fn = CFUNCTYPE(c_int, c_void_p, c_void_p)
+        def cb_func(cb_arg0, cb_arg1):
+            cb_arg0 = map(ctx=arg0.ctx, ptr=(cb_arg0))
+            try:
+                arg1(cb_arg0)
+            except BaseException as e:
+                exc_info[0] = e
+                return -1
+            return 0
+        cb = fn(cb_func)
+        ctx = arg0.ctx
+        res = isl.isl_map_list_foreach(arg0.ptr, cb, None)
+        if exc_info[0] is not None:
+            raise exc_info[0]
+        if res < 0:
+            raise
+    def insert(arg0, arg1, arg2):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        try:
+            if not arg2.__class__ is map:
+                arg2 = map(arg2)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_insert(isl.isl_map_list_copy(arg0.ptr), arg1, isl.isl_map_copy(arg2.ptr))
+        obj = map_list(ctx=ctx, ptr=res)
+        return obj
+    def size(arg0):
+        try:
+            if not arg0.__class__ is map_list:
+                arg0 = map_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_map_list_size(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
+
+isl.isl_map_list_alloc.restype = c_void_p
+isl.isl_map_list_alloc.argtypes = [Context, c_int]
+isl.isl_map_list_from_map.restype = c_void_p
+isl.isl_map_list_from_map.argtypes = [c_void_p]
+isl.isl_map_list_read_from_str.restype = c_void_p
+isl.isl_map_list_read_from_str.argtypes = [Context, c_char_p]
+isl.isl_map_list_add.restype = c_void_p
+isl.isl_map_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_map_list_get_at.restype = c_void_p
+isl.isl_map_list_get_at.argtypes = [c_void_p, c_int]
+isl.isl_map_list_clear.restype = c_void_p
+isl.isl_map_list_clear.argtypes = [c_void_p]
+isl.isl_map_list_concat.restype = c_void_p
+isl.isl_map_list_concat.argtypes = [c_void_p, c_void_p]
+isl.isl_map_list_drop.restype = c_void_p
+isl.isl_map_list_drop.argtypes = [c_void_p, c_int, c_int]
+isl.isl_map_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
+isl.isl_map_list_insert.restype = c_void_p
+isl.isl_map_list_insert.argtypes = [c_void_p, c_int, c_void_p]
+isl.isl_map_list_size.argtypes = [c_void_p]
+isl.isl_map_list_copy.restype = c_void_p
+isl.isl_map_list_copy.argtypes = [c_void_p]
+isl.isl_map_list_free.restype = c_void_p
+isl.isl_map_list_free.argtypes = [c_void_p]
+isl.isl_map_list_to_str.restype = POINTER(c_char)
+isl.isl_map_list_to_str.argtypes = [c_void_p]
+
 class multi_id(object):
     def __init__(self, *args, **keywords):
         if "ptr" in keywords:
@@ -10810,6 +11805,18 @@
             return 'isl.multi_id("""%s""")' % s
         else:
             return 'isl.multi_id("%s")' % s
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_get_at(arg0.ptr, arg1)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def flat_range_product(arg0, arg1):
         try:
             if not arg0.__class__ is multi_id:
@@ -10825,18 +11832,6 @@
         res = isl.isl_multi_id_flat_range_product(isl.isl_multi_id_copy(arg0.ptr), isl.isl_multi_id_copy(arg1.ptr))
         obj = multi_id(ctx=ctx, ptr=res)
         return obj
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_id_get_at(arg0.ptr, arg1)
-        obj = id(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def list(arg0):
         try:
             if not arg0.__class__ is multi_id:
@@ -10849,18 +11844,6 @@
         return obj
     def get_list(arg0):
         return arg0.list()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is multi_id:
-                arg0 = multi_id(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_id_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
     def plain_is_equal(arg0, arg1):
         try:
             if not arg0.__class__ is multi_id:
@@ -10918,25 +11901,37 @@
         if res < 0:
             raise
         return int(res)
+    def space(arg0):
+        try:
+            if not arg0.__class__ is multi_id:
+                arg0 = multi_id(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_id_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
 
 isl.isl_multi_id_from_id_list.restype = c_void_p
 isl.isl_multi_id_from_id_list.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_id_read_from_str.restype = c_void_p
 isl.isl_multi_id_read_from_str.argtypes = [Context, c_char_p]
-isl.isl_multi_id_flat_range_product.restype = c_void_p
-isl.isl_multi_id_flat_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_id_get_at.restype = c_void_p
 isl.isl_multi_id_get_at.argtypes = [c_void_p, c_int]
+isl.isl_multi_id_flat_range_product.restype = c_void_p
+isl.isl_multi_id_flat_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_id_get_list.restype = c_void_p
 isl.isl_multi_id_get_list.argtypes = [c_void_p]
-isl.isl_multi_id_get_space.restype = c_void_p
-isl.isl_multi_id_get_space.argtypes = [c_void_p]
 isl.isl_multi_id_plain_is_equal.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_id_range_product.restype = c_void_p
 isl.isl_multi_id_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_id_set_at.restype = c_void_p
 isl.isl_multi_id_set_at.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_multi_id_size.argtypes = [c_void_p]
+isl.isl_multi_id_get_space.restype = c_void_p
+isl.isl_multi_id_get_space.argtypes = [c_void_p]
 isl.isl_multi_id_copy.restype = c_void_p
 isl.isl_multi_id_copy.argtypes = [c_void_p]
 isl.isl_multi_id_free.restype = c_void_p
@@ -10996,6 +11991,18 @@
             obj = multi_val(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_get_at(arg0.ptr, arg1)
+        obj = val(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def flat_range_product(arg0, arg1):
         try:
             if not arg0.__class__ is multi_val:
@@ -11011,18 +12018,28 @@
         res = isl.isl_multi_val_flat_range_product(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
         obj = multi_val(ctx=ctx, ptr=res)
         return obj
-    def at(arg0, arg1):
+    def has_range_tuple_id(arg0):
         try:
             if not arg0.__class__ is multi_val:
                 arg0 = multi_val(arg0)
         except:
             raise
         ctx = arg0.ctx
-        res = isl.isl_multi_val_get_at(arg0.ptr, arg1)
-        obj = val(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
+        res = isl.isl_multi_val_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def involves_nan(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_involves_nan(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
     def list(arg0):
         try:
             if not arg0.__class__ is multi_val:
@@ -11035,29 +12052,6 @@
         return obj
     def get_list(arg0):
         return arg0.list()
-    def space(arg0):
-        try:
-            if not arg0.__class__ is multi_val:
-                arg0 = multi_val(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_val_get_space(arg0.ptr)
-        obj = space(ctx=ctx, ptr=res)
-        return obj
-    def get_space(arg0):
-        return arg0.space()
-    def involves_nan(arg0):
-        try:
-            if not arg0.__class__ is multi_val:
-                arg0 = multi_val(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_multi_val_involves_nan(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
     def max(arg0, arg1):
         try:
             if not arg0.__class__ is multi_val:
@@ -11144,6 +12138,28 @@
         res = isl.isl_multi_val_range_product(isl.isl_multi_val_copy(arg0.ptr), isl.isl_multi_val_copy(arg1.ptr))
         obj = multi_val(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
+    def reset_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_reset_range_tuple_id(isl.isl_multi_val_copy(arg0.ptr))
+        obj = multi_val(ctx=ctx, ptr=res)
+        return obj
     def scale(*args):
         if len(args) == 2 and args[1].__class__ is multi_val:
             ctx = args[0].ctx
@@ -11195,6 +12211,19 @@
         res = isl.isl_multi_val_set_at(isl.isl_multi_val_copy(arg0.ptr), arg1, isl.isl_val_copy(arg2.ptr))
         obj = multi_val(ctx=ctx, ptr=res)
         return obj
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_multi_val_set_range_tuple_id(isl.isl_multi_val_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = multi_val(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def size(arg0):
         try:
             if not arg0.__class__ is multi_val:
@@ -11206,6 +12235,18 @@
         if res < 0:
             raise
         return int(res)
+    def space(arg0):
+        try:
+            if not arg0.__class__ is multi_val:
+                arg0 = multi_val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_multi_val_get_space(arg0.ptr)
+        obj = space(ctx=ctx, ptr=res)
+        return obj
+    def get_space(arg0):
+        return arg0.space()
     def sub(arg0, arg1):
         try:
             if not arg0.__class__ is multi_val:
@@ -11241,15 +12282,14 @@
 isl.isl_multi_val_add.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_add_val.restype = c_void_p
 isl.isl_multi_val_add_val.argtypes = [c_void_p, c_void_p]
-isl.isl_multi_val_flat_range_product.restype = c_void_p
-isl.isl_multi_val_flat_range_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_get_at.restype = c_void_p
 isl.isl_multi_val_get_at.argtypes = [c_void_p, c_int]
+isl.isl_multi_val_flat_range_product.restype = c_void_p
+isl.isl_multi_val_flat_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_val_has_range_tuple_id.argtypes = [c_void_p]
+isl.isl_multi_val_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_val_get_list.restype = c_void_p
 isl.isl_multi_val_get_list.argtypes = [c_void_p]
-isl.isl_multi_val_get_space.restype = c_void_p
-isl.isl_multi_val_get_space.argtypes = [c_void_p]
-isl.isl_multi_val_involves_nan.argtypes = [c_void_p]
 isl.isl_multi_val_max.restype = c_void_p
 isl.isl_multi_val_max.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_min.restype = c_void_p
@@ -11261,6 +12301,10 @@
 isl.isl_multi_val_product.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_range_product.restype = c_void_p
 isl.isl_multi_val_range_product.argtypes = [c_void_p, c_void_p]
+isl.isl_multi_val_get_range_tuple_id.restype = c_void_p
+isl.isl_multi_val_get_range_tuple_id.argtypes = [c_void_p]
+isl.isl_multi_val_reset_range_tuple_id.restype = c_void_p
+isl.isl_multi_val_reset_range_tuple_id.argtypes = [c_void_p]
 isl.isl_multi_val_scale_multi_val.restype = c_void_p
 isl.isl_multi_val_scale_multi_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_scale_val.restype = c_void_p
@@ -11271,7 +12315,11 @@
 isl.isl_multi_val_scale_down_val.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_set_at.restype = c_void_p
 isl.isl_multi_val_set_at.argtypes = [c_void_p, c_int, c_void_p]
+isl.isl_multi_val_set_range_tuple_id.restype = c_void_p
+isl.isl_multi_val_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_size.argtypes = [c_void_p]
+isl.isl_multi_val_get_space.restype = c_void_p
+isl.isl_multi_val_get_space.argtypes = [c_void_p]
 isl.isl_multi_val_sub.restype = c_void_p
 isl.isl_multi_val_sub.argtypes = [c_void_p, c_void_p]
 isl.isl_multi_val_zero.restype = c_void_p
@@ -11321,9 +12369,21 @@
         return obj
     def get_multi_val(arg0):
         return arg0.multi_val()
+    def to_set(arg0):
+        try:
+            if not arg0.__class__ is point:
+                arg0 = point(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_point_to_set(isl.isl_point_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
 
 isl.isl_point_get_multi_val.restype = c_void_p
 isl.isl_point_get_multi_val.argtypes = [c_void_p]
+isl.isl_point_to_set.restype = c_void_p
+isl.isl_point_to_set.argtypes = [c_void_p]
 isl.isl_point_copy.restype = c_void_p
 isl.isl_point_copy.argtypes = [c_void_p]
 isl.isl_point_free.restype = c_void_p
@@ -11345,6 +12405,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_pw_aff_list_from_pw_aff(isl.isl_pw_aff_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_pw_aff_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -11380,6 +12444,18 @@
         res = isl.isl_pw_aff_list_add(isl.isl_pw_aff_list_copy(arg0.ptr), isl.isl_pw_aff_copy(arg1.ptr))
         obj = pw_aff_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is pw_aff_list:
+                arg0 = pw_aff_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_aff_list_get_at(arg0.ptr, arg1)
+        obj = pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is pw_aff_list:
@@ -11427,30 +12503,17 @@
             cb_arg0 = pw_aff(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_pw_aff_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is pw_aff_list:
-                arg0 = pw_aff_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_pw_aff_list_get_at(arg0.ptr, arg1)
-        obj = pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is pw_aff_list:
@@ -11482,8 +12545,12 @@
 isl.isl_pw_aff_list_alloc.argtypes = [Context, c_int]
 isl.isl_pw_aff_list_from_pw_aff.restype = c_void_p
 isl.isl_pw_aff_list_from_pw_aff.argtypes = [c_void_p]
+isl.isl_pw_aff_list_read_from_str.restype = c_void_p
+isl.isl_pw_aff_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_pw_aff_list_add.restype = c_void_p
 isl.isl_pw_aff_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_aff_list_get_at.restype = c_void_p
+isl.isl_pw_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_pw_aff_list_clear.restype = c_void_p
 isl.isl_pw_aff_list_clear.argtypes = [c_void_p]
 isl.isl_pw_aff_list_concat.restype = c_void_p
@@ -11491,8 +12558,6 @@
 isl.isl_pw_aff_list_drop.restype = c_void_p
 isl.isl_pw_aff_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_pw_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_pw_aff_list_get_at.restype = c_void_p
-isl.isl_pw_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_pw_aff_list_insert.restype = c_void_p
 isl.isl_pw_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_pw_aff_list_size.argtypes = [c_void_p]
@@ -11517,6 +12582,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_pw_multi_aff_list_from_pw_multi_aff(isl.isl_pw_multi_aff_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_pw_multi_aff_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -11552,6 +12621,18 @@
         res = isl.isl_pw_multi_aff_list_add(isl.isl_pw_multi_aff_list_copy(arg0.ptr), isl.isl_pw_multi_aff_copy(arg1.ptr))
         obj = pw_multi_aff_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is pw_multi_aff_list:
+                arg0 = pw_multi_aff_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_pw_multi_aff_list_get_at(arg0.ptr, arg1)
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is pw_multi_aff_list:
@@ -11599,30 +12680,17 @@
             cb_arg0 = pw_multi_aff(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_pw_multi_aff_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is pw_multi_aff_list:
-                arg0 = pw_multi_aff_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_pw_multi_aff_list_get_at(arg0.ptr, arg1)
-        obj = pw_multi_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is pw_multi_aff_list:
@@ -11654,8 +12722,12 @@
 isl.isl_pw_multi_aff_list_alloc.argtypes = [Context, c_int]
 isl.isl_pw_multi_aff_list_from_pw_multi_aff.restype = c_void_p
 isl.isl_pw_multi_aff_list_from_pw_multi_aff.argtypes = [c_void_p]
+isl.isl_pw_multi_aff_list_read_from_str.restype = c_void_p
+isl.isl_pw_multi_aff_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_pw_multi_aff_list_add.restype = c_void_p
 isl.isl_pw_multi_aff_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_pw_multi_aff_list_get_at.restype = c_void_p
+isl.isl_pw_multi_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_pw_multi_aff_list_clear.restype = c_void_p
 isl.isl_pw_multi_aff_list_clear.argtypes = [c_void_p]
 isl.isl_pw_multi_aff_list_concat.restype = c_void_p
@@ -11663,8 +12735,6 @@
 isl.isl_pw_multi_aff_list_drop.restype = c_void_p
 isl.isl_pw_multi_aff_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_pw_multi_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_pw_multi_aff_list_get_at.restype = c_void_p
-isl.isl_pw_multi_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_pw_multi_aff_list_insert.restype = c_void_p
 isl.isl_pw_multi_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_pw_multi_aff_list_size.argtypes = [c_void_p]
@@ -11705,17 +12775,6 @@
             return 'isl.schedule("""%s""")' % s
         else:
             return 'isl.schedule("%s")' % s
-    @staticmethod
-    def from_domain(arg0):
-        try:
-            if not arg0.__class__ is union_set:
-                arg0 = union_set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_from_domain(isl.isl_union_set_copy(arg0.ptr))
-        obj = schedule(ctx=ctx, ptr=res)
-        return obj
     def domain(arg0):
         try:
             if not arg0.__class__ is schedule:
@@ -11728,6 +12787,17 @@
         return obj
     def get_domain(arg0):
         return arg0.domain()
+    @staticmethod
+    def from_domain(arg0):
+        try:
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_from_domain(isl.isl_union_set_copy(arg0.ptr))
+        obj = schedule(ctx=ctx, ptr=res)
+        return obj
     def map(arg0):
         try:
             if not arg0.__class__ is schedule:
@@ -11740,6 +12810,13 @@
         return obj
     def get_map(arg0):
         return arg0.map()
+    def pullback(*args):
+        if len(args) == 2 and args[1].__class__ is union_pw_multi_aff:
+            ctx = args[0].ctx
+            res = isl.isl_schedule_pullback_union_pw_multi_aff(isl.isl_schedule_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr))
+            obj = schedule(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def root(arg0):
         try:
             if not arg0.__class__ is schedule:
@@ -11752,26 +12829,19 @@
         return obj
     def get_root(arg0):
         return arg0.root()
-    def pullback(*args):
-        if len(args) == 2 and args[1].__class__ is union_pw_multi_aff:
-            ctx = args[0].ctx
-            res = isl.isl_schedule_pullback_union_pw_multi_aff(isl.isl_schedule_copy(args[0].ptr), isl.isl_union_pw_multi_aff_copy(args[1].ptr))
-            obj = schedule(ctx=ctx, ptr=res)
-            return obj
-        raise Error
 
 isl.isl_schedule_read_from_str.restype = c_void_p
 isl.isl_schedule_read_from_str.argtypes = [Context, c_char_p]
-isl.isl_schedule_from_domain.restype = c_void_p
-isl.isl_schedule_from_domain.argtypes = [c_void_p]
 isl.isl_schedule_get_domain.restype = c_void_p
 isl.isl_schedule_get_domain.argtypes = [c_void_p]
+isl.isl_schedule_from_domain.restype = c_void_p
+isl.isl_schedule_from_domain.argtypes = [c_void_p]
 isl.isl_schedule_get_map.restype = c_void_p
 isl.isl_schedule_get_map.argtypes = [c_void_p]
-isl.isl_schedule_get_root.restype = c_void_p
-isl.isl_schedule_get_root.argtypes = [c_void_p]
 isl.isl_schedule_pullback_union_pw_multi_aff.restype = c_void_p
 isl.isl_schedule_pullback_union_pw_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_schedule_get_root.restype = c_void_p
+isl.isl_schedule_get_root.argtypes = [c_void_p]
 isl.isl_schedule_copy.restype = c_void_p
 isl.isl_schedule_copy.argtypes = [c_void_p]
 isl.isl_schedule_free.restype = c_void_p
@@ -11809,16 +12879,6 @@
             return 'isl.schedule_constraints("""%s""")' % s
         else:
             return 'isl.schedule_constraints("%s")' % s
-    def compute_schedule(arg0):
-        try:
-            if not arg0.__class__ is schedule_constraints:
-                arg0 = schedule_constraints(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_constraints_compute_schedule(isl.isl_schedule_constraints_copy(arg0.ptr))
-        obj = schedule(ctx=ctx, ptr=res)
-        return obj
     def coincidence(arg0):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11831,6 +12891,16 @@
         return obj
     def get_coincidence(arg0):
         return arg0.coincidence()
+    def compute_schedule(arg0):
+        try:
+            if not arg0.__class__ is schedule_constraints:
+                arg0 = schedule_constraints(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_constraints_compute_schedule(isl.isl_schedule_constraints_copy(arg0.ptr))
+        obj = schedule(ctx=ctx, ptr=res)
+        return obj
     def conditional_validity(arg0):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11879,6 +12949,17 @@
         return obj
     def get_domain(arg0):
         return arg0.domain()
+    @staticmethod
+    def on_domain(arg0):
+        try:
+            if not arg0.__class__ is union_set:
+                arg0 = union_set(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_constraints_on_domain(isl.isl_union_set_copy(arg0.ptr))
+        obj = schedule_constraints(ctx=ctx, ptr=res)
+        return obj
     def proximity(arg0):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11891,29 +12972,6 @@
         return obj
     def get_proximity(arg0):
         return arg0.proximity()
-    def validity(arg0):
-        try:
-            if not arg0.__class__ is schedule_constraints:
-                arg0 = schedule_constraints(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_constraints_get_validity(arg0.ptr)
-        obj = union_map(ctx=ctx, ptr=res)
-        return obj
-    def get_validity(arg0):
-        return arg0.validity()
-    @staticmethod
-    def on_domain(arg0):
-        try:
-            if not arg0.__class__ is union_set:
-                arg0 = union_set(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_constraints_on_domain(isl.isl_union_set_copy(arg0.ptr))
-        obj = schedule_constraints(ctx=ctx, ptr=res)
-        return obj
     def set_coincidence(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_constraints:
@@ -11994,13 +13052,25 @@
         res = isl.isl_schedule_constraints_set_validity(isl.isl_schedule_constraints_copy(arg0.ptr), isl.isl_union_map_copy(arg1.ptr))
         obj = schedule_constraints(ctx=ctx, ptr=res)
         return obj
+    def validity(arg0):
+        try:
+            if not arg0.__class__ is schedule_constraints:
+                arg0 = schedule_constraints(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_constraints_get_validity(arg0.ptr)
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
+    def get_validity(arg0):
+        return arg0.validity()
 
 isl.isl_schedule_constraints_read_from_str.restype = c_void_p
 isl.isl_schedule_constraints_read_from_str.argtypes = [Context, c_char_p]
-isl.isl_schedule_constraints_compute_schedule.restype = c_void_p
-isl.isl_schedule_constraints_compute_schedule.argtypes = [c_void_p]
 isl.isl_schedule_constraints_get_coincidence.restype = c_void_p
 isl.isl_schedule_constraints_get_coincidence.argtypes = [c_void_p]
+isl.isl_schedule_constraints_compute_schedule.restype = c_void_p
+isl.isl_schedule_constraints_compute_schedule.argtypes = [c_void_p]
 isl.isl_schedule_constraints_get_conditional_validity.restype = c_void_p
 isl.isl_schedule_constraints_get_conditional_validity.argtypes = [c_void_p]
 isl.isl_schedule_constraints_get_conditional_validity_condition.restype = c_void_p
@@ -12009,12 +13079,10 @@
 isl.isl_schedule_constraints_get_context.argtypes = [c_void_p]
 isl.isl_schedule_constraints_get_domain.restype = c_void_p
 isl.isl_schedule_constraints_get_domain.argtypes = [c_void_p]
-isl.isl_schedule_constraints_get_proximity.restype = c_void_p
-isl.isl_schedule_constraints_get_proximity.argtypes = [c_void_p]
-isl.isl_schedule_constraints_get_validity.restype = c_void_p
-isl.isl_schedule_constraints_get_validity.argtypes = [c_void_p]
 isl.isl_schedule_constraints_on_domain.restype = c_void_p
 isl.isl_schedule_constraints_on_domain.argtypes = [c_void_p]
+isl.isl_schedule_constraints_get_proximity.restype = c_void_p
+isl.isl_schedule_constraints_get_proximity.argtypes = [c_void_p]
 isl.isl_schedule_constraints_set_coincidence.restype = c_void_p
 isl.isl_schedule_constraints_set_coincidence.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_constraints_set_conditional_validity.restype = c_void_p
@@ -12025,6 +13093,8 @@
 isl.isl_schedule_constraints_set_proximity.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_constraints_set_validity.restype = c_void_p
 isl.isl_schedule_constraints_set_validity.argtypes = [c_void_p, c_void_p]
+isl.isl_schedule_constraints_get_validity.restype = c_void_p
+isl.isl_schedule_constraints_get_validity.argtypes = [c_void_p]
 isl.isl_schedule_constraints_copy.restype = c_void_p
 isl.isl_schedule_constraints_copy.argtypes = [c_void_p]
 isl.isl_schedule_constraints_free.restype = c_void_p
@@ -12139,6 +13209,24 @@
         res = isl.isl_schedule_node_ancestor(isl.isl_schedule_node_copy(arg0.ptr), arg1)
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
+    def ancestor_child_position(arg0, arg1):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is schedule_node:
+                arg1 = schedule_node(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_ancestor_child_position(arg0.ptr, arg1.ptr)
+        if res < 0:
+            raise
+        return int(res)
+    def get_ancestor_child_position(arg0, arg1):
+        return arg0.ancestor_child_position(arg1)
     def child(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
@@ -12149,6 +13237,19 @@
         res = isl.isl_schedule_node_child(isl.isl_schedule_node_copy(arg0.ptr), arg1)
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
+    def child_position(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_child_position(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
+    def get_child_position(arg0):
+        return arg0.child_position()
     def every_descendant(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
@@ -12161,16 +13262,15 @@
             cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0))
             try:
                 res = arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 1 if res else 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_schedule_node_every_descendant(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
         return bool(res)
@@ -12196,16 +13296,15 @@
             cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_schedule_node_foreach_ancestor_top_down(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
     def foreach_descendant_top_down(arg0, arg1):
@@ -12220,16 +13319,15 @@
             cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=isl.isl_schedule_node_copy(cb_arg0))
             try:
                 res = arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 1 if res else 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_schedule_node_foreach_descendant_top_down(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
     @staticmethod
@@ -12254,115 +13352,6 @@
         res = isl.isl_schedule_node_from_extension(isl.isl_union_map_copy(arg0.ptr))
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
-    def ancestor_child_position(arg0, arg1):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        try:
-            if not arg1.__class__ is schedule_node:
-                arg1 = schedule_node(arg1)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_ancestor_child_position(arg0.ptr, arg1.ptr)
-        if res < 0:
-            raise
-        return int(res)
-    def get_ancestor_child_position(arg0, arg1):
-        return arg0.ancestor_child_position(arg1)
-    def child_position(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_child_position(arg0.ptr)
-        if res < 0:
-            raise
-        return int(res)
-    def get_child_position(arg0):
-        return arg0.child_position()
-    def prefix_schedule_multi_union_pw_aff(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(arg0.ptr)
-        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_prefix_schedule_multi_union_pw_aff(arg0):
-        return arg0.prefix_schedule_multi_union_pw_aff()
-    def prefix_schedule_union_map(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_prefix_schedule_union_map(arg0.ptr)
-        obj = union_map(ctx=ctx, ptr=res)
-        return obj
-    def get_prefix_schedule_union_map(arg0):
-        return arg0.prefix_schedule_union_map()
-    def prefix_schedule_union_pw_multi_aff(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(arg0.ptr)
-        obj = union_pw_multi_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_prefix_schedule_union_pw_multi_aff(arg0):
-        return arg0.prefix_schedule_union_pw_multi_aff()
-    def schedule(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_schedule(arg0.ptr)
-        obj = schedule(ctx=ctx, ptr=res)
-        return obj
-    def get_schedule(arg0):
-        return arg0.schedule()
-    def shared_ancestor(arg0, arg1):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        try:
-            if not arg1.__class__ is schedule_node:
-                arg1 = schedule_node(arg1)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_shared_ancestor(arg0.ptr, arg1.ptr)
-        obj = schedule_node(ctx=ctx, ptr=res)
-        return obj
-    def get_shared_ancestor(arg0, arg1):
-        return arg0.shared_ancestor(arg1)
-    def tree_depth(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_get_tree_depth(arg0.ptr)
-        if res < 0:
-            raise
-        return int(res)
-    def get_tree_depth(arg0):
-        return arg0.tree_depth()
     def graft_after(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
@@ -12581,16 +13570,15 @@
             cb_arg0 = schedule_node(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 res = arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return None
             return isl.isl_schedule_node_copy(res.ptr)
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_schedule_node_map_descendant_bottom_up(isl.isl_schedule_node_copy(arg0.ptr), cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
     def n_children(arg0):
@@ -12654,6 +13642,42 @@
         res = isl.isl_schedule_node_parent(isl.isl_schedule_node_copy(arg0.ptr))
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
+    def prefix_schedule_multi_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff(arg0.ptr)
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_prefix_schedule_multi_union_pw_aff(arg0):
+        return arg0.prefix_schedule_multi_union_pw_aff()
+    def prefix_schedule_union_map(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_prefix_schedule_union_map(arg0.ptr)
+        obj = union_map(ctx=ctx, ptr=res)
+        return obj
+    def get_prefix_schedule_union_map(arg0):
+        return arg0.prefix_schedule_union_map()
+    def prefix_schedule_union_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(arg0.ptr)
+        obj = union_pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_prefix_schedule_union_pw_multi_aff(arg0):
+        return arg0.prefix_schedule_union_pw_multi_aff()
     def previous_sibling(arg0):
         try:
             if not arg0.__class__ is schedule_node:
@@ -12674,11 +13698,55 @@
         res = isl.isl_schedule_node_root(isl.isl_schedule_node_copy(arg0.ptr))
         obj = schedule_node(ctx=ctx, ptr=res)
         return obj
+    def schedule(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_schedule(arg0.ptr)
+        obj = schedule(ctx=ctx, ptr=res)
+        return obj
+    def get_schedule(arg0):
+        return arg0.schedule()
+    def shared_ancestor(arg0, arg1):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is schedule_node:
+                arg1 = schedule_node(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_shared_ancestor(arg0.ptr, arg1.ptr)
+        obj = schedule_node(ctx=ctx, ptr=res)
+        return obj
+    def get_shared_ancestor(arg0, arg1):
+        return arg0.shared_ancestor(arg1)
+    def tree_depth(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_get_tree_depth(arg0.ptr)
+        if res < 0:
+            raise
+        return int(res)
+    def get_tree_depth(arg0):
+        return arg0.tree_depth()
 
 isl.isl_schedule_node_ancestor.restype = c_void_p
 isl.isl_schedule_node_ancestor.argtypes = [c_void_p, c_int]
+isl.isl_schedule_node_get_ancestor_child_position.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_node_child.restype = c_void_p
 isl.isl_schedule_node_child.argtypes = [c_void_p, c_int]
+isl.isl_schedule_node_get_child_position.argtypes = [c_void_p]
 isl.isl_schedule_node_every_descendant.argtypes = [c_void_p, c_void_p, c_void_p]
 isl.isl_schedule_node_first_child.restype = c_void_p
 isl.isl_schedule_node_first_child.argtypes = [c_void_p]
@@ -12688,19 +13756,6 @@
 isl.isl_schedule_node_from_domain.argtypes = [c_void_p]
 isl.isl_schedule_node_from_extension.restype = c_void_p
 isl.isl_schedule_node_from_extension.argtypes = [c_void_p]
-isl.isl_schedule_node_get_ancestor_child_position.argtypes = [c_void_p, c_void_p]
-isl.isl_schedule_node_get_child_position.argtypes = [c_void_p]
-isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.restype = c_void_p
-isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.argtypes = [c_void_p]
-isl.isl_schedule_node_get_prefix_schedule_union_map.restype = c_void_p
-isl.isl_schedule_node_get_prefix_schedule_union_map.argtypes = [c_void_p]
-isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.restype = c_void_p
-isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.argtypes = [c_void_p]
-isl.isl_schedule_node_get_schedule.restype = c_void_p
-isl.isl_schedule_node_get_schedule.argtypes = [c_void_p]
-isl.isl_schedule_node_get_shared_ancestor.restype = c_void_p
-isl.isl_schedule_node_get_shared_ancestor.argtypes = [c_void_p, c_void_p]
-isl.isl_schedule_node_get_tree_depth.argtypes = [c_void_p]
 isl.isl_schedule_node_graft_after.restype = c_void_p
 isl.isl_schedule_node_graft_after.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_node_graft_before.restype = c_void_p
@@ -12736,10 +13791,21 @@
 isl.isl_schedule_node_order_before.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_node_parent.restype = c_void_p
 isl.isl_schedule_node_parent.argtypes = [c_void_p]
+isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.restype = c_void_p
+isl.isl_schedule_node_get_prefix_schedule_multi_union_pw_aff.argtypes = [c_void_p]
+isl.isl_schedule_node_get_prefix_schedule_union_map.restype = c_void_p
+isl.isl_schedule_node_get_prefix_schedule_union_map.argtypes = [c_void_p]
+isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.restype = c_void_p
+isl.isl_schedule_node_get_prefix_schedule_union_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_schedule_node_previous_sibling.restype = c_void_p
 isl.isl_schedule_node_previous_sibling.argtypes = [c_void_p]
 isl.isl_schedule_node_root.restype = c_void_p
 isl.isl_schedule_node_root.argtypes = [c_void_p]
+isl.isl_schedule_node_get_schedule.restype = c_void_p
+isl.isl_schedule_node_get_schedule.argtypes = [c_void_p]
+isl.isl_schedule_node_get_shared_ancestor.restype = c_void_p
+isl.isl_schedule_node_get_shared_ancestor.argtypes = [c_void_p, c_void_p]
+isl.isl_schedule_node_get_tree_depth.argtypes = [c_void_p]
 isl.isl_schedule_node_copy.restype = c_void_p
 isl.isl_schedule_node_copy.argtypes = [c_void_p]
 isl.isl_schedule_node_free.restype = c_void_p
@@ -12800,31 +13866,6 @@
         return obj
     def get_ast_isolate_option(arg0):
         return arg0.ast_isolate_option()
-    def partial_schedule(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_band_get_partial_schedule(arg0.ptr)
-        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_partial_schedule(arg0):
-        return arg0.partial_schedule()
-    def permutable(arg0):
-        try:
-            if not arg0.__class__ is schedule_node:
-                arg0 = schedule_node(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_schedule_node_band_get_permutable(arg0.ptr)
-        if res < 0:
-            raise
-        return bool(res)
-    def get_permutable(arg0):
-        return arg0.permutable()
     def member_get_coincident(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
@@ -12872,6 +13913,31 @@
         if res < 0:
             raise
         return int(res)
+    def partial_schedule(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_band_get_partial_schedule(arg0.ptr)
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_partial_schedule(arg0):
+        return arg0.partial_schedule()
+    def permutable(arg0):
+        try:
+            if not arg0.__class__ is schedule_node:
+                arg0 = schedule_node(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_schedule_node_band_get_permutable(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def get_permutable(arg0):
+        return arg0.permutable()
     def scale(arg0, arg1):
         try:
             if not arg0.__class__ is schedule_node:
@@ -13012,15 +14078,15 @@
 isl.isl_schedule_node_band_get_ast_build_options.argtypes = [c_void_p]
 isl.isl_schedule_node_band_get_ast_isolate_option.restype = c_void_p
 isl.isl_schedule_node_band_get_ast_isolate_option.argtypes = [c_void_p]
-isl.isl_schedule_node_band_get_partial_schedule.restype = c_void_p
-isl.isl_schedule_node_band_get_partial_schedule.argtypes = [c_void_p]
-isl.isl_schedule_node_band_get_permutable.argtypes = [c_void_p]
 isl.isl_schedule_node_band_member_get_coincident.argtypes = [c_void_p, c_int]
 isl.isl_schedule_node_band_member_set_coincident.restype = c_void_p
 isl.isl_schedule_node_band_member_set_coincident.argtypes = [c_void_p, c_int, c_int]
 isl.isl_schedule_node_band_mod.restype = c_void_p
 isl.isl_schedule_node_band_mod.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_node_band_n_member.argtypes = [c_void_p]
+isl.isl_schedule_node_band_get_partial_schedule.restype = c_void_p
+isl.isl_schedule_node_band_get_partial_schedule.argtypes = [c_void_p]
+isl.isl_schedule_node_band_get_permutable.argtypes = [c_void_p]
 isl.isl_schedule_node_band_scale.restype = c_void_p
 isl.isl_schedule_node_band_scale.argtypes = [c_void_p, c_void_p]
 isl.isl_schedule_node_band_scale_down.restype = c_void_p
@@ -13541,6 +14607,19 @@
             obj = space(ctx=ctx, ptr=res)
             return obj
         raise Error
+    def add_param(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_space_add_param_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = space(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def add_unnamed_tuple(*args):
         if len(args) == 2 and type(args[1]) == int:
             ctx = args[0].ctx
@@ -13568,6 +14647,38 @@
         res = isl.isl_space_domain(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def domain_map_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_domain_map_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def domain_map_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_domain_map_pw_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def domain_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_get_domain_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_domain_tuple_id(arg0):
+        return arg0.domain_tuple_id()
     def flatten_domain(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13588,6 +14699,58 @@
         res = isl.isl_space_flatten_range(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def has_domain_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_has_domain_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def has_range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_has_range_tuple_id(arg0.ptr)
+        if res < 0:
+            raise
+        return bool(res)
+    def identity_multi_aff_on_domain(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_identity_multi_aff_on_domain(isl.isl_space_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def identity_multi_pw_aff_on_domain(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_identity_multi_pw_aff_on_domain(isl.isl_space_copy(arg0.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def identity_pw_multi_aff_on_domain(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_identity_pw_multi_aff_on_domain(isl.isl_space_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def is_equal(arg0, arg1):
         try:
             if not arg0.__class__ is space:
@@ -13625,6 +14788,101 @@
         res = isl.isl_space_map_from_set(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def multi_aff(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is aff_list:
+                arg1 = aff_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_multi_aff(isl.isl_space_copy(arg0.ptr), isl.isl_aff_list_copy(arg1.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def multi_aff_on_domain(*args):
+        if len(args) == 2 and args[1].__class__ is multi_val:
+            ctx = args[0].ctx
+            res = isl.isl_space_multi_aff_on_domain_multi_val(isl.isl_space_copy(args[0].ptr), isl.isl_multi_val_copy(args[1].ptr))
+            obj = multi_aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
+    def multi_id(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is id_list:
+                arg1 = id_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_multi_id(isl.isl_space_copy(arg0.ptr), isl.isl_id_list_copy(arg1.ptr))
+        obj = multi_id(ctx=ctx, ptr=res)
+        return obj
+    def multi_pw_aff(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is pw_aff_list:
+                arg1 = pw_aff_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_multi_pw_aff(isl.isl_space_copy(arg0.ptr), isl.isl_pw_aff_list_copy(arg1.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def multi_union_pw_aff(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is union_pw_aff_list:
+                arg1 = union_pw_aff_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_multi_union_pw_aff(isl.isl_space_copy(arg0.ptr), isl.isl_union_pw_aff_list_copy(arg1.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def multi_val(arg0, arg1):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        try:
+            if not arg1.__class__ is val_list:
+                arg1 = val_list(arg1)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_multi_val(isl.isl_space_copy(arg0.ptr), isl.isl_val_list_copy(arg1.ptr))
+        obj = multi_val(ctx=ctx, ptr=res)
+        return obj
+    def param_aff_on_domain(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_space_param_aff_on_domain_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = aff(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def params(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13660,6 +14918,26 @@
         res = isl.isl_space_range(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def range_map_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_range_map_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def range_map_pw_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_range_map_pw_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = pw_multi_aff(ctx=ctx, ptr=res)
+        return obj
     def range_reverse(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13670,6 +14948,18 @@
         res = isl.isl_space_range_reverse(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def range_tuple_id(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_get_range_tuple_id(arg0.ptr)
+        obj = id(ctx=ctx, ptr=res)
+        return obj
+    def get_range_tuple_id(arg0):
+        return arg0.range_tuple_id()
     def reverse(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13680,6 +14970,32 @@
         res = isl.isl_space_reverse(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def set_domain_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_space_set_domain_tuple_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = space(ctx=ctx, ptr=res)
+            return obj
+        raise Error
+    def set_range_tuple(*args):
+        if len(args) == 2 and (args[1].__class__ is id or type(args[1]) == str):
+            args = list(args)
+            try:
+                if not args[1].__class__ is id:
+                    args[1] = id(args[1])
+            except:
+                raise
+            ctx = args[0].ctx
+            res = isl.isl_space_set_range_tuple_id(isl.isl_space_copy(args[0].ptr), isl.isl_id_copy(args[1].ptr))
+            obj = space(ctx=ctx, ptr=res)
+            return obj
+        raise Error
     def uncurry(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13696,6 +15012,26 @@
         res = isl.isl_space_unit(ctx)
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def universe_map(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_universe_map(isl.isl_space_copy(arg0.ptr))
+        obj = map(ctx=ctx, ptr=res)
+        return obj
+    def universe_set(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_universe_set(isl.isl_space_copy(arg0.ptr))
+        obj = set(ctx=ctx, ptr=res)
+        return obj
     def unwrap(arg0):
         try:
             if not arg0.__class__ is space:
@@ -13716,41 +15052,145 @@
         res = isl.isl_space_wrap(isl.isl_space_copy(arg0.ptr))
         obj = space(ctx=ctx, ptr=res)
         return obj
+    def zero_aff_on_domain(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_zero_aff_on_domain(isl.isl_space_copy(arg0.ptr))
+        obj = aff(ctx=ctx, ptr=res)
+        return obj
+    def zero_multi_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_zero_multi_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_aff(ctx=ctx, ptr=res)
+        return obj
+    def zero_multi_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_zero_multi_pw_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def zero_multi_union_pw_aff(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_zero_multi_union_pw_aff(isl.isl_space_copy(arg0.ptr))
+        obj = multi_union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def zero_multi_val(arg0):
+        try:
+            if not arg0.__class__ is space:
+                arg0 = space(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_space_zero_multi_val(isl.isl_space_copy(arg0.ptr))
+        obj = multi_val(ctx=ctx, ptr=res)
+        return obj
 
 isl.isl_space_add_named_tuple_id_ui.restype = c_void_p
 isl.isl_space_add_named_tuple_id_ui.argtypes = [c_void_p, c_void_p, c_int]
+isl.isl_space_add_param_id.restype = c_void_p
+isl.isl_space_add_param_id.argtypes = [c_void_p, c_void_p]
 isl.isl_space_add_unnamed_tuple_ui.restype = c_void_p
 isl.isl_space_add_unnamed_tuple_ui.argtypes = [c_void_p, c_int]
 isl.isl_space_curry.restype = c_void_p
 isl.isl_space_curry.argtypes = [c_void_p]
 isl.isl_space_domain.restype = c_void_p
 isl.isl_space_domain.argtypes = [c_void_p]
+isl.isl_space_domain_map_multi_aff.restype = c_void_p
+isl.isl_space_domain_map_multi_aff.argtypes = [c_void_p]
+isl.isl_space_domain_map_pw_multi_aff.restype = c_void_p
+isl.isl_space_domain_map_pw_multi_aff.argtypes = [c_void_p]
+isl.isl_space_get_domain_tuple_id.restype = c_void_p
+isl.isl_space_get_domain_tuple_id.argtypes = [c_void_p]
 isl.isl_space_flatten_domain.restype = c_void_p
 isl.isl_space_flatten_domain.argtypes = [c_void_p]
 isl.isl_space_flatten_range.restype = c_void_p
 isl.isl_space_flatten_range.argtypes = [c_void_p]
+isl.isl_space_has_domain_tuple_id.argtypes = [c_void_p]
+isl.isl_space_has_range_tuple_id.argtypes = [c_void_p]
+isl.isl_space_identity_multi_aff_on_domain.restype = c_void_p
+isl.isl_space_identity_multi_aff_on_domain.argtypes = [c_void_p]
+isl.isl_space_identity_multi_pw_aff_on_domain.restype = c_void_p
+isl.isl_space_identity_multi_pw_aff_on_domain.argtypes = [c_void_p]
+isl.isl_space_identity_pw_multi_aff_on_domain.restype = c_void_p
+isl.isl_space_identity_pw_multi_aff_on_domain.argtypes = [c_void_p]
 isl.isl_space_is_equal.argtypes = [c_void_p, c_void_p]
 isl.isl_space_is_wrapping.argtypes = [c_void_p]
 isl.isl_space_map_from_set.restype = c_void_p
 isl.isl_space_map_from_set.argtypes = [c_void_p]
+isl.isl_space_multi_aff.restype = c_void_p
+isl.isl_space_multi_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_space_multi_aff_on_domain_multi_val.restype = c_void_p
+isl.isl_space_multi_aff_on_domain_multi_val.argtypes = [c_void_p, c_void_p]
+isl.isl_space_multi_id.restype = c_void_p
+isl.isl_space_multi_id.argtypes = [c_void_p, c_void_p]
+isl.isl_space_multi_pw_aff.restype = c_void_p
+isl.isl_space_multi_pw_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_space_multi_union_pw_aff.restype = c_void_p
+isl.isl_space_multi_union_pw_aff.argtypes = [c_void_p, c_void_p]
+isl.isl_space_multi_val.restype = c_void_p
+isl.isl_space_multi_val.argtypes = [c_void_p, c_void_p]
+isl.isl_space_param_aff_on_domain_id.restype = c_void_p
+isl.isl_space_param_aff_on_domain_id.argtypes = [c_void_p, c_void_p]
 isl.isl_space_params.restype = c_void_p
 isl.isl_space_params.argtypes = [c_void_p]
 isl.isl_space_product.restype = c_void_p
 isl.isl_space_product.argtypes = [c_void_p, c_void_p]
 isl.isl_space_range.restype = c_void_p
 isl.isl_space_range.argtypes = [c_void_p]
+isl.isl_space_range_map_multi_aff.restype = c_void_p
+isl.isl_space_range_map_multi_aff.argtypes = [c_void_p]
+isl.isl_space_range_map_pw_multi_aff.restype = c_void_p
+isl.isl_space_range_map_pw_multi_aff.argtypes = [c_void_p]
 isl.isl_space_range_reverse.restype = c_void_p
 isl.isl_space_range_reverse.argtypes = [c_void_p]
+isl.isl_space_get_range_tuple_id.restype = c_void_p
+isl.isl_space_get_range_tuple_id.argtypes = [c_void_p]
 isl.isl_space_reverse.restype = c_void_p
 isl.isl_space_reverse.argtypes = [c_void_p]
+isl.isl_space_set_domain_tuple_id.restype = c_void_p
+isl.isl_space_set_domain_tuple_id.argtypes = [c_void_p, c_void_p]
+isl.isl_space_set_range_tuple_id.restype = c_void_p
+isl.isl_space_set_range_tuple_id.argtypes = [c_void_p, c_void_p]
 isl.isl_space_uncurry.restype = c_void_p
 isl.isl_space_uncurry.argtypes = [c_void_p]
 isl.isl_space_unit.restype = c_void_p
 isl.isl_space_unit.argtypes = [Context]
+isl.isl_space_universe_map.restype = c_void_p
+isl.isl_space_universe_map.argtypes = [c_void_p]
+isl.isl_space_universe_set.restype = c_void_p
+isl.isl_space_universe_set.argtypes = [c_void_p]
 isl.isl_space_unwrap.restype = c_void_p
 isl.isl_space_unwrap.argtypes = [c_void_p]
 isl.isl_space_wrap.restype = c_void_p
 isl.isl_space_wrap.argtypes = [c_void_p]
+isl.isl_space_zero_aff_on_domain.restype = c_void_p
+isl.isl_space_zero_aff_on_domain.argtypes = [c_void_p]
+isl.isl_space_zero_multi_aff.restype = c_void_p
+isl.isl_space_zero_multi_aff.argtypes = [c_void_p]
+isl.isl_space_zero_multi_pw_aff.restype = c_void_p
+isl.isl_space_zero_multi_pw_aff.argtypes = [c_void_p]
+isl.isl_space_zero_multi_union_pw_aff.restype = c_void_p
+isl.isl_space_zero_multi_union_pw_aff.argtypes = [c_void_p]
+isl.isl_space_zero_multi_val.restype = c_void_p
+isl.isl_space_zero_multi_val.argtypes = [c_void_p]
 isl.isl_space_copy.restype = c_void_p
 isl.isl_space_copy.argtypes = [c_void_p]
 isl.isl_space_free.restype = c_void_p
@@ -14027,6 +15467,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_union_pw_aff_list_from_union_pw_aff(isl.isl_union_pw_aff_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_union_pw_aff_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -14062,6 +15506,18 @@
         res = isl.isl_union_pw_aff_list_add(isl.isl_union_pw_aff_list_copy(arg0.ptr), isl.isl_union_pw_aff_copy(arg1.ptr))
         obj = union_pw_aff_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_pw_aff_list:
+                arg0 = union_pw_aff_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_pw_aff_list_get_at(arg0.ptr, arg1)
+        obj = union_pw_aff(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is union_pw_aff_list:
@@ -14109,30 +15565,17 @@
             cb_arg0 = union_pw_aff(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_pw_aff_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is union_pw_aff_list:
-                arg0 = union_pw_aff_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_pw_aff_list_get_at(arg0.ptr, arg1)
-        obj = union_pw_aff(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is union_pw_aff_list:
@@ -14164,8 +15607,12 @@
 isl.isl_union_pw_aff_list_alloc.argtypes = [Context, c_int]
 isl.isl_union_pw_aff_list_from_union_pw_aff.restype = c_void_p
 isl.isl_union_pw_aff_list_from_union_pw_aff.argtypes = [c_void_p]
+isl.isl_union_pw_aff_list_read_from_str.restype = c_void_p
+isl.isl_union_pw_aff_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_union_pw_aff_list_add.restype = c_void_p
 isl.isl_union_pw_aff_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_union_pw_aff_list_get_at.restype = c_void_p
+isl.isl_union_pw_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_union_pw_aff_list_clear.restype = c_void_p
 isl.isl_union_pw_aff_list_clear.argtypes = [c_void_p]
 isl.isl_union_pw_aff_list_concat.restype = c_void_p
@@ -14173,8 +15620,6 @@
 isl.isl_union_pw_aff_list_drop.restype = c_void_p
 isl.isl_union_pw_aff_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_union_pw_aff_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_union_pw_aff_list_get_at.restype = c_void_p
-isl.isl_union_pw_aff_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_union_pw_aff_list_insert.restype = c_void_p
 isl.isl_union_pw_aff_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_union_pw_aff_list_size.argtypes = [c_void_p]
@@ -14199,6 +15644,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_union_set_list_from_union_set(isl.isl_union_set_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_union_set_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -14234,6 +15683,18 @@
         res = isl.isl_union_set_list_add(isl.isl_union_set_list_copy(arg0.ptr), isl.isl_union_set_copy(arg1.ptr))
         obj = union_set_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is union_set_list:
+                arg0 = union_set_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_union_set_list_get_at(arg0.ptr, arg1)
+        obj = union_set(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is union_set_list:
@@ -14281,30 +15742,17 @@
             cb_arg0 = union_set(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_union_set_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is union_set_list:
-                arg0 = union_set_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_union_set_list_get_at(arg0.ptr, arg1)
-        obj = union_set(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is union_set_list:
@@ -14336,8 +15784,12 @@
 isl.isl_union_set_list_alloc.argtypes = [Context, c_int]
 isl.isl_union_set_list_from_union_set.restype = c_void_p
 isl.isl_union_set_list_from_union_set.argtypes = [c_void_p]
+isl.isl_union_set_list_read_from_str.restype = c_void_p
+isl.isl_union_set_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_union_set_list_add.restype = c_void_p
 isl.isl_union_set_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_union_set_list_get_at.restype = c_void_p
+isl.isl_union_set_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_union_set_list_clear.restype = c_void_p
 isl.isl_union_set_list_clear.argtypes = [c_void_p]
 isl.isl_union_set_list_concat.restype = c_void_p
@@ -14345,8 +15797,6 @@
 isl.isl_union_set_list_drop.restype = c_void_p
 isl.isl_union_set_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_union_set_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_union_set_list_get_at.restype = c_void_p
-isl.isl_union_set_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_union_set_list_insert.restype = c_void_p
 isl.isl_union_set_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_union_set_list_size.argtypes = [c_void_p]
@@ -14451,6 +15901,17 @@
         ctx = arg0.ctx
         res = isl.isl_val_cmp_si(arg0.ptr, arg1)
         return res
+    def den_si(arg0):
+        try:
+            if not arg0.__class__ is val:
+                arg0 = val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_val_get_den_si(arg0.ptr)
+        return res
+    def get_den_si(arg0):
+        return arg0.den_si()
     def div(arg0, arg1):
         try:
             if not arg0.__class__ is val:
@@ -14523,28 +15984,6 @@
         if res < 0:
             raise
         return bool(res)
-    def den_si(arg0):
-        try:
-            if not arg0.__class__ is val:
-                arg0 = val(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_val_get_den_si(arg0.ptr)
-        return res
-    def get_den_si(arg0):
-        return arg0.den_si()
-    def num_si(arg0):
-        try:
-            if not arg0.__class__ is val:
-                arg0 = val(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_val_get_num_si(arg0.ptr)
-        return res
-    def get_num_si(arg0):
-        return arg0.num_si()
     def gt(arg0, arg1):
         try:
             if not arg0.__class__ is val:
@@ -14861,6 +16300,17 @@
         res = isl.isl_val_negone(ctx)
         obj = val(ctx=ctx, ptr=res)
         return obj
+    def num_si(arg0):
+        try:
+            if not arg0.__class__ is val:
+                arg0 = val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_val_get_num_si(arg0.ptr)
+        return res
+    def get_num_si(arg0):
+        return arg0.num_si()
     @staticmethod
     def one():
         ctx = Context.getDefaultInstance()
@@ -14901,6 +16351,16 @@
         res = isl.isl_val_sub(isl.isl_val_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr))
         obj = val(ctx=ctx, ptr=res)
         return obj
+    def to_list(arg0):
+        try:
+            if not arg0.__class__ is val:
+                arg0 = val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_val_to_list(isl.isl_val_copy(arg0.ptr))
+        obj = val_list(ctx=ctx, ptr=res)
+        return obj
     def trunc(arg0):
         try:
             if not arg0.__class__ is val:
@@ -14930,6 +16390,7 @@
 isl.isl_val_ceil.restype = c_void_p
 isl.isl_val_ceil.argtypes = [c_void_p]
 isl.isl_val_cmp_si.argtypes = [c_void_p, c_long]
+isl.isl_val_get_den_si.argtypes = [c_void_p]
 isl.isl_val_div.restype = c_void_p
 isl.isl_val_div.argtypes = [c_void_p, c_void_p]
 isl.isl_val_eq.argtypes = [c_void_p, c_void_p]
@@ -14938,8 +16399,6 @@
 isl.isl_val_gcd.restype = c_void_p
 isl.isl_val_gcd.argtypes = [c_void_p, c_void_p]
 isl.isl_val_ge.argtypes = [c_void_p, c_void_p]
-isl.isl_val_get_den_si.argtypes = [c_void_p]
-isl.isl_val_get_num_si.argtypes = [c_void_p]
 isl.isl_val_gt.argtypes = [c_void_p, c_void_p]
 isl.isl_val_infty.restype = c_void_p
 isl.isl_val_infty.argtypes = [Context]
@@ -14977,6 +16436,7 @@
 isl.isl_val_neginfty.argtypes = [Context]
 isl.isl_val_negone.restype = c_void_p
 isl.isl_val_negone.argtypes = [Context]
+isl.isl_val_get_num_si.argtypes = [c_void_p]
 isl.isl_val_one.restype = c_void_p
 isl.isl_val_one.argtypes = [Context]
 isl.isl_val_pow2.restype = c_void_p
@@ -14984,6 +16444,8 @@
 isl.isl_val_sgn.argtypes = [c_void_p]
 isl.isl_val_sub.restype = c_void_p
 isl.isl_val_sub.argtypes = [c_void_p, c_void_p]
+isl.isl_val_to_list.restype = c_void_p
+isl.isl_val_to_list.argtypes = [c_void_p]
 isl.isl_val_trunc.restype = c_void_p
 isl.isl_val_trunc.argtypes = [c_void_p]
 isl.isl_val_zero.restype = c_void_p
@@ -15015,6 +16477,10 @@
             self.ctx = Context.getDefaultInstance()
             self.ptr = isl.isl_val_list_from_val(isl.isl_val_copy(args[0].ptr))
             return
+        if len(args) == 1 and type(args[0]) == str:
+            self.ctx = Context.getDefaultInstance()
+            self.ptr = isl.isl_val_list_read_from_str(self.ctx, args[0].encode('ascii'))
+            return
         raise Error
     def __del__(self):
         if hasattr(self, 'ptr'):
@@ -15050,6 +16516,18 @@
         res = isl.isl_val_list_add(isl.isl_val_list_copy(arg0.ptr), isl.isl_val_copy(arg1.ptr))
         obj = val_list(ctx=ctx, ptr=res)
         return obj
+    def at(arg0, arg1):
+        try:
+            if not arg0.__class__ is val_list:
+                arg0 = val_list(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_val_list_get_at(arg0.ptr, arg1)
+        obj = val(ctx=ctx, ptr=res)
+        return obj
+    def get_at(arg0, arg1):
+        return arg0.at(arg1)
     def clear(arg0):
         try:
             if not arg0.__class__ is val_list:
@@ -15097,30 +16575,17 @@
             cb_arg0 = val(ctx=arg0.ctx, ptr=(cb_arg0))
             try:
                 arg1(cb_arg0)
-            except:
-                import sys
-                exc_info[0] = sys.exc_info()
+            except BaseException as e:
+                exc_info[0] = e
                 return -1
             return 0
         cb = fn(cb_func)
         ctx = arg0.ctx
         res = isl.isl_val_list_foreach(arg0.ptr, cb, None)
-        if exc_info[0] != None:
-            raise (exc_info[0][0], exc_info[0][1], exc_info[0][2])
+        if exc_info[0] is not None:
+            raise exc_info[0]
         if res < 0:
             raise
-    def at(arg0, arg1):
-        try:
-            if not arg0.__class__ is val_list:
-                arg0 = val_list(arg0)
-        except:
-            raise
-        ctx = arg0.ctx
-        res = isl.isl_val_list_get_at(arg0.ptr, arg1)
-        obj = val(ctx=ctx, ptr=res)
-        return obj
-    def get_at(arg0, arg1):
-        return arg0.at(arg1)
     def insert(arg0, arg1, arg2):
         try:
             if not arg0.__class__ is val_list:
@@ -15152,8 +16617,12 @@
 isl.isl_val_list_alloc.argtypes = [Context, c_int]
 isl.isl_val_list_from_val.restype = c_void_p
 isl.isl_val_list_from_val.argtypes = [c_void_p]
+isl.isl_val_list_read_from_str.restype = c_void_p
+isl.isl_val_list_read_from_str.argtypes = [Context, c_char_p]
 isl.isl_val_list_add.restype = c_void_p
 isl.isl_val_list_add.argtypes = [c_void_p, c_void_p]
+isl.isl_val_list_get_at.restype = c_void_p
+isl.isl_val_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_val_list_clear.restype = c_void_p
 isl.isl_val_list_clear.argtypes = [c_void_p]
 isl.isl_val_list_concat.restype = c_void_p
@@ -15161,8 +16630,6 @@
 isl.isl_val_list_drop.restype = c_void_p
 isl.isl_val_list_drop.argtypes = [c_void_p, c_int, c_int]
 isl.isl_val_list_foreach.argtypes = [c_void_p, c_void_p, c_void_p]
-isl.isl_val_list_get_at.restype = c_void_p
-isl.isl_val_list_get_at.argtypes = [c_void_p, c_int]
 isl.isl_val_list_insert.restype = c_void_p
 isl.isl_val_list_insert.argtypes = [c_void_p, c_int, c_void_p]
 isl.isl_val_list_size.argtypes = [c_void_p]
diff --git a/lib/External/isl/interface/isl_config.h.in b/lib/External/isl/interface/isl_config.h.in
index 4bf1b29..e116521 100644
--- a/lib/External/isl/interface/isl_config.h.in
+++ b/lib/External/isl/interface/isl_config.h.in
@@ -36,6 +36,9 @@
 /* Define if clang/Basic/DiagnosticOptions.h exists */
 #undef HAVE_BASIC_DIAGNOSTICOPTIONS_H
 
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
+
 /* Define if Driver constructor takes CXXIsProduction argument */
 #undef HAVE_CXXISPRODUCTION
 
diff --git a/lib/External/isl/interface/ltmain.sh b/lib/External/isl/interface/ltmain.sh
index 0cb7f90..48cea9b 100644
--- a/lib/External/isl/interface/ltmain.sh
+++ b/lib/External/isl/interface/ltmain.sh
@@ -1,12 +1,12 @@
 #! /bin/sh
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
+##               by inline-source v2018-07-24.06
 
-# libtool (GNU libtool) 2.4.6
+# libtool (GNU libtool) 2.4.6.42-b88ce-dirty
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -31,8 +31,8 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-14"
-package_revision=2.4.6
+VERSION=2.4.6.42-b88ce-dirty
+package_revision=2.4.6.42
 
 
 ## ------ ##
@@ -64,34 +64,25 @@
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2018-07-24.06; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
 
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2004-2018 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
 
 ## ------ ##
@@ -140,9 +131,6 @@
 	fi"
 done
 
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -159,6 +147,26 @@
 fi
 
 
+# func_unset VAR
+# --------------
+# Portably unset VAR.
+# In some shells, an 'unset VAR' statement leaves a non-zero return
+# status if VAR is already unset, which might be problematic if the
+# statement is used at the end of a function (thus poisoning its return
+# value) or when 'set -e' is active (causing even a spurious abort of
+# the script in this case).
+func_unset ()
+{
+    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
+}
+
+
+# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
+func_unset CDPATH
+
+# Make sure ${,E,F}GREP behave sanely.
+func_unset GREP_OPTIONS
+
 
 ## ------------------------- ##
 ## Locate command utilities. ##
@@ -259,7 +267,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
   rm -f conftest.sed
   SED=$func_path_progs_result
 }
@@ -295,7 +303,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
   GREP=$func_path_progs_result
 }
 
@@ -387,7 +395,7 @@
 # putting '$debug_cmd' at the start of all your functions, you can get
 # bash to show function call trace with:
 #
-#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
 debug_cmd=${debug_cmd-":"}
 exit_cmd=:
 
@@ -580,16 +588,16 @@
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1091,85 +1099,199 @@
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
+      fi
+
+      # Quote for eval.
+      case $func_quote_portable_result in
         *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
+
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero or more
+# specifiers listed below separated by ',' character.  This function returns two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         be used later in func_quote to get output like: 'echo "a b"' instead
+#         of 'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
 {
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
         ;;
     esac
 
-    func_quote_for_expand_result=$_G_arg
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
+        ;;
+    esac
+}
+
+
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1215,8 +1337,8 @@
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1241,8 +1363,8 @@
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
@@ -1369,30 +1491,26 @@
 # End:
 #! /bin/sh
 
-# Set a version string for this script.
-scriptversion=2015-10-07.11; # UTC
-
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
 
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2010-2018 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Set a version string for this script.
+scriptversion=2018-07-24.06; # UTC
 
 
 ## ------ ##
@@ -1415,7 +1533,7 @@
 #
 # In order for the '--version' option to work, you will need to have a
 # suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
+# starting with '# Written by ' and ending with '# Copyright'.
 #
 # For '-h' and '--help' to work, you will also need a one line
 # description of your script's purpose in a comment directly above the
@@ -1427,7 +1545,7 @@
 # to display verbose messages only when your user has specified
 # '--verbose'.
 #
-# After sourcing this file, you can plug processing for additional
+# After sourcing this file, you can plug in processing for additional
 # options by amending the variables from the 'Configuration' section
 # below, and following the instructions in the 'Option parsing'
 # section further down.
@@ -1476,8 +1594,8 @@
 ## ------------------------- ##
 
 # This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
+# in the main code.  A hook is just a list of function names that can be
+# run in order later on.
 
 # func_hookable FUNC_NAME
 # -----------------------
@@ -1510,7 +1628,8 @@
 
 # func_remove_hook FUNC_NAME HOOK_FUNC
 # ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+# Remove HOOK_FUNC from the list of hook functions to be called by
+# FUNC_NAME.
 func_remove_hook ()
 {
     $debug_cmd
@@ -1519,10 +1638,28 @@
 }
 
 
+# func_propagate_result FUNC_NAME_A FUNC_NAME_B
+# ---------------------------------------------
+# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
+# *_result variable of FUNC_NAME_B.
+func_propagate_result ()
+{
+    $debug_cmd
+
+    func_propagate_result_result=:
+    if eval "test \"\${${1}_result+set}\" = set"
+    then
+      eval "${2}_result=\$${1}_result"
+    else
+      func_propagate_result_result=false
+    fi
+}
+
+
 # func_run_hooks FUNC_NAME [ARG]...
 # ---------------------------------
 # Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
+# It's assumed that the list of hook functions contains nothing more
 # than a whitespace-delimited list of legal shell function names, and
 # no effort is wasted trying to catch shell meta-characters or preserve
 # whitespace.
@@ -1530,26 +1667,21 @@
 {
     $debug_cmd
 
-    _G_rc_run_hooks=false
-
     case " $hookable_fns " in
       *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+      *) func_fatal_error "'$1' does not support hook functions." ;;
     esac
 
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      if eval $_G_hook '"$@"'; then
-        # store returned options list back into positional
-        # parameters for next 'cmd' execution.
-        eval _G_hook_result=\$${_G_hook}_result
-        eval set dummy "$_G_hook_result"; shift
-        _G_rc_run_hooks=:
+      func_unset "${_G_hook}_result"
+      eval $_G_hook '${1+"$@"}'
+      func_propagate_result $_G_hook func_run_hooks
+      if $func_propagate_result_result; then
+        eval set dummy "$func_run_hooks_result"; shift
       fi
     done
-
-    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1559,14 +1691,16 @@
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, you may remove/edit
-# any options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
-# hook's caller know that it should pay attention to
-# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
-# arguments are left untouched by the hook and therefore caller will ignore the
-# result variable.
+# full positional parameter list from your hook function.  You may remove
+# or edit any options that you action, and then pass back the remaining
+# unprocessed options in '<hooked_function_name>_result', escaped
+# suitably for 'eval'.
+#
+# The '<hooked_function_name>_result' variable is automatically unset
+# before your hook gets called; for best performance, only set the
+# *_result variable when necessary (i.e. don't call the 'func_quote'
+# function unnecessarily because it can be an expensive operation on some
+# machines).
 #
 # Like this:
 #
@@ -1578,11 +1712,8 @@
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#        # No change in '$@' (ignored completely by this hook).  There is
-#        # no need to do the equivalent (but slower) action:
-#        # func_quote_for_eval ${1+"$@"}
-#        # my_options_prep_result=$func_quote_for_eval_result
-#        false
+#        # No change in '$@' (ignored completely by this hook).  Leave
+#        # my_options_prep_result variable intact.
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1593,7 +1724,7 @@
 #
 #        args_changed=false
 #
-#        # Note that for efficiency, we parse as many options as we can
+#        # Note that, for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
@@ -1610,18 +1741,17 @@
 #                         args_changed=:
 #                         ;;
 #            *)           # Make sure the first unrecognised option "$_G_opt"
-#                         # is added back to "$@", we could need that later
-#                         # if $args_changed is true.
+#                         # is added back to "$@" in case we need it later,
+#                         # if $args_changed was set to 'true'.
 #                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
+#        # Only call 'func_quote' here if we processed at least one argument.
 #        if $args_changed; then
-#          func_quote_for_eval ${1+"$@"}
-#          my_silent_option_result=$func_quote_for_eval_result
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
 #        fi
-#
-#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1632,8 +1762,6 @@
 #
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
@@ -1649,13 +1777,8 @@
 {
     $debug_cmd
 
-    _G_func_options_finish_exit=false
-    if func_run_hooks func_options ${1+"$@"}; then
-      func_options_finish_result=$func_run_hooks_result
-      _G_func_options_finish_exit=:
-    fi
-
-    $_G_func_options_finish_exit
+    func_run_hooks func_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_finish
 }
 
 
@@ -1668,28 +1791,27 @@
 {
     $debug_cmd
 
-    _G_rc_options=false
+    _G_options_quoted=false
 
     for my_func in options_prep parse_options validate_options options_finish
     do
-      if eval func_$my_func '${1+"$@"}'; then
-        eval _G_res_var='$'"func_${my_func}_result"
-        eval set dummy "$_G_res_var" ; shift
-        _G_rc_options=:
+      func_unset func_${my_func}_result
+      func_unset func_run_hooks_result
+      eval func_$my_func '${1+"$@"}'
+      func_propagate_result func_$my_func func_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_options_result"; shift
+        _G_options_quoted=:
       fi
     done
 
-    # Save modified positional parameters for caller.  As a top-level
-    # options-parser function we always need to set the 'func_options_result'
-    # variable (regardless the $_G_rc_options value).
-    if $_G_rc_options; then
-      func_options_result=$_G_res_var
-    else
-      func_quote_for_eval ${1+"$@"}
-      func_options_result=$func_quote_for_eval_result
-    fi
-
-    $_G_rc_options
+    $_G_options_quoted || {
+      # As we (func_options) are top-level options-parser function and
+      # nobody quoted "$@" for us yet, we need to do it explicitly for
+      # caller.
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    }
 }
 
 
@@ -1699,8 +1821,7 @@
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
 # needs to propagate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
+# modified list must be put in 'func_run_hooks_result' before returning.
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1710,14 +1831,8 @@
     opt_verbose=false
     opt_warning_types=
 
-    _G_rc_options_prep=false
-    if func_run_hooks func_options_prep ${1+"$@"}; then
-      _G_rc_options_prep=:
-      # save modified positional parameters for caller
-      func_options_prep_result=$func_run_hooks_result
-    fi
-
-    $_G_rc_options_prep
+    func_run_hooks func_options_prep ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_prep
 }
 
 
@@ -1729,27 +1844,32 @@
 {
     $debug_cmd
 
-    func_parse_options_result=
-
-    _G_rc_parse_options=false
+    _G_parse_options_requote=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      if func_run_hooks func_parse_options ${1+"$@"}; then
-        eval set dummy "$func_run_hooks_result"; shift
-        _G_rc_parse_options=:
+      func_run_hooks func_parse_options ${1+"$@"}
+      func_propagate_result func_run_hooks func_parse_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_parse_options_result"; shift
+        # Even though we may have changed "$@", we passed the "$@" array
+        # down into the hook and it quoted it for us (because we are in
+        # this if-branch).  No need to quote it again.
+        _G_parse_options_requote=false
       fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      # We expect that one of the options parsed in this function matches
+      # and thus we remove _G_opt from "$@" and need to re-quote.
       _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
+                      func_echo "enabling shell trace mode" >&2
                       $debug_cmd
                       ;;
 
@@ -1760,7 +1880,7 @@
 
         --warnings|--warning|-W)
                       if test $# = 0 && func_missing_arg $_G_opt; then
-                        _G_rc_parse_options=:
+                        _G_parse_options_requote=:
                         break
                       fi
                       case " $warning_categories $1" in
@@ -1815,7 +1935,7 @@
                       shift
                       ;;
 
-        --)           _G_rc_parse_options=: ; break ;;
+        --)           _G_parse_options_requote=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
         *)            set dummy "$_G_opt" ${1+"$@"}; shift
                       _G_match_parse_options=false
@@ -1823,17 +1943,16 @@
                       ;;
       esac
 
-      $_G_match_parse_options && _G_rc_parse_options=:
+      if $_G_match_parse_options; then
+        _G_parse_options_requote=:
+      fi
     done
 
-
-    if $_G_rc_parse_options; then
+    if $_G_parse_options_requote; then
       # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      func_parse_options_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
     fi
-
-    $_G_rc_parse_options
 }
 
 
@@ -1846,21 +1965,14 @@
 {
     $debug_cmd
 
-    _G_rc_validate_options=false
-
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    if func_run_hooks func_validate_options ${1+"$@"}; then
-      # save modified positional parameters for caller
-      func_validate_options_result=$func_run_hooks_result
-      _G_rc_validate_options=:
-    fi
+    func_run_hooks func_validate_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_validate_options
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
-
-    $_G_rc_validate_options
 }
 
 
@@ -1916,8 +2028,8 @@
 
 # func_split_equals STRING
 # ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables
+# after splitting STRING at the '=' sign.
 test -z "$_G_HAVE_XSI_OPS" \
     && (eval 'x=a/b/c;
       test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
@@ -1932,8 +2044,9 @@
 
       func_split_equals_lhs=${1%%=*}
       func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
+      if test "x$func_split_equals_lhs" = "x$1"; then
+        func_split_equals_rhs=
+      fi
   }'
 else
   # ...otherwise fall back to using expr, which is often a shell builtin.
@@ -2011,31 +2124,44 @@
 # func_version
 # ------------
 # Echo version message to standard output and exit.
+# The version message is extracted from the calling file's header
+# comments, with leading '# ' stripped:
+#   1. First display the progname and version
+#   2. Followed by the header comment line matching  /^# Written by /
+#   3. Then a blank line followed by the first following line matching
+#      /^# Copyright /
+#   4. Immediately followed by any lines between the previous matches,
+#      except lines preceding the intervening completely blank line.
+# For example, see the header comments of this file.
 func_version ()
 {
     $debug_cmd
 
     printf '%s\n' "$progname $scriptversion"
     $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
+        /^# Written by /!b
+        s|^# ||; p; n
+
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
         }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
         }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
+
+        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+        G
+        s|\(\n\)\n*|\1|g
+        p; q' < "$progpath"
 
     exit $?
 }
@@ -2045,12 +2171,12 @@
 # mode: shell-script
 # sh-indentation: 2
 # eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
 # time-stamp-time-zone: "UTC"
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+scriptversion='(GNU libtool) 2.4.6.42-b88ce-dirty'
 
 
 # func_echo ARG...
@@ -2141,7 +2267,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-14
+       version:        $progname (GNU libtool) 2.4.6.42-b88ce-dirty
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
@@ -2197,7 +2323,7 @@
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
+    func_fatal_error ${1+"$@"} \
       "See the $PACKAGE documentation for more information." \
       "Fatal configuration error."
 }
@@ -2375,11 +2501,9 @@
 
     if $_G_rc_lt_options_prep; then
       # Pass back the list of options.
-      func_quote_for_eval ${1+"$@"}
-      libtool_options_prep_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
     fi
-
-    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2482,11 +2606,9 @@
 
     if $_G_rc_lt_parse_options; then
       # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      libtool_parse_options_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
     fi
-
-    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -2543,8 +2665,8 @@
     }
 
     # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3510,8 +3632,8 @@
       esac
     done
 
-    func_quote_for_eval "$libobj"
-    test "X$libobj" != "X$func_quote_for_eval_result" \
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3584,8 +3706,8 @@
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_for_eval "$srcfile"
-    qsrcfile=$func_quote_for_eval_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4188,8 +4310,8 @@
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_for_eval "$nonopt"
-      install_prog="$func_quote_for_eval_result "
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
       arg=$1
       shift
     else
@@ -4199,8 +4321,8 @@
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_for_eval "$arg"
-    func_append install_prog "$func_quote_for_eval_result"
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4257,12 +4379,12 @@
       esac
 
       # Aesthetically quote the argument.
-      func_quote_for_eval "$arg"
-      func_append install_prog " $func_quote_for_eval_result"
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
       if test -n "$arg2"; then
-	func_quote_for_eval "$arg2"
+	func_quote_arg pretty "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_for_eval_result"
+      func_append install_shared_prog " $func_quote_arg_result"
     done
 
     test -z "$install_prog" && \
@@ -4273,8 +4395,8 @@
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-	func_quote_for_eval "$install_override_mode"
-	func_append install_shared_prog " -m $func_quote_for_eval_result"
+	func_quote_arg pretty "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_arg_result"
       fi
     fi
 
@@ -4570,8 +4692,8 @@
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
 	        $opt_quiet || {
-	          func_quote_for_expand "$relink_command"
-		  eval "func_echo $func_quote_for_expand_result"
+	          func_quote_arg expand,pretty "$relink_command"
+		  eval "func_echo $func_quote_arg_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
@@ -5350,7 +5472,8 @@
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5360,7 +5483,7 @@
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6703,9 +6826,9 @@
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_for_eval "$arg"
-      qarg=$func_quote_for_eval_unquoted_result
-      func_append libtool_args " $func_quote_for_eval_result"
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7303,9 +7426,9 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $func_quote_for_eval_result"
-	  func_append compiler_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $func_quote_arg_result"
+	  func_append compiler_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7319,10 +7442,10 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $wl$func_quote_for_eval_result"
-	  func_append compiler_flags " $wl$func_quote_for_eval_result"
-	  func_append linker_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $wl$func_quote_arg_result"
+	  func_append compiler_flags " $wl$func_quote_arg_result"
+	  func_append linker_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7346,8 +7469,8 @@
 
       # -msg_* for osf cc
       -msg_*)
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7368,14 +7491,12 @@
       # -stdlib=*            select c++ std lib with clang
       # -fsanitize=*         Clang/GCC memory and address sanitizer
       # -fuse-ld=*           Linker select flags for GCC
-      # -static-*            direct GCC to link specific libraries statically
-      # -fcilkplus           Cilk Plus language extension features for C/C++
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+      -specs=*|-fsanitize=*|-fuse-ld=*)
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7396,15 +7517,15 @@
 	  continue
         else
 	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
+	  func_quote_arg pretty "$arg"
+	  arg=$func_quote_arg_result
         fi
 	;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       *.$objext)
@@ -7524,8 +7645,8 @@
       *)
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
       esac # arg
 
@@ -7666,10 +7787,7 @@
 	case $pass in
 	dlopen) libs=$dlfiles ;;
 	dlpreopen) libs=$dlprefiles ;;
-	link)
-	  libs="$deplibs %DEPLIBS%"
-	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-	  ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
 	esac
       fi
       if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7988,19 +8106,19 @@
 	    # It is a libtool convenience library, so add in its objects.
 	    func_append convenience " $ladir/$objdir/$old_library"
 	    func_append old_convenience " $ladir/$objdir/$old_library"
-	    tmp_libs=
-	    for deplib in $dependency_libs; do
-	      deplibs="$deplib $deplibs"
-	      if $opt_preserve_dup_deps; then
-		case "$tmp_libs " in
-		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
-		esac
-	      fi
-	      func_append tmp_libs " $deplib"
-	    done
 	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
 	    func_fatal_error "'$lib' is not a convenience library"
 	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done
 	  continue
 	fi # $pass = conv
 
@@ -8924,9 +9042,6 @@
 	    revision=$number_minor
 	    lt_irix_increment=no
 	    ;;
-	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
-	    ;;
 	  esac
 	  ;;
 	no)
@@ -10037,8 +10152,8 @@
 	    for cmd in $concat_cmds; do
 	      IFS=$save_ifs
 	      $opt_quiet || {
-		  func_quote_for_expand "$cmd"
-		  eval "func_echo $func_quote_for_expand_result"
+		  func_quote_arg expand,pretty "$cmd"
+		  eval "func_echo $func_quote_arg_result"
 	      }
 	      $opt_dry_run || eval "$cmd" || {
 		lt_exit=$?
@@ -10131,8 +10246,8 @@
 	  eval cmd=\"$cmd\"
 	  IFS=$save_ifs
 	  $opt_quiet || {
-	    func_quote_for_expand "$cmd"
-	    eval "func_echo $func_quote_for_expand_result"
+	    func_quote_arg expand,pretty "$cmd"
+	    eval "func_echo $func_quote_arg_result"
 	  }
 	  $opt_dry_run || eval "$cmd" || {
 	    lt_exit=$?
@@ -10606,12 +10721,13 @@
 	  elif eval var_value=\$$var; test -z "$var_value"; then
 	    relink_command="$var=; export $var; $relink_command"
 	  else
-	    func_quote_for_eval "$var_value"
-	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	    func_quote_arg pretty "$var_value"
+	    relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
 	  fi
 	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+	func_quote eval cd "`pwd`"
+	func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
+	relink_command=$func_quote_arg_unquoted_result
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10851,13 +10967,15 @@
 	elif eval var_value=\$$var; test -z "$var_value"; then
 	  relink_command="$var=; export $var; $relink_command"
 	else
-	  func_quote_for_eval "$var_value"
-	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  func_quote_arg pretty,unquoted "$var_value"
+	  relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      func_quote eval cd "`pwd`"
+      relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      func_quote_arg pretty,unquoted "$relink_command"
+      relink_command=$func_quote_arg_unquoted_result
       if test yes = "$hardcode_automatic"; then
 	relink_command=
       fi
diff --git a/lib/External/isl/interface/missing b/lib/External/isl/interface/missing
old mode 100644
new mode 100755
index 625aeb1..8d0eaad
--- a/lib/External/isl/interface/missing
+++ b/lib/External/isl/interface/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/lib/External/isl/interface/plain_cpp.cc b/lib/External/isl/interface/plain_cpp.cc
new file mode 100644
index 0000000..ae15c34
--- /dev/null
+++ b/lib/External/isl/interface/plain_cpp.cc
@@ -0,0 +1,1917 @@
+/*
+ * Copyright 2016, 2017 Tobias Grosser. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOBIAS GROSSER ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TOBIAS GROSSER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as
+ * representing official policies, either expressed or implied, of
+ * Tobias Grosser.
+ */
+
+#include <cstdarg>
+#include <cstdio>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "plain_cpp.h"
+#include "isl_config.h"
+
+/* Print string formatted according to "fmt" to ostream "os".
+ *
+ * This osprintf method allows us to use printf style formatting constructs when
+ * writing to an ostream.
+ */
+static void osprintf(ostream &os, const char *format, va_list arguments)
+{
+	va_list copy;
+	char *string_pointer;
+	size_t size;
+
+	va_copy(copy, arguments);
+	size = vsnprintf(NULL, 0, format, copy);
+	string_pointer = new char[size + 1];
+	va_end(copy);
+	vsnprintf(string_pointer, size + 1, format, arguments);
+	os << string_pointer;
+	delete[] string_pointer;
+}
+
+/* Print string formatted according to "fmt" to ostream "os".
+ *
+ * This osprintf method allows us to use printf style formatting constructs when
+ * writing to an ostream.
+ */
+static void osprintf(ostream &os, const char *format, ...)
+{
+	va_list arguments;
+
+	va_start(arguments, format);
+	osprintf(os, format, arguments);
+	va_end(arguments);
+}
+
+/* Print string formatted according to "fmt" to ostream "os"
+ * with the given indentation.
+ *
+ * This osprintf method allows us to use printf style formatting constructs when
+ * writing to an ostream.
+ */
+static void osprintf(ostream &os, int indent, const char *format, ...)
+{
+	va_list arguments;
+
+	osprintf(os, "%*s", indent, " ");
+	va_start(arguments, format);
+	osprintf(os, format, arguments);
+	va_end(arguments);
+}
+
+/* Convert "l" to a string.
+ */
+static std::string to_string(long l)
+{
+	std::ostringstream strm;
+	strm << l;
+	return strm.str();
+}
+
+/* Construct a generator for plain C++ bindings.
+ *
+ * "checked" is set if C++ bindings should be generated
+ * that rely on the user to check for error conditions.
+ */
+plain_cpp_generator::plain_cpp_generator(SourceManager &SM,
+	set<RecordDecl *> &exported_types,
+	set<FunctionDecl *> exported_functions, set<FunctionDecl *> functions,
+	bool checked) :
+		cpp_generator(SM, exported_types, exported_functions,
+			functions),
+		checked(checked)
+{
+}
+
+/* Generate a cpp interface based on the extracted types and functions.
+ *
+ * Print first a set of forward declarations for all isl wrapper
+ * classes, then the declarations of the classes, and at the end all
+ * implementations.
+ *
+ * If checked C++ bindings are being generated,
+ * then wrap them in a namespace to avoid conflicts
+ * with the default C++ bindings (with automatic checks using exceptions).
+ */
+void plain_cpp_generator::generate()
+{
+	ostream &os = cout;
+
+	osprintf(os, "\n");
+	osprintf(os, "namespace isl {\n\n");
+	if (checked)
+		osprintf(os, "namespace checked {\n\n");
+
+	print_forward_declarations(os);
+	osprintf(os, "\n");
+	print_declarations(os);
+	osprintf(os, "\n");
+	print_implementations(os);
+
+	if (checked)
+		osprintf(os, "} // namespace checked\n");
+	osprintf(os, "} // namespace isl\n");
+}
+
+/* Print forward declarations for all classes to "os".
+*/
+void plain_cpp_generator::print_forward_declarations(ostream &os)
+{
+	map<string, isl_class>::iterator ci;
+
+	osprintf(os, "// forward declarations\n");
+
+	for (ci = classes.begin(); ci != classes.end(); ++ci)
+		print_class_forward_decl(os, ci->second);
+}
+
+/* Print all declarations to "os".
+ */
+void plain_cpp_generator::print_declarations(ostream &os)
+{
+	map<string, isl_class>::iterator ci;
+	bool first = true;
+
+	for (ci = classes.begin(); ci != classes.end(); ++ci) {
+		if (first)
+			first = false;
+		else
+			osprintf(os, "\n");
+
+		print_class(os, ci->second);
+	}
+}
+
+/* Print all implementations to "os".
+ */
+void plain_cpp_generator::print_implementations(ostream &os)
+{
+	map<string, isl_class>::iterator ci;
+	bool first = true;
+
+	for (ci = classes.begin(); ci != classes.end(); ++ci) {
+		if (first)
+			first = false;
+		else
+			osprintf(os, "\n");
+
+		print_class_impl(os, ci->second);
+	}
+}
+
+/* If the printed class is a subclass that is based on a type function,
+ * then introduce a "type" field that holds the value of the type
+ * corresponding to the subclass and make the fields of the class
+ * accessible to the "isa" and "as" methods of the (immediate) superclass.
+ * In particular, "isa" needs access to the type field itself,
+ * while "as" needs access to the private constructor.
+ * In case of the "isa" method, all instances are made friends
+ * to avoid access right confusion.
+ */
+void plain_cpp_generator::decl_printer::print_subclass_type()
+{
+	std::string super;
+	const char *cppname = cppstring.c_str();
+	const char *supername;
+
+	if (!clazz.is_type_subclass())
+		return;
+
+	super = type2cpp(clazz.superclass_name);
+	supername = super.c_str();
+	osprintf(os, "  template <class T>\n");
+	osprintf(os, "  friend %s %s::isa() const;\n",
+		generator.isl_bool2cpp().c_str(), supername);
+	osprintf(os, "  friend %s %s::as<%s>() const;\n",
+		cppname, supername, cppname);
+	osprintf(os, "  static const auto type = %s;\n",
+		clazz.subclass_name.c_str());
+}
+
+/* Print declarations for class "clazz" to "os".
+ *
+ * If "clazz" is a subclass based on a type function,
+ * then it is made to inherit from the (immediate) superclass and
+ * a "type" attribute is added for use in the "as" and "isa"
+ * methods of the superclass.
+ *
+ * Conversely, if "clazz" is a superclass with a type function,
+ * then declare those "as" and "isa" methods.
+ *
+ * The pointer to the isl object is only added for classes that
+ * are not subclasses, since subclasses refer to the same isl object.
+ */
+void plain_cpp_generator::print_class(ostream &os, const isl_class &clazz)
+{
+	decl_printer printer(os, clazz, *this);
+	const char *name = clazz.name.c_str();
+	const char *cppname = printer.cppstring.c_str();
+
+	osprintf(os, "// declarations for isl::%s\n", cppname);
+
+	printer.print_class_factory();
+	osprintf(os, "\n");
+	osprintf(os, "class %s ", cppname);
+	if (clazz.is_type_subclass())
+		osprintf(os, ": public %s ",
+			type2cpp(clazz.superclass_name).c_str());
+	osprintf(os, "{\n");
+	printer.print_subclass_type();
+	printer.print_class_factory("  friend ");
+	osprintf(os, "\n");
+	osprintf(os, "protected:\n");
+	if (!clazz.is_type_subclass()) {
+		osprintf(os, "  %s *ptr = nullptr;\n", name);
+		osprintf(os, "\n");
+	}
+	printer.print_protected_constructors();
+	osprintf(os, "\n");
+	osprintf(os, "public:\n");
+	printer.print_public_constructors();
+	printer.print_constructors();
+	printer.print_copy_assignment();
+	printer.print_destructor();
+	printer.print_ptr();
+	printer.print_downcast();
+	printer.print_ctx();
+	osprintf(os, "\n");
+	printer.print_persistent_callbacks();
+	printer.print_methods();
+	printer.print_set_enums();
+
+	osprintf(os, "};\n");
+}
+
+/* Print forward declaration of class "clazz" to "os".
+ */
+void plain_cpp_generator::print_class_forward_decl(ostream &os,
+	const isl_class &clazz)
+{
+	std::string cppstring = type2cpp(clazz);
+	const char *cppname = cppstring.c_str();
+
+	osprintf(os, "class %s;\n", cppname);
+}
+
+/* Print global factory functions.
+ *
+ * Each class has two global factory functions:
+ *
+ * 	set manage(__isl_take isl_set *ptr);
+ * 	set manage_copy(__isl_keep isl_set *ptr);
+ *
+ * A user can construct isl C++ objects from a raw pointer and indicate whether
+ * they intend to take the ownership of the object or not through these global
+ * factory functions. This ensures isl object creation is very explicit and
+ * pointers are not converted by accident. Thanks to overloading, manage() and
+ * manage_copy() can be called on any isl raw pointer and the corresponding
+ * object is automatically created, without the user having to choose the right
+ * isl object type.
+ *
+ * For a subclass based on a type function, no factory functions
+ * are introduced because they share the C object type with
+ * the superclass.
+ */
+void plain_cpp_generator::decl_printer::print_class_factory(
+	const std::string &prefix)
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	if (clazz.is_type_subclass())
+		return;
+
+	os << prefix;
+	osprintf(os, "inline %s manage(__isl_take %s *ptr);\n", cppname, name);
+	os << prefix;
+	osprintf(os, "inline %s manage_copy(__isl_keep %s *ptr);\n",
+		cppname, name);
+}
+
+/* Print declarations of protected constructors.
+ *
+ * Each class has currently one protected constructor:
+ *
+ * 	1) Constructor from a plain isl_* C pointer
+ *
+ * Example:
+ *
+ * 	set(__isl_take isl_set *ptr);
+ *
+ * The raw pointer constructor is kept protected. Object creation is only
+ * possible through manage() or manage_copy().
+ */
+void plain_cpp_generator::decl_printer::print_protected_constructors()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	osprintf(os, "  inline explicit %s(__isl_take %s *ptr);\n", cppname,
+		 name);
+}
+
+/* Print declarations of public constructors.
+ *
+ * Each class currently has two public constructors:
+ *
+ * 	1) A default constructor
+ * 	2) A copy constructor
+ *
+ * Example:
+ *
+ *	set();
+ *	set(const set &set);
+ */
+void plain_cpp_generator::decl_printer::print_public_constructors()
+{
+	const char *cppname = cppstring.c_str();
+	osprintf(os, "  inline /* implicit */ %s();\n", cppname);
+
+	osprintf(os, "  inline /* implicit */ %s(const %s &obj);\n",
+		 cppname, cppname);
+}
+
+/* Print declarations for "method".
+ */
+void plain_cpp_generator::decl_printer::print_method(
+	const ConversionMethod &method)
+{
+	print_full_method_header(method);
+}
+
+/* Print declarations for "method".
+ */
+void plain_cpp_generator::decl_printer::print_method(const Method &method)
+{
+	print_full_method_header(method);
+}
+
+/* Print declarations of copy assignment operator.
+ *
+ * Each class has one assignment operator.
+ *
+ * 	isl:set &set::operator=(set obj)
+ *
+ */
+void plain_cpp_generator::decl_printer::print_copy_assignment()
+{
+	const char *cppname = cppstring.c_str();
+
+	osprintf(os, "  inline %s &operator=(%s obj);\n", cppname, cppname);
+}
+
+/* Print declaration of destructor.
+ *
+ * No explicit destructor is needed for type based subclasses.
+ */
+void plain_cpp_generator::decl_printer::print_destructor()
+{
+	const char *cppname = cppstring.c_str();
+
+	if (clazz.is_type_subclass())
+		return;
+
+	osprintf(os, "  inline ~%s();\n", cppname);
+}
+
+/* Print declaration of pointer functions.
+ * Since type based subclasses share the pointer with their superclass,
+ * they can also reuse these functions from the superclass.
+ *
+ * To obtain a raw pointer three functions are provided:
+ *
+ * 	1) __isl_give isl_set *copy()
+ *
+ * 	  Returns a pointer to a _copy_ of the internal object
+ *
+ * 	2) __isl_keep isl_set *get()
+ *
+ * 	  Returns a pointer to the internal object
+ *
+ * 	3) __isl_give isl_set *release()
+ *
+ * 	  Returns a pointer to the internal object and resets the
+ * 	  internal pointer to nullptr.
+ *
+ * We also provide functionality to explicitly check if a pointer is
+ * currently managed by this object.
+ *
+ * 	4) bool is_null()
+ *
+ * 	  Check if the current object is a null pointer.
+ *
+ * The functions get() and release() model the value_ptr proposed in
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf.
+ * The copy() function is an extension to allow the user to explicitly
+ * copy the underlying object.
+ *
+ * Also generate a declaration to delete copy() for r-values, for
+ * r-values release() should be used to avoid unnecessary copies.
+ */
+void plain_cpp_generator::decl_printer::print_ptr()
+{
+	const char *name = clazz.name.c_str();
+
+	if (clazz.is_type_subclass())
+		return;
+
+	osprintf(os, "  inline __isl_give %s *copy() const &;\n", name);
+	osprintf(os, "  inline __isl_give %s *copy() && = delete;\n", name);
+	osprintf(os, "  inline __isl_keep %s *get() const;\n", name);
+	osprintf(os, "  inline __isl_give %s *release();\n", name);
+	osprintf(os, "  inline bool is_null() const;\n");
+}
+
+/* Print a template declaration with given indentation
+ * for the "isa_type" method that ensures it is only enabled
+ * when called with a template argument
+ * that represents a type that is equal to that
+ * of the return type of the type function of "super".
+ * In particular, "isa_type" gets called from "isa"
+ * with as template argument the type of the "type" field
+ * of the subclass.
+ * The check ensures that this subclass is in fact a direct subclass
+ * of "super".
+ */
+void plain_cpp_generator::decl_printer::print_isa_type_template(int indent,
+	const isl_class &super)
+{
+	osprintf(os, indent,
+		"template <typename T,\n");
+	osprintf(os, indent,
+		"        typename = typename std::enable_if<std::is_same<\n");
+	osprintf(os, indent,
+		"                const decltype(%s(NULL)),\n",
+		super.fn_type->getNameAsString().c_str());
+	osprintf(os, indent,
+		"                const T>::value>::type>\n");
+}
+
+/* Print declarations for the "as" and "isa" methods, if the printed class
+ * is a superclass with a type function.
+ *
+ * "isa" checks whether an object is of a given subclass type.
+ * "isa_type" does the same, but gets passed the value of the type field
+ * of the subclass as a function argument and the type of this field
+ * as a template argument.
+ * "as" tries to cast an object to a given subclass type, returning
+ * an invalid object if the object is not of the given type.
+ */
+void plain_cpp_generator::decl_printer::print_downcast()
+{
+	if (!clazz.fn_type)
+		return;
+
+	osprintf(os, "private:\n");
+	print_isa_type_template(2, clazz);
+	osprintf(os, "  inline %s isa_type(T subtype) const;\n",
+		generator.isl_bool2cpp().c_str());
+	osprintf(os, "public:\n");
+	osprintf(os, "  template <class T> inline %s isa() const;\n",
+		generator.isl_bool2cpp().c_str());
+	osprintf(os, "  template <class T> inline T as() const;\n");
+}
+
+/* Print the declaration of the ctx method.
+ */
+void plain_cpp_generator::decl_printer::print_ctx()
+{
+	std::string ns = generator.isl_namespace();
+
+	osprintf(os, "  inline %sctx ctx() const;\n", ns.c_str());
+}
+
+/* Add a space to the return type "type" if needed,
+ * i.e., if it is not the type of a pointer.
+ */
+static string add_space_to_return_type(const string &type)
+{
+	if (type[type.size() - 1] == '*')
+		return type;
+	return type + " ";
+}
+
+/* Print the prototype of the static inline method that is used
+ * as the C callback set by "method".
+ */
+void plain_cpp_generator::plain_printer::print_persistent_callback_prototype(
+	FunctionDecl *method)
+{
+	string callback_name, rettype, c_args;
+	ParmVarDecl *param = persistent_callback_arg(method);
+	const FunctionProtoType *callback;
+	QualType ptype;
+	string classname;
+
+	ptype = param->getType();
+	callback = extract_prototype(ptype);
+
+	rettype = callback->getReturnType().getAsString();
+	rettype = add_space_to_return_type(rettype);
+	callback_name = clazz.persistent_callback_name(method);
+	c_args = generator.generate_callback_args(ptype, false);
+
+	if (!declarations)
+		classname = type2cpp(clazz) + "::";
+
+	osprintf(os, "%s%s%s(%s)",
+		 rettype.c_str(), classname.c_str(),
+		 callback_name.c_str(), c_args.c_str());
+}
+
+/* Print the prototype of the method for setting the callback function
+ * set by "method".
+ */
+void
+plain_cpp_generator::plain_printer::print_persistent_callback_setter_prototype(
+	FunctionDecl *method)
+{
+	string classname, callback_name, cpptype;
+	ParmVarDecl *param = persistent_callback_arg(method);
+
+	if (!declarations)
+		classname = type2cpp(clazz) + "::";
+
+	cpptype = generator.param2cpp(param->getOriginalType());
+	callback_name = clazz.persistent_callback_name(method);
+	osprintf(os, "void %sset_%s_data(const %s &%s)",
+		classname.c_str(), callback_name.c_str(), cpptype.c_str(),
+		param->getName().str().c_str());
+}
+
+/* Given a method "method" for setting a persistent callback,
+ * print the fields that are needed for marshalling the callback.
+ *
+ * In particular, print
+ * - the declaration of a data structure for storing the C++ callback function
+ * - a shared pointer to such a data structure
+ * - the declaration of a static inline method
+ *   for use as the C callback function
+ * - the declaration of a private method for setting the callback function
+ */
+void plain_cpp_generator::decl_printer::print_persistent_callback_data(
+	FunctionDecl *method)
+{
+	string callback_name;
+	ParmVarDecl *param = generator.persistent_callback_arg(method);
+
+	callback_name = clazz.persistent_callback_name(method);
+	print_callback_data_decl(param, callback_name);
+	osprintf(os, ";\n");
+	osprintf(os, "  std::shared_ptr<%s_data> %s_data;\n",
+		callback_name.c_str(), callback_name.c_str());
+	osprintf(os, "  static inline ");
+	print_persistent_callback_prototype(method);
+	osprintf(os, ";\n");
+	osprintf(os, "  inline ");
+	print_persistent_callback_setter_prototype(method);
+	osprintf(os, ";\n");
+}
+
+/* Print declarations needed for the persistent callbacks of the class.
+ *
+ * In particular, if there are any persistent callbacks, then
+ * print a private method for copying callback data from
+ * one object to another,
+ * private data for keeping track of the persistent callbacks and
+ * public methods for setting the persistent callbacks.
+ */
+void plain_cpp_generator::decl_printer::print_persistent_callbacks()
+{
+	const char *cppname = cppstring.c_str();
+
+	if (!clazz.has_persistent_callbacks())
+		return;
+
+	osprintf(os, "private:\n");
+	osprintf(os, "  inline %s &copy_callbacks(const %s &obj);\n",
+		cppname, cppname);
+	for (const auto &callback : clazz.persistent_callbacks)
+		print_persistent_callback_data(callback);
+
+	osprintf(os, "public:\n");
+	for (const auto &callback : clazz.persistent_callbacks)
+		print_method(Method(clazz, callback));
+}
+
+/* Print a declaration for the "get" method "fd",
+ * using a name that includes the "get_" prefix.
+ */
+void plain_cpp_generator::decl_printer::print_get_method(FunctionDecl *fd)
+{
+	string base = clazz.base_method_name(fd);
+
+	print_method(Method(clazz, fd, base));
+}
+
+/* Print implementations for class "clazz" to "os".
+ */
+void plain_cpp_generator::print_class_impl(ostream &os, const isl_class &clazz)
+{
+	impl_printer printer(os, clazz, *this);
+	const char *cppname = printer.cppstring.c_str();
+
+	osprintf(os, "// implementations for isl::%s", cppname);
+
+	printer.print_class_factory();
+	printer.print_public_constructors();
+	printer.print_protected_constructors();
+	printer.print_constructors();
+	printer.print_copy_assignment();
+	printer.print_destructor();
+	printer.print_ptr();
+	printer.print_downcast();
+	printer.print_ctx();
+	printer.print_persistent_callbacks();
+	printer.print_methods();
+	printer.print_set_enums();
+	printer.print_stream_insertion();
+}
+
+/* Print code for throwing an exception corresponding to the last error
+ * that occurred on "saved_ctx".
+ * This assumes that a valid isl::ctx is available in the "saved_ctx" variable,
+ * e.g., through a prior call to print_save_ctx.
+ */
+static void print_throw_last_error(ostream &os)
+{
+	osprintf(os, "    exception::throw_last_error(saved_ctx);\n");
+}
+
+/* Print code with the given indentation
+ * for throwing an exception_invalid with the given message.
+ */
+static void print_throw_invalid(ostream &os, int indent, const char *msg)
+{
+	osprintf(os, indent,
+		"exception::throw_invalid(\"%s\", __FILE__, __LINE__);\n", msg);
+}
+
+/* Print code for throwing an exception on NULL input.
+ */
+static void print_throw_NULL_input(ostream &os)
+{
+	print_throw_invalid(os, 4, "NULL input");
+}
+
+/* Print code with the given indentation
+ * for acting on an invalid error with message "msg".
+ * In particular, throw an exception_invalid.
+ * In the checked C++ bindings, isl_die is called instead with the code
+ * in "checked_code".
+ */
+void plain_cpp_generator::print_invalid(ostream &os, int indent,
+	const char *msg, const char *checked_code)
+{
+	if (checked)
+		osprintf(os, indent,
+			"isl_die(ctx().get(), isl_error_invalid, "
+			"\"%s\", %s);\n", msg, checked_code);
+	else
+		print_throw_invalid(os, indent, msg);
+}
+
+/* Print an operator for inserting objects of the class
+ * into an output stream.
+ *
+ * Unless checked C++ bindings are being generated,
+ * the operator requires its argument to be non-NULL.
+ * An exception is thrown if anything went wrong during the printing.
+ * During this printing, isl is made not to print any error message
+ * because the error message is included in the exception.
+ *
+ * If checked C++ bindings are being generated and anything went wrong,
+ * then record this failure in the output stream.
+ */
+void plain_cpp_generator::impl_printer::print_stream_insertion()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	if (!clazz.fn_to_str)
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "inline std::ostream &operator<<(std::ostream &os, ");
+	osprintf(os, "const %s &obj)\n", cppname);
+	osprintf(os, "{\n");
+	print_check_ptr_start("obj.get()");
+	osprintf(os, "  char *str = %s_to_str(obj.get());\n", name);
+	print_check_ptr_end("str");
+	if (generator.checked) {
+		osprintf(os, "  if (!str) {\n");
+		osprintf(os, "    os.setstate(std::ios_base::badbit);\n");
+		osprintf(os, "    return os;\n");
+		osprintf(os, "  }\n");
+	}
+	osprintf(os, "  os << str;\n");
+	osprintf(os, "  free(str);\n");
+	osprintf(os, "  return os;\n");
+	osprintf(os, "}\n");
+}
+
+/* Print code that checks that "ptr" is not NULL at input.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void plain_cpp_generator::impl_printer::print_check_ptr(const char *ptr)
+{
+	if (generator.checked)
+		return;
+
+	osprintf(os, "  if (!%s)\n", ptr);
+	print_throw_NULL_input(os);
+}
+
+/* Print code that checks that "ptr" is not NULL at input and
+ * that saves a copy of the isl_ctx of "ptr" for a later check.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void plain_cpp_generator::impl_printer::print_check_ptr_start(const char *ptr)
+{
+	if (generator.checked)
+		return;
+
+	print_check_ptr(ptr);
+	osprintf(os, "  auto saved_ctx = %s_get_ctx(%s);\n",
+		clazz.name.c_str(), ptr);
+	print_on_error_continue();
+}
+
+/* Print code that checks that "ptr" is not NULL at the end.
+ * A copy of the isl_ctx is expected to have been saved by
+ * code generated by print_check_ptr_start.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void plain_cpp_generator::impl_printer::print_check_ptr_end(const char *ptr)
+{
+	if (generator.checked)
+		return;
+
+	osprintf(os, "  if (!%s)\n", ptr);
+	print_throw_last_error(os);
+}
+
+/* Print implementation of global factory functions.
+ *
+ * Each class has two global factory functions:
+ *
+ * 	set manage(__isl_take isl_set *ptr);
+ * 	set manage_copy(__isl_keep isl_set *ptr);
+ *
+ * Unless checked C++ bindings are being generated,
+ * both functions require the argument to be non-NULL.
+ * An exception is thrown if anything went wrong during the copying
+ * in manage_copy.
+ * During the copying, isl is made not to print any error message
+ * because the error message is included in the exception.
+ *
+ * For a subclass based on a type function, no factory functions
+ * are introduced because they share the C object type with
+ * the superclass.
+ */
+void plain_cpp_generator::impl_printer::print_class_factory()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	if (clazz.is_type_subclass())
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "%s manage(__isl_take %s *ptr) {\n", cppname, name);
+	print_check_ptr("ptr");
+	osprintf(os, "  return %s(ptr);\n", cppname);
+	osprintf(os, "}\n");
+
+	osprintf(os, "%s manage_copy(__isl_keep %s *ptr) {\n", cppname,
+		name);
+	print_check_ptr_start("ptr");
+	osprintf(os, "  ptr = %s_copy(ptr);\n", name);
+	print_check_ptr_end("ptr");
+	osprintf(os, "  return %s(ptr);\n", cppname);
+	osprintf(os, "}\n");
+}
+
+/* Print implementations of protected constructors.
+ *
+ * The pointer to the isl object is either initialized directly or
+ * through the (immediate) superclass.
+ */
+void plain_cpp_generator::impl_printer::print_protected_constructors()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+	bool subclass = clazz.is_type_subclass();
+
+	osprintf(os, "\n");
+	osprintf(os, "%s::%s(__isl_take %s *ptr)\n", cppname, cppname, name);
+	if (subclass)
+		osprintf(os, "    : %s(ptr) {}\n",
+			type2cpp(clazz.superclass_name).c_str());
+	else
+		osprintf(os, "    : ptr(ptr) {}\n");
+}
+
+/* Print implementations of public constructors.
+ *
+ * The pointer to the isl object is either initialized directly or
+ * through the (immediate) superclass.
+ *
+ * If the class has any persistent callbacks, then copy them
+ * from the original object in the copy constructor.
+ * If the class is a subclass, then the persistent callbacks
+ * are assumed to be copied by the copy constructor of the superclass.
+ *
+ * Throw an exception from the copy constructor if anything went wrong
+ * during the copying or if the input is NULL, if any copying is performed.
+ * During the copying, isl is made not to print any error message
+ * because the error message is included in the exception.
+ * No exceptions are thrown if checked C++ bindings
+ * are being generated,
+ */
+void plain_cpp_generator::impl_printer::print_public_constructors()
+{
+	std::string super;
+	const char *cppname = cppstring.c_str();
+	bool subclass = clazz.is_type_subclass();
+
+	osprintf(os, "\n");
+	if (subclass)
+		super = type2cpp(clazz.superclass_name);
+	osprintf(os, "%s::%s()\n", cppname, cppname);
+	if (subclass)
+		osprintf(os, "    : %s() {}\n\n", super.c_str());
+	else
+		osprintf(os, "    : ptr(nullptr) {}\n\n");
+	osprintf(os, "%s::%s(const %s &obj)\n", cppname, cppname, cppname);
+	if (subclass)
+		osprintf(os, "    : %s(obj)\n", super.c_str());
+	else
+		osprintf(os, "    : ptr(nullptr)\n");
+	osprintf(os, "{\n");
+	if (!subclass) {
+		print_check_ptr_start("obj.ptr");
+		osprintf(os, "  ptr = obj.copy();\n");
+		if (clazz.has_persistent_callbacks())
+			osprintf(os, "  copy_callbacks(obj);\n");
+		print_check_ptr_end("ptr");
+	}
+	osprintf(os, "}\n");
+}
+
+/* Print definition for "method",
+ * without any automatic type conversions.
+ *
+ * This method distinguishes three kinds of methods: member methods, static
+ * methods, and constructors.
+ *
+ * Member methods and static methods return a newly managed
+ * isl C++ object.
+ *
+ * Constructors create a new object from a given set of input parameters. They
+ * do not return a value, but instead update the pointer stored inside the
+ * newly created object.
+ *
+ * Unless checked C++ bindings are being generated,
+ * the inputs of the method are first checked for being valid isl objects and
+ * a copy of the associated isl::ctx is saved (if needed).
+ * If any failure occurs, either during the check for the inputs or
+ * during the isl function call, an exception is thrown.
+ * During the function call, isl is made not to print any error message
+ * because the error message is included in the exception.
+ */
+void plain_cpp_generator::impl_printer::print_method(const Method &method)
+{
+	string methodname = method.fd->getName().str();
+	int num_params = method.c_num_params();
+
+	osprintf(os, "\n");
+	print_full_method_header(method);
+	osprintf(os, "{\n");
+	print_argument_validity_check(method);
+	print_save_ctx(method);
+	print_on_error_continue();
+
+	if (method.callback)
+		print_callback_local(method.callback);
+
+	osprintf(os, "  auto res = %s", methodname.c_str());
+
+	Method::print_arg_list(os, 0, num_params, [&] (int i) {
+		method.print_param_use(os, i);
+	});
+	osprintf(os, ";\n");
+
+	print_exceptional_execution_check(method);
+	if (method.kind == Method::Kind::constructor) {
+		osprintf(os, "  ptr = res;\n");
+	} else {
+		print_method_return(method);
+	}
+
+	osprintf(os, "}\n");
+}
+
+/* Convert argument of type "src" to "dst", with a name specified by "dst".
+ *
+ * If "src" is the same as "dst", then no argument conversion is needed.
+ *
+ * Otherwise, call the conversion function
+ * with as arguments the isl_ctx of the object and the argument name,
+ * or simply the argument name if the source type is an isl type.
+ * This means this isl_ctx should be available.
+ */
+void plain_cpp_generator::impl_printer::print_arg_conversion(ParmVarDecl *dst,
+	ParmVarDecl *src)
+{
+	std::string name = dst->getName().str();
+	QualType type = dst->getOriginalType();
+	string cpptype = generator.param2cpp(type);
+
+	if (dst == src)
+		os << name;
+	else if (is_isl_type(src->getOriginalType()))
+		os << cpptype << "(" << name << ")";
+	else
+		os << cpptype << "(ctx(), " << name << ")";
+}
+
+/* Print a definition for "method",
+ * where "this" or at least one of the argument types needs to be converted.
+ *
+ * "method" is assumed to be a member method.
+ *
+ * The generated method performs the required conversion(s) and
+ * calls the method generated without conversions.
+ *
+ * Perform a conversion from the argument in the method declaration
+ * (as specified by Method::get_param) to the argument of the C function,
+ * if needed.
+ * Such a conversion may require the isl_ctx to be available.
+ * In order to be able to use this isl_ctx, the current object needs
+ * to valid.  The validity of other arguments is checked
+ * by the called method.
+ */
+void plain_cpp_generator::impl_printer::print_method(
+	const ConversionMethod &method)
+{
+	if (method.kind != Method::Kind::member_method)
+		die("Automatic conversion currently only supported "
+		    "for object methods");
+
+	osprintf(os, "\n");
+	print_full_method_header(method);
+	osprintf(os, "{\n");
+	print_check_ptr("ptr");
+	osprintf(os, "  return ");
+	method.print_call(os, generator.isl_namespace());
+	method.print_cpp_arg_list(os, [&] (int i) {
+		ParmVarDecl *param = method.fd->getParamDecl(i);
+
+		print_arg_conversion(param, method.get_param(i));
+	});
+	osprintf(os, ";\n");
+	osprintf(os, "}\n");
+}
+
+/* Print implementation of copy assignment operator.
+ *
+ * If the class has any persistent callbacks, then copy them
+ * from the original object.
+ */
+void plain_cpp_generator::impl_printer::print_copy_assignment()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	osprintf(os, "\n");
+	osprintf(os, "%s &%s::operator=(%s obj) {\n", cppname,
+		 cppname, cppname);
+	osprintf(os, "  std::swap(this->ptr, obj.ptr);\n", name);
+	if (clazz.has_persistent_callbacks())
+		osprintf(os, "  copy_callbacks(obj);\n");
+	osprintf(os, "  return *this;\n");
+	osprintf(os, "}\n");
+}
+
+/* Print implementation of destructor.
+ *
+ * No explicit destructor is needed for type based subclasses.
+ */
+void plain_cpp_generator::impl_printer::print_destructor()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+
+	if (clazz.is_type_subclass())
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "%s::~%s() {\n", cppname, cppname);
+	osprintf(os, "  if (ptr)\n");
+	osprintf(os, "    %s_free(ptr);\n", name);
+	osprintf(os, "}\n");
+}
+
+/* Print a check that the persistent callback corresponding to "fd"
+ * is not set, throwing an exception (or printing an error message
+ * and returning nullptr) if it is set.
+ */
+void plain_cpp_generator::print_check_no_persistent_callback(ostream &os,
+	const isl_class &clazz, FunctionDecl *fd)
+{
+	string callback_name = clazz.persistent_callback_name(fd);
+
+	osprintf(os, "  if (%s_data)\n", callback_name.c_str());
+	print_invalid(os, 4, "cannot release object with persistent callbacks",
+			    "return nullptr");
+}
+
+/* Print implementation of ptr() functions.
+ * Since type based subclasses share the pointer with their superclass,
+ * they can also reuse these functions from the superclass.
+ *
+ * If an object has persistent callbacks set, then the underlying
+ * C object pointer cannot be released because it references data
+ * in the C++ object.
+ */
+void plain_cpp_generator::impl_printer::print_ptr()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+	set<FunctionDecl *>::const_iterator in;
+	const set<FunctionDecl *> &callbacks = clazz.persistent_callbacks;
+
+	if (clazz.is_type_subclass())
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "__isl_give %s *%s::copy() const & {\n", name, cppname);
+	osprintf(os, "  return %s_copy(ptr);\n", name);
+	osprintf(os, "}\n\n");
+	osprintf(os, "__isl_keep %s *%s::get() const {\n", name, cppname);
+	osprintf(os, "  return ptr;\n");
+	osprintf(os, "}\n\n");
+	osprintf(os, "__isl_give %s *%s::release() {\n", name, cppname);
+	for (in = callbacks.begin(); in != callbacks.end(); ++in)
+		generator.print_check_no_persistent_callback(os, clazz, *in);
+	osprintf(os, "  %s *tmp = ptr;\n", name);
+	osprintf(os, "  ptr = nullptr;\n");
+	osprintf(os, "  return tmp;\n");
+	osprintf(os, "}\n\n");
+	osprintf(os, "bool %s::is_null() const {\n", cppname);
+	osprintf(os, "  return ptr == nullptr;\n");
+	osprintf(os, "}\n");
+}
+
+/* Print implementations for the "as" and "isa" methods, if the printed class
+ * is a superclass with a type function.
+ *
+ * "isa" checks whether an object is of a given subclass type.
+ * "isa_type" does the same, but gets passed the value of the type field
+ * of the subclass as a function argument and the type of this field
+ * as a template argument.
+ * "as" casts an object to a given subclass type, erroring out
+ * if the object is not of the given type.
+ *
+ * If the input is an invalid object, then these methods raise
+ * an exception.
+ * If checked bindings are being generated,
+ * then an invalid boolean or object is returned instead.
+ */
+void plain_cpp_generator::impl_printer::print_downcast()
+{
+	const char *cppname = cppstring.c_str();
+
+	if (!clazz.fn_type)
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "template <typename T, typename>\n");
+	osprintf(os, "%s %s::isa_type(T subtype) const\n",
+		generator.isl_bool2cpp().c_str(), cppname);
+	osprintf(os, "{\n");
+	osprintf(os, "  if (is_null())\n");
+	if (generator.checked)
+		osprintf(os, "    return boolean();\n");
+	else
+		print_throw_NULL_input(os);
+	osprintf(os, "  return %s(get()) == subtype;\n",
+		clazz.fn_type->getNameAsString().c_str());
+	osprintf(os, "}\n");
+
+	osprintf(os, "template <class T>\n");
+	osprintf(os, "%s %s::isa() const\n",
+		generator.isl_bool2cpp().c_str(), cppname);
+	osprintf(os, "{\n");
+	osprintf(os, "  return isa_type<decltype(T::type)>(T::type);\n");
+	osprintf(os, "}\n");
+
+	osprintf(os, "template <class T>\n");
+	osprintf(os, "T %s::as() const\n", cppname);
+	osprintf(os, "{\n");
+	if (generator.checked)
+		osprintf(os, " if (isa<T>().is_false())\n");
+	else
+		osprintf(os, " if (!isa<T>())\n");
+	generator.print_invalid(os, 4, "not an object of the requested subtype",
+		    "return T()");
+	osprintf(os, "  return T(copy());\n");
+	osprintf(os, "}\n");
+}
+
+/* Print the implementation of the ctx method.
+ */
+void plain_cpp_generator::impl_printer::print_ctx()
+{
+	const char *name = clazz.name.c_str();
+	const char *cppname = cppstring.c_str();
+	std::string ns = generator.isl_namespace();
+
+	osprintf(os, "\n");
+	osprintf(os, "%sctx %s::ctx() const {\n", ns.c_str(), cppname);
+	osprintf(os, "  return %sctx(%s_get_ctx(ptr));\n", ns.c_str(), name);
+	osprintf(os, "}\n");
+}
+
+/* Print the implementations of the methods needed for the persistent callbacks
+ * of the class.
+ */
+void plain_cpp_generator::impl_printer::print_persistent_callbacks()
+{
+	const char *cppname = cppstring.c_str();
+	string classname = type2cpp(clazz);
+
+	if (!clazz.has_persistent_callbacks())
+		return;
+
+	osprintf(os, "\n");
+	osprintf(os, "%s &%s::copy_callbacks(const %s &obj)\n",
+		cppname, classname.c_str(), cppname);
+	osprintf(os, "{\n");
+	for (const auto &callback : clazz.persistent_callbacks) {
+		string callback_name = clazz.persistent_callback_name(callback);
+
+		osprintf(os, "  %s_data = obj.%s_data;\n",
+			callback_name.c_str(), callback_name.c_str());
+	}
+	osprintf(os, "  return *this;\n");
+	osprintf(os, "}\n");
+
+	for (const auto &callback : clazz.persistent_callbacks)
+		print_set_persistent_callback(Method(clazz, callback));
+}
+
+/* Print a definition for the "get" method "fd" in class "clazz",
+ * using a name that includes the "get_" prefix, to "os".
+ *
+ * This definition simply calls the variant without the "get_" prefix and
+ * returns its result.
+ * Note that static methods are not considered to be "get" methods.
+ */
+void plain_cpp_generator::impl_printer::print_get_method(FunctionDecl *fd)
+{
+	string get_name = clazz.base_method_name(fd);
+	string name = clazz.method_name(fd);
+	int num_params = fd->getNumParams();
+
+	osprintf(os, "\n");
+	print_full_method_header(Method(clazz, fd, get_name));
+	osprintf(os, "{\n");
+	osprintf(os, "  return %s(", name.c_str());
+	for (int i = 1; i < num_params; ++i) {
+		ParmVarDecl *param = fd->getParamDecl(i);
+
+		if (i != 1)
+			osprintf(os, ", ");
+		osprintf(os, "%s", param->getName().str().c_str());
+	}
+	osprintf(os, ");\n");
+	osprintf(os, "}\n");
+}
+
+/* Print code that checks that all isl object arguments to "method" are valid
+ * (not NULL) and throws an exception if they are not.
+ *
+ * If checked bindings are being generated,
+ * then no such check is performed.
+ */
+void plain_cpp_generator::impl_printer::print_argument_validity_check(
+	const Method &method)
+{
+	int n;
+	bool first = true;
+
+	if (generator.checked)
+		return;
+
+	n = method.num_params();
+	for (int i = 0; i < n; ++i) {
+		bool is_this;
+		ParmVarDecl *param = method.fd->getParamDecl(i);
+		string name = param->getName().str();
+		const char *name_str = name.c_str();
+		QualType type = param->getOriginalType();
+
+		is_this = i == 0 && method.kind == Method::Kind::member_method;
+		if (!is_this && (is_isl_ctx(type) || !is_isl_type(type)))
+			continue;
+
+		if (first)
+			osprintf(os, "  if (");
+		else
+			osprintf(os, " || ");
+
+		if (is_this)
+			osprintf(os, "!ptr");
+		else
+			osprintf(os, "%s.is_null()", name_str);
+
+		first = false;
+	}
+	if (first)
+		return;
+	osprintf(os, ")\n");
+	print_throw_NULL_input(os);
+}
+
+/* Print code for saving a copy of the isl::ctx available at the start
+ * of the method "method" in a "saved_ctx" variable,
+ * for use in exception handling.
+ *
+ * If checked bindings are being generated,
+ * then the "saved_ctx" variable is not needed.
+ * If "method" is a member function, then obtain the isl_ctx from
+ * the "this" object.
+ * If the first argument of the method is an isl::ctx, then use that one.
+ * Otherwise, save a copy of the isl::ctx associated to the first argument
+ * of isl object type.
+ */
+void plain_cpp_generator::impl_printer::print_save_ctx(const Method &method)
+{
+	int n;
+	ParmVarDecl *param = method.fd->getParamDecl(0);
+	QualType type = param->getOriginalType();
+
+	if (generator.checked)
+		return;
+	if (method.kind == Method::Kind::member_method) {
+		osprintf(os, "  auto saved_ctx = ctx();\n");
+		return;
+	}
+	if (is_isl_ctx(type)) {
+		std::string name;
+
+		name = param->getName().str();
+		osprintf(os, "  auto saved_ctx = %s;\n", name.c_str());
+		return;
+	}
+	n = method.num_params();
+	for (int i = 0; i < n; ++i) {
+		ParmVarDecl *param = method.fd->getParamDecl(i);
+		QualType type = param->getOriginalType();
+
+		if (!is_isl_type(type))
+			continue;
+		osprintf(os, "  auto saved_ctx = %s.ctx();\n",
+			param->getName().str().c_str());
+		return;
+	}
+}
+
+/* Print code to make isl not print an error message when an error occurs
+ * within the current scope (if exceptions are available),
+ * since the error message will be included in the exception.
+ * If exceptions are not available, then exception::on_error
+ * is set to ISL_ON_ERROR_ABORT and isl is therefore made to abort instead.
+ *
+ * If checked bindings are being generated,
+ * then leave it to the user to decide what isl should do on error.
+ * Otherwise, assume that a valid isl::ctx is available
+ * in the "saved_ctx" variable,
+ * e.g., through a prior call to print_save_ctx.
+ */
+void plain_cpp_generator::impl_printer::print_on_error_continue()
+{
+	if (generator.checked)
+		return;
+	osprintf(os, "  options_scoped_set_on_error saved_on_error(saved_ctx, "
+		     "exception::on_error);\n");
+}
+
+/* Print code to "os" that checks whether any of the persistent callbacks
+ * of the class of "method" is set and if it failed with an exception.
+ * If so, the "eptr" in the corresponding data structure contains the exception
+ * that was caught and that needs to be rethrown.
+ * This field is cleared because the callback and its data may get reused.
+ *
+ * The check only needs to be generated for member methods since
+ * an object is needed for any of the persistent callbacks to be set.
+ */
+static void print_persistent_callback_exceptional_execution_check(ostream &os,
+	const Method &method)
+{
+	if (method.kind != Method::Kind::member_method)
+		return;
+
+	for (const auto &pcb : method.clazz.persistent_callbacks) {
+		auto callback_name = method.clazz.persistent_callback_name(pcb);
+
+		osprintf(os, "  if (%s_data && %s_data->eptr) {\n",
+			callback_name.c_str(), callback_name.c_str());
+		osprintf(os, "    std::exception_ptr eptr = %s_data->eptr;\n",
+			callback_name.c_str());
+		osprintf(os, "    %s_data->eptr = nullptr;\n",
+			callback_name.c_str());
+		osprintf(os, "    std::rethrow_exception(eptr);\n");
+		osprintf(os, "  }\n");
+	}
+}
+
+/* Print code that checks whether the execution of the core of "method"
+ * was successful.
+ *
+ * If checked bindings are being generated,
+ * then no checks are performed.
+ *
+ * Otherwise, first check if any of the callbacks failed with
+ * an exception.  If so, the "eptr" in the corresponding data structure
+ * contains the exception that was caught and that needs to be rethrown.
+ * Then check if the function call failed in any other way and throw
+ * the appropriate exception.
+ * In particular, if the return type is isl_stat, isl_bool or isl_size,
+ * then a negative value indicates a failure.  If the return type
+ * is an isl type, then a NULL value indicates a failure.
+ * Assume print_save_ctx has made sure that a valid isl::ctx
+ * is available in the "ctx" variable.
+ */
+void plain_cpp_generator::impl_printer::print_exceptional_execution_check(
+	const Method &method)
+{
+	bool check_null, check_neg;
+	QualType return_type = method.fd->getReturnType();
+
+	if (generator.checked)
+		return;
+
+	print_persistent_callback_exceptional_execution_check(os, method);
+
+	if (method.callback) {
+		std::string name;
+
+		name = method.callback->getName().str();
+		osprintf(os, "  if (%s_data.eptr)\n", name.c_str());
+		osprintf(os, "    std::rethrow_exception(%s_data.eptr);\n",
+			name.c_str());
+	}
+
+	check_neg = is_isl_neg_error(return_type);
+	check_null = is_isl_type(return_type);
+	if (!check_null && !check_neg)
+		return;
+
+	if (check_neg)
+		osprintf(os, "  if (res < 0)\n");
+	else
+		osprintf(os, "  if (!res)\n");
+	print_throw_last_error(os);
+}
+
+/* Return a pointer to the appropriate type printer,
+ * i.e., the regular type printer or the checked type printer
+ * depending on the setting of this->checked.
+ */
+std::unique_ptr<cpp_type_printer> plain_cpp_generator::type_printer()
+{
+	cpp_type_printer *printer;
+
+	if (checked)
+		printer = new checked_cpp_type_printer();
+	else
+		printer = new cpp_type_printer();
+
+	return std::unique_ptr<cpp_type_printer>(printer);
+}
+
+/* Return the C++ return type of the method "method".
+ *
+ * Use the appropriate type printer.
+ */
+std::string plain_cpp_generator::get_return_type(const Method &method)
+{
+	return type_printer()->return_type(method);
+}
+
+/* Given a method "method" for setting a persistent callback of its class,
+ * print the implementations of the methods needed for that callback.
+ *
+ * In particular, print
+ * - the implementation of a static inline method
+ *   for use as the C callback function
+ * - the definition of a private method for setting the callback function
+ * - the public method for constructing a new object with the callback set.
+ */
+void plain_cpp_generator::impl_printer::print_set_persistent_callback(
+	const Method &method)
+{
+	string fullname = method.fd->getName().str();
+	ParmVarDecl *param = persistent_callback_arg(method.fd);
+	string pname;
+	string callback_name = clazz.persistent_callback_name(method.fd);
+
+	osprintf(os, "\n");
+	print_persistent_callback_prototype(method.fd);
+	osprintf(os, "\n");
+	osprintf(os, "{\n");
+	print_callback_body(2, param, callback_name);
+	osprintf(os, "}\n\n");
+
+	pname = param->getName().str();
+	print_persistent_callback_setter_prototype(method.fd);
+	osprintf(os, "\n");
+	osprintf(os, "{\n");
+	print_check_ptr_start("ptr");
+	osprintf(os, "  %s_data = std::make_shared<struct %s_data>();\n",
+		callback_name.c_str(), callback_name.c_str());
+	osprintf(os, "  %s_data->func = %s;\n",
+		callback_name.c_str(), pname.c_str());
+	osprintf(os, "  ptr = %s(ptr, &%s, %s_data.get());\n",
+		fullname.c_str(), callback_name.c_str(), callback_name.c_str());
+	print_check_ptr_end("ptr");
+	osprintf(os, "}\n\n");
+
+	print_full_method_header(method);
+	osprintf(os, "{\n");
+	osprintf(os, "  auto copy = *this;\n");
+	osprintf(os, "  copy.set_%s_data(%s);\n",
+		callback_name.c_str(), pname.c_str());
+	osprintf(os, "  return copy;\n");
+	osprintf(os, "}\n");
+}
+
+/* Print the return statement of the C++ method "method".
+ *
+ * The result of the corresponding isl function is returned as a new
+ * object if the underlying isl function returns an isl_* ptr, as a bool
+ * if the isl function returns an isl_bool, as void if the isl functions
+ * returns an isl_stat,
+ * as std::string if the isl function returns 'const char *', and as
+ * unmodified return value otherwise.
+ * If checked C++ bindings are being generated,
+ * then an isl_bool return type is transformed into a boolean and
+ * an isl_stat into a stat since no exceptions can be generated
+ * on negative results from the isl function.
+ * If the method returns a new instance of the same object type and
+ * if the class has any persistent callbacks, then the data
+ * for these callbacks are copied from the original to the new object.
+ * If "clazz" is a subclass that is based on a type function and
+ * if the return type corresponds to the superclass data type,
+ * then it is replaced by the subclass data type.
+ */
+void plain_cpp_generator::impl_printer::print_method_return(
+	const Method &method)
+{
+	QualType return_type = method.fd->getReturnType();
+	string rettype_str = generator.get_return_type(method);
+	bool returns_super = method.is_subclass_mutator();
+
+	if (is_isl_type(return_type) ||
+		    (generator.checked && is_isl_neg_error(return_type))) {
+		osprintf(os, "  return manage(res)");
+		if (is_mutator(clazz, method.fd) &&
+		    clazz.has_persistent_callbacks())
+			osprintf(os, ".copy_callbacks(*this)");
+		if (returns_super)
+			osprintf(os, ".as<%s>()", rettype_str.c_str());
+		osprintf(os, ";\n");
+	} else if (is_isl_stat(return_type)) {
+		osprintf(os, "  return;\n");
+	} else if (is_string(return_type)) {
+		osprintf(os, "  std::string tmp(res);\n");
+		if (gives(method.fd))
+			osprintf(os, "  free(res);\n");
+		osprintf(os, "  return tmp;\n");
+	} else {
+		osprintf(os, "  return res;\n");
+	}
+}
+
+/* Print the header for "method", including the terminating semicolon
+ * in case of a declaration and a newline.
+ *
+ * Use the appropriate type printer to print argument and return types.
+ */
+void plain_cpp_generator::plain_printer::print_full_method_header(
+	const Method &method)
+{
+	auto type_printer = generator.type_printer();
+
+	print_method_header(method, *type_printer);
+
+	if (declarations)
+		osprintf(os, ";");
+	osprintf(os, "\n");
+}
+
+/* Generate the list of argument types for a callback function of
+ * type "type".  If "cpp" is set, then generate the C++ type list, otherwise
+ * the C type list.
+ *
+ * Use the appropriate type printer.
+ * For the plain C++ interface, the argument position is irrelevant,
+ * so simply pass in -1.
+ */
+string plain_cpp_generator::generate_callback_args(QualType type, bool cpp)
+{
+	return type_printer()->generate_callback_args(-1, type, cpp);
+}
+
+/* Generate the full cpp type of a callback function of type "type".
+ *
+ * Use the appropriate type printer.
+ * For the plain C++ interface, the argument position is irrelevant,
+ * so simply pass in -1.
+ */
+string plain_cpp_generator::generate_callback_type(QualType type)
+{
+	return type_printer()->generate_callback_type(-1, type);
+}
+
+/* Print the call to the C++ callback function "call",
+ * with the given indentation, wrapped
+ * for use inside the lambda function that is used as the C callback function,
+ * in the case where checked C++ bindings are being generated.
+ *
+ * In particular, print
+ *
+ *        auto ret = @call@;
+ *        return ret.release();
+ */
+void plain_cpp_generator::impl_printer::print_wrapped_call_checked(int indent,
+	const string &call)
+{
+	osprintf(os, indent, "auto ret = %s;\n", call.c_str());
+	osprintf(os, indent, "return ret.release();\n");
+}
+
+/* Print the call to the C++ callback function "call",
+ * with the given indentation and with return type "rtype", wrapped
+ * for use inside the lambda function that is used as the C callback function.
+ *
+ * In particular, print
+ *
+ *        ISL_CPP_TRY {
+ *          @call@;
+ *          return isl_stat_ok;
+ *        } ISL_CPP_CATCH_ALL {
+ *          data->eptr = std::current_exception();
+ *          return isl_stat_error;
+ *        }
+ * or
+ *        ISL_CPP_TRY {
+ *          auto ret = @call@;
+ *          return ret ? isl_bool_true : isl_bool_false;
+ *        } ISL_CPP_CATCH_ALL {
+ *          data->eptr = std::current_exception();
+ *          return isl_bool_error;
+ *        }
+ * or
+ *        ISL_CPP_TRY {
+ *          auto ret = @call@;
+ *          return ret.release();
+ *        } ISL_CPP_CATCH_ALL {
+ *          data->eptr = std::current_exception();
+ *          return NULL;
+ *        }
+ *
+ * depending on the return type.
+ *
+ * where ISL_CPP_TRY is defined to "try" and ISL_CPP_CATCH_ALL to "catch (...)"
+ * (if exceptions are available).
+ *
+ * If checked C++ bindings are being generated, then
+ * the call is wrapped differently.
+ */
+void plain_cpp_generator::impl_printer::print_wrapped_call(int indent,
+	const string &call, QualType rtype)
+{
+	if (generator.checked)
+		return print_wrapped_call_checked(indent, call);
+
+	osprintf(os, indent, "ISL_CPP_TRY {\n");
+	if (is_isl_stat(rtype))
+		osprintf(os, indent, "  %s;\n", call.c_str());
+	else
+		osprintf(os, indent, "  auto ret = %s;\n", call.c_str());
+	if (is_isl_stat(rtype))
+		osprintf(os, indent, "  return isl_stat_ok;\n");
+	else if (is_isl_bool(rtype))
+		osprintf(os, indent,
+			"  return ret ? isl_bool_true : isl_bool_false;\n");
+	else
+		osprintf(os, indent, "  return ret.release();\n");
+	osprintf(os, indent, "} ISL_CPP_CATCH_ALL {\n");
+	osprintf(os, indent, "  data->eptr = std::current_exception();\n");
+	if (is_isl_stat(rtype))
+		osprintf(os, indent, "  return isl_stat_error;\n");
+	else if (is_isl_bool(rtype))
+		osprintf(os, indent, "  return isl_bool_error;\n");
+	else
+		osprintf(os, indent, "  return NULL;\n");
+	osprintf(os, indent, "}\n");
+}
+
+/* Print the declaration for a "prefix"_data data structure
+ * that can be used for passing to a C callback function
+ * containing a copy of the C++ callback function "param",
+ * along with an std::exception_ptr that is used to store any
+ * exceptions thrown in the C++ callback.
+ *
+ * If the C callback is of the form
+ *
+ *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
+ *
+ * then the following declaration is printed:
+ *
+ *      struct <prefix>_data {
+ *        std::function<stat(map)> func;
+ *        std::exception_ptr eptr;
+ *      }
+ *
+ * (without a newline or a semicolon).
+ *
+ * The std::exception_ptr object is not added to "prefix"_data
+ * if checked C++ bindings are being generated.
+ */
+void plain_cpp_generator::plain_printer::print_callback_data_decl(
+	ParmVarDecl *param,
+	const string &prefix)
+{
+	string cpp_args;
+
+	cpp_args = generator.generate_callback_type(param->getType());
+
+	osprintf(os, "  struct %s_data {\n", prefix.c_str());
+	osprintf(os, "    %s func;\n", cpp_args.c_str());
+	if (!generator.checked)
+		osprintf(os, "    std::exception_ptr eptr;\n");
+	osprintf(os, "  }");
+}
+
+/* Given a group of methods with the same name,
+ * should extra methods be added that take as arguments
+ * those types that can be converted to the original argument type
+ * through a unary constructor?
+ *
+ * Note that even if this method returns true,
+ * the extra methods are only printed by the caller
+ * if exactly one of the methods in the group was originally defined
+ * in the printed class.
+ * Signal that they should be printed if the group contains
+ * both methods originally defined in the printed class and
+ * methods that have been copied from an ancestor
+ * by checking whether there are at least two methods in the group.
+ */
+bool plain_cpp_generator::plain_printer::want_descendent_overloads(
+	const function_set &methods)
+{
+	return methods.size() > 1;
+}
+
+/* Print the body of C function callback with the given indentation
+ * that can be use as an argument to "param" for marshalling
+ * the corresponding C++ callback.
+ * The data structure that contains the C++ callback is of type
+ * "prefix"_data.
+ *
+ * For a callback of the form
+ *
+ *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
+ *
+ * the following code is generated:
+ *
+ *        auto *data = static_cast<struct <prefix>_data *>(arg_1);
+ *        ISL_CPP_TRY {
+ *          stat ret = (data->func)(manage(arg_0));
+ *          return isl_stat_ok;
+ *        } ISL_CPP_CATCH_ALL {
+ *          data->eptr = std::current_exception();
+ *          return isl_stat_error;
+ *        }
+ *
+ * If checked C++ bindings are being generated, then
+ * generate the following code:
+ *
+ *        auto *data = static_cast<struct <prefix>_data *>(arg_1);
+ *        stat ret = (data->func)(manage(arg_0));
+ *        return isl_stat(ret);
+ */
+void plain_cpp_generator::impl_printer::print_callback_body(int indent,
+	ParmVarDecl *param, const string &prefix)
+{
+	QualType ptype, rtype;
+	string call, last_idx;
+	const FunctionProtoType *callback;
+	int num_params;
+
+	ptype = param->getType();
+
+	callback = extract_prototype(ptype);
+	rtype = callback->getReturnType();
+	num_params = callback->getNumArgs();
+
+	last_idx = ::to_string(num_params - 1);
+
+	call = "(data->func)(";
+	for (long i = 0; i < num_params - 1; i++) {
+		if (!generator.callback_takes_argument(param, i))
+			call += "manage_copy";
+		else
+			call += "manage";
+		call += "(arg_" + ::to_string(i) + ")";
+		if (i != num_params - 2)
+			call += ", ";
+	}
+	call += ")";
+
+	osprintf(os, indent,
+		 "auto *data = static_cast<struct %s_data *>(arg_%s);\n",
+		 prefix.c_str(), last_idx.c_str());
+	print_wrapped_call(indent, call, rtype);
+}
+
+/* Print the local variables that are needed for a callback argument,
+ * in particular, print a lambda function that wraps the callback and
+ * a pointer to the actual C++ callback function.
+ *
+ * For a callback of the form
+ *
+ *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
+ *
+ * the following lambda function is generated:
+ *
+ *      auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat {
+ *        auto *data = static_cast<struct fn_data *>(arg_1);
+ *        try {
+ *          stat ret = (data->func)(manage(arg_0));
+ *          return isl_stat_ok;
+ *        } catch (...) {
+ *          data->eptr = std::current_exception();
+ *          return isl_stat_error;
+ *        }
+ *      };
+ *
+ * A copy of the std::function C++ callback function is stored in
+ * a fn_data data structure for passing to the C callback function,
+ * along with an std::exception_ptr that is used to store any
+ * exceptions thrown in the C++ callback.
+ *
+ *      struct fn_data {
+ *        std::function<stat(map)> func;
+ *        std::exception_ptr eptr;
+ *      } fn_data = { fn };
+ *
+ * This std::function object represents the actual user
+ * callback function together with the locally captured state at the caller.
+ *
+ * The lambda function is expected to be used as a C callback function
+ * where the lambda itself is provided as the function pointer and
+ * where the user void pointer is a pointer to fn_data.
+ * The std::function object is extracted from the pointer to fn_data
+ * inside the lambda function.
+ *
+ * The std::exception_ptr object is not added to fn_data
+ * if checked C++ bindings are being generated.
+ * The body of the generated lambda function then is as follows:
+ *
+ *        stat ret = (data->func)(manage(arg_0));
+ *        return isl_stat(ret);
+ *
+ * If the C callback does not take its arguments, then
+ * manage_copy is used instead of manage.
+ */
+void plain_cpp_generator::impl_printer::print_callback_local(ParmVarDecl *param)
+{
+	string pname;
+	QualType ptype, rtype;
+	string c_args, cpp_args, rettype;
+	const FunctionProtoType *callback;
+
+	pname = param->getName().str();
+	ptype = param->getType();
+
+	c_args = generator.generate_callback_args(ptype, false);
+
+	callback = extract_prototype(ptype);
+	rtype = callback->getReturnType();
+	rettype = rtype.getAsString();
+
+	print_callback_data_decl(param, pname);
+	osprintf(os, " %s_data = { %s };\n", pname.c_str(), pname.c_str());
+	osprintf(os, "  auto %s_lambda = [](%s) -> %s {\n",
+		 pname.c_str(), c_args.c_str(), rettype.c_str());
+	print_callback_body(4, param, pname);
+	osprintf(os, "  };\n");
+}
+
+/* Return the C++ counterpart to the isl_bool type.
+ *
+ * For the checked C++ bindings this is "boolean".
+ */
+std::string checked_cpp_type_printer::isl_bool() const
+{
+	return "boolean";
+}
+
+/* Return the C++ counterpart to the isl_bool type.
+ *
+ * Use the appropriate type printer.
+ */
+string plain_cpp_generator::isl_bool2cpp()
+{
+	return type_printer()->isl_bool();
+}
+
+/* Return the C++ counterpart to the isl_stat type.
+ *
+ * For the checked C++ bindings this is "stat".
+ */
+string checked_cpp_type_printer::isl_stat() const
+{
+	return "stat";
+}
+
+/* Return the C++ counterpart to the isl_size type.
+ *
+ * For the checked C++ bindings this is "class size".
+ */
+string checked_cpp_type_printer::isl_size() const
+{
+	return "class size";
+}
+
+/* Return the namespace of the generated C++ bindings.
+ *
+ * For the checked C++ bindings this is "isl::checked::".
+ */
+std::string checked_cpp_type_printer::isl_namespace() const
+{
+	return "isl::checked::";
+}
+
+/* Return the namespace of the generated C++ bindings.
+ *
+ * Use the appropriate type printer.
+ */
+string plain_cpp_generator::isl_namespace()
+{
+	return type_printer()->isl_namespace();
+}
+
+/* Translate parameter or return type "type" to its C++ name counterpart.
+ *
+ * Use the appropriate type printer.
+ * For the plain C++ interface, the argument position is irrelevant,
+ * so simply pass in -1.
+ */
+string plain_cpp_generator::param2cpp(QualType type)
+{
+	return type_printer()->param(-1, type);
+}
diff --git a/lib/External/isl/interface/plain_cpp.h b/lib/External/isl/interface/plain_cpp.h
new file mode 100644
index 0000000..2644802
--- /dev/null
+++ b/lib/External/isl/interface/plain_cpp.h
@@ -0,0 +1,152 @@
+#ifndef ISL_INTERFACE_PLAIN_CPP_H
+#define ISL_INTERFACE_PLAIN_CPP_H
+
+#include <functional>
+#include <memory>
+
+#include "cpp.h"
+#include "generator.h"
+
+using namespace std;
+using namespace clang;
+
+/* A type printer for converting argument and return types
+ * to string representations of the corresponding types
+ * in the checked C++ interface.
+ */
+struct checked_cpp_type_printer : public cpp_type_printer {
+	virtual std::string isl_bool() const override;
+	virtual std::string isl_stat() const override;
+	virtual std::string isl_size() const override;
+	virtual std::string isl_namespace() const override;
+};
+
+/* Generator for plain C++ bindings.
+ *
+ * "checked" is set if C++ bindings should be generated
+ * that rely on the user to check for error conditions.
+ */
+class plain_cpp_generator : public cpp_generator {
+	struct plain_printer;
+	struct decl_printer;
+	struct impl_printer;
+protected:
+	bool checked;
+public:
+	plain_cpp_generator(SourceManager &SM,
+		set<RecordDecl *> &exported_types,
+		set<FunctionDecl *> exported_functions,
+		set<FunctionDecl *> functions,
+		bool checked = false);
+
+	virtual void generate();
+private:
+	void print_forward_declarations(ostream &os);
+	void print_declarations(ostream &os);
+	void print_class(ostream &os, const isl_class &clazz);
+	void print_class_forward_decl(ostream &os, const isl_class &clazz);
+	void print_implementations(ostream &os);
+	void print_class_impl(ostream &os, const isl_class &clazz);
+	void print_check_no_persistent_callback(ostream &os,
+		const isl_class &clazz, FunctionDecl *fd);
+	void print_invalid(ostream &os, int indent, const char *msg,
+		const char *checked_code);
+	void print_method_param_use(ostream &os, ParmVarDecl *param,
+		bool load_from_this_ptr);
+	std::unique_ptr<cpp_type_printer> type_printer();
+	std::string get_return_type(const Method &method);
+	string generate_callback_args(QualType type, bool cpp);
+	string generate_callback_type(QualType type);
+	string isl_bool2cpp();
+	string isl_namespace();
+	string param2cpp(QualType type);
+};
+
+/* A helper class for printing method declarations and definitions
+ * of a class for the plain C++ interface.
+ *
+ * "generator" is the C++ interface generator printing the classes.
+ */
+struct plain_cpp_generator::plain_printer : public cpp_generator::class_printer {
+	plain_cpp_generator &generator;
+
+	plain_printer(std::ostream &os, const isl_class &clazz,
+			plain_cpp_generator &generator, bool is_declaration) :
+		class_printer(os, clazz, generator, is_declaration),
+		generator(generator) {}
+
+	void print_persistent_callback_prototype(FunctionDecl *method);
+	void print_persistent_callback_setter_prototype(FunctionDecl *method);
+	void print_full_method_header(const Method &method);
+	void print_callback_data_decl(ParmVarDecl *param, const string &name);
+	virtual bool want_descendent_overloads(const function_set &methods)
+		override;
+};
+
+/* A helper class for printing method declarations of a class.
+ */
+struct plain_cpp_generator::decl_printer :
+	public plain_cpp_generator::plain_printer
+{
+	decl_printer(std::ostream &os, const isl_class &clazz,
+			plain_cpp_generator &generator) :
+		plain_printer(os, clazz, generator, true) {}
+
+	void print_subclass_type();
+	void print_class_factory(const std::string &prefix = std::string());
+	void print_protected_constructors();
+	void print_copy_assignment();
+	void print_public_constructors();
+	void print_destructor();
+	void print_ptr();
+	void print_isa_type_template(int indent, const isl_class &super);
+	void print_downcast();
+	void print_ctx();
+	void print_persistent_callback_data(FunctionDecl *method);
+	void print_persistent_callbacks();
+	virtual void print_method(const Method &method) override;
+	virtual void print_method(const ConversionMethod &method) override;
+	virtual void print_get_method(FunctionDecl *fd) override;
+};
+
+/* A helper class for printing method definitions of a class.
+ */
+struct plain_cpp_generator::impl_printer :
+	public plain_cpp_generator::plain_printer
+{
+	impl_printer(std::ostream &os, const isl_class &clazz,
+			plain_cpp_generator &generator) :
+		plain_printer(os, clazz, generator, false) {}
+
+	void print_arg_conversion(ParmVarDecl *dst, ParmVarDecl *src);
+	virtual void print_method(const Method &method) override;
+	virtual void print_method(const ConversionMethod &method) override;
+	virtual void print_get_method(FunctionDecl *fd) override;
+	void print_check_ptr(const char *ptr);
+	void print_check_ptr_start(const char *ptr);
+	void print_check_ptr_end(const char *ptr);
+	void print_class_factory();
+	void print_protected_constructors();
+	void print_public_constructors();
+	void print_copy_assignment();
+	void print_destructor();
+	void print_ptr();
+	void print_downcast();
+	void print_ctx();
+	void print_set_persistent_callback(const Method &method);
+	void print_persistent_callbacks();
+	void print_argument_validity_check(const Method &method);
+	void print_save_ctx(const Method &method);
+	void print_on_error_continue();
+	void print_exceptional_execution_check(const Method &method);
+	void print_method_return(const Method &method);
+	void print_stream_insertion();
+	void print_wrapped_call_checked(int indent, const std::string &call);
+	void print_wrapped_call(int indent, const std::string &call,
+		QualType rtype);
+	void print_callback_body(int indent, ParmVarDecl *param,
+		const string &name);
+	void print_callback_local(ParmVarDecl *param);
+};
+
+#endif
diff --git a/lib/External/isl/interface/python.cc b/lib/External/isl/interface/python.cc
index fe8cd0c..686bcc7 100644
--- a/lib/External/isl/interface/python.cc
+++ b/lib/External/isl/interface/python.cc
@@ -257,9 +257,8 @@
 		printf("cb_arg%d", i);
 	}
 	printf(")\n");
-	printf("            except:\n");
-	printf("                import sys\n");
-	printf("                exc_info[0] = sys.exc_info()\n");
+	printf("            except BaseException as e:\n");
+	printf("                exc_info[0] = e\n");
 	if (is_isl_stat(return_type) || is_isl_bool(return_type))
 		printf("                return -1\n");
 	else
@@ -325,9 +324,8 @@
  */
 static void print_rethrow(int indent, const char *exc_info)
 {
-	print_indent(indent, "if %s != None:\n", exc_info);
-	print_indent(indent, "    raise (%s[0], %s[1], %s[2])\n",
-		exc_info, exc_info, exc_info);
+	print_indent(indent, "if %s is not None:\n", exc_info);
+	print_indent(indent, "    raise %s\n", exc_info);
 }
 
 /* Print code with the given indentation that checks
diff --git a/lib/External/isl/interface/set_lang_defaults_arg4.h b/lib/External/isl/interface/set_lang_defaults_arg4.h
new file mode 100644
index 0000000..82af7ff
--- /dev/null
+++ b/lib/External/isl/interface/set_lang_defaults_arg4.h
@@ -0,0 +1,16 @@
+#include <string>
+#include <vector>
+
+#include <clang/Lex/PreprocessorOptions.h>
+
+/* Convert a clang::PreprocessorOptions to the fourth argument
+ * of CompilerInvocation::setLangDefaults, which may be either
+ * a clang::PreprocessorOptions itself or its Includes.
+ */
+struct setLangDefaultsArg4 {
+	setLangDefaultsArg4(clang::PreprocessorOptions &PO) : PO(PO) {}
+	operator clang::PreprocessorOptions &() { return PO; }
+	operator std::vector<std::string> &() { return PO.Includes; }
+
+	clang::PreprocessorOptions &PO;
+};
diff --git a/lib/External/isl/interface/template_cpp.cc b/lib/External/isl/interface/template_cpp.cc
new file mode 100644
index 0000000..bf13803
--- /dev/null
+++ b/lib/External/isl/interface/template_cpp.cc
@@ -0,0 +1,2817 @@
+/*
+ * Copyright 2020 Cerebras Systems. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CEREBRAS SYSTEMS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CEREBRAS SYSTEMS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as
+ * representing official policies, either expressed or implied, of
+ * Cerebras Systems.
+ */
+
+#include <ctype.h>
+
+#include <algorithm>
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "template_cpp.h"
+#include "isl_config.h"
+
+/* The textual representation of this tuple kind.
+ *
+ * By default, the textual representation is just the name.
+ */
+std::string TupleKind::to_string() const
+{
+	return name;
+}
+
+/* Return the parameters of this tuple kind.
+ *
+ * By default, there are no parameters.
+ */
+std::vector<std::string> TupleKind::params() const
+{
+	return { };
+}
+
+/* Apply the substitution "subs" to this tuple kind and return the result.
+ * "self" is a shared pointer to this.
+ *
+ * If the name of this tuple kind appears in the substitution,
+ * then return the corresponding tuple kind pointer.
+ * Otherwise, return "self".
+ */
+TupleKindPtr TupleKind::apply(const Substitution &subs,
+	const TupleKindPtr &self) const
+{
+	if (subs.count(name) != 0)
+		return subs.at(name);
+	return self;
+}
+
+/* Apply the substitution "subs" to "tuple" and return the result.
+ */
+static TupleKindPtr apply(const TupleKindPtr tuple, const Substitution &subs)
+{
+	return tuple->apply(subs, tuple);
+}
+
+/* Return the left child of this tuple kind.
+ *
+ * Since this is not a pair, there is no left child.
+ */
+TupleKindPtr TupleKind::left() const
+{
+	return TupleKindPtr();
+}
+
+/* Return the right child of this tuple kind.
+ *
+ * Since this is not a pair, there is no right child.
+ */
+TupleKindPtr TupleKind::right() const
+{
+	return TupleKindPtr();
+}
+
+/* Helper class used to construct a pointer to a tuple kind
+ * that refers to a non-template type.
+ */
+struct Fixed {
+};
+
+/* Construct a pointer to a tuple kind that refers to a non-template type.
+ *
+ * Use an empty string as name.  Since this is a non-template type,
+ * the kind name will never appear in the generated code.
+ */
+TupleKindPtr::TupleKindPtr(Fixed) : Base(std::make_shared<TupleKind>(""))
+{
+}
+
+/* Tuple pointers for non-template types.
+ */
+static TupleKindPtr Ctx{Fixed()};
+static TupleKindPtr Integer{Fixed()};
+static TupleKindPtr Str{Fixed()};
+static TupleKindPtr Res{Fixed()};
+
+/* Special tuple pointers.
+ * Anonymous appears in the generated code but cannot be unified
+ * with anything else since it is a predefined template argument.
+ * Leaf can only be unified with something that is not a pair and
+ * does not appear in the generated code.
+ */
+static TupleKindPtr Anonymous("Anonymous");
+static TupleKindPtr Leaf("Leaf");
+
+/* Placeholder tuple pointers that refer to (part of) the domain or range.
+ */
+static TupleKindPtr Domain("Domain");
+static TupleKindPtr Domain2("Domain2");
+static TupleKindPtr Domain3("Domain3");
+static TupleKindPtr Range("Range");
+static TupleKindPtr Range2("Range2");
+static TupleKindPtr Range3("Range3");
+
+/* A representation of a proper tuple kind that is used as a template
+ * parameter or a template argument.
+ */
+struct ProperTupleKind : public TupleKind {
+	ProperTupleKind(const std::string &name) : TupleKind(name) {}
+
+	virtual std::vector<std::string> params() const override;
+};
+
+/* Return the parameters of this tuple kind.
+ *
+ * Return the name of this tuple kind, unless it is the special Anonymous
+ * predefined template argument.
+ */
+std::vector<std::string> ProperTupleKind::params() const
+{
+	if (Anonymous.get() == this)
+		return { };
+	return { name };
+}
+
+/* Construct a pointer to a tuple kind that refers
+ * to a proper tuple kind with the given name.
+ */
+TupleKindPtr::TupleKindPtr(const std::string &name) :
+	Base(std::make_shared<ProperTupleKind>(name))
+{
+}
+
+/* A tuple kind that represents an anonymous pair of nested tuple kinds.
+ */
+struct Pair : public TupleKind {
+	Pair(const TupleKindPtr &tuple1, const TupleKindPtr &tuple2) :
+		TupleKind(""), tuple1(tuple1), tuple2(tuple2) {}
+
+	virtual std::string to_string() const override;
+	virtual std::vector<std::string> params() const override;
+	virtual TupleKindPtr apply(const Substitution &match,
+		const TupleKindPtr &self) const override;
+	virtual TupleKindPtr left() const override;
+	virtual TupleKindPtr right() const override;
+
+	const TupleKindPtr tuple1;
+	const TupleKindPtr tuple2;
+};
+
+/* The textual representation of this tuple kind.
+ *
+ * The textual representation of a pair is of the form "pair<tuple1, tuple2>".
+ */
+std::string Pair::to_string() const
+{
+	return std::string("pair<") + tuple1->to_string() + ", " +
+					tuple2->to_string() + ">";
+}
+
+/* Add the elements of "vec2" that do not already appear in "vec1"
+ * at the end of "vec1".
+ *
+ * The two vectors are assumed not to have any repeated elements.
+ * The updated vector will then also not have repeated elements.
+ */
+static void combine(std::vector<std::string> &vec1,
+	const std::vector<std::string> &vec2)
+{
+	for (const auto &s : vec2)
+		if (std::find(vec1.begin(), vec1.end(), s) == vec1.end())
+			vec1.emplace_back(s);
+}
+
+/* Return the parameters of this tuple kind.
+ *
+ * Combine the parameters of the two nested tuple kinds.
+ */
+std::vector<std::string> Pair::params() const
+{
+	auto names1 = tuple1->params();
+	auto names2 = tuple2->params();
+
+	combine(names1, names2);
+
+	return names1;
+}
+
+/* Apply the substitution "subs" to this tuple kind and return the result.
+ * "self" is a shared pointer to this.
+ *
+ * Construct a new tuple kind consisting of the result of applying
+ * the substitution to the two nested tuple kinds.
+ */
+TupleKindPtr Pair::apply(const Substitution &subs, const TupleKindPtr &self)
+	const
+{
+	return TupleKindPtr(::apply(tuple1, subs), ::apply(tuple2, subs));
+}
+
+/* Return the left child of this tuple kind.
+ */
+TupleKindPtr Pair::left() const
+{
+	return tuple1;
+}
+
+/* Return the right child of this tuple kind.
+ */
+TupleKindPtr Pair::right() const
+{
+	return tuple2;
+}
+
+/* Construct a pointer to a tuple kind that refers
+ * to the given pair of nested tuple kinds.
+ */
+TupleKindPtr::TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right)
+	: Base(std::make_shared<Pair>(left, right))
+{
+}
+
+/* Is this a kind of object representing an anonymous function?
+ */
+bool Kind::is_anon() const
+{
+	return size() != 0 && back() == Anonymous;
+}
+
+/* Is this a kind of object with a single tuple?
+ */
+bool Kind::is_set() const
+{
+	return size() == 1;
+}
+
+/* Is this a kind of object with a single, anonymous tuple?
+ */
+bool Kind::is_anon_set() const
+{
+	return is_set() && is_anon();
+}
+
+/* Return the parameters of this kind.
+ *
+ * Collect the parameters of the tuple kinds in the sequence.
+ */
+std::vector<std::string> Kind::params() const
+{
+	std::vector<std::string> params;
+
+	for (const auto &tuple : *this)
+		combine(params, tuple->params());
+
+	return params;
+}
+
+/* Apply the substitution "subs" to this kind and return the result.
+ *
+ * Apply the substitution to each of the tuple kinds in the sequence.
+ */
+Kind Kind::apply(const Substitution &subs) const
+{
+	Kind applied;
+
+	for (const auto &tuple : *this)
+		applied.emplace_back(::apply(tuple, subs));
+
+	return applied;
+}
+
+/* A signature of a method in terms of kinds,
+ * consisting of a return kind and a sequence of argument kinds.
+ */
+struct Signature {
+	Kind ret;
+	std::vector<Kind> args;
+
+	std::vector<std::string> params() const;
+	Signature apply(const Substitution &match) const;
+};
+
+/* Return the parameters of this signature.
+ *
+ * Collect the parameters of the argument kinds and the return kind.
+ */
+std::vector<std::string> Signature::params() const
+{
+	std::vector<std::string> params;
+
+	for (const auto &arg : args)
+		combine(params, arg.params());
+	combine(params, ret.params());
+
+	return params;
+}
+
+/* Apply the substitution "subs" to this kind and return the result.
+ *
+ * Apply the substitution to the argument kinds and the return kind.
+ */
+Signature Signature::apply(const Substitution &subs) const
+{
+	std::vector<Kind> applied_args;
+
+	for (const auto &arg : args)
+		applied_args.emplace_back(arg.apply(subs));
+
+	return { ret.apply(subs), applied_args };
+}
+
+/* Return a renaming substitution that renames the elements of "params"
+ * using names starting with "prefix".
+ */
+static Substitution param_renamer(const std::vector<std::string> &params,
+	const std::string &prefix)
+{
+	Substitution renamer;
+	int n = 0;
+
+	for (const auto &name : params) {
+		auto suffix = std::to_string(++n);
+		auto arg_name = prefix + suffix;
+		auto arg = TupleKindPtr(arg_name);
+
+		if (name == Leaf->name)
+			generator::die("Leaf cannot be renamed");
+
+		renamer.emplace(name, arg);
+	}
+
+	return renamer;
+}
+
+/* Does the vector "v" contain the element "el"?
+ */
+static bool contains(const std::vector<std::string> &v, const std::string &el)
+{
+	 return find(v.begin(), v.end(), el) != v.end();
+ }
+
+
+/* Return the shared elements of "v1" and "v2", preserving the order
+ * of those elements in "v1".
+ */
+static std::vector<std::string> intersect(const std::vector<std::string> &v1,
+	const std::vector<std::string> &v2)
+{
+	std::vector<std::string> intersection;
+
+	for (const auto &el : v1)
+		if (contains(v2, el))
+			intersection.push_back(el);
+
+	return intersection;
+}
+
+/* Return a renaming substitution that renames
+ * any parameters that appears in both "sig" and "kind".
+ */
+static Substitution shared_param_renamer(const Signature &sig, const Kind &kind)
+{
+	return param_renamer(intersect(sig.params(), kind.params()), "Arg");
+}
+
+/* Signatures for unary operations.
+ * Functions have at least one tuple.
+ */
+static Signature un_params = { { }, { { } } };
+static Signature un_set = { { Domain }, { { Domain } } };
+static Signature un_map = { { Domain, Range }, { { Domain, Range } } };
+static std::vector<Signature> un_op = { un_params, un_set, un_map };
+static std::vector<Signature> fn_un_op = { un_set, un_map };
+
+/* Signatures for binary operations, with the second argument
+ * possibly referring to part of the first argument.
+ * Functions have at least one tuple.
+ */
+static Signature bin_params = { { }, { { }, { } } };
+static Signature bin_set = { { Domain }, { { Domain }, { Domain } } };
+static Signature bin_map =
+	{ { Domain, Range }, { { Domain, Range }, { Domain, Range } } };
+static std::vector<Signature> bin_op = { bin_params, bin_set, bin_map };
+static std::vector<Signature> fn_bin_op = { bin_set, bin_map };
+static Signature bin_set_params = { { Domain }, { { Domain }, { } } };
+static Signature bin_map_params =
+	{ { Domain, Range }, { { Domain, Range }, { } } };
+static Signature bin_map_domain =
+	{ { Domain, Range }, { { Domain, Range }, { Domain } } };
+static Signature bin_map_range =
+	{ { Domain, Range }, { { Domain, Range }, { Range } } };
+
+/* Signatures for binary operations, where the second argument
+ * is an identifier (with an anonymous tuple).
+ */
+static Signature bin_params_anon = { { }, { { }, { Anonymous } } };
+static Signature bin_set_anon = { { Domain }, { { Domain }, { Anonymous } } };
+static Signature bin_map_anon =
+	{ { Domain, Range }, { { Domain, Range }, { Anonymous } } };
+static std::vector<Signature> bin_op_anon =
+	{ bin_params_anon, bin_set_anon, bin_map_anon };
+
+/* Signatures for ternary operations, where the last two arguments are integers.
+ */
+static Signature ter_params_int_int =
+	{ { }, { { }, { Integer }, { Integer } } };
+static Signature ter_set_int_int =
+	{ { Domain }, { { Domain }, { Integer }, { Integer } } };
+static Signature ter_map_int_int =
+	{ { Domain, Range }, { { Domain, Range }, { Integer }, { Integer } } };
+static std::vector<Signature> ter_int_int =
+	{ ter_params_int_int, ter_set_int_int, ter_map_int_int };
+
+/* Signatures for ternary operations.
+ * Functions have at least one tuple.
+ */
+static Signature ter_set =
+	{ { Domain }, { { Domain }, { Domain }, { Domain } } };
+static Signature ter_map =
+	{ { Domain, Range },
+	  { { Domain, Range }, { Domain, Range }, { Domain, Range } } };
+static std::vector<Signature> fn_ter_op = { ter_set, ter_map };
+
+/* Signatures for naming a leaf tuple using an identifier (with an anonymous
+ * tuple).
+ */
+static Signature update_set = { { Domain2 }, { { Leaf }, { Anonymous } } };
+static Signature update_domain =
+	{ { Domain2, Range }, { { Leaf, Range }, { Anonymous } } };
+static Signature update_range =
+	{ { Domain, Range2 }, { { Domain, Leaf }, { Anonymous } } };
+
+/* Signatures for the functions "min" and "max", which can be either
+ * unary or binary operations.
+ */
+static std::vector<Signature> min_max = { un_set, bin_set, un_map, bin_map };
+
+/* Signatures for adding an unnamed tuple to an object with zero or one tuple.
+ */
+static Signature to_set = { { Domain }, { { }, { Integer } } };
+static Signature add_range = { { Domain, Range }, { { Domain }, { Integer } } };
+/* Signatures for adding a named tuple to an object with zero or one tuple.
+ */
+static Signature to_set_named =
+	{ { Domain }, { { }, { Anonymous }, { Integer } } };
+static Signature add_range_named =
+	{ { Domain, Range }, { { Domain }, { Anonymous }, { Integer } } };
+
+/* Signatures for methods applying a map to a set, a function or
+ * part of a map.
+ */
+static Signature set_forward = { { Range }, { { Domain }, { Domain, Range } } };
+static Signature domain_forward =
+	{ { Domain2, Range }, { { Domain, Range }, { Domain, Domain2 } } };
+static Signature range_forward =
+	{ { Domain, Range2 }, { { Domain, Range }, { Range, Range2 } } };
+
+/* Signatures for methods plugging in a function into a set, a function or
+ * part of a map.
+ */
+static Signature set_backward =
+	{ { Domain2 }, { { Domain }, { Domain2, Domain } } };
+static Signature domain_backward =
+	{ { Domain2, Range }, { { Domain, Range }, { Domain2, Domain } } };
+static Signature range_backward =
+	{ { Domain, Range2 }, { { Domain, Range }, { Range2, Range } } };
+static Signature domain_wrapped_domain_backward =
+	{ { { Domain3, Domain2 }, Range },
+	  { { { Domain, Domain2 }, Range }, { Domain3, Domain } } };
+
+/* Signatures for methods binding a set, a function,
+ * or (part of) a map to parameters or an object of the same kind.
+ */
+static Signature bind_set = { { }, { { Domain }, { Domain } } };
+static Signature bind_domain = { { Range }, { { Domain, Range }, { Domain } } };
+static Signature bind_range = { { Domain }, { { Domain, Range }, { Range } } };
+static Signature bind_domain_wrapped_domain =
+	{ { Range2, Range }, { { { Domain2, Range2 }, Range }, { Domain2 } } };
+
+/* Signatures for functions that take a callback accepting
+ * objects of the same kind (but a different type).
+ *
+ * The return and argument kinds of the callback appear
+ * at the position of the callback.
+ */
+static Signature each_params = { { Res }, { { }, { Res }, { } } };
+static Signature each_set = { { Res }, { { Domain }, { Res }, { Domain } } };
+static Signature each_map =
+	{ { Res }, { { Domain, Range }, { Res }, { Domain, Range } } };
+static std::vector<Signature> each = { each_params, each_set, each_map };
+
+/* Signature for creating a map from a range,
+ * where the domain is given by an extra argument.
+ */
+static Signature map_from_range_and_domain =
+	{ { Domain, Range }, { { Range }, { Domain } } };
+
+/* Signature for creating a map from a domain,
+ * where the range is given by an extra argument.
+ */
+static Signature map_from_domain_and_range =
+	{ { Domain, Range }, { { Domain }, { Range } } };
+
+/* Signatures for creating an anonymous set from a parameter set.
+ * or a map from a domain, where the range is anonymous.
+ */
+static Signature anonymous_set_from_params = { { Anonymous }, { { } } };
+static Signature anonymous_map_from_domain =
+	{ { Domain, Anonymous }, { { Domain } } };
+static std::vector<Signature> anonymous_from_domain =
+	{ anonymous_set_from_params, anonymous_map_from_domain };
+
+/* Signature for creating a set from a parameter set,
+ * where the domain is given by an extra argument.
+ */
+static Signature set_from_params = { { Domain }, { { }, { Domain } } };
+
+/* Signatures for creating an anonymous function from a domain,
+ * where the second argument is an identifier (with an anonymous tuple).
+ */
+static Signature anonymous_set_from_params_bin_anon =
+	{ { Anonymous }, { { }, { Anonymous } } };
+static Signature anonymous_map_from_domain_bin_anon =
+	{ { Domain, Anonymous }, { { Domain }, { Anonymous } } };
+static std::vector<Signature> anonymous_from_domain_bin_anon = {
+	  anonymous_set_from_params_bin_anon,
+	  anonymous_map_from_domain_bin_anon
+	};
+
+/* Signature for creating a map from a domain,
+ * where the range tuple is equal to the domain tuple.
+ */
+static Signature set_to_map = { { Domain, Domain }, { { Domain } } };
+
+/* Signatures for obtaining the range or the domain of a map.
+ * In case of a transformation, the domain and range are the same.
+ */
+static Signature domain = { { Domain }, { { Domain, Range } } };
+static Signature range = { { Range }, { { Domain, Range } } };
+static Signature transformation_domain = { { Domain }, { { Domain, Domain } } };
+
+/* Signatures for obtaining the parameter domain of a set or map.
+ */
+static Signature set_params = { { }, { { Domain } } };
+static Signature map_params = { { }, { { Domain, Range } } };
+
+/* Signatures for obtaining the domain of a function.
+ */
+static std::vector<Signature> fn_domain = { domain, set_params };
+
+/* Signatures for interchanging (wrapped) domain and range.
+ */
+static Signature map_reverse = { { Range, Domain }, { { Domain, Range } } };
+static Signature map_range_reverse =
+	{ { Domain, { Range, Range2} }, { { Domain, { Range2, Range} } } };
+
+/* Signatures for constructing products.
+ */
+static Signature set_product =
+	{ { { Domain, Range } }, { { Domain }, { Range } } };
+static Signature map_product =
+	{ { { Domain, Domain2 }, { Range, Range2 } },
+	  { { Domain, Range }, { Domain2, Range2 } } };
+static Signature domain_product =
+	{ { { Domain, Domain2 }, Range },
+	  { { Domain, Range }, { Domain2, Range } } };
+static Signature range_product =
+	{ { Domain, { Range, Range2 } },
+	  { { Domain, Range }, { Domain, Range2 } } };
+
+/* Signatures for obtaining factors from a product.
+ */
+static Signature domain_factor_domain =
+	{ { Domain, Range }, { { { Domain, Domain2 }, Range } } };
+static Signature domain_factor_range =
+	{ { Domain2, Range }, { { { Domain, Domain2 }, Range } } };
+static Signature range_factor_domain =
+	{ { Domain, Range }, { { Domain, { Range, Range2 } } } };
+static Signature range_factor_range =
+	{ { Domain, Range2 }, { { Domain, { Range, Range2 } } } };
+
+/* Signatures for (un)currying.
+ */
+static Signature curry =
+	{ { Domain, { Range, Range2 } },
+	  { { { Domain, Range }, Range2 } } };
+static Signature uncurry =
+	{ { { Domain, Range }, Range2 },
+	  { { Domain, { Range, Range2 } } } };
+
+/* Signatures for (un)wrapping.
+ */
+static Signature wrap = { { { Domain, Range } }, { { Domain, Range } } };
+static Signature unwrap = { { Domain, Range }, { { { Domain, Range } } } };
+
+/* Signatures for constructing objects that map to the domain or range
+ * of a map.
+ */
+static Signature domain_map =
+	{ { { Domain, Range }, Domain }, { { Domain, Range } } };
+static Signature range_map =
+	{ { { Domain, Range }, Range }, { { Domain, Range } } };
+
+/* Signature for applying a comparison between the domain and the range
+ * of a map.
+ */
+static Signature map_cmp =
+	{ { Domain, Domain }, { { Domain, Domain }, { Domain, Range } } };
+
+/* Signature for creating a set corresponding to the domains
+ * of two functions.
+ */
+static Signature set_join =
+	{ { Domain }, { { Domain, Range }, { Domain, Range } } };
+
+/* Signatures for flattening the domain or range of a map,
+ * replacing it with either an anonymous tuple or a tuple with a given name.
+ */
+static Signature anonymize_nested_domain =
+	{ { Anonymous, Range2 }, { { { Domain, Range }, Range2 } } };
+static Signature anonymize_nested_range =
+	{ { Domain, Anonymous }, { { Domain, { Range, Range2 } } } };
+static Signature replace_nested_domain =
+	{ { Domain2, Range2 },
+	  { { { Domain, Range }, Range2 }, { Anonymous} } };
+static Signature replace_nested_range =
+	{ { Domain, Range3 }, { { Domain, { Range, Range2 } }, { Anonymous} } };
+static std::vector<Signature> flatten_domain =
+	{ anonymize_nested_domain, replace_nested_domain };
+static std::vector<Signature> flatten_range =
+	{ anonymize_nested_range, replace_nested_range };
+
+/* Signatures for "set_at" methods.
+ */
+static Signature set_at_set =
+	{ { Domain }, { { Domain }, { Integer }, { Anonymous } } };
+static Signature set_at_map =
+	{ { Domain, Range },
+	  { { Domain, Range }, { Integer }, { Domain, Anonymous } } };
+static std::vector<Signature> set_at = { set_at_set, set_at_map };
+
+/* Signatures for "list" methods, extracting a list
+ * from a multi-expression.
+ */
+static Signature to_list_set = { { Anonymous }, { { Domain } } };
+static Signature to_list_map = { { Domain, Anonymous }, { { Domain, Range } } };
+
+/* Signatures for functions constructing an object from only an isl::ctx.
+ */
+static Signature ctx_params = { { }, { { Ctx } } };
+static Signature ctx_set = { { Domain }, { { Ctx } } };
+static Signature ctx_map = { { Domain, Range }, { { Ctx } } };
+
+/* Helper structure for sorting the keys of static_methods and
+ * special_member_methods such that the larger keys appear first.
+ * In particular, a key should appear before any key that appears
+ * as a substring in the key.
+ * Note that this sorting is currently only important
+ * for special_member_methods.
+ */
+struct larger_infix {
+	bool operator()(const std::string &x, const std::string &y) const {
+		if (x.length() > y. length())
+			return true;
+		return x < y;
+	}
+};
+
+/* A map from part of a type name to a sequence of signatures.
+ */
+typedef std::map<std::string, std::vector<Signature>, larger_infix> infix_map;
+
+/* A map from a method name to a map from part of a type name
+ * to a sequence of signatures.
+ */
+typedef std::map<std::string, infix_map> infix_map_map;
+
+/* Signatures for static methods.
+ *
+ * The "unit" static method is only available in a 0-tuple space.
+ *
+ * The "empty" static method creates union objects with the relevant
+ * number of tuples.
+ *
+ * The "universe" static methods create objects from the corresponding spaces.
+ */
+static const infix_map_map static_methods {
+	{ "unit",
+	  { { "space",			{ ctx_params } } }
+	},
+	{ "empty",
+	  {
+	    { "union_set",		{ ctx_params, ctx_set } },
+	    { "union_map",		{ ctx_map } },
+	    { "union_pw_multi_aff",	{ ctx_set, ctx_map } },
+	  }
+	},
+	{ "universe",
+	  {
+	    { "set",			{ un_params, un_set } },
+	    { "map",			{ un_map } },
+	  }
+	},
+};
+
+/* Signatures for unary operations that either take something in a set space
+ * and return something in the same space or take something in a map space
+ * and return something in the range of that space.
+ */
+static std::vector<Signature> range_op = { un_set, range };
+
+/* Signatures for binary operations where the second argument
+ * is a (multi-)value.
+ */
+static std::vector<Signature> bin_val = { bin_set, bin_map_range };
+
+/* The (default) signatures for methods with a given name.
+ * Some of these are overridden by special_member_methods.
+ */
+static const std::unordered_map<std::string, std::vector<Signature>>
+member_methods {
+	{ "add",		bin_op },
+	{ "add_constant",	bin_val },
+	{ "add_named_tuple",	{ to_set_named, add_range_named } },
+	{ "add_param",		bin_op_anon },
+	{ "add_unnamed_tuple",	{ to_set, add_range } },
+	{ "apply",		{ set_forward, range_forward } },
+	{ "apply_domain",	{ domain_forward } },
+	{ "apply_range",	{ range_forward } },
+	{ "as",			un_op },
+	{ "as_map",		{ un_map } },
+	{ "as_union_map",	{ un_map } },
+	{ "as_set",		{ un_set } },
+	{ "bind",		{ bind_set, bind_range } },
+	{ "bind_domain",	{ bind_domain } },
+	{ "bind_range",		{ bind_range } },
+	{ "bind_domain_wrapped_domain",
+				{ bind_domain_wrapped_domain } },
+	{ "ceil",		fn_un_op },
+	{ "coalesce",		un_op },
+	{ "cond",		fn_ter_op },
+	{ "constant_multi_val",	range_op },
+	{ "curry",		{ curry } },
+	{ "deltas",		{ transformation_domain } },
+	{ "detect_equalities",	un_op },
+	{ "domain",		fn_domain },
+	{ "domain_factor_domain",
+				{ domain_factor_domain } },
+	{ "domain_factor_range",
+				{ domain_factor_range } },
+	{ "domain_map",		{ domain_map } },
+	{ "domain_product",	{ domain_product } },
+	{ "drop",		ter_int_int },
+	{ "eq_at",		{ map_cmp } },
+	{ "every",		each },
+	{ "extract",		bin_op },
+	{ "flatten_domain",	flatten_domain },
+	{ "flatten_range",	flatten_range },
+	{ "floor",		fn_un_op },
+	{ "foreach",		each },
+	{ "ge_set",		{ set_join } },
+	{ "gt_set",		{ set_join } },
+	{ "gist",		bin_op },
+	{ "gist_domain",	{ bin_map_domain } },
+	{ "identity",		{ un_map, set_to_map } },
+	{ "identity_on_domain",	{ set_to_map } },
+	{ "indicator_function",	anonymous_from_domain },
+	{ "insert_domain",	{ map_from_range_and_domain } },
+	{ "intersect",		bin_op },
+	{ "intersect_params",	{ bin_set_params, bin_map_params } },
+	{ "intersect_domain",	{ bin_map_domain } },
+	{ "intersect_range",	{ bin_map_range } },
+	{ "le_set",		{ set_join } },
+	{ "lt_set",		{ set_join } },
+	{ "lex_le_at",		{ map_cmp } },
+	{ "lex_lt_at",		{ map_cmp } },
+	{ "lex_ge_at",		{ map_cmp } },
+	{ "lex_gt_at",		{ map_cmp } },
+	{ "lexmin",		fn_un_op },
+	{ "lexmax",		fn_un_op },
+	{ "list",		{ to_list_set, to_list_map } },
+	{ "lower_bound",	fn_bin_op },
+	{ "map_from_set",	{ set_to_map } },
+	{ "max",		min_max },
+	{ "max_multi_val",	range_op },
+	{ "min",		min_max },
+	{ "min_multi_val",	range_op },
+	{ "mod",		bin_val },
+	{ "on_domain",		{ map_from_domain_and_range } },
+	{ "neg",		fn_un_op },
+	{ "offset",		fn_un_op },
+	{ "param_on_domain",	anonymous_from_domain_bin_anon },
+	{ "params",		{ set_params, map_params } },
+	{ "plain_multi_val_if_fixed",
+				{ un_set } },
+	{ "preimage",		{ set_backward } },
+	{ "preimage_domain",	{ domain_backward } },
+	{ "preimage_domain_wrapped_domain",
+				{ domain_wrapped_domain_backward } },
+	{ "preimage_range",	{ range_backward } },
+	{ "product",		{ set_product, map_product } },
+	{ "project_out_param",	bin_op_anon },
+	{ "project_out_all_params",
+				un_op },
+	{ "pullback",		{ domain_backward, bind_domain } },
+	{ "range",		{ range } },
+	{ "range_factor_domain",
+				{ range_factor_domain } },
+	{ "range_factor_range",	{ range_factor_range } },
+	{ "range_lattice_tile",	{ un_map } },
+	{ "range_map",		{ range_map } },
+	{ "range_product",	{ range_product } },
+	{ "range_simple_fixed_box_hull",
+				{ un_map } },
+	{ "reverse",		{ map_reverse } },
+	{ "range_reverse",	{ map_range_reverse } },
+	{ "scale",		bin_val },
+	{ "scale_down",		bin_val },
+	{ "set_at",		set_at },
+	{ "set_domain_tuple",	{ update_domain } },
+	{ "set_range_tuple",	{ update_set, update_range } },
+	{ "simple_fixed_box_hull",
+				{ un_set } },
+	{ "sub",		fn_bin_op },
+	{ "subtract",		bin_op },
+	{ "subtract_domain",	{ bin_map_domain } },
+	{ "subtract_range",	{ bin_map_range } },
+	{ "translation",	{ set_to_map } },
+	{ "to",			un_op },
+	{ "unbind_params",	{ set_from_params } },
+	{ "unbind_params_insert_domain",
+				{ map_from_range_and_domain } },
+	{ "uncurry",		{ uncurry } },
+	{ "union_add",		fn_bin_op },
+	{ "unite",		bin_op },
+	{ "universe",		un_op },
+	{ "unwrap",		{ unwrap } },
+	{ "upper_bound",	fn_bin_op },
+	{ "wrap",		{ wrap } },
+	{ "zero",		fn_un_op },
+	{ "zero_on_domain",	{ anonymous_map_from_domain } },
+};
+
+/* Signatures for methods of types containing a given substring
+ * that override the default signatures, where larger substrings
+ * appear first.
+ *
+ * In particular, "gist" is usually a regular binary operation,
+ * but for any type derived from "aff", the argument refers
+ * to the domain of the function.
+ *
+ * The "size" method can usually simply be inherited from
+ * the corresponding plain C++ type, but for a "fixed_box",
+ * the size lives in the space of the box or its range.
+ *
+ * The "space" method is usually a regular unary operation
+ * that returns the single space of the elements in the object,
+ * with the same number of tuples.
+ * However, a "union" object may contain elements from many spaces and
+ * therefore its space only refers to the symbolic constants and
+ * has zero tuples, except if it is also a "multi_union" object,
+ * in which case it has a fixed range space and the space of the object
+ * has a single tuple.
+ * Note that since "space' is also the name of a template class,
+ * the default space method is handled by print_type_named_member_method.
+ */
+static const infix_map_map special_member_methods {
+	{ "gist",
+	  { { "aff",		{ bin_set_params, bin_map_domain } } }
+	},
+	{ "size",
+	  { { "fixed_box",	range_op } },
+	},
+	{ "space",
+	  {
+	    { "multi_union",	range_op },
+	    { "union",		{ un_params, set_params, map_params } },
+	  }
+	},
+};
+
+/* Generic kinds for objects with zero, one or two tuples,
+ * the last of which may be anonymous.
+ */
+static Kind params{};
+static Kind set_type{ Domain };
+static Kind set_anon{ Anonymous };
+static Kind map_type{ Domain, Range };
+static Kind map_anon{ Domain, Anonymous };
+
+/* The initial sequence of specialization kinds for base types.
+ * The specialization kinds for other types are derived
+ * from the corresponding base types.
+ *
+ * In particular, this sequence specifies how many tuples
+ * a given type can have and whether it is anonymous.
+ *
+ * "space" can have any number of tuples.
+ * "set" and "point" can have zero or one tuple.
+ * "map" can only have two tuples.
+ * "aff" can have one or two tuples, the last of which is anonymous.
+ * "fixed_box" can represent a (proper) set) or a map.
+ * "val" and "id" are treated as anonymous sets so that
+ * they can form the basis of "multi_val" and "multi_id".
+ */
+static const std::unordered_map<std::string, std::vector<Kind>> base_kinds {
+	{ "space",	{ params, set_type, map_type } },
+	{ "set",	{ params, set_type } },
+	{ "point",	{ params, set_type } },
+	{ "map",	{ map_type } },
+	{ "aff",	{ set_anon, map_anon } },
+	{ "fixed_box",	{ set_type, map_type } },
+	{ "val",	{ set_anon } },
+	{ "id",		{ set_anon } },
+};
+
+/* Prefixes introduced by type constructors.
+ */
+static const std::unordered_set<std::string> type_prefixes {
+	"basic",
+	"multi",
+	"pw",
+	"union",
+};
+
+/* If "type" has a "_list" suffix, then return "type" with this suffix removed.
+ * Otherwise, simply return "type".
+ */
+static std::string drop_list(const std::string &type)
+{
+	size_t pos = type.rfind('_');
+
+	if (pos == std::string::npos)
+		return type;
+	if (type.substr(pos + 1) == "list")
+		return type.substr(0, pos);
+	return type;
+}
+
+/* Given the name of a plain C++ type, return the base type
+ * from which it was derived using type constructors.
+ *
+ * In particular, drop any "list" suffix and
+ * drop any prefixes from type_prefixes, stopping
+ * as soon as a base type is found for which kinds have been registered
+ * in base_kinds.
+ */
+static std::string base_type(const std::string &type)
+{
+	auto base = type;
+	size_t pos;
+
+	base = drop_list(base);
+	while (base_kinds.count(base) == 0 &&
+			(pos = base.find('_')) != std::string::npos &&
+			type_prefixes.count(base.substr(0, pos)) != 0) {
+		base = base.substr(pos + 1);
+	}
+
+	return base;
+}
+
+/* A mapping from anonymous kinds to named kinds.
+ */
+static std::map<Kind, Kind> anon_to_named {
+	{ set_anon, set_type },
+	{ map_anon, map_type },
+};
+
+/* Given a sequence of anonymous kinds, replace them
+ * by the corresponding named kinds.
+ */
+static std::vector<Kind> add_name(const std::vector<Kind> &tuples)
+{
+	std::vector<Kind> named;
+
+	for (const auto &tuple : tuples)
+		named.emplace_back(anon_to_named.at(tuple));
+
+	return named;
+}
+
+/* Add a template class called "name", of which the methods are described
+ * by "clazz" and where the corresponding base type has kinds "base_kinds".
+ *
+ * If this template class is a multi-expression, then it was derived
+ * from an anonymous function type.  Replace the final Anonymous
+ * tuple kind by a placeholder in this case.
+ */
+void template_cpp_generator::add_template_class(const isl_class &clazz,
+	const std::string &name, const std::vector<Kind> &base_kinds)
+{
+	auto isl_namespace = cpp_type_printer().isl_namespace();
+	auto super = isl_namespace + name;
+	auto class_tuples = base_kinds;
+
+	if (name.find("multi_") != std::string::npos)
+		class_tuples = add_name(class_tuples);
+	template_classes.emplace(name,
+		template_class{name, super, clazz, class_tuples});
+}
+
+/* Construct a templated C++ bindings generator from
+ * the exported types and functions and the set of all declared functions.
+ *
+ * On top of the initialization of the shared parts
+ * of C++ bindings generators, add a template class
+ * for each plain C++ class for which template kinds
+ * have been defined.
+ * In particular, determine the base type from which the plain C++ class
+ * was derived using type constructors and check if any template kinds
+ * have been registered for this base type.
+ */
+template_cpp_generator::template_cpp_generator(clang::SourceManager &SM,
+	std::set<clang::RecordDecl *> &exported_types,
+	std::set<clang::FunctionDecl *> exported_functions,
+	std::set<clang::FunctionDecl *> functions) :
+		cpp_generator(SM, exported_types, exported_functions,
+			functions)
+{
+	for (const auto &kvp : classes) {
+		const auto &clazz = kvp.second;
+		std::string name = type2cpp(clazz);
+		std::string base = base_type(name);
+
+		if (base_kinds.count(base) == 0)
+			continue;
+		add_template_class(clazz, name, base_kinds.at(base));
+	}
+}
+
+/* Call "fn" on each template class.
+ */
+void template_cpp_generator::foreach_template_class(
+	const std::function<void(const template_class &)> &fn) const
+{
+	for (const auto &kvp : template_classes)
+		fn(kvp.second);
+}
+
+/* Print forward declarations for all template classes to "os".
+ *
+ * For template classes that represent an anonymous function
+ * that can also have a domain tuple, provide an <name>_on alias
+ * that adds the fixed Anonymous tuple kind.
+ */
+void template_cpp_generator::print_forward_declarations(std::ostream &os)
+{
+	foreach_template_class([&os] (const template_class &template_class) {
+		auto name = template_class.class_name;
+
+		os << "\n";
+		os << "template <typename...>\n";
+		os << "struct " << name << ";\n";
+
+		if (!template_class.is_anon())
+			return;
+		if (template_class.is_anon_set())
+			return;
+
+		os << "\n";
+		os << "template <typename...Ts>\n";
+		os << "using " << name << "_on = "
+		   << name << "<Ts..., Anonymous>;\n";
+	});
+}
+
+/* Print friend declarations for all template classes to "os".
+ */
+void template_cpp_generator::print_friends(std::ostream &os)
+{
+	foreach_template_class([&os] (const template_class &template_class) {
+		os << "  template <typename...>\n";
+		os << "  friend struct " << template_class.class_name << ";\n";
+	});
+}
+
+/* Print a template parameter or argument.
+ * In case of a std::string, it's a template parameter
+ * that needs to be declared.
+ */
+static void print_template_arg(std::ostream &os, const std::string &arg)
+{
+	os << "typename " << arg;
+}
+
+/* Print a template parameter or argument.
+ * In case of a TupleKindPtr, it's a template argument.
+ */
+static void print_template_arg(std::ostream &os, const TupleKindPtr &kind)
+{
+	os << kind->to_string();
+}
+
+/* Print a sequence of template parameters (std::string) or
+ * arguments (TupleKindPtr) "args", without the enclosing angle brackets.
+ */
+template <typename List>
+static void print_pure_template_args(std::ostream &os, const List &args)
+{
+	for (size_t i = 0; i < args.size(); ++i) {
+		if (i != 0)
+			os << ", ";
+		print_template_arg(os, args[i]);
+	}
+}
+
+/* Print a sequence of template parameters (std::string) or
+ * arguments (TupleKindPtr) "args".
+ */
+template <typename List>
+static void print_template_args(std::ostream &os, const List &args)
+{
+	os << "<";
+	print_pure_template_args(os, args);
+	os << ">";
+}
+
+/* Print a declaration of the template parameters "params".
+ */
+static void print_template(std::ostream &os,
+	const std::vector<std::string> &params)
+{
+	os << "template ";
+	print_template_args(os, params);
+	os << "\n";
+}
+
+/* Print a declaration of the template parameters "params",
+ * if there are any.
+ */
+static void print_non_empty_template(std::ostream &os,
+	const std::vector<std::string> &params)
+{
+	if (params.size() > 0)
+		print_template(os, params);
+}
+
+/* Print a bare template type, i.e., without namespace,
+ * consisting of the type "type" and the kind "kind" to "os".
+ *
+ * In particular, print "type" followed by the template arguments
+ * as specified by "kind".
+ */
+static void print_bare_template_type(std::ostream &os, const std::string &type,
+	const Kind &kind)
+{
+	os << type;
+	print_template_args(os, kind);
+}
+
+/* A specific instance of "template_class", with tuple kinds given by "kind".
+ */
+struct specialization {
+	struct template_class &template_class;
+	Kind kind;
+
+	const std::string &base_name() const;
+	const std::string &class_name() const;
+};
+
+/* The name of the plain C++ interface class
+ * from which this template class (instance) derives.
+ */
+const std::string &specialization::base_name() const
+{
+	return template_class.super_name;
+}
+
+/* The name of the template class.
+ */
+const std::string &specialization::class_name() const
+{
+	return template_class.class_name;
+}
+
+/* Helper class for printing the specializations of template classes
+ * that is used to print both the class declarations and the class definitions.
+ *
+ * "os" is the stream onto which the classes should be printed.
+ * "generator" is the templated C++ interface generator printing the classes.
+ */
+struct specialization_printer {
+	specialization_printer(std::ostream &os,
+			template_cpp_generator &generator) :
+		os(os), generator(generator) {}
+
+	virtual void print_class(const specialization &instance) const = 0;
+	void print_classes() const;
+
+	std::ostream &os;
+	template_cpp_generator &generator;
+};
+
+/* Print all specializations of all template classes.
+ *
+ * Each class has a predefined set of initial specializations,
+ * but while such a specialization is being printed,
+ * the need for other specializations may arise and
+ * these are added at the end of the list of specializations.
+ * That is, class_tuples.size() may change during the execution
+ * of the loop.
+ *
+ * For each specialization of a template class, call
+ * the print_class virtual method.
+ */
+void specialization_printer::print_classes() const
+{
+	for (auto &kvp : generator.template_classes) {
+		auto &template_class = kvp.second;
+		const auto &class_tuples = template_class.class_tuples;
+
+		for (size_t i = 0; i < class_tuples.size(); ++i)
+			print_class({ template_class, class_tuples[i] });
+	}
+}
+
+/* A helper class for printing method declarations and definitions
+ * of a template class specialization.
+ *
+ * "instance" is the template class specialization for which methods
+ * are printed.
+ * "generator" is the templated C++ interface generator printing the classes.
+ */
+struct template_cpp_generator::class_printer :
+		public cpp_generator::class_printer {
+	class_printer(const specialization &instance,
+			const specialization_printer &instance_printer,
+			bool is_declaration);
+
+	void print_return_type(const Method &method, const Kind &kind)
+		const;
+	void print_method_template_arguments(const Signature &sig);
+	void print_method_header(const Method &method, const Signature &sig);
+	bool print_special_method(const Method &method,
+		const infix_map_map &special_methods);
+	void print_static_method(const Method &method);
+	void print_constructor(const Method &method);
+	bool is_return_kind(const Method &method, const Kind &return_kind);
+	void add_specialization(const Kind &kind);
+	bool print_matching_method(const Method &method, const Signature &sig,
+		const Kind &match_arg);
+	bool print_matching_method(const Method &method, const Signature &sig);
+	void print_matching_method(const Method &method,
+		const std::vector<Signature> &signatures);
+	void print_at_method(const Method &method);
+	bool print_special_member_method(const Method &method);
+	bool print_type_named_member_method(const Method &method);
+	bool print_member_method_with_name(const Method &method,
+		const std::string &name);
+	void print_member_method(const Method &method);
+	void print_any_method(const Method &method);
+	virtual void print_method(const Method &method) override;
+	virtual void print_method(const ConversionMethod &method) override;
+	virtual void print_method_sig(const Method &method,
+		const Signature &sig, bool deleted) = 0;
+	virtual bool want_descendent_overloads(const function_set &methods)
+		override;
+	void print_all_methods();
+
+	const specialization &instance;
+	template_cpp_generator &generator;
+};
+
+/* Construct a class_printer from the template class specialization
+ * for which methods are printed and
+ * the printer of the template class.
+ *
+ * The template class printer is only used to obtain the output stream and
+ * the templated C++ interface generator printing the classes.
+ */
+template_cpp_generator::class_printer::class_printer(
+		const specialization &instance,
+		const specialization_printer &instance_printer,
+		bool is_declaration) :
+	cpp_generator::class_printer(instance_printer.os,
+		instance.template_class.clazz, instance_printer.generator,
+		is_declaration),
+	instance(instance), generator(instance_printer.generator)
+{
+}
+
+/* An abstract template type printer, where the way of obtaining
+ * the argument kind is specified by the subclasses.
+ */
+struct template_cpp_type_printer : public cpp_type_printer {
+	template_cpp_type_printer() {}
+
+	std::string base(const std::string &type, const Kind &kind) const;
+	virtual Kind kind(int arg) const = 0;
+	virtual std::string qualified(int arg, const std::string &cpp_type)
+		const override;
+};
+
+/* Print a template type consisting of the type "type" and the kind "kind",
+ * including the "typed::" namespace specifier.
+ */
+std::string template_cpp_type_printer::base(const std::string &type,
+	const Kind &kind) const
+{
+	std::ostringstream ss;
+
+	ss << "typed::";
+	print_bare_template_type(ss, type, kind);
+	return ss.str();
+}
+
+/* Return the qualified form of the given C++ isl type name appearing
+ * in argument position "arg" (-1 for return type).
+ *
+ * isl::ctx is not templated, so if "cpp_type" is "ctx",
+ * then print a non-templated version.
+ * Otherwise, look up the kind of the argument and print
+ * the corresponding template type.
+ */
+std::string template_cpp_type_printer::qualified(int arg,
+	const std::string &cpp_type) const
+{
+	if (cpp_type == "ctx")
+		return cpp_type_printer::qualified(arg, cpp_type);
+
+	return base(cpp_type, kind(arg));
+}
+
+/* A template type printer for printing types with a fixed kind.
+ *
+ * "fixed_kind" is the fixed kind.
+ */
+struct template_cpp_kind_type_printer : public template_cpp_type_printer {
+	template_cpp_kind_type_printer(const Kind &kind) :
+		template_cpp_type_printer(), fixed_kind(kind) {}
+
+	virtual Kind kind(int arg) const override;
+
+	const Kind &fixed_kind;
+};
+
+/* Return the kind of the argument at position "arg",
+ * where position -1 refers to the return type.
+ *
+ * Always use the fixed kind.
+ */
+Kind template_cpp_kind_type_printer::kind(int arg) const
+{
+	return fixed_kind;
+}
+
+/* A template type printer for printing a method with a given signature.
+ *
+ * "sig" is the signature of the method being printed.
+ */
+struct template_cpp_arg_type_printer : public template_cpp_type_printer {
+	template_cpp_arg_type_printer(const Signature &sig) :
+		template_cpp_type_printer(), sig(sig) {}
+
+	virtual Kind kind(int arg) const override;
+
+	const Signature &sig;
+};
+
+/* Return the kind of the argument at position "arg",
+ * where position -1 refers to the return type.
+ *
+ * Look up the kind in the signature.
+ */
+Kind template_cpp_arg_type_printer::kind(int arg) const
+{
+	int n_args = sig.args.size();
+
+	if (arg < 0)
+		return sig.ret;
+	if (arg >= n_args)
+		generator::die("argument out of bounds");
+	return sig.args[arg];
+}
+
+/* A template type printer for printing a method with a given signature
+ * as part of a template class specialization of a given kind.
+ *
+ * "class_kind" is the template class specialization kind.
+ */
+struct template_method_type_printer : public template_cpp_arg_type_printer {
+	template_method_type_printer(const Signature &sig,
+			const Kind &class_kind) :
+		template_cpp_arg_type_printer(sig),
+		class_kind(class_kind) {}
+
+	virtual std::string class_type(const std::string &cpp_name)
+		const override;
+
+	const Kind &class_kind;
+};
+
+/* Print the class type "cpp_name".
+ *
+ * Print the templated version using the template class specialization kind.
+ */
+std::string template_method_type_printer::class_type(
+	const std::string &cpp_name) const
+{
+	return base(cpp_name, class_kind);
+}
+
+/* Print the templated return type of "method" of the kind "return_kind".
+ *
+ * Construct a type printer with "return_kind" as fixed kind and
+ * use it to print the return type.
+ */
+void template_cpp_generator::class_printer::print_return_type(
+	const Method &method, const Kind &return_kind) const
+{
+	template_cpp_kind_type_printer printer(return_kind);
+
+	os << printer.return_type(method);
+}
+
+/* Remove the initial "n" elements from "v".
+ */
+template <typename T>
+static void drop_initial(std::vector<T> &v, size_t n)
+{
+	v.erase(v.begin(), v.begin() + n);
+}
+
+/* If a method with signature "sig" requires additional template parameters
+ * compared to those of the class, then print a declaration for them.
+ * If this->declarations is set, then this will be part of a method declaration,
+ * requiring extra indentation.
+ *
+ * Construct the sequence of all required template parameters
+ * with those of the template class appearing first.
+ * If this sequence has any parameters not induced by the template class itself,
+ * then print a declaration for these extra parameters.
+ */
+void template_cpp_generator::class_printer::print_method_template_arguments(
+	const Signature &sig)
+{
+	std::vector<std::string> class_params, method_params;
+
+	class_params = instance.kind.params();
+	method_params = class_params;
+	combine(method_params, sig.params());
+
+	if (class_params.size() == method_params.size())
+		return;
+
+	drop_initial(method_params, class_params.size());
+
+	if (declarations)
+		os << "  ";
+	print_template(os, method_params);
+}
+
+/* Print the header for "method" with signature "sig".
+ *
+ * First print any additional template parameters that may be required and
+ * then print a regular method header, using a template type printer.
+ */
+void template_cpp_generator::class_printer::print_method_header(
+	const Method &method, const Signature &sig)
+{
+	template_method_type_printer type_printer(sig, instance.kind);
+
+	print_method_template_arguments(sig);
+	cpp_generator::class_printer::print_method_header(method,
+							type_printer);
+}
+
+/* Given a group of methods with the same name,
+ * should extra methods be added that take as arguments
+ * those types that can be converted to the original argument type
+ * through a unary constructor?
+ *
+ * Since type deduction does not consider implicit conversions,
+ * these extra methods should always be printed.
+ */
+bool template_cpp_generator::class_printer::want_descendent_overloads(
+	const function_set &methods)
+{
+	return true;
+}
+
+/* Print all constructors and methods that forward
+ * to the corresponding methods in the plain C++ interface class.
+ */
+void template_cpp_generator::class_printer::print_all_methods()
+{
+	print_constructors();
+	print_methods();
+}
+
+/* A helper class for printing method declarations
+ * of a template class specialization.
+ */
+struct template_cpp_generator::method_decl_printer :
+		public template_cpp_generator::class_printer {
+	method_decl_printer(const specialization &instance,
+			const struct specialization_printer &instance_printer) :
+		class_printer(instance, instance_printer, true) {}
+
+	virtual void print_method_sig(const Method &method,
+		const Signature &sig, bool deleted) override;
+	virtual void print_get_method(FunctionDecl *fd) override;
+};
+
+/* Print a declaration of the method "method" with signature "sig".
+ * Mark is "delete" if "deleted" is set.
+ */
+void template_cpp_generator::method_decl_printer::print_method_sig(
+	const Method &method, const Signature &sig, bool deleted)
+{
+	print_method_header(method, sig);
+	if (deleted)
+		os << " = delete";
+	os << ";\n";
+}
+
+/* Return the total number of arguments in the signature for "method",
+ * taking into account a possible callback argument.
+ *
+ * In particular, if the method has a callback argument,
+ * then the return kind of the callback appears at the position
+ * of the callback and the kinds of the arguments (except
+ * the user pointer argument) appear in the following positions.
+ */
+static int total_params(const Method &method)
+{
+	int n = method.num_params();
+
+	if (method.callback) {
+		auto callback_type = method.callback->getType();
+		auto callback = generator::extract_prototype(callback_type);
+
+		n += callback->getNumArgs() - 1;
+	}
+
+	return n;
+}
+
+/* Return a signature for "method" that matches "instance".
+ */
+static Signature instance_sig(const Method &method,
+	const specialization &instance)
+{
+	std::vector<Kind> args(total_params(method));
+
+	args[0] = instance.kind;
+	return { instance.kind, args };
+}
+
+/* Print a declaration for the "get" method "fd",
+ * using a name that includes the "get_" prefix.
+ *
+ * These methods are only included in the plain interface.
+ * Explicitly delete them from the templated interface.
+ */
+void template_cpp_generator::method_decl_printer::print_get_method(
+	FunctionDecl *fd)
+{
+	Method method(clazz, fd, clazz.base_method_name(fd));
+
+	print_method_sig(method, instance_sig(method, instance), true);
+}
+
+/* A helper class for printing method definitions
+ * of a template class specialization.
+ */
+struct template_cpp_generator::method_impl_printer :
+		public template_cpp_generator::class_printer {
+	method_impl_printer(const specialization &instance,
+			const struct specialization_printer &instance_printer) :
+		class_printer(instance, instance_printer, false) {}
+
+	void print_callback_method_body(const Method &method,
+		const Signature &sig);
+	void print_method_body(const Method &method, const Signature &sig);
+	void print_constructor_body(const Method &method, const Signature &sig);
+	virtual void print_method_sig(const Method &method,
+		const Signature &sig, bool deleted) override;
+	virtual void print_get_method(FunctionDecl *fd) override;
+};
+
+/* Print a definition of the constructor "method" with signature "sig".
+ *
+ * Simply pass all arguments to the constructor of the corresponding
+ * plain type.
+ */
+void template_cpp_generator::method_impl_printer::print_constructor_body(
+	const Method &method, const Signature &sig)
+{
+	const auto &base_name = instance.base_name();
+
+	os << "  : " << base_name;
+	method.print_cpp_arg_list(os, [&] (int i) {
+		os << method.fd->getParamDecl(i)->getName().str();
+	});
+	os << "\n";
+
+	os << "{\n";
+	os << "}\n";
+}
+
+/* Print the arguments of the callback function "callback" to "os",
+ * calling "print_arg" with the type and the name of the arguments,
+ * where the type is obtained from "type_printer" with argument positions
+ * shifted by "shift".
+ */
+static void print_callback_args(std::ostream &os,
+	const FunctionProtoType *callback, const cpp_type_printer &type_printer,
+	int shift,
+	const std::function<void(const std::string &type,
+		const std::string &name)> &print_arg)
+{
+	auto n_arg = callback->getNumArgs() - 1;
+
+	Method::print_arg_list(os, 0, n_arg, [&] (int i) {
+		auto type = callback->getArgType(i);
+		auto name = "arg" + std::to_string(i);
+		auto cpptype = type_printer.param(shift + i, type);
+
+		print_arg(cpptype, name);
+	});
+}
+
+/* Print a lambda for passing to the plain method corresponding to "method"
+ * with signature "sig".
+ *
+ * The method is assumed to have only the callback as argument,
+ * which means the arguments of the callback are shifted by 2
+ * with respect to the arguments of the signature
+ * (one for the position of the callback argument plus
+ * one for the return kind of the callback).
+ *
+ * The lambda takes arguments with plain isl types and
+ * calls the callback of "method" with templated arguments.
+ */
+static void print_callback_lambda(std::ostream &os, const Method &method,
+	const Signature &sig)
+{
+	auto callback_type = method.callback->getType();
+	auto callback_name = method.callback->getName().str();
+	auto callback = generator::extract_prototype(callback_type);
+
+	if (method.num_params() != 2)
+		generator::die("callback is assumed to be single argument");
+
+	os << "  auto lambda = [&] ";
+	print_callback_args(os, callback, cpp_type_printer(), 2,
+		[&] (const std::string &type, const std::string &name) {
+			os << type << " " << name;
+		});
+	os << " {\n";
+
+	os << "    return " << callback_name;
+	print_callback_args(os, callback, template_cpp_arg_type_printer(sig), 2,
+		[&] (const std::string &type, const std::string &name) {
+			os << type << "(" << name << ")";
+		});
+	os << ";\n";
+
+	os << "  };\n";
+}
+
+/* Print a definition of the member method "method", which is known
+ * to have a callback argument, with signature "sig".
+ *
+ * First print a lambda for passing to the corresponding plain method and
+ * calling the callback of "method" with templated arguments.
+ * Then call the plain method, replacing the original callback
+ * by the lambda.
+ *
+ * The return value is assumed to be isl_bool or isl_stat
+ * so that no conversion to a template type is required.
+ */
+void template_cpp_generator::method_impl_printer::print_callback_method_body(
+	const Method &method, const Signature &sig)
+{
+	const auto &base_name = instance.base_name();
+	auto return_type = method.fd->getReturnType();
+
+	if (!is_isl_bool(return_type) && !is_isl_stat(return_type))
+		die("only isl_bool and isl_stat return types are supported");
+
+	os << "{\n";
+
+	print_callback_lambda(os, method, sig);
+
+	os << "  return ";
+	os << base_name << "::" << method.name;
+	method.print_cpp_arg_list(os, [&] (int i) {
+		auto param = method.fd->getParamDecl(i);
+
+		if (param == method.callback)
+			os << "lambda";
+		else
+			os << param->getName().str();
+	});
+	os << ";\n";
+
+	os << "}\n";
+}
+
+/* Print a definition of the member or static method "method"
+ * with signature "sig".
+ *
+ * The body calls the corresponding method of the base class
+ * in the plain interface and
+ * then casts the result to the templated result type.
+ */
+void template_cpp_generator::method_impl_printer::print_method_body(
+	const Method &method, const Signature &sig)
+{
+	const auto &base_name = instance.base_name();
+
+	os << "{\n";
+	os << "  auto res = ";
+	os << base_name << "::" << method.name;
+	method.print_cpp_arg_list(os, [&] (int i) {
+		os << method.fd->getParamDecl(i)->getName().str();
+	});
+	os << ";\n";
+
+	os << "  return ";
+	print_return_type(method, sig.ret);
+	os << "(res);\n";
+	os << "}\n";
+}
+
+/* Print a definition of the method "method" with signature "sig",
+ * if "deleted" is not set.
+ *
+ * If "deleted" is set, then the corresponding declaration
+ * is marked "delete" and no definition needs to be printed.
+ *
+ * Otherwise print the method header, preceded by the template parameters,
+ * if needed.
+ * The body depends on whether the method is a constructor or
+ * takes a callback.
+ */
+void template_cpp_generator::method_impl_printer::print_method_sig(
+	const Method &method, const Signature &sig, bool deleted)
+{
+	if (deleted)
+		return;
+
+	os << "\n";
+	print_non_empty_template(os, instance.kind.params());
+	print_method_header(method, sig);
+	os << "\n";
+	if (method.kind == Method::Kind::constructor)
+		print_constructor_body(method, sig);
+	else if (method.callback)
+		print_callback_method_body(method, sig);
+	else
+		print_method_body(method, sig);
+}
+
+/* Print a definition for the "get" method "fd" in class "clazz",
+ * using a name that includes the "get_" prefix, to "os".
+ *
+ * The declarations of these methods are explicitly delete'd
+ * so no definition needs to be printed.
+ */
+void template_cpp_generator::method_impl_printer::print_get_method(
+	FunctionDecl *fd)
+{
+}
+
+/* Print a declaration or definition of the static method "method",
+ * if it has a signature specified by static_methods.
+ */
+void template_cpp_generator::class_printer::print_static_method(
+	const Method &method)
+{
+	print_special_method(method, static_methods);
+}
+
+/* Signatures for constructors of multi-expressions
+ * from a space and a list.
+ */
+static Signature from_list_set = { { Domain }, { { Domain }, { Anonymous } } };
+static Signature from_list_map =
+	{ { Domain, Range }, { { Domain, Range }, { Domain, Anonymous } } };
+
+/* Signatures for constructors from a string.
+ */
+static Signature params_from_str = { { }, { { Ctx }, { Str } } };
+static Signature set_from_str = { { Domain }, { { Ctx }, { Str } } };
+static Signature map_from_str = { { Domain, Range }, { { Ctx }, { Str } } };
+static std::vector<Signature> from_str =
+	{ params_from_str, set_from_str, map_from_str };
+
+/* Signature for a constructor from an integer.
+ */
+static Signature int_from_si = { { Anonymous }, { { Ctx }, { Integer } } };
+
+/* Signatures for constructors of lists from the initial number
+ * of elements.
+ */
+static Signature alloc_params = { { }, { { Ctx }, { Integer } } };
+static Signature alloc_set = { { Domain }, { { Ctx }, { Integer } } };
+static Signature alloc_map = { { Domain, Range }, { { Ctx }, { Integer } } };
+
+/* Signatures for constructors and methods named after some other class.
+ *
+ * Two forms of constructors are handled
+ * - conversion from another object
+ * - construction of a multi-expression from a space and a list
+ *
+ * Methods named after some other class also come in two forms
+ * - extraction of information such as the space or a list
+ * - construction of a multi-expression from a space and a list
+ *
+ * In both cases, the first form is a unary operation and
+ * the second has an extra argument with a kind that is equal
+ * to that of the first argument, except that the final tuple is anonymous.
+ */
+static std::vector<Signature> constructor_sig = {
+	un_params,
+	un_set,
+	un_map,
+	from_list_set,
+	from_list_map,
+};
+
+/* Signatures for constructors derived from methods
+ * with the given names that override the default signatures.
+ */
+static const std::unordered_map<std::string, std::vector<Signature>>
+special_constructors {
+	{ "alloc",		{ alloc_params, alloc_set, alloc_map } },
+	{ "int_from_si",	{ int_from_si } },
+	{ "read_from_str",	from_str },
+};
+
+/* Print a declaration or definition of the constructor "method".
+ */
+void template_cpp_generator::class_printer::print_constructor(
+	const Method &method)
+{
+	if (special_constructors.count(method.name) != 0) {
+		const auto &sigs = special_constructors.at(method.name);
+		return print_matching_method(method, sigs);
+	}
+	print_matching_method(method, constructor_sig);
+}
+
+/* Does this template class represent an anonymous function?
+ *
+ * If any specialization represents an anonymous function,
+ * then every specialization does, so simply check
+ * the first specialization.
+ */
+bool template_class::is_anon() const
+{
+	return class_tuples[0].is_anon();
+}
+
+/* Does this template class represent an anonymous value?
+ *
+ * That is, is there only a single specialization that moreover
+ * has a single, anonymous tuple?
+ */
+bool template_class::is_anon_set() const
+{
+	return class_tuples.size() == 1 && class_tuples[0].is_anon_set();
+}
+
+/* Update the substitution "sub" to map "general" to "specific"
+ * if "specific" is a special case of "general" consistent with "sub",
+ * given that "general" is not a pair and can be assigned "specific".
+ * Return true if successful.
+ * Otherwise, return false.
+ *
+ * Check whether "general" is already assigned something in "sub".
+ * If so, it must be assigned "specific".
+ * Otherwise, there is a conflict.
+ */
+static bool update_sub_base(Substitution &sub, const TupleKindPtr &general,
+	const TupleKindPtr &specific)
+{
+	auto name = general->name;
+
+	if (sub.count(name) != 0 && sub.at(name) != specific)
+		return false;
+	sub.emplace(name, specific);
+	return true;
+}
+
+/* Update the substitution "sub" to map "general" to "specific"
+ * if "specific" is a special case of "general" consistent with "sub".
+ * Return true if successful.
+ * Otherwise, return false.
+ *
+ * If "general" is a pair and "specific" is not,
+ * then "specific" cannot be a special case.
+ * If both are pairs, then update the substitution based
+ * on both sides.
+ * If "general" is Anonymous, then "specific" must be Anonymous as well.
+ * If "general" is Leaf, then "specific" cannot be a pair.
+ *
+ * Otherwise, assign "specific" to "general", if possible.
+ */
+static bool update_sub(Substitution &sub, const TupleKindPtr &general,
+	const TupleKindPtr &specific)
+{
+	if (general->left() && !specific->left())
+		return false;
+	if (general->left())
+		return update_sub(sub, general->left(), specific->left()) &&
+		    update_sub(sub, general->right(), specific->right());
+	if (general == Anonymous && specific != Anonymous)
+		return false;
+	if (general == Leaf && specific->left())
+		return false;
+
+	return update_sub_base(sub, general, specific);
+}
+
+/* Check if "specific" is a special case of "general" and,
+ * if so, return true along with a substitution
+ * that maps "general" to "specific".
+ * Otherwise return false.
+ *
+ * This can only happen if the number of tuple kinds is the same.
+ * If so, start with an empty substitution and update it
+ * for each pair of tuple kinds, checking that each update succeeds.
+ */
+static std::pair<bool, Substitution> specializer(const Kind &general,
+	const Kind &specific)
+{
+	Substitution specializer;
+
+	if (general.size() != specific.size())
+		return { false, Substitution() };
+
+	for (size_t i = 0; i < general.size(); ++i) {
+		auto general_tuple = general[i];
+
+		if (!update_sub(specializer, general[i], specific[i]))
+			return { false, Substitution() };
+	}
+
+	return { true, specializer };
+}
+
+/* Is "kind1" equivalent to "kind2"?
+ * That is, is each a special case of the other?
+ */
+static bool equivalent(const Kind &kind1, const Kind &kind2)
+{
+	return specializer(kind1, kind2).first &&
+	       specializer(kind2, kind1).first;
+}
+
+/* Add the specialization "kind" to the sequence of specializations,
+ * provided there is no equivalent specialization already in there.
+ */
+void template_class::add_specialization(const Kind &kind)
+{
+	for (const auto &special : class_tuples)
+		if (equivalent(special, kind))
+			return;
+	class_tuples.emplace_back(kind);
+}
+
+/* A type printer that prints the plain interface type,
+ * without namespace.
+ */
+struct plain_cpp_type_printer : public cpp_type_printer {
+	plain_cpp_type_printer() {}
+
+	virtual std::string qualified(int arg, const std::string &cpp_type)
+		const override;
+};
+
+/* Return the qualified form of the given C++ isl type name appearing
+ * in argument position "arg" (-1 for return type).
+ *
+ * For printing the plain type without namespace, no modifications
+ * are required.
+ */
+std::string plain_cpp_type_printer::qualified(int arg,
+	const std::string &cpp_type) const
+{
+	return cpp_type;
+}
+
+/* Return a string representation of the plain type "type".
+ *
+ * For the plain printer, the argument position is irrelevant,
+ * so simply pass in -1.
+ */
+static std::string plain_type(QualType type)
+{
+	return plain_cpp_type_printer().param(-1, type);
+}
+
+/* Return a string representation of the plain return type of "method".
+ */
+static std::string plain_return_type(const Method &method)
+{
+	return plain_type(method.fd->getReturnType());
+}
+
+/* Return that part of the signature "sig" that should match
+ * the template class specialization for the given method.
+ *
+ * In particular, if the method is a regular member method,
+ * then the instance should match the first argument.
+ * Otherwise, it should match the return kind.
+ */
+static const Kind &matching_kind(const Method &method, const Signature &sig)
+{
+	if (method.kind == Method::Kind::member_method)
+		return sig.args[0];
+	else
+		return sig.ret;
+}
+
+/* Is it possible for "template_class" to have the given kind?
+ *
+ * If the template class represents an anonymous function,
+ * then so must the given kind.
+ * There should also be specialization with the same number of tuple kinds.
+ */
+static bool has_kind(const template_class &template_class, const Kind &kind)
+{
+	if (template_class.is_anon() && !kind.is_anon())
+		return false;
+	for (const auto &class_tuple : template_class.class_tuples)
+		if (class_tuple.size() == kind.size())
+			return true;
+	return false;
+}
+
+/* Is "return_kind" a possible kind for the return type of "method"?
+ *
+ * If the return type is not a template class,
+ * then "return_kind" should not have any template parameters.
+ * Otherwise, "return_kind" should be a valid kind for the template class.
+ */
+bool template_cpp_generator::class_printer::is_return_kind(
+	const Method &method, const Kind &return_kind)
+{
+	const auto &template_classes = generator.template_classes;
+	auto return_type = plain_return_type(method);
+
+	if (template_classes.count(return_type) == 0)
+		return return_kind.params().size() == 0;
+	return has_kind(template_classes.at(return_type), return_kind);
+}
+
+/* Is "kind" a placeholder that can be assigned something else
+ * in a substitution?
+ *
+ * Anonymous can only be mapped to itself.  This is taken care of
+ * by assign().
+ * Leaf can only be assigned a placeholder, but there is no need
+ * to handle this specifically since Leaf can still be assigned
+ * to the placeholder.
+ */
+static bool assignable(const TupleKindPtr &kind)
+{
+	return kind != Anonymous && kind != Leaf;
+}
+
+/* Return a substitution that maps "kind1" to "kind2", if possible.
+ * Otherwise return an empty substitution.
+ *
+ * Check if "kind1" can be assigned anything or
+ * if "kind1" and "kind2" are identical.
+ * The latter case handles mapping Anonymous to itself.
+ */
+static Substitution assign(const TupleKindPtr &kind1, const TupleKindPtr &kind2)
+{
+	Substitution res;
+
+	if (assignable(kind1) || kind1 == kind2)
+		res.emplace(kind1->name, kind2);
+	return res;
+}
+
+/* Return a substitution that first applies "first" and then "second".
+ *
+ * The result consists of "second" and of "second" applied to "first".
+ */
+static Substitution compose(const Substitution &first,
+	const Substitution &second)
+{
+	Substitution res = second;
+
+	for (const auto &kvp : first)
+		res.emplace(kvp.first, apply(kvp.second, second));
+
+	return res;
+}
+
+static Substitution compute_unifier(const TupleKindPtr &kind1,
+	const TupleKindPtr &kind2);
+
+/* Try and extend "unifier" with a unifier for "kind1" and "kind2".
+ * Return the resulting unifier if successful.
+ * Otherwise, return an empty substitution.
+ *
+ * First apply "unifier" to "kind1" and "kind2".
+ * Then compute a unifier for the resulting tuple kinds and
+ * combine it with "unifier".
+ */
+static Substitution combine_unifiers(const TupleKindPtr &kind1,
+	const TupleKindPtr &kind2, const Substitution &unifier)
+{
+	auto k1 = apply(kind1, unifier);
+	auto k2 = apply(kind2, unifier);
+	auto u = compute_unifier(k1, k2);
+	if (u.size() == 0)
+		return Substitution();
+	return compose(unifier, u);
+}
+
+/* Try and compute a unifier of "kind1" and "kind2",
+ * i.e., a substitution that produces the same result when
+ * applied to both "kind1" and "kind2",
+ * for the case where both "kind1" and "kind2" are pairs.
+ * Return this unifier if it was found.
+ * Return an empty substitution if no unifier can be found.
+ *
+ * First compute a unifier for the left parts of the pairs and,
+ * if successful, combine it with a unifier for the right parts.
+ */
+static Substitution compute_pair_unifier(const TupleKindPtr &kind1,
+	const TupleKindPtr &kind2)
+{
+	auto unifier_left = compute_unifier(kind1->left(), kind2->left());
+	if (unifier_left.size() == 0)
+		return Substitution();
+	return combine_unifiers(kind1->right(), kind2->right(), unifier_left);
+}
+
+/* Try and compute a unifier of "kind1" and "kind2",
+ * i.e., a substitution that produces the same result when
+ * applied to both "kind1" and "kind2".
+ * Return this unifier if it was found.
+ * Return an empty substitution if no unifier can be found.
+ *
+ * If one of the tuple kinds is a pair then assign it
+ * to the other tuple kind, if possible.
+ * If neither is a pair, then try and assign one to the other.
+ * Otherwise, let compute_pair_unifier compute a unifier.
+ *
+ * Note that an assignment is added to the unifier even
+ * if "kind1" and "kind2" are identical.
+ * This ensures that a successful substitution is never empty.
+ */
+static Substitution compute_unifier(const TupleKindPtr &kind1,
+	const TupleKindPtr &kind2)
+{
+	if (kind1->left() && !kind2->left())
+		return assign(kind2, kind1);
+	if (!kind1->left() && kind2->left())
+		return assign(kind1, kind2);
+	if (!kind1->left() && !kind2->left()) {
+		if (assignable(kind1))
+			return assign(kind1, kind2);
+		else
+			return assign(kind2, kind1);
+	}
+
+	return compute_pair_unifier(kind1, kind2);
+}
+
+/* Try and compute a unifier of "kind1" and "kind2",
+ * i.e., a substitution that produces the same result when
+ * applied to both "kind1" and "kind2".
+ * Return this unifier if it was found.
+ * Return an empty substitution if no unifier can be found.
+ *
+ * Start with an empty substitution and compute a unifier for
+ * each pair of tuple kinds, combining the results.
+ * If no combined unifier can be found or
+ * if the numbers of tuple kinds are different, then return
+ * an empty substitution.
+ * This assumes that the number of tuples is greater than zero,
+ * as otherwise an empty substitution would be returned as well.
+ */
+static Substitution compute_unifier(const Kind &kind1, const Kind &kind2)
+{
+	Substitution unifier;
+
+	if (kind1.size() != kind2.size())
+		return Substitution();
+
+	for (size_t i = 0; i < kind1.size(); ++i)
+		unifier = combine_unifiers(kind1[i], kind2[i], unifier);
+
+	return unifier;
+}
+
+/* Try and construct a Kind that is a specialization of both "general" and
+ * "specific", where "specific" is known _not_ to be a specialization
+ * of "general" and not to contain any Leaf.
+ *
+ * First check whether "general" is a specialization of "specific".
+ * If so, simply return "general".
+ * Otherwise, rename the placeholders in the two kinds apart and
+ * try and compute a unifier.
+ * If this succeeds, then return the result of applying the unifier.
+ */
+static std::pair<bool, Kind> unify(const Kind &general, const Kind &specific)
+{
+	if (specializer(specific, general).first) {
+		return { true, general };
+	} else {
+		auto rename = param_renamer(specific.params(), "T");
+		auto renamed = specific.apply(rename);
+		auto unifier = compute_unifier(general, renamed);
+
+		if (unifier.size() == 0)
+			return { false, { } };
+
+		return { true, general.apply(unifier) };
+	}
+}
+
+/* Try and add a template class specialization corresponding to "kind".
+ * The new specialization needs to be a specialization of both
+ * the current specialization and "kind".
+ *
+ * The current template class specialization is known not to be a special case
+ * of "kind".
+ *
+ * Try and unify the two kinds and, if this succeeds, add the result
+ * to this list of template class specializations.
+ */
+void template_cpp_generator::class_printer::add_specialization(
+	const Kind &kind)
+{
+	auto maybe_unified = unify(kind, instance.kind);
+
+	if (!maybe_unified.first)
+		return;
+	instance.template_class.add_specialization(maybe_unified.second);
+}
+
+/* Print a declaration or definition of the method "method"
+ * if the template class specialization matches "match_arg".
+ * Return true if so.
+ * "sig" is the complete signature, of which "match_arg" refers
+ * to the first argument or the return type.
+ *
+ * Since "sig" may have parameters with the same names as
+ * those in instance.kind, rename them apart first.
+ *
+ * If the template class specialization is a special case of
+ * (the renamed) "match_arg"
+ * then apply the specializer to the complete (renamed) signature,
+ * check that the return kind is allowed and, if so,
+ * print the declaration or definition using the specialized signature.
+ *
+ * If the template class specialization is not a special case of "match_arg"
+ * then add a further specialization to the list of specializations
+ * of the template class.
+ */
+bool template_cpp_generator::class_printer::print_matching_method(
+	const Method &method, const Signature &sig, const Kind &match_arg)
+{
+	auto rename = shared_param_renamer(sig, instance.kind);
+	auto renamed_arg = match_arg.apply(rename);
+	auto maybe_specializer = specializer(renamed_arg, instance.kind);
+	if (maybe_specializer.first) {
+		const auto &specializer = maybe_specializer.second;
+		auto specialized_sig = sig.apply(rename).apply(specializer);
+		if (!is_return_kind(method, specialized_sig.ret))
+			return false;
+
+		print_method_sig(method, specialized_sig, false);
+	} else {
+		add_specialization(match_arg);
+	}
+	return maybe_specializer.first;
+}
+
+/* Is the first argument of "method" of type "isl_ctx *"?
+ */
+static bool first_arg_is_ctx(const Method &method)
+{
+	return generator::first_arg_is_isl_ctx(method.fd);
+}
+
+/* Is the first signature argument set to { Ctx }?
+ */
+static bool first_kind_is_ctx(const Signature &sig)
+{
+	return sig.args[0].size() > 0 && sig.args[0][0] == Ctx;
+}
+
+/* Print a declaration or definition of the member method "method"
+ * if it matches the signature "sig".
+ * Return true if so.
+ *
+ * First determine the part of the signature that needs to match
+ * the template class specialization and
+ * check that it has the same number of template arguments.
+ * Also check that the number of arguments of the signature
+ * matches that of the method.
+ * If there is at least one argument, then check that the first method argument
+ * is an isl_ctx if and only if the first signature argument is Ctx.
+ *
+ * If these tests succeed, proceed with the actual matching.
+ */
+bool template_cpp_generator::class_printer::print_matching_method(
+	const Method &method, const Signature &sig)
+{
+	auto match_arg = matching_kind(method, sig);
+	int n_args = sig.args.size();
+
+	if (match_arg.size() != instance.kind.size())
+		return false;
+	if (n_args != total_params(method))
+		return false;
+	if (n_args > 0 && first_arg_is_ctx(method) != first_kind_is_ctx(sig))
+		return false;
+
+	return print_matching_method(method, sig, match_arg);
+}
+
+/* Print a declaration or definition of the member method "method"
+ * for each matching signature in "signatures".
+ *
+ * If there is no matching signature in "signatures",
+ * then explicitly delete the method (using a signature based on
+ * the specialization) so that it is not inherited from the base class.
+ */
+void template_cpp_generator::class_printer::print_matching_method(
+	const Method &method, const std::vector<Signature> &signatures)
+{
+	auto any = false;
+
+	for (const auto &sig : signatures)
+		if (print_matching_method(method, sig))
+			any = true;
+
+	if (!any)
+		print_method_sig(method, instance_sig(method, instance), true);
+}
+
+/* Signatures for "at" methods applied to a multi-expression,
+ * which make the final tuple anonymous.
+ */
+static Signature select_set = { { Anonymous }, { { Domain }, { Integer } } };
+static Signature select_map =
+	{ { Domain, Anonymous }, { { Domain, Range }, { Integer } } };
+static std::vector<Signature> at_select = { select_set, select_map };
+
+/* Signatures for other "at" methods applied to a list,
+ * which do not modify the tuple kind.
+ */
+static Signature bin_set_int = { { Domain }, { { Domain }, { Integer } } };
+static Signature bin_map_int =
+	{ { Domain, Range }, { { Domain, Range }, { Integer } } };
+static std::vector<Signature> at_keep = { bin_set_int, bin_map_int };
+
+/* Print a declaration or definition of the "at" member method "method".
+ *
+ * There are two types of methods called "at".
+ * One type extracts an element from a multi-expression and
+ * the other extracts an element from a list.
+ *
+ * In the first case, the return type is an anonymous function
+ * while the object type is not.  In this case, the return kind
+ * should have a final Anonymous tuple.
+ * Otherwise, the return kind should be the same as the object kind.
+ */
+void template_cpp_generator::class_printer::print_at_method(
+	const Method &method)
+{
+	auto anon = instance.template_class.is_anon();
+	auto return_type = plain_return_type(method);
+	auto return_class = generator.template_classes.at(return_type);
+
+	if (!anon && return_class.is_anon())
+		return print_matching_method(method, at_select);
+	else
+		return print_matching_method(method, at_keep);
+}
+
+/* Does the string "s" contain "sub" as a substring?
+ */
+static bool contains(const std::string &s, const std::string &sub)
+{
+	return s.find(sub) != std::string::npos;
+}
+
+/* Print a declaration or definition of the member method "method",
+ * if it has a special signature in "special_methods".
+ * Return true if this is the case.
+ *
+ * Check if any special signatures are specified for this method and
+ * if the class name matches any of those with special signatures.
+ * If so, pick the one with the best match, i.e., the first match
+ * since the largest keys appear first.
+ */
+bool template_cpp_generator::class_printer::print_special_method(
+	const Method &method, const infix_map_map &special_methods)
+{
+	if (special_methods.count(method.name) == 0)
+		return false;
+
+	for (const auto &kvp : special_methods.at(method.name)) {
+		if (!contains(instance.template_class.class_name, kvp.first))
+			continue;
+		print_matching_method(method, kvp.second);
+		return true;
+	}
+
+	return false;
+}
+
+/* Print a declaration or definition of the member method "method",
+ * if it has a special signature specified by special_member_methods.
+ * Return true if this is the case.
+ */
+bool template_cpp_generator::class_printer::print_special_member_method(
+	const Method &method)
+{
+	return print_special_method(method, special_member_methods);
+}
+
+/* Print a declaration or definition of the member method "method",
+ * if it is named after a template class.  Return true if this is the case.
+ */
+bool template_cpp_generator::class_printer::print_type_named_member_method(
+	const Method &method)
+{
+	if (generator.template_classes.count(method.name) == 0)
+		return false;
+
+	print_matching_method(method, constructor_sig);
+
+	return true;
+}
+
+/* Print a declaration or definition of the member method "method"
+ * using a signature associated to method name "name", if there is any.
+ * Return true if this is the case.
+ */
+bool template_cpp_generator::class_printer::print_member_method_with_name(
+	const Method &method, const std::string &name)
+{
+	if (member_methods.count(name) == 0)
+		return false;
+
+	print_matching_method(method, member_methods.at(name));
+	return true;
+}
+
+/* If "sub" appears inside "str", then remove the first occurrence and
+ * return the result.  Otherwise, simply return "str".
+ */
+static std::string drop_occurrence(const std::string &str,
+	const std::string &sub)
+{
+	auto res = str;
+	auto pos = str.find(sub);
+
+	if (pos != std::string::npos)
+		res.erase(pos, sub.length());
+
+	return res;
+}
+
+/* If "sub" appears in "str" next to an underscore, then remove the combination.
+ * Otherwise, simply return "str".
+ */
+static std::string drop_underscore_occurrence(const std::string &str,
+	const std::string &sub)
+{
+	auto res = drop_occurrence(str, sub + "_");
+	if (res != str)
+		return res;
+	return drop_occurrence(res, std::string("_") + sub);
+}
+
+/* Return the name of "method", with the name of the return type,
+ * along with an underscore, removed, if this combination appears in the name.
+ * Otherwise, simply return the name.
+ */
+const std::string name_without_return(const Method &method)
+{
+	auto return_infix = plain_return_type(method);
+	return drop_underscore_occurrence(method.name, return_infix);
+}
+
+/* If this method has a callback, then remove the type
+ * of the first argument of the callback from the name of the method.
+ * Otherwise, simply return the name of the method.
+ */
+const std::string callback_name(const Method &method)
+{
+	if (!method.callback)
+		return method.name;
+
+	auto type = method.callback->getType();
+	auto callback = cpp_generator::extract_prototype(type);
+	auto arg_type = plain_type(callback->getArgType(0));
+	return generator::drop_suffix(method.name, "_" + arg_type);
+}
+
+/* Print a declaration or definition of the member method "method".
+ *
+ * If the method is called "at", then it requires special treatment.
+ * Otherwise, check if the signature is overridden for this class or
+ * if the method is named after some other type.
+ * Otherwise look for an appropriate signature using different variations
+ * of the method name.  First try the method name itself,
+ * then the method name with the return type removed and
+ * finally the method name with the callback argument type removed.
+ */
+void template_cpp_generator::class_printer::print_member_method(
+	const Method &method)
+{
+	if (method.name == "at")
+		return print_at_method(method);
+	if (print_special_member_method(method))
+		return;
+	if (print_type_named_member_method(method))
+		return;
+	if (print_member_method_with_name(method, method.name))
+		return;
+	if (print_member_method_with_name(method, name_without_return(method)))
+		return;
+	if (print_member_method_with_name(method, callback_name(method)))
+		return;
+}
+
+/* Print a declaration or definition of "method" based on its type.
+ */
+void template_cpp_generator::class_printer::print_any_method(
+	const Method &method)
+{
+	switch (method.kind) {
+	case Method::Kind::static_method:
+		print_static_method(method);
+		break;
+	case Method::Kind::constructor:
+		print_constructor(method);
+		break;
+	case Method::Kind::member_method:
+		print_member_method(method);
+		break;
+	}
+}
+
+/* Print a declaration or definition of "method".
+ *
+ * Mark the method as not requiring copies of the arguments.
+ */
+void template_cpp_generator::class_printer::print_method(const Method &method)
+{
+	print_any_method(NoCopyMethod(method));
+}
+
+/* Print a declaration or definition of "method".
+ *
+ * Note that a ConversionMethod is already marked
+ * as not requiring copies of the arguments.
+ */
+void template_cpp_generator::class_printer::print_method(
+	const ConversionMethod &method)
+{
+	print_any_method(method);
+}
+
+/* Helper class for printing the declarations for
+ * template class specializations.
+ */
+struct template_cpp_generator::class_decl_printer :
+	public specialization_printer
+{
+	class_decl_printer(std::ostream &os,
+				template_cpp_generator &generator) :
+		specialization_printer(os, generator) {}
+
+	void print_arg_subclass_constructor(const specialization &instance,
+		const std::vector<std::string> &params) const;
+	void print_super_constructor(const specialization &instance) const;
+	virtual void print_class(const specialization &instance) const override;
+};
+
+/* Print the declaration and definition of a constructor
+ * for the template class specialization "instance" taking
+ * an instance with more specialized template arguments,
+ * where "params" holds the template parameters of "instance".
+ * It is assumed that there is at least one template parameter as otherwise
+ * there are no template arguments to be specialized and
+ * no constructor needs to be printed.
+ *
+ * In particular, the constructor takes an object of the same instance where
+ * for each template parameter, the corresponding template argument
+ * of the input object is a subclass of the template argument
+ * of the constructed object.
+ *
+ * Pick fresh names for all template parameters and
+ * add a constructor with these fresh names as extra template parameters and
+ * a constraint requiring that each of them is a subclass
+ * of the corresponding class template parameter.
+ * The plain C++ interface object of the constructed object is initialized with
+ * the plain C++ interface object of the constructor argument.
+ */
+void template_cpp_generator::class_decl_printer::print_arg_subclass_constructor(
+	const specialization &instance,
+	const std::vector<std::string> &params) const
+{
+	const auto &class_name = instance.class_name();
+	auto rename = param_renamer(params, "Arg");
+	auto derived = instance.kind.apply(rename);
+
+	os << "  template ";
+	os << "<";
+	print_pure_template_args(os, derived.params());
+	os << ",\n";
+	os << "            typename std::enable_if<\n";
+	for (size_t i = 0; i < params.size(); ++i) {
+		if (i != 0)
+			os << " &&\n";
+		os << "              std::is_base_of<"
+		   << params[i] << ", "
+		   << rename.at(params[i])->params()[0] << ">{}";
+	}
+	os << ",\n";
+	os << "            bool>::type = true>";
+	os << "\n";
+	os << "  " << class_name << "(const ";
+	print_bare_template_type(os, class_name, derived);
+	os << " &obj) : " << instance.base_name() << "(obj) {}\n";
+}
+
+/* Print the declaration and definition of a constructor
+ * for the template class specialization "instance" taking
+ * an instance of the base class.
+ *
+ * If the instance kind is that of an anonymous set
+ * (i.e., it has a single tuple that is set to Anonymous),
+ * then allow the constructor to be called externally.
+ * This is mostly useful for being able to use isl::val and
+ * isl::typed::val<Anonymous> interchangeably and similarly for isl::id.
+ *
+ * If the instance is of any other kind, then make this constructor private
+ * to avoid objects of the plain interface being converted automatically.
+ * Also make sure that it does not apply to any type derived
+ * from the base class.  In particular, this makes sure it does
+ * not apply to any other specializations of this template class as
+ * otherwise any conflict in specializations would simply point
+ * to the private constructor.
+ *
+ * A factory method is added to be able to perform the conversion explicitly,
+ * with an explicit specification of the template arguments.
+ */
+void template_cpp_generator::class_decl_printer::print_super_constructor(
+	const specialization &instance) const
+{
+	bool hide = !instance.kind.is_anon_set();
+	const auto &base_name = instance.base_name();
+	const auto &arg_name = hide ? "base" : base_name;
+
+	if (hide) {
+		os << " private:\n";
+		os << "  template <typename base,\n";
+		os << "            typename std::enable_if<\n";
+		os << "              std::is_same<base, " << base_name
+		   << ">{}, bool>::type = true>\n";
+	}
+	os << "  " << instance.class_name()
+	   << "(const " << arg_name << " &obj) : "
+	   << base_name << "(obj) {}\n";
+	if (hide)
+		os << " public:\n";
+	os << "  static " << instance.class_name() << " from"
+	   << "(const " << base_name << " &obj) {\n";
+	os << "    return " << instance.class_name() << "(obj);\n";
+	os << "  }\n";
+}
+
+/* Print a "declaration" for the given template class specialization.
+ * In particular, print the class definition and the method declarations.
+ *
+ * The template parameters are the distinct variable names
+ * in the instance kind.
+ *
+ * Each instance of the template class derives from the corresponding
+ * plain C++ interface class.
+ *
+ * All (other) template classes are made friends of this template class
+ * to allow them to call the private constructor taking an object
+ * of the plain interface.
+ *
+ * Besides the constructors and methods that forward
+ * to the corresponding methods in the plain C++ interface class,
+ * some extra constructors are defined.
+ * The default zero-argument constructor is useful for declaring
+ * a variable that only gets assigned a value at a later stage.
+ * The constructor taking an instance with more specialized
+ * template arguments is useful for lifting the class hierarchy
+ * of the template arguments to the template class.
+ * The constructor taking an instance of the base class
+ * is useful for (explicitly) constructing a template type
+ * from a plain type.
+ */
+void template_cpp_generator::class_decl_printer::print_class(
+	const specialization &instance) const
+{
+	const auto &class_name = instance.class_name();
+	auto params = instance.kind.params();
+
+	os << "\n";
+
+	print_template(os, params);
+
+	os << "struct ";
+	print_bare_template_type(os, class_name, instance.kind);
+	os << " : public " << instance.base_name() << " {\n";
+
+	generator.print_friends(os);
+	os << "\n";
+
+	os << "  " << class_name << "() = default;\n";
+	if (params.size() != 0)
+		print_arg_subclass_constructor(instance, params);
+	print_super_constructor(instance);
+	method_decl_printer(instance, *this).print_all_methods();
+
+	os << "};\n";
+}
+
+/* Helper class for printing the definitions of template class specializations.
+ */
+struct template_cpp_generator::class_impl_printer :
+	public specialization_printer
+{
+	class_impl_printer(std::ostream &os,
+				template_cpp_generator &generator) :
+		specialization_printer(os, generator) {}
+
+	virtual void print_class(const specialization &instance) const override;
+};
+
+/* Print a definition for the given template class specialization.
+ *
+ * In particular, print definitions
+ * for the constructors and methods that forward
+ * to the corresponding methods in the plain C++ interface class.
+ * The extra constructors declared in the class definition
+ * are defined inline.
+ */
+void template_cpp_generator::class_impl_printer::print_class(
+	const specialization &instance) const
+{
+	method_impl_printer(instance, *this).print_all_methods();
+}
+
+/* Generate a templated cpp interface
+ * based on the extracted types and functions.
+ *
+ * First print forward declarations for all template classes,
+ * then the declarations of the classes, and at the end all
+ * method implementations.
+ */
+void template_cpp_generator::generate()
+{
+	ostream &os = std::cout;
+
+	os << "\n";
+
+	print_forward_declarations(os);
+	class_decl_printer(os, *this).print_classes();
+	class_impl_printer(os, *this).print_classes();
+}
diff --git a/lib/External/isl/interface/template_cpp.h b/lib/External/isl/interface/template_cpp.h
new file mode 100644
index 0000000..a141a48
--- /dev/null
+++ b/lib/External/isl/interface/template_cpp.h
@@ -0,0 +1,118 @@
+#ifndef ISL_INTERFACE_TEMPLATE_CPP_H
+#define ISL_INTERFACE_TEMPLATE_CPP_H
+
+#include <initializer_list>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+
+#include "cpp.h"
+
+struct Fixed;
+
+struct TupleKind;
+
+/* A shared pointer to a TupleKind.
+ */
+struct TupleKindPtr : public std::shared_ptr<const TupleKind> {
+  using Base = std::shared_ptr<const TupleKind>;
+  TupleKindPtr() = default;
+  TupleKindPtr(Fixed);
+  TupleKindPtr(Base base) : Base(base) {}
+  TupleKindPtr(const std::string &name);
+  TupleKindPtr(const TupleKindPtr &left, const TupleKindPtr &right);
+};
+
+/* A substitution mapping leaf tuple kind names to tuple kinds.
+ */
+using Substitution = std::unordered_map<std::string, TupleKindPtr>;
+
+/* A representation of a (possibly improper) tuple kind.
+ * That is, this also includes tuple kinds for types
+ * that do not have any tuples.
+ *
+ * The kind could be a name (the base case) or
+ * a (currently) unnamed nested pair of tuple kinds.
+ */
+struct TupleKind {
+	TupleKind(const std::string &name) : name(name) {}
+
+	virtual std::string to_string() const;
+	virtual std::vector<std::string> params() const;
+	virtual TupleKindPtr apply(const Substitution &subs,
+		const TupleKindPtr &self) const;
+	virtual TupleKindPtr left() const;
+	virtual TupleKindPtr right() const;
+
+	const std::string name;
+};
+
+/* A sequence of tuple kinds, representing a kind of objects.
+ */
+struct Kind : public std::vector<TupleKindPtr> {
+	Kind() {}
+	Kind(std::initializer_list<TupleKindPtr> list) : vector(list) {}
+
+	bool is_anon() const;
+	bool is_set() const;
+	bool is_anon_set() const;
+	std::vector<std::string> params() const;
+	Kind apply(const Substitution &subs) const;
+};
+
+/* A representation of a template class.
+ *
+ * "class_name" is the name of the template class.
+ * "super_name" is the (fully qualified) name of the corresponding
+ * plain C++ interface class, from which this template class derives.
+ * "clazz" describes the plain class.
+ *
+ * "class_tuples" contains the specializations.
+ * It is initialized with a predefined set of specializations,
+ * but may be extended during the generations of the specializations.
+ */
+struct template_class {
+	const std::string class_name;
+	const std::string super_name;
+	const isl_class &clazz;
+
+	std::vector<Kind> class_tuples;
+
+	bool is_anon() const;
+	bool is_anon_set() const;
+	void add_specialization(const Kind &kind);
+};
+
+/* A generator for templated C++ bindings.
+ *
+ * "template_classes" contains all generated template classes,
+ * keyed on their names.
+ */
+class template_cpp_generator : public cpp_generator {
+	struct class_printer;
+	struct method_decl_printer;
+	struct method_impl_printer;
+	struct class_decl_printer;
+	struct class_impl_printer;
+
+	void add_template_class(const isl_class &clazz, const std::string &name,
+		const std::vector<Kind> &base_kinds);
+public:
+	template_cpp_generator(clang::SourceManager &SM,
+		std::set<clang::RecordDecl *> &exported_types,
+		std::set<clang::FunctionDecl *> exported_functions,
+		std::set<clang::FunctionDecl *> functions);
+
+	virtual void generate() override;
+	void foreach_template_class(
+		const std::function<void(const template_class &)> &fn) const;
+	void print_forward_declarations(std::ostream &os);
+	void print_friends(std::ostream &os);
+
+	std::map<std::string, template_class> template_classes;
+};
+
+#endif
diff --git a/lib/External/isl/isl_aff.c b/lib/External/isl/isl_aff.c
index b840a52..40ca78d 100644
--- a/lib/External/isl/isl_aff.c
+++ b/lib/External/isl/isl_aff.c
@@ -5,6 +5,7 @@
  * Copyright 2014      INRIA Rocquencourt
  * Copyright 2016      Sven Verdoolaege
  * Copyright 2018,2020 Cerebras Systems
+ * Copyright 2021      Sven Verdoolaege
  *
  * Use of this software is governed by the MIT license
  *
@@ -37,21 +38,25 @@
 #define EL_BASE aff
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 #undef EL_BASE
 #define EL_BASE pw_aff
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 #undef EL_BASE
 #define EL_BASE pw_multi_aff
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 #undef EL_BASE
 #define EL_BASE union_pw_aff
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 #undef EL_BASE
 #define EL_BASE union_pw_multi_aff
@@ -159,6 +164,14 @@
 	return isl_aff_zero_on_domain(isl_local_space_from_space(space));
 }
 
+/* This function performs the same operation as isl_aff_zero_on_domain_space,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space)
+{
+	return isl_aff_zero_on_domain_space(space);
+}
+
 /* Return a piecewise affine expression defined on the specified domain
  * that is equal to zero.
  */
@@ -332,6 +345,16 @@
 	return NULL;
 }
 
+/* This function performs the same operation as
+ * isl_aff_param_on_domain_space_id,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_aff *isl_space_param_aff_on_domain_id(
+	__isl_take isl_space *space, __isl_take isl_id *id)
+{
+	return isl_aff_param_on_domain_space_id(space, id);
+}
+
 __isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
 {
 	if (!aff)
@@ -4063,6 +4086,15 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_multi_aff_domain_map,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
+	__isl_take isl_space *space)
+{
+	return isl_multi_aff_domain_map(space);
+}
+
 /* Given a map space, return an isl_multi_aff that maps a wrapped copy
  * of the space to its range.
  */
@@ -4107,6 +4139,15 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_multi_aff_range_map,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_multi_aff *isl_space_range_map_multi_aff(
+	__isl_take isl_space *space)
+{
+	return isl_multi_aff_range_map(space);
+}
+
 /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
  * of the space to its domain.
  */
@@ -4116,6 +4157,15 @@
 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_domain_map(space));
 }
 
+/* This function performs the same operation as isl_pw_multi_aff_domain_map,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff(
+	__isl_take isl_space *space)
+{
+	return isl_pw_multi_aff_domain_map(space);
+}
+
 /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
  * of the space to its range.
  */
@@ -4125,6 +4175,15 @@
 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
 }
 
+/* This function performs the same operation as isl_pw_multi_aff_range_map,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff(
+	__isl_take isl_space *space)
+{
+	return isl_pw_multi_aff_range_map(space);
+}
+
 /* Given the space of a set and a range of set dimensions,
  * construct an isl_multi_aff that projects out those dimensions.
  */
@@ -4198,6 +4257,15 @@
 	return isl_pw_multi_aff_from_multi_aff(ma);
 }
 
+/* This function performs the same operation as isl_pw_multi_aff_from_multi_aff,
+ * but is considered as a function on an isl_multi_aff when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff(
+	__isl_take isl_multi_aff *ma)
+{
+	return isl_pw_multi_aff_from_multi_aff(ma);
+}
+
 /* Create a piecewise multi-affine expression in the given space that maps each
  * input dimension to the corresponding output dimension.
  */
@@ -4219,6 +4287,16 @@
 	return isl_pw_multi_aff_from_multi_aff(ma);
 }
 
+/* This function performs the same operation as
+ * isl_pw_multi_aff_identity_on_domain_space,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain(
+	__isl_take isl_space *space)
+{
+	return isl_pw_multi_aff_identity_on_domain_space(space);
+}
+
 /* Exploit the equalities in "eq" to simplify the affine expressions.
  */
 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
@@ -4444,6 +4522,7 @@
 #include <isl_pw_move_dims_templ.c>
 #include <isl_pw_neg_templ.c>
 #include <isl_pw_pullback_templ.c>
+#include <isl_pw_range_tuple_id_templ.c>
 #include <isl_pw_union_opt.c>
 
 #undef BASE
@@ -5057,7 +5136,7 @@
  *
  *	-e(...) + c2 + m x >= 0
  *
- * where m > 1 and e only depends on parameters and input dimemnsions?
+ * where m > 1 and e only depends on parameters and input dimensions?
  *
  * "offset" is the offset of the output dimensions
  * "pos" is the position of output dimension x.
@@ -5092,7 +5171,7 @@
  *
  *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
  *
- * where m > 1 and e only depends on parameters and input dimemnsions,
+ * where m > 1 and e only depends on parameters and input dimensions,
  * and such that
  *
  *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
@@ -5459,11 +5538,27 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_pw_multi_aff_from_map,
+ * but is considered as a function on an isl_map when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map)
+{
+	return isl_pw_multi_aff_from_map(map);
+}
+
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
 {
 	return isl_pw_multi_aff_from_map(set);
 }
 
+/* This function performs the same operation as isl_pw_multi_aff_from_set,
+ * but is considered as a function on an isl_set when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set)
+{
+	return isl_pw_multi_aff_from_set(set);
+}
+
 /* Convert "map" into an isl_pw_multi_aff (if possible) and
  * add it to *user.
  */
@@ -5512,6 +5607,16 @@
 	return upma;
 }
 
+/* This function performs the same operation as
+ * isl_union_pw_multi_aff_from_union_map,
+ * but is considered as a function on an isl_union_map when exported.
+ */
+__isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff(
+	__isl_take isl_union_map *umap)
+{
+	return isl_union_pw_multi_aff_from_union_map(umap);
+}
+
 /* Try and create an isl_union_pw_multi_aff that is equivalent
  * to the given isl_union_set.
  * The isl_union_set is required to be a singleton in each space.
@@ -5624,7 +5729,7 @@
 	return maff;
 }
 
-/* Plug in "subs" for dimension "type", "pos" of "pma".
+/* Plug in "subs" for input dimension "pos" of "pma".
  *
  * pma is of the form
  *
@@ -5643,7 +5748,7 @@
  * and this contribution should simply be discarded.
  */
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
-	__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_pw_multi_aff *pma, unsigned pos,
 	__isl_keep isl_pw_aff *subs)
 {
 	int i, j, n;
@@ -5665,7 +5770,7 @@
 					isl_set_copy(pma->p[i].set),
 					isl_set_copy(subs->p[j].set));
 			common = isl_set_substitute(common,
-					type, pos, subs->p[j].aff);
+					pos, subs->p[j].aff);
 			empty = isl_set_plain_is_empty(common);
 			if (empty < 0 || empty) {
 				isl_set_free(common);
@@ -5676,7 +5781,7 @@
 
 			res_ij = isl_multi_aff_substitute(
 					isl_multi_aff_copy(pma->p[i].maff),
-					type, pos, subs->p[j].aff);
+					isl_dim_in, pos, subs->p[j].aff);
 
 			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
 		}
@@ -6076,7 +6181,7 @@
 
 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
  */
-__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
+__isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
 	__isl_keep isl_pw_multi_aff *pma, int pos)
 {
 	int i;
@@ -6106,6 +6211,14 @@
 	return pa;
 }
 
+/* This is an alternative name for the function above.
+ */
+__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
+	__isl_keep isl_pw_multi_aff *pma, int pos)
+{
+	return isl_pw_multi_aff_get_at(pma, pos);
+}
+
 /* Return an isl_pw_multi_aff with the given "set" as domain and
  * an unnamed zero-dimensional range.
  */
@@ -6500,6 +6613,37 @@
 #include <isl_multi_zero_templ.c>
 #include <isl_multi_unbind_params_templ.c>
 
+/* Is every element of "mpa" defined over a single universe domain?
+ */
+isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa)
+{
+	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_isa_aff);
+}
+
+/* Given that every element of "mpa" is defined over a single universe domain,
+ * return the corresponding base expressions.
+ */
+__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
+	__isl_take isl_multi_pw_aff *mpa)
+{
+	int i;
+	isl_size n;
+	isl_multi_aff *ma;
+
+	n = isl_multi_pw_aff_size(mpa);
+	if (n < 0)
+		mpa = isl_multi_pw_aff_free(mpa);
+	ma = isl_multi_aff_alloc(isl_multi_pw_aff_get_space(mpa));
+	for (i = 0; i < n; ++i) {
+		isl_aff *aff;
+
+		aff = isl_pw_aff_as_aff(isl_multi_pw_aff_get_at(mpa, i));
+		ma = isl_multi_aff_set_aff(ma, i, aff);
+	}
+	isl_multi_pw_aff_free(mpa);
+	return ma;
+}
+
 /* If "mpa" has an explicit domain, then intersect the domain of "map"
  * with this explicit domain.
  */
@@ -6809,6 +6953,15 @@
 	return mpa;
 }
 
+/* This function performs the same operation as isl_multi_pw_aff_from_multi_aff,
+ * but is considered as a function on an isl_multi_aff when exported.
+ */
+__isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff(
+	__isl_take isl_multi_aff *ma)
+{
+	return isl_multi_pw_aff_from_multi_aff(ma);
+}
+
 /* Construct and return a multi piecewise affine expression
  * that is equal to the given piecewise multi affine expression.
  *
@@ -6847,6 +7000,16 @@
 	return mpa;
 }
 
+/* This function performs the same operation as
+ * isl_multi_pw_aff_from_pw_multi_aff,
+ * but is considered as a function on an isl_pw_multi_aff when exported.
+ */
+__isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff(
+	__isl_take isl_pw_multi_aff *pma)
+{
+	return isl_multi_pw_aff_from_pw_multi_aff(pma);
+}
+
 /* Do "pa1" and "pa2" represent the same function?
  *
  * We first check if they are obviously equal.
@@ -7649,7 +7812,7 @@
 /* Return a multi affine expression that is equal to "mv" on domain
  * space "space".
  */
-__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
+__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space(
 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
 {
 	int i;
@@ -7686,6 +7849,24 @@
 	return NULL;
 }
 
+/* This is an alternative name for the function above.
+ */
+__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
+	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
+{
+	return isl_multi_aff_multi_val_on_domain_space(space, mv);
+}
+
+/* This function performs the same operation as
+ * isl_multi_aff_multi_val_on_domain_space,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val(
+	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
+{
+	return isl_multi_aff_multi_val_on_domain_space(space, mv);
+}
+
 /* Return a piecewise multi-affine expression
  * that is equal to "mv" on "domain".
  */
@@ -7701,6 +7882,16 @@
 	return isl_pw_multi_aff_alloc(domain, ma);
 }
 
+/* This function performs the same operation as
+ * isl_pw_multi_aff_multi_val_on_domain,
+ * but is considered as a function on an isl_set when exported.
+ */
+__isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val(
+	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
+{
+	return isl_pw_multi_aff_multi_val_on_domain(domain, mv);
+}
+
 /* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
  * mv is the value that should be attained on each domain set
  * res collects the results
@@ -8510,6 +8701,7 @@
 #include <isl_multi_nan_templ.c>
 #include <isl_multi_tuple_id_templ.c>
 #include <isl_multi_union_add_templ.c>
+#include <isl_multi_zero_space_templ.c>
 
 /* Does "mupa" have a non-trivial explicit domain?
  *
@@ -8585,6 +8777,16 @@
 	return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
 }
 
+/* This function performs the same operation as
+ * isl_multi_union_pw_aff_from_multi_aff, but is considered as a function on an
+ * isl_multi_aff when exported.
+ */
+__isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff(
+        __isl_take isl_multi_aff *ma)
+{
+        return isl_multi_union_pw_aff_from_multi_aff(ma);
+}
+
 /* Construct and return a multi union piecewise affine expression
  * that is equal to the given multi piecewise affine expression.
  */
@@ -8712,6 +8914,17 @@
 	return NULL;
 }
 
+/* This function performs the same operation as
+ * isl_multi_union_pw_aff_from_union_pw_multi_aff,
+ * but is considered as a function on an isl_union_pw_multi_aff when exported.
+ */
+__isl_give isl_multi_union_pw_aff *
+isl_union_pw_multi_aff_as_multi_union_pw_aff(
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
+}
+
 /* Try and create an isl_multi_union_pw_aff that is equivalent
  * to the given isl_union_map.
  * The isl_union_map is required to be single-valued in each space.
@@ -8727,6 +8940,16 @@
 	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
 }
 
+/* This function performs the same operation as
+ * isl_multi_union_pw_aff_from_union_map,
+ * but is considered as a function on an isl_union_map when exported.
+ */
+__isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff(
+	__isl_take isl_union_map *umap)
+{
+	return isl_multi_union_pw_aff_from_union_map(umap);
+}
+
 /* Return a multiple union piecewise affine expression
  * that is equal to "mv" on "domain", assuming "domain" and "mv"
  * have been aligned.
diff --git a/lib/External/isl/isl_aff_map.c b/lib/External/isl/isl_aff_map.c
index 29366f5..f661b82 100644
--- a/lib/External/isl/isl_aff_map.c
+++ b/lib/External/isl/isl_aff_map.c
@@ -228,6 +228,14 @@
 	return isl_map_from_multi_aff_internal(ma);
 }
 
+/* This function performs the same operation as isl_map_from_multi_aff,
+ * but is considered as a function on an isl_multi_aff when exported.
+ */
+__isl_give isl_map *isl_multi_aff_as_map(__isl_take isl_multi_aff *ma)
+{
+	return isl_map_from_multi_aff(ma);
+}
+
 /* Construct a set mapping the parameter domain the multi-affine expression
  * to its space, with each dimension in the space equated to the
  * corresponding affine expression.
@@ -239,6 +247,14 @@
 	return isl_map_from_multi_aff_internal(ma);
 }
 
+/* This function performs the same operation as isl_set_from_multi_aff,
+ * but is considered as a function on an isl_multi_aff when exported.
+ */
+__isl_give isl_set *isl_multi_aff_as_set(__isl_take isl_multi_aff *ma)
+{
+	return isl_set_from_multi_aff(ma);
+}
+
 /* Construct a basic map mapping a domain in the given space to
  * to an n-dimensional range, with n the number of elements in the list,
  * where each coordinate in the range is prescribed by the
@@ -315,6 +331,14 @@
 	return isl_map_from_pw_aff_internal(pwaff);
 }
 
+/* This function performs the same operation as isl_map_from_pw_aff,
+ * but is considered as a function on an isl_pw_aff when exported.
+ */
+__isl_give isl_map *isl_pw_aff_as_map(__isl_take isl_pw_aff *pa)
+{
+	return isl_map_from_pw_aff(pa);
+}
+
 /* Construct a one-dimensional set with as parameter domain
  * the domain of pwaff and the single set dimension
  * corresponding to the affine expressions.
@@ -376,6 +400,14 @@
 	return isl_map_from_pw_multi_aff_internal(pma);
 }
 
+/* This function performs the same operation as isl_map_from_pw_multi_aff,
+ * but is considered as a function on an isl_pw_multi_aff when exported.
+ */
+__isl_give isl_map *isl_pw_multi_aff_as_map(__isl_take isl_pw_multi_aff *pma)
+{
+	return isl_map_from_pw_multi_aff(pma);
+}
+
 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
 {
 	if (check_input_is_set(isl_pw_multi_aff_peek_space(pma)) < 0)
@@ -383,6 +415,14 @@
 	return set_from_map(isl_map_from_pw_multi_aff_internal(pma));
 }
 
+/* This function performs the same operation as isl_set_from_pw_multi_aff,
+ * but is considered as a function on an isl_pw_multi_aff when exported.
+ */
+__isl_give isl_set *isl_pw_multi_aff_as_set(__isl_take isl_pw_multi_aff *pma)
+{
+	return isl_set_from_pw_multi_aff(pma);
+}
+
 /* Construct a set or map mapping the shared (parameter) domain
  * of the piecewise affine expressions to the range of "mpa"
  * with each dimension in the range equated to the
@@ -438,6 +478,14 @@
 	return map_from_multi_pw_aff(mpa);
 }
 
+/* This function performs the same operation as isl_map_from_multi_pw_aff,
+ * but is considered as a function on an isl_multi_pw_aff when exported.
+ */
+__isl_give isl_map *isl_multi_pw_aff_as_map(__isl_take isl_multi_pw_aff *mpa)
+{
+	return isl_map_from_multi_pw_aff(mpa);
+}
+
 /* Construct a set mapping the shared parameter domain
  * of the piecewise affine expressions to the space of "mpa"
  * with each dimension in the range equated to the
@@ -450,6 +498,14 @@
 	return set_from_map(map_from_multi_pw_aff(mpa));
 }
 
+/* This function performs the same operation as isl_set_from_multi_pw_aff,
+ * but is considered as a function on an isl_multi_pw_aff when exported.
+ */
+__isl_give isl_set *isl_multi_pw_aff_as_set(__isl_take isl_multi_pw_aff *mpa)
+{
+	return isl_set_from_multi_pw_aff(mpa);
+}
+
 /* Convert "pa" to an isl_map and add it to *umap.
  */
 static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user)
@@ -528,3 +584,13 @@
 	isl_union_map_free(umap);
 	return NULL;
 }
+
+/* This function performs the same operation as
+ * isl_union_map_from_union_pw_multi_aff,
+ * but is considered as a function on an isl_union_pw_multi_aff when exported.
+ */
+__isl_give isl_union_map *isl_union_pw_multi_aff_as_union_map(
+	__isl_take isl_union_pw_multi_aff *upma)
+{
+	return isl_union_map_from_union_pw_multi_aff(upma);
+}
diff --git a/lib/External/isl/isl_aff_private.h b/lib/External/isl/isl_aff_private.h
index 8c94f04..473add3 100644
--- a/lib/External/isl/isl_aff_private.h
+++ b/lib/External/isl/isl_aff_private.h
@@ -7,6 +7,7 @@
 #include <isl/local_space.h>
 #include <isl_int.h>
 #include <isl_reordering.h>
+#include <isl/stream.h>
 
 /* ls represents the domain space.
  *
@@ -101,6 +102,8 @@
 __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
 	__isl_take isl_mat *div, int *exp);
 
+__isl_give isl_aff *isl_stream_read_aff(__isl_keep isl_stream *s);
+
 __isl_give isl_pw_aff *isl_pw_aff_alloc_size(__isl_take isl_space *space,
 	int n);
 __isl_give isl_pw_aff *isl_pw_aff_reset_space(__isl_take isl_pw_aff *pwaff,
@@ -126,6 +129,8 @@
 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
 	isl_int f);
 
+__isl_give isl_pw_aff *isl_stream_read_pw_aff(__isl_keep isl_stream *s);
+
 isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff,
 	__isl_keep isl_space *space);
 isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
@@ -176,9 +181,15 @@
 __isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
 	__isl_take isl_basic_set *eq);
 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
-	__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
+	__isl_take isl_pw_multi_aff *pma, unsigned pos,
 	__isl_keep isl_pw_aff *subs);
 
+__isl_give isl_pw_multi_aff *isl_stream_read_pw_multi_aff(
+	__isl_keep isl_stream *s);
+
+__isl_give isl_union_pw_aff *isl_stream_read_union_pw_aff(
+	__isl_keep isl_stream *s);
+
 isl_stat isl_pw_aff_check_named_params(__isl_keep isl_pw_aff *pa);
 isl_stat isl_multi_aff_check_named_params(__isl_keep isl_multi_aff *ma);
 isl_stat isl_pw_multi_aff_check_named_params(__isl_keep isl_pw_multi_aff *pma);
diff --git a/lib/External/isl/isl_ast_build.c b/lib/External/isl/isl_ast_build.c
index c62f47c..a0776e8 100644
--- a/lib/External/isl/isl_ast_build.c
+++ b/lib/External/isl/isl_ast_build.c
@@ -648,9 +648,9 @@
 /* Return the position of the dimension in build->domain for which
  * an AST node is currently being generated.
  */
-int isl_ast_build_get_depth(__isl_keep isl_ast_build *build)
+isl_size isl_ast_build_get_depth(__isl_keep isl_ast_build *build)
 {
-	return build ? build->depth : -1;
+	return build ? build->depth : isl_size_error;
 }
 
 /* Prepare for generating code for the next level.
@@ -1373,14 +1373,14 @@
 {
 	isl_space *space;
 	isl_multi_aff *ma;
-	int pos;
+	isl_size pos;
 	isl_aff *aff, *offset;
 	isl_val *stride;
 
-	if (!build)
+	pos = isl_ast_build_get_depth(build);
+	if (pos < 0)
 		return NULL;
 
-	pos = isl_ast_build_get_depth(build);
 	space = isl_ast_build_get_space(build, 1);
 	space = isl_space_map_from_set(space);
 	ma = isl_multi_aff_identity(space);
@@ -1438,16 +1438,16 @@
 __isl_give isl_ast_build *isl_ast_build_detect_strides(
 	__isl_take isl_ast_build *build, __isl_take isl_set *set)
 {
-	int pos;
+	isl_size pos;
 	isl_bool no_stride;
 	isl_val *stride;
 	isl_aff *offset;
 	isl_stride_info *si;
 
-	if (!build)
+	pos = isl_ast_build_get_depth(build);
+	if (pos < 0)
 		goto error;
 
-	pos = isl_ast_build_get_depth(build);
 	si = isl_set_get_stride_info(set, pos);
 	stride = isl_stride_info_get_stride(si);
 	offset = isl_stride_info_get_offset(si);
@@ -1949,7 +1949,7 @@
  *
  *	f + s a
  *
- * with a an integer, return s through *stride.
+ * with a an integer, return s.
  */
 __isl_give isl_val *isl_ast_build_get_stride(__isl_keep isl_ast_build *build,
 	int pos)
diff --git a/lib/External/isl/isl_ast_build_private.h b/lib/External/isl/isl_ast_build_private.h
index 9767679..1128e63 100644
--- a/lib/External/isl/isl_ast_build_private.h
+++ b/lib/External/isl/isl_ast_build_private.h
@@ -203,7 +203,7 @@
 	__isl_take isl_ast_build *build);
 __isl_give isl_ast_build *isl_ast_build_increase_depth(
 	__isl_take isl_ast_build *build);
-int isl_ast_build_get_depth(__isl_keep isl_ast_build *build);
+isl_size isl_ast_build_get_depth(__isl_keep isl_ast_build *build);
 isl_size isl_ast_build_dim(__isl_keep isl_ast_build *build,
 	enum isl_dim_type type);
 __isl_give isl_space *isl_ast_build_get_space(
diff --git a/lib/External/isl/isl_ast_codegen.c b/lib/External/isl/isl_ast_codegen.c
index 7f891a0..d337c4e 100644
--- a/lib/External/isl/isl_ast_codegen.c
+++ b/lib/External/isl/isl_ast_codegen.c
@@ -743,12 +743,15 @@
 	int degenerate, __isl_keep isl_basic_set *bounds,
 	__isl_keep isl_ast_build *build)
 {
-	int depth, has_stride;
+	isl_size depth;
+	isl_bool has_stride;
 	isl_space *space;
 	isl_set *dom, *set;
 
 	depth = isl_ast_build_get_depth(build);
 	has_stride = isl_ast_build_has_stride(build, depth);
+	if (depth < 0 || has_stride < 0)
+		return isl_set_free(guard);
 	if (!has_stride && !degenerate)
 		return guard;
 
@@ -783,7 +786,7 @@
  *
  * We set the initialization part of the for loop to the single
  * value attained by the current dimension.
- * The increment and condition are not strictly needed as the are known
+ * The increment and condition are not strictly needed as they are known
  * to be "1" and "iterator <= value" respectively.
  */
 static __isl_give isl_ast_graft *refine_degenerate(
@@ -1060,14 +1063,14 @@
  */
 static __isl_give isl_ast_expr *for_inc(__isl_keep isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	isl_val *v;
 	isl_ctx *ctx;
 
-	if (!build)
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
 		return NULL;
 	ctx = isl_ast_build_get_ctx(build);
-	depth = isl_ast_build_get_depth(build);
 
 	if (!isl_ast_build_has_stride(build, depth))
 		return isl_ast_expr_alloc_int_si(ctx, 1);
@@ -1178,7 +1181,7 @@
 	__isl_take isl_constraint_list *c_upper,
 	__isl_keep isl_set *domain, __isl_keep isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	isl_ctx *ctx;
 	isl_pw_aff_list *lower;
 	int use_list;
@@ -1186,10 +1189,10 @@
 	isl_pw_aff_list *upper_list = NULL;
 	isl_size n_lower, n_upper;
 
-	if (!graft || !c_lower || !c_upper || !build)
+	depth = isl_ast_build_get_depth(build);
+	if (!graft || !c_lower || !c_upper || depth < 0)
 		goto error;
 
-	depth = isl_ast_build_get_depth(build);
 	ctx = isl_ast_graft_get_ctx(graft);
 
 	n_lower = isl_constraint_list_n_constraint(c_lower);
@@ -1284,13 +1287,17 @@
 	__isl_keep isl_set *domain, __isl_keep isl_ast_build *build)
 {
 	struct isl_ast_count_constraints_data data;
+	isl_size depth;
 	isl_constraint_list *lower;
 	isl_constraint_list *upper;
 
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		list = isl_constraint_list_free(list);
 	if (!list)
 		return isl_ast_graft_free(graft);
 
-	data.pos = isl_ast_build_get_depth(build);
+	data.pos = depth;
 
 	list = isl_constraint_list_sort(list, &cmp_constraint, &data.pos);
 	if (!list)
@@ -1345,14 +1352,14 @@
 static __isl_give isl_ast_node *create_for(__isl_keep isl_ast_build *build,
 	int degenerate)
 {
-	int depth;
+	isl_size depth;
 	isl_id *id;
 	isl_ast_node *node;
 
-	if (!build)
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
 		return NULL;
 
-	depth = isl_ast_build_get_depth(build);
 	id = isl_ast_build_get_iterator_id(build, depth);
 	node = isl_ast_node_alloc_for(id);
 	if (degenerate)
@@ -1475,7 +1482,7 @@
 	__isl_take isl_basic_set *bounds, __isl_take isl_set *domain,
 	__isl_take isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	int degenerate;
 	isl_bool eliminated;
 	isl_size n;
@@ -1495,6 +1502,8 @@
 	build = isl_ast_build_set_executed(build, isl_union_map_copy(executed));
 
 	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		build = isl_ast_build_free(build);
 	sub_build = isl_ast_build_copy(build);
 	bounds = isl_basic_set_remove_redundancies(bounds);
 	bounds = isl_ast_build_specialize_basic_set(sub_build, bounds);
@@ -1695,6 +1704,7 @@
 	__isl_take isl_ast_build *build)
 {
 	struct isl_check_scaled_data data;
+	isl_size depth;
 	isl_ctx *ctx;
 	isl_aff *offset;
 	isl_val *d;
@@ -1703,7 +1713,10 @@
 	if (!isl_options_get_ast_build_scale_strides(ctx))
 		return create_node_scaled(executed, bounds, domain, build);
 
-	data.depth = isl_ast_build_get_depth(build);
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		build = isl_ast_build_free(build);
+	data.depth = depth;
 	if (!isl_ast_build_has_stride(build, data.depth))
 		return create_node_scaled(executed, bounds, domain, build);
 
@@ -1986,7 +1999,8 @@
 static isl_stat add_nodes(__isl_take isl_basic_set_list *scc, void *user)
 {
 	struct isl_add_nodes_data *data = user;
-	int i, depth;
+	int i;
+	isl_size depth;
 	isl_size n;
 	isl_basic_set *bset, *first;
 	isl_basic_set_list *list;
@@ -2006,6 +2020,8 @@
 	}
 
 	depth = isl_ast_build_get_depth(data->build);
+	if (depth < 0)
+		bset = isl_basic_set_free(bset);
 	space = isl_basic_set_get_space(bset);
 	space = isl_space_map_from_set(space);
 	gt = isl_basic_map_universe(space);
@@ -2064,7 +2080,7 @@
 {
 	isl_ctx *ctx;
 	struct isl_add_nodes_data data;
-	int depth;
+	isl_size depth;
 	isl_size n;
 
 	n = isl_basic_set_list_n_basic_set(domain_list);
@@ -2083,7 +2099,7 @@
 	depth = isl_ast_build_get_depth(build);
 	data.executed = executed;
 	data.build = build;
-	if (isl_basic_set_list_foreach_scc(domain_list,
+	if (depth < 0 || isl_basic_set_list_foreach_scc(domain_list,
 					&domain_follows_at_depth, &depth,
 					&add_nodes, &data) < 0)
 		data.list = isl_ast_graft_list_free(data.list);
@@ -2186,7 +2202,7 @@
 	__isl_keep isl_basic_set_list *domain_list,
 	__isl_keep isl_union_map *executed, __isl_keep isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	struct isl_ast_generate_parallel_domains_data data;
 
 	data.n = isl_basic_set_list_n_basic_set(domain_list);
@@ -2197,6 +2213,8 @@
 		return generate_sorted_domains(domain_list, executed, build);
 
 	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		return NULL;
 	data.list = NULL;
 	data.executed = executed;
 	data.build = build;
@@ -2252,16 +2270,16 @@
 	__isl_keep isl_ast_build *build)
 {
 	isl_set *domain;
-	int depth;
+	isl_size depth;
 	isl_size dim;
 
+	depth = isl_ast_build_get_depth(build);
 	dim = isl_map_dim(map, isl_dim_out);
-	if (dim < 0)
+	if (depth < 0 || dim < 0)
 		return isl_map_domain(isl_map_free(map));
 	map = isl_map_drop_constraints_involving_dims(map, isl_dim_out, 0, dim);
 
 	domain = isl_map_domain(map);
-	depth = isl_ast_build_get_depth(build);
 	dim = isl_set_dim(domain, isl_dim_set);
 	domain = isl_set_detect_equalities(domain);
 	domain = isl_set_drop_constraints_involving_dims(domain,
@@ -2628,14 +2646,16 @@
 	int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
 {
 	int i, n;
-	int empty;
-	int depth;
+	isl_bool empty;
+	isl_size depth;
 	isl_multi_aff *expansion;
 	isl_basic_map *bmap;
 	isl_aff *lower = NULL;
 	isl_ast_build *stride_build;
 
 	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		domain = isl_set_free(domain);
 
 	domain = isl_ast_build_eliminate_inner(build, domain);
 	domain = isl_set_intersect(domain, isl_ast_build_get_domain(build));
@@ -3286,7 +3306,7 @@
 	isl_basic_set *hull;
 	isl_set *shared, *inner;
 	isl_bool equal;
-	int depth;
+	isl_size depth;
 	isl_size n;
 	isl_size dim;
 
@@ -3296,11 +3316,11 @@
 	if (n <= 1)
 		return isl_bool_false;
 	dim = isl_set_dim(domain, isl_dim_set);
-	if (dim < 0)
+	depth = isl_ast_build_get_depth(build);
+	if (dim < 0 || depth < 0)
 		return isl_bool_error;
 
 	inner = isl_set_copy(domain);
-	depth = isl_ast_build_get_depth(build);
 	inner = isl_set_drop_constraints_not_involving_dims(inner,
 					    isl_dim_set, depth, dim - depth);
 	hull = isl_set_plain_unshifted_simple_hull(isl_set_copy(inner));
@@ -3410,13 +3430,13 @@
 	__isl_keep isl_ast_build *build)
 {
 	isl_set *hull;
-	int depth;
+	isl_size depth;
 	isl_size dim;
 
 	domain = isl_ast_build_specialize(build, domain);
 	depth = isl_ast_build_get_depth(build);
 	dim = isl_set_dim(domain, isl_dim_set);
-	if (dim < 0)
+	if (depth < 0 || dim < 0)
 		return isl_set_free(domain);
 	domain = isl_set_eliminate(domain, isl_dim_set, depth, dim - depth);
 	domain = isl_set_remove_unknown_divs(domain);
@@ -3606,7 +3626,8 @@
 static __isl_give isl_ast_graft_list *generate_shifted_component_tree(
 	__isl_take isl_union_map *executed, __isl_take isl_ast_build *build)
 {
-	int i, depth;
+	int i;
+	isl_size depth;
 	int empty, has_isolate;
 	isl_space *space;
 	isl_union_set *schedule_domain;
@@ -3638,11 +3659,14 @@
 		isl_set_free(domain);
 		return generate_shifted_component_tree_base(executed, build, 0);
 	}
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		goto error;
+
 	isolated = isl_ast_build_eliminate(build, isolated);
 	hull = isl_set_unshifted_simple_hull(isolated);
 	isolated = isl_set_from_basic_set(hull);
 
-	depth = isl_ast_build_get_depth(build);
 	space = isl_space_map_from_set(isl_set_get_space(isolated));
 	gt = isl_map_universe(space);
 	for (i = 0; i < depth; ++i)
@@ -3946,16 +3970,18 @@
 static __isl_give isl_union_map *construct_shifted_executed(
 	struct isl_set_map_pair *domain, int *order, int n,
 	__isl_keep isl_val *stride, __isl_keep isl_multi_val *offset,
-	__isl_take isl_ast_build *build)
+	__isl_keep isl_ast_build *build)
 {
 	int i;
 	isl_union_map *executed;
 	isl_space *space;
 	isl_map *map;
-	int depth;
+	isl_size depth;
 	isl_constraint *c;
 
 	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		return NULL;
 	space = isl_ast_build_get_space(build, 1);
 	executed = isl_union_map_empty(isl_space_copy(space));
 	space = isl_space_map_from_set(space);
@@ -4029,7 +4055,7 @@
 {
 	isl_ast_graft_list *list;
 	int first;
-	int depth;
+	isl_size depth;
 	isl_val *val;
 	isl_multi_val *mv;
 	isl_space *space;
@@ -4039,7 +4065,7 @@
 	depth = isl_ast_build_get_depth(build);
 
 	first = first_offset(domain, order, n, build);
-	if (first < 0)
+	if (depth < 0 || first < 0)
 		goto error;
 
 	mv = isl_multi_val_copy(offset);
@@ -4160,7 +4186,7 @@
 	__isl_take isl_ast_build *build)
 {
 	int i, d;
-	int depth;
+	isl_size depth;
 	isl_ctx *ctx;
 	isl_map *map;
 	isl_set *deltas;
@@ -4172,6 +4198,8 @@
 	int res = 0;
 
 	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
+		goto error;
 
 	skip = n == 1;
 	if (skip >= 0 && !skip)
@@ -4752,6 +4780,7 @@
 	int i;
 	isl_ctx *ctx = isl_ast_build_get_ctx(build);
 	isl_size n = isl_union_map_n_map(executed);
+	isl_size depth;
 	struct isl_any_scheduled_after_data data;
 	struct isl_set_map_pair *next;
 	struct isl_tarjan_graph *g = NULL;
@@ -4770,10 +4799,11 @@
 	if (isl_union_map_foreach_map(executed, &extract_domain, &next) < 0)
 		goto error;
 
-	if (!build)
+	depth = isl_ast_build_get_depth(build);
+	if (depth < 0)
 		goto error;
 	data.build = build;
-	data.depth = isl_ast_build_get_depth(build);
+	data.depth = depth;
 	data.group_coscheduled = isl_options_get_ast_build_group_coscheduled(ctx);
 	g = isl_tarjan_graph_init(ctx, n, &any_scheduled_after, &data);
 	if (!g)
@@ -4833,7 +4863,7 @@
 static __isl_give isl_ast_graft_list *generate_next_level(
 	__isl_take isl_union_map *executed, __isl_take isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	isl_size dim;
 	isl_size n;
 
@@ -4849,7 +4879,7 @@
 
 	depth = isl_ast_build_get_depth(build);
 	dim = isl_ast_build_dim(build, isl_dim_set);
-	if (dim < 0)
+	if (depth < 0 || dim < 0)
 		goto error;
 	if (depth >= dim)
 		return generate_inner_level(executed, build);
diff --git a/lib/External/isl/isl_ast_graft.c b/lib/External/isl/isl_ast_graft.c
index 7a09986..03e8449 100644
--- a/lib/External/isl/isl_ast_graft.c
+++ b/lib/External/isl/isl_ast_graft.c
@@ -110,24 +110,24 @@
 {
 	int i;
 	isl_size n;
-	int depth;
+	isl_size depth;
 	isl_size dim;
 	isl_ast_graft *graft_0;
 	isl_bool equal = isl_bool_true;
 	isl_bool skip;
 
 	n = isl_ast_graft_list_n_ast_graft(list);
-	if (n < 0)
+	depth = isl_ast_build_get_depth(build);
+	if (n < 0 || depth < 0)
 		return isl_bool_error;
 	graft_0 = isl_ast_graft_list_get_ast_graft(list, 0);
 	if (!graft_0)
 		return isl_bool_error;
 
-	depth = isl_ast_build_get_depth(build);
 	dim = isl_set_dim(graft_0->guard, isl_dim_set);
 	if (dim < 0)
-		return isl_bool_error;
-	if (dim <= depth)
+		skip = isl_bool_error;
+	else if (dim <= depth)
 		skip = isl_bool_false;
 	else
 		skip = isl_set_involves_dims(graft_0->guard,
@@ -161,12 +161,12 @@
 static __isl_give isl_set *hoist_guard(__isl_take isl_set *guard,
 	__isl_keep isl_ast_build *build)
 {
-	int depth;
+	isl_size depth;
 	isl_size dim;
 
 	depth = isl_ast_build_get_depth(build);
 	dim = isl_set_dim(guard, isl_dim_set);
-	if (dim < 0)
+	if (depth < 0 || dim < 0)
 		return isl_set_free(guard);
 	if (depth < dim) {
 		guard = isl_set_remove_divs_involving_dims(guard,
@@ -473,13 +473,14 @@
 	__isl_keep isl_ast_build *build)
 {
 	isl_size n;
-	int depth;
+	isl_size depth;
 	isl_ast_graft *last;
 	isl_space *space;
 	isl_basic_set *enforced;
 
 	n = isl_ast_graft_list_n_ast_graft(list);
-	if (n < 0 || !graft)
+	depth = isl_ast_build_get_depth(build);
+	if (n < 0 || depth < 0 || !graft)
 		goto error;
 	extend_body(body, isl_ast_node_copy(graft->node));
 	if (!*body)
@@ -487,7 +488,6 @@
 
 	last = isl_ast_graft_list_get_ast_graft(list, n - 1);
 
-	depth = isl_ast_build_get_depth(build);
 	space = isl_ast_build_get_space(build, 1);
 	enforced = isl_basic_set_empty(space);
 	enforced = update_enforced(enforced, last, depth);
@@ -760,18 +760,18 @@
 {
 	int i;
 	isl_size n;
-	int depth;
+	isl_size depth;
 	isl_space *space;
 	isl_basic_set *enforced;
 
 	n = isl_ast_graft_list_n_ast_graft(list);
-	if (n < 0)
+	depth = isl_ast_build_get_depth(build);
+	if (n < 0 || depth < 0)
 		return NULL;
 
 	space = isl_ast_build_get_space(build, 1);
 	enforced = isl_basic_set_empty(space);
 
-	depth = isl_ast_build_get_depth(build);
 	for (i = 0; i < n; ++i) {
 		isl_ast_graft *graft;
 
diff --git a/lib/External/isl/isl_box.c b/lib/External/isl/isl_box.c
index d7c5ce1..d4eb54f 100644
--- a/lib/External/isl/isl_box.c
+++ b/lib/External/isl/isl_box.c
@@ -432,6 +432,48 @@
 	return box;
 }
 
+/* Check whether the output elements lie on a rectangular lattice,
+ * possibly depending on the parameters and the input dimensions.
+ * Return a tile in this lattice.
+ * If no stride information can be found, then return a tile of size 1
+ * (and offset 0).
+ *
+ * Obtain stride information in each output dimension separately and
+ * combine the results.
+ */
+__isl_give isl_fixed_box *isl_map_get_range_lattice_tile(
+	__isl_keep isl_map *map)
+{
+	int i;
+	isl_size n;
+	isl_space *space;
+	isl_fixed_box *box;
+
+	n = isl_map_dim(map, isl_dim_out);
+	if (n < 0)
+		return NULL;
+	space = isl_map_get_space(map);
+	box = isl_fixed_box_init(space);
+
+	for (i = 0; i < n; ++i) {
+		isl_val *stride;
+		isl_aff *offset;
+		isl_stride_info *si;
+
+		si = isl_map_get_range_stride_info(map, i);
+		stride = isl_stride_info_get_stride(si);
+		offset = isl_stride_info_get_offset(si);
+		isl_stride_info_free(si);
+
+		box = isl_fixed_box_set_valid_extent(box, i, offset, stride);
+
+		isl_aff_free(offset);
+		isl_val_free(stride);
+	}
+
+	return box;
+}
+
 #undef BASE
 #define BASE multi_val
 #include "print_yaml_field_templ.c"
diff --git a/lib/External/isl/isl_coalesce.c b/lib/External/isl/isl_coalesce.c
index ba876ac..e7cefa0 100644
--- a/lib/External/isl/isl_coalesce.c
+++ b/lib/External/isl/isl_coalesce.c
@@ -498,7 +498,7 @@
  * replaced if the total number of constraints does not increase.
  * While the number of integer divisions in the two basic maps
  * is assumed to be the same, the actual definitions may be different.
- * We only copy the definition from one of the basic map if it is
+ * We only copy the definition from one of the basic maps if it is
  * the same as that of the other basic map.  Otherwise, we mark
  * the integer division as unknown and simplify the basic map
  * in an attempt to recover the integer division definition.
@@ -3533,7 +3533,7 @@
 	return change;
 }
 
-/* Check if the union of and the basic maps represented by info[i] and info[j]
+/* Check if the union of the basic maps represented by info[i] and info[j]
  * can be represented by a single basic map, by aligning or equating
  * their integer divisions.
  * If so, replace the pair by the single basic map and return
@@ -3606,6 +3606,8 @@
  * If no such list can be constructed, then the number of elements
  * in the returned list is smaller than the number of integer divisions
  * in "bmap_i".
+ * The integer division of "bmap_i" and "bmap_j" are assumed to be known and
+ * not contain any nested divs.
  */
 static __isl_give isl_aff_list *set_up_substitutions(
 	__isl_keep isl_basic_map *bmap_i, __isl_keep isl_basic_map *bmap_j,
diff --git a/lib/External/isl/isl_constraint.c b/lib/External/isl/isl_constraint.c
index f69e339..4fc7aba 100644
--- a/lib/External/isl/isl_constraint.c
+++ b/lib/External/isl/isl_constraint.c
@@ -574,24 +574,6 @@
 	return constraint;
 }
 
-__isl_give isl_constraint *isl_constraint_set_coefficient(
-	__isl_take isl_constraint *constraint,
-	enum isl_dim_type type, int pos, isl_int v)
-{
-	constraint = isl_constraint_cow(constraint);
-	if (isl_constraint_check_range(constraint, type, pos, 1) < 0)
-		return isl_constraint_free(constraint);
-
-	constraint->v = isl_vec_cow(constraint->v);
-	if (!constraint->v)
-		return isl_constraint_free(constraint);
-
-	pos += isl_local_space_offset(constraint->ls, type);
-	isl_int_set(constraint->v->el[pos], v);
-
-	return constraint;
-}
-
 /* Replace the coefficient of the variable of type "type" at position "pos"
  * of "constraint" by "v".
  */
diff --git a/lib/External/isl/isl_id.c b/lib/External/isl/isl_id.c
index 982d9eb..ab0f75b 100644
--- a/lib/External/isl/isl_id.c
+++ b/lib/External/isl/isl_id.c
@@ -15,6 +15,7 @@
 #define EL_BASE id
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 /* A special, static isl_id to use as domains (and ranges)
  * of sets and parameters domains.
diff --git a/lib/External/isl/isl_list_read_templ.c b/lib/External/isl/isl_list_read_templ.c
new file mode 100644
index 0000000..25b3478
--- /dev/null
+++ b/lib/External/isl/isl_list_read_templ.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017      Sven Verdoolaege
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege.
+ */
+
+#include <isl/stream.h>
+
+#include <isl_list_macro.h>
+
+/* Read a list of elements of type EL from "s".
+ * The input format corresponds to the way lists are printed
+ * by isl_printer_print_list_*.
+ * In particular, the elements are separated by a comma and
+ * the entire list is surrounded by parentheses.
+ */
+static __isl_give LIST(EL) *FN(isl_stream_read,LIST(EL_BASE))(isl_stream *s)
+{
+	isl_ctx *ctx;
+	LIST(EL) *list;
+
+	if (!s)
+		return NULL;
+	ctx = isl_stream_get_ctx(s);
+	list = FN(LIST(EL),alloc)(ctx, 0);
+	if (!list)
+		return NULL;
+	if (isl_stream_eat(s, '(') < 0)
+		return FN(LIST(EL),free)(list);
+	do {
+		EL *el;
+
+		el = FN(isl_stream_read,EL_BASE)(s);
+		list = FN(LIST(EL),add)(list, el);
+		if (!list)
+			return NULL;
+	} while (isl_stream_eat_if_available(s, ','));
+	if (isl_stream_eat(s, ')') < 0)
+		return FN(LIST(EL),free)(list);
+	return list;
+}
+
+/* Read a list of elements of type EL from the string "str".
+ * The input format corresponds to the way lists are printed
+ * by isl_printer_print_list_*.
+ * In particular, the elements are separated by a comma and
+ * the entire list is surrounded by parentheses.
+ */
+__isl_give LIST(EL) *FN(LIST(EL),read_from_str)(isl_ctx *ctx,
+	const char *str)
+{
+	LIST(EL) *list;
+	isl_stream *s;
+
+	s = isl_stream_new_str(ctx, str);
+	if (!s)
+		return NULL;
+	list = FN(isl_stream_read,LIST(EL_BASE))(s);
+	isl_stream_free(s);
+	return list;
+}
diff --git a/lib/External/isl/isl_list_templ.c b/lib/External/isl/isl_list_templ.c
index 03bea20..cfb4f33 100644
--- a/lib/External/isl/isl_list_templ.c
+++ b/lib/External/isl/isl_list_templ.c
@@ -606,6 +606,14 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_*_list_from_*,
+ * but is considered as a function on the element when exported.
+ */
+__isl_give LIST(EL) *FN(EL,to_list)(__isl_take EL *el)
+{
+	return FN(FN(LIST(EL),from),EL_BASE)(el);
+}
+
 /* Append the elements of "list2" to "list1", where "list1" is known
  * to have only a single reference and enough room to hold
  * the extra elements.
diff --git a/lib/External/isl/isl_map.c b/lib/External/isl/isl_map.c
index 6b6f301..516106c 100644
--- a/lib/External/isl/isl_map.c
+++ b/lib/External/isl/isl_map.c
@@ -112,11 +112,32 @@
 	return isl_space_dim(isl_map_peek_space(map), type);
 }
 
+/* Return the dimensionality of the domain (tuple) of the map.
+ */
+isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map)
+{
+	return isl_map_dim(map, isl_dim_in);
+}
+
+/* Return the dimensionality of the range (tuple) of the map.
+ */
+isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map)
+{
+	return isl_map_dim(map, isl_dim_out);
+}
+
 isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
 {
 	return isl_map_dim(set_to_map(set), type);
 }
 
+/* Return the dimensionality of the (tuple of the) set.
+ */
+isl_size isl_set_tuple_dim(__isl_keep isl_set *set)
+{
+	return isl_set_dim(set, isl_dim_set);
+}
+
 /* Return the position of the variables of the given type
  * within the sequence of variables of "bmap".
  */
@@ -742,6 +763,22 @@
 	return isl_map_reset_space(map, isl_map_get_space(map));
 }
 
+/* Replace the identifier of the domain tuple of "map" by "id".
+ */
+__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
+	__isl_take isl_id *id)
+{
+	return isl_map_set_tuple_id(map, isl_dim_in, id);
+}
+
+/* Replace the identifier of the range tuple of "map" by "id".
+ */
+__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
+	__isl_take isl_id *id)
+{
+	return isl_map_set_tuple_id(map, isl_dim_out, id);
+}
+
 __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set,
 	__isl_take isl_id *id)
 {
@@ -770,12 +807,40 @@
 	return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
 }
 
+/* Does the domain tuple of "map" have an identifier?
+ */
+isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map)
+{
+	return isl_map_has_tuple_id(map, isl_dim_in);
+}
+
+/* Does the range tuple of "map" have an identifier?
+ */
+isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map)
+{
+	return isl_map_has_tuple_id(map, isl_dim_out);
+}
+
 __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
 	enum isl_dim_type type)
 {
 	return map ? isl_space_get_tuple_id(map->dim, type) : NULL;
 }
 
+/* Return the identifier of the domain tuple of "map", assuming it has one.
+ */
+__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map)
+{
+	return isl_map_get_tuple_id(map, isl_dim_in);
+}
+
+/* Return the identifier of the range tuple of "map", assuming it has one.
+ */
+__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map)
+{
+	return isl_map_get_tuple_id(map, isl_dim_out);
+}
+
 isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set)
 {
 	return isl_map_has_tuple_id(set, isl_dim_set);
@@ -2103,19 +2168,22 @@
  * Since the basic map has conflicting constraints,
  * it must have at least one constraint, except perhaps
  * if it was already explicitly marked as being empty.
- * Do nothing in the latter case.
+ * Do nothing in the latter case, i.e., if it has been marked empty and
+ * has no constraints.
  */
 __isl_give isl_basic_map *isl_basic_map_set_to_empty(
 	__isl_take isl_basic_map *bmap)
 {
 	int i = 0;
 	isl_bool empty;
+	isl_size n;
 	isl_size total;
 
+	n = isl_basic_map_n_constraint(bmap);
 	empty = isl_basic_map_plain_is_empty(bmap);
-	if (empty < 0)
+	if (n < 0 || empty < 0)
 		return isl_basic_map_free(bmap);
-	if (empty)
+	if (n == 0 && empty)
 		return bmap;
 	total = isl_basic_map_dim(bmap, isl_dim_all);
 	if (total < 0)
@@ -3423,6 +3491,14 @@
 	return isl_map_from_basic_map(bset);
 }
 
+/* This function performs the same operation as isl_set_from_basic_set,
+ * but is considered as a function on an isl_basic_set when exported.
+ */
+__isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset)
+{
+	return isl_set_from_basic_set(bset);
+}
+
 __isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
 {
 	struct isl_map *map;
@@ -3711,6 +3787,41 @@
 	return isl_basic_set_intersect(bset1, bset2);
 }
 
+/* Does "map" consist of a single disjunct, without any local variables?
+ */
+static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
+{
+	isl_size n_div;
+
+	if (!map)
+		return isl_bool_error;
+	if (map->n != 1)
+		return isl_bool_false;
+	n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
+	if (n_div < 0)
+		return isl_bool_error;
+	if (n_div != 0)
+		return isl_bool_false;
+	return isl_bool_true;
+}
+
+/* Check that "map" consists of a single disjunct, without any local variables.
+ */
+static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
+{
+	isl_bool ok;
+
+	ok = is_convex_no_locals(map);
+	if (ok < 0)
+		return isl_stat_error;
+	if (ok)
+		return isl_stat_ok;
+
+	isl_die(isl_map_get_ctx(map), isl_error_internal,
+		"unexpectedly not convex or involving local variables",
+		return isl_stat_error);
+}
+
 /* Special case of isl_map_intersect, where both map1 and map2
  * are convex, without any divs and such that either map1 or map2
  * contains a single constraint.  This constraint is then simply
@@ -3719,10 +3830,9 @@
 static __isl_give isl_map *map_intersect_add_constraint(
 	__isl_take isl_map *map1, __isl_take isl_map *map2)
 {
-	isl_assert(map1->ctx, map1->n == 1, goto error);
-	isl_assert(map2->ctx, map1->n == 1, goto error);
-	isl_assert(map1->ctx, map1->p[0]->n_div == 0, goto error);
-	isl_assert(map2->ctx, map1->p[0]->n_div == 0, goto error);
+	if (check_convex_no_locals(map1) < 0 ||
+	    check_convex_no_locals(map2) < 0)
+		goto error;
 
 	if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
 		return isl_map_intersect(map2, map1);
@@ -3788,8 +3898,8 @@
 		return map2;
 	}
 
-	if (map1->n == 1 && map2->n == 1 &&
-	    map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
+	if (is_convex_no_locals(map1) == isl_bool_true &&
+	    is_convex_no_locals(map2) == isl_bool_true &&
 	    isl_space_is_equal(map1->dim, map2->dim) &&
 	    (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
 	     map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
@@ -6277,6 +6387,14 @@
 	return map;
 }
 
+/* This function performs the same operation as isl_map_universe,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
+{
+	return isl_map_universe(space);
+}
+
 __isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
 {
 	struct isl_set *set;
@@ -6287,6 +6405,14 @@
 	return set;
 }
 
+/* This function performs the same operation as isl_set_universe,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space)
+{
+	return isl_set_universe(space);
+}
+
 __isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
 {
 	int i;
@@ -13399,129 +13525,19 @@
 	return isl_basic_map_get_div(bset, pos);
 }
 
-/* Plug in "subs" for dimension "type", "pos" of "bset".
- *
- * Let i be the dimension to replace and let "subs" be of the form
- *
- *	f/d
- *
- * Any integer division with a non-zero coefficient for i,
- *
- *	floor((a i + g)/m)
- *
- * is replaced by
- *
- *	floor((a f + d g)/(m d))
- *
- * Constraints of the form
- *
- *	a i + g
- *
- * are replaced by
- *
- *	a f + d g
- *
- * We currently require that "subs" is an integral expression.
- * Handling rational expressions may require us to add stride constraints
- * as we do in isl_basic_set_preimage_multi_aff.
- */
-__isl_give isl_basic_set *isl_basic_set_substitute(
-	__isl_take isl_basic_set *bset,
-	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
-{
-	int i;
-	isl_int v;
-	isl_ctx *ctx;
-	isl_size n_div;
-
-	if (bset && isl_basic_set_plain_is_empty(bset))
-		return bset;
-
-	bset = isl_basic_set_cow(bset);
-	if (!bset || !subs)
-		goto error;
-
-	ctx = isl_basic_set_get_ctx(bset);
-	if (!isl_space_is_equal(bset->dim, subs->ls->dim))
-		isl_die(ctx, isl_error_invalid,
-			"spaces don't match", goto error);
-	n_div = isl_local_space_dim(subs->ls, isl_dim_div);
-	if (n_div < 0)
-		goto error;
-	if (n_div != 0)
-		isl_die(ctx, isl_error_unsupported,
-			"cannot handle divs yet", goto error);
-	if (!isl_int_is_one(subs->v->el[0]))
-		isl_die(ctx, isl_error_invalid,
-			"can only substitute integer expressions", goto error);
-
-	pos += isl_basic_set_offset(bset, type);
-
-	isl_int_init(v);
-
-	for (i = 0; i < bset->n_eq; ++i) {
-		if (isl_int_is_zero(bset->eq[i][pos]))
-			continue;
-		isl_int_set(v, bset->eq[i][pos]);
-		isl_int_set_si(bset->eq[i][pos], 0);
-		isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
-				v, subs->v->el + 1, subs->v->size - 1);
-	}
-
-	for (i = 0; i < bset->n_ineq; ++i) {
-		if (isl_int_is_zero(bset->ineq[i][pos]))
-			continue;
-		isl_int_set(v, bset->ineq[i][pos]);
-		isl_int_set_si(bset->ineq[i][pos], 0);
-		isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
-				v, subs->v->el + 1, subs->v->size - 1);
-	}
-
-	for (i = 0; i < bset->n_div; ++i) {
-		if (isl_int_is_zero(bset->div[i][1 + pos]))
-			continue;
-		isl_int_set(v, bset->div[i][1 + pos]);
-		isl_int_set_si(bset->div[i][1 + pos], 0);
-		isl_seq_combine(bset->div[i] + 1,
-				subs->v->el[0], bset->div[i] + 1,
-				v, subs->v->el + 1, subs->v->size - 1);
-		isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]);
-	}
-
-	isl_int_clear(v);
-
-	bset = isl_basic_set_simplify(bset);
-	return isl_basic_set_finalize(bset);
-error:
-	isl_basic_set_free(bset);
-	return NULL;
-}
-
-/* Plug in "subs" for dimension "type", "pos" of "set".
+/* Plug in "subs" for set dimension "pos" of "set".
  */
 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
-	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
+	unsigned pos, __isl_keep isl_aff *subs)
 {
-	int i;
+	isl_multi_aff *ma;
 
 	if (set && isl_set_plain_is_empty(set))
 		return set;
 
-	set = isl_set_cow(set);
-	if (!set || !subs)
-		goto error;
-
-	for (i = set->n - 1; i >= 0; --i) {
-		set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
-		set = set_from_map(remove_if_empty(set_to_map(set), i));
-		if (!set)
-			return NULL;
-	}
-
-	return set;
-error:
-	isl_set_free(set);
-	return NULL;
+	ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
+	ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
+	return isl_set_preimage_multi_aff(set, ma);
 }
 
 /* Check if the range of "ma" is compatible with the domain or range
diff --git a/lib/External/isl/isl_map_list.c b/lib/External/isl/isl_map_list.c
index cb94c35..3314fa7 100644
--- a/lib/External/isl/isl_map_list.c
+++ b/lib/External/isl/isl_map_list.c
@@ -20,6 +20,7 @@
 #define EL_BASE map
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 #undef EL
 #define EL isl_union_map
diff --git a/lib/External/isl/isl_map_private.h b/lib/External/isl/isl_map_private.h
index 5ddd3c8..c52e835 100644
--- a/lib/External/isl/isl_map_private.h
+++ b/lib/External/isl/isl_map_private.h
@@ -500,7 +500,7 @@
 	isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2));
 
 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
-	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs);
+	unsigned pos, __isl_keep isl_aff *subs);
 
 __isl_give isl_set *isl_set_gist_params_basic_set(__isl_take isl_set *set,
 	__isl_take isl_basic_set *context);
diff --git a/lib/External/isl/isl_map_subtract.c b/lib/External/isl/isl_map_subtract.c
index 66e423b..6431b3d 100644
--- a/lib/External/isl/isl_map_subtract.c
+++ b/lib/External/isl/isl_map_subtract.c
@@ -643,7 +643,7 @@
 }
 
 /* A diff collector that aborts as soon as its add function is called,
- * setting empty to 0.
+ * setting empty to isl_false.
  */
 struct isl_is_empty_diff_collector {
 	struct isl_diff_collector dc;
diff --git a/lib/External/isl/isl_multi_identity_templ.c b/lib/External/isl/isl_multi_identity_templ.c
index d598d11..1ffeadf 100644
--- a/lib/External/isl/isl_multi_identity_templ.c
+++ b/lib/External/isl/isl_multi_identity_templ.c
@@ -72,6 +72,16 @@
 	return FN(MULTI(BASE),identity)(isl_space_map_from_set(space));
 }
 
+/* This function performs the same operation as
+ * isl_multi_*_identity_on_domain_space,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give MULTI(BASE) *FN(FN(isl_space_identity_multi,BASE),on_domain)(
+	__isl_take isl_space *space)
+{
+	return FN(MULTI(BASE),identity_on_domain_space)(space);
+}
+
 /* Create a multi expression in the same space as "multi" that maps each
  * input dimension to the corresponding output dimension.
  */
diff --git a/lib/External/isl/isl_multi_templ.c b/lib/External/isl/isl_multi_templ.c
index 40790c7..3777024 100644
--- a/lib/External/isl/isl_multi_templ.c
+++ b/lib/External/isl/isl_multi_templ.c
@@ -479,6 +479,15 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_multi_*_from_*_list,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give MULTI(BASE) *FN(isl_space_multi,BASE)(__isl_take isl_space *space,
+	__isl_take LIST(EL) *list)
+{
+	return FN(FN(MULTI(BASE),from),LIST(BASE))(space, list);
+}
+
 __isl_give MULTI(BASE) *FN(MULTI(BASE),drop_dims)(
 	__isl_take MULTI(BASE) *multi,
 	enum isl_dim_type type, unsigned first, unsigned n)
diff --git a/lib/External/isl/isl_multi_tuple_id_templ.c b/lib/External/isl/isl_multi_tuple_id_templ.c
index 03f74d4..87f9fe6 100644
--- a/lib/External/isl/isl_multi_tuple_id_templ.c
+++ b/lib/External/isl/isl_multi_tuple_id_templ.c
@@ -28,6 +28,18 @@
 	return isl_space_has_tuple_id(multi->space, type);
 }
 
+/* Does the (range) tuple of "multi" have an identifier?
+ *
+ * Technically, the implementation should use isl_dim_set if "multi"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+isl_bool FN(MULTI(BASE),has_range_tuple_id)(__isl_keep MULTI(BASE) *multi)
+{
+	return FN(MULTI(BASE),has_tuple_id)(multi, isl_dim_out);
+}
+
 /* Return the id of the specified tuple.
  */
 __isl_give isl_id *FN(MULTI(BASE),get_tuple_id)(__isl_keep MULTI(BASE) *multi,
@@ -36,6 +48,19 @@
 	return multi ? isl_space_get_tuple_id(multi->space, type) : NULL;
 }
 
+/* Return the identifier of the (range) tuple of "multi", assuming it has one.
+ *
+ * Technically, the implementation should use isl_dim_set if "multi"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+__isl_give isl_id *FN(MULTI(BASE),get_range_tuple_id)(
+	__isl_keep MULTI(BASE) *multi)
+{
+	return FN(MULTI(BASE),get_tuple_id)(multi, isl_dim_out);
+}
+
 __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_name)(
 	__isl_keep MULTI(BASE) *multi, enum isl_dim_type type,
 	const char *s)
@@ -71,6 +96,19 @@
 	return NULL;
 }
 
+/* Replace the identifier of the (range) tuple of "multi" by "id".
+ *
+ * Technically, the implementation should use isl_dim_set if "multi"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+__isl_give MULTI(BASE) *FN(MULTI(BASE),set_range_tuple_id)(
+	__isl_take MULTI(BASE) *multi, __isl_take isl_id *id)
+{
+	return FN(MULTI(BASE),set_tuple_id)(multi, isl_dim_out, id);
+}
+
 /* Drop the id on the specified tuple.
  */
 __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_tuple_id)(
@@ -92,3 +130,16 @@
 
 	return FN(MULTI(BASE),reset_space)(multi, space);
 }
+
+/* Drop the identifier of the (range) tuple of "multi".
+ *
+ * Technically, the implementation should use isl_dim_set if "multi"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_range_tuple_id)(
+	__isl_take MULTI(BASE) *multi)
+{
+	return FN(MULTI(BASE),reset_tuple_id)(multi, isl_dim_out);
+}
diff --git a/lib/External/isl/isl_multi_zero_space_templ.c b/lib/External/isl/isl_multi_zero_space_templ.c
new file mode 100644
index 0000000..8bd027b
--- /dev/null
+++ b/lib/External/isl/isl_multi_zero_space_templ.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020      Cerebras Systems
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
+ */
+
+#include <isl/space.h>
+
+#include "isl_multi_macro.h"
+
+/* This function performs the same operation as isl_multi_*_zero,
+ * but is considered as a function on an isl_space when exported.
+ */
+__isl_give MULTI(BASE) *FN(isl_space_zero_multi,BASE)(
+	__isl_take isl_space *space)
+{
+	return FN(MULTI(BASE),zero)(space);
+}
diff --git a/lib/External/isl/isl_multi_zero_templ.c b/lib/External/isl/isl_multi_zero_templ.c
index 2dbc582..dee3a8f 100644
--- a/lib/External/isl/isl_multi_zero_templ.c
+++ b/lib/External/isl/isl_multi_zero_templ.c
@@ -49,3 +49,5 @@
 	isl_space_free(space);
 	return NULL;
 }
+
+#include "isl_multi_zero_space_templ.c"
diff --git a/lib/External/isl/isl_point.c b/lib/External/isl/isl_point.c
index be41c53..f7da706 100644
--- a/lib/External/isl/isl_point.c
+++ b/lib/External/isl/isl_point.c
@@ -634,6 +634,14 @@
 	return isl_set_from_basic_set(bset);
 }
 
+/* This function performs the same operation as isl_set_from_point,
+ * but is considered as a function on an isl_point when exported.
+ */
+__isl_give isl_set *isl_point_to_set(__isl_take isl_point *pnt)
+{
+	return isl_set_from_point(pnt);
+}
+
 /* Construct a union set, containing the single element "pnt".
  * If "pnt" is void, then return an empty union set.
  */
diff --git a/lib/External/isl/isl_polynomial.c b/lib/External/isl/isl_polynomial.c
index 5577e07..0aac613 100644
--- a/lib/External/isl/isl_polynomial.c
+++ b/lib/External/isl/isl_polynomial.c
@@ -4773,6 +4773,33 @@
 	isl_pw_qpolynomial *pwqp;
 };
 
+/* Call "fn" on "bset" and return the result,
+ * but first check if "bset" has any redundant constraints or
+ * implicit equality constraints.
+ * If so, there may be further opportunities for detecting factors or
+ * removing equality constraints, so recursively call
+ * the top-level isl_basic_set_multiplicative_call.
+ */
+static __isl_give isl_pw_qpolynomial *multiplicative_call_base(
+	__isl_take isl_basic_set *bset,
+	__isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset))
+{
+	isl_size n1, n2, n_eq;
+
+	n1 = isl_basic_set_n_constraint(bset);
+	if (n1 < 0)
+		bset = isl_basic_set_free(bset);
+	bset = isl_basic_set_remove_redundancies(bset);
+	bset = isl_basic_set_detect_equalities(bset);
+	n2 = isl_basic_set_n_constraint(bset);
+	n_eq = isl_basic_set_n_equality(bset);
+	if (n2 < 0 || n_eq < 0)
+		bset = isl_basic_set_free(bset);
+	else if (n2 < n1 || n_eq > 0)
+		return isl_basic_set_multiplicative_call(bset, fn);
+	return fn(bset);
+}
+
 /* isl_factorizer_every_factor_basic_set callback that applies
  * data->fn to the factor "bset" and multiplies in the result
  * in data->pwqp.
@@ -4781,9 +4808,11 @@
 	__isl_keep isl_basic_set *bset, void *user)
 {
 	struct isl_multiplicative_call_data_pw_qpolynomial *data = user;
+	isl_pw_qpolynomial *res;
 
 	bset = isl_basic_set_copy(bset);
-	data->pwqp = isl_pw_qpolynomial_mul(data->pwqp, data->fn(bset));
+	res = multiplicative_call_base(bset, data->fn);
+	data->pwqp = isl_pw_qpolynomial_mul(data->pwqp, res);
 	if (!data->pwqp)
 		return isl_bool_error;
 
@@ -4812,7 +4841,7 @@
 		goto error;
 	if (f->n_group == 0) {
 		isl_factorizer_free(f);
-		return fn(bset);
+		return multiplicative_call_base(bset, fn);
 	}
 
 	space = isl_basic_set_get_space(bset);
diff --git a/lib/External/isl/isl_pw_range_tuple_id_templ.c b/lib/External/isl/isl_pw_range_tuple_id_templ.c
new file mode 100644
index 0000000..37392f5
--- /dev/null
+++ b/lib/External/isl/isl_pw_range_tuple_id_templ.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018      Sven Verdoolaege
+ * Copyright 2019      Cerebras Systems
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege,
+ * Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
+ */
+
+/* Does the (range) tuple of "pw" have an identifier?
+ *
+ * Technically, the implementation should use isl_dim_set if "pw"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+isl_bool FN(PW,has_range_tuple_id)(__isl_keep PW *pw)
+{
+	return FN(PW,has_tuple_id)(pw, isl_dim_out);
+}
+
+/* Return the identifier of the (range) tuple of "pw", assuming it has one.
+ *
+ * Technically, the implementation should use isl_dim_set if "pw"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+__isl_give isl_id *FN(PW,get_range_tuple_id)(__isl_keep PW *pw)
+{
+	return FN(PW,get_tuple_id)(pw, isl_dim_out);
+}
+
+/* Replace the identifier of the (range) tuple of "pw" by "id".
+ *
+ * Technically, the implementation should use isl_dim_set if "pw"
+ * lives in a set space and isl_dim_out if it lives in a map space.
+ * Internally, however, it can be assumed that isl_dim_set is equal
+ * to isl_dim_out.
+ */
+__isl_give PW *FN(PW,set_range_tuple_id)(__isl_take PW *pw,
+	__isl_take isl_id *id)
+{
+	return FN(PW,set_tuple_id)(pw, isl_dim_out, id);
+}
diff --git a/lib/External/isl/isl_schedule_constraints.c b/lib/External/isl/isl_schedule_constraints.c
index 3d92b53..38a3c6f 100644
--- a/lib/External/isl/isl_schedule_constraints.c
+++ b/lib/External/isl/isl_schedule_constraints.c
@@ -176,11 +176,17 @@
 }
 
 /* Replace the constraints of type "type" in "sc" by "c".
+ *
+ * First detect any equality constraints that may be implicit in "c"
+ * in order to try and improve the accuracy of the input (and therefore
+ * also the output) of the isl_set_coefficients calls
+ * that are eventually performed on (some of) these constraints.
  */
 static __isl_give isl_schedule_constraints *isl_schedule_constraints_set(
 	__isl_take isl_schedule_constraints *sc, enum isl_edge_type type,
 	__isl_take isl_union_map *c)
 {
+	c = isl_union_map_detect_equalities(c);
 	if (!sc || !c)
 		goto error;
 
diff --git a/lib/External/isl/isl_set_list.c b/lib/External/isl/isl_set_list.c
index 2a6749a..e505552 100644
--- a/lib/External/isl/isl_set_list.c
+++ b/lib/External/isl/isl_set_list.c
@@ -30,3 +30,4 @@
 #define EL_BASE union_set
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
diff --git a/lib/External/isl/isl_space.c b/lib/External/isl/isl_space.c
index 1aa0f60..fd67a89 100644
--- a/lib/External/isl/isl_space.c
+++ b/lib/External/isl/isl_space.c
@@ -578,6 +578,24 @@
 	return isl_bool_ok(space->tuple_id[type - isl_dim_in] != NULL);
 }
 
+/* Does the domain tuple of the map space "space" have an identifier?
+ */
+isl_bool isl_space_has_domain_tuple_id(__isl_keep isl_space *space)
+{
+	if (isl_space_check_is_map(space) < 0)
+		return isl_bool_error;
+	return isl_space_has_tuple_id(space, isl_dim_in);
+}
+
+/* Does the range tuple of the map space "space" have an identifier?
+ */
+isl_bool isl_space_has_range_tuple_id(__isl_keep isl_space *space)
+{
+	if (isl_space_check_is_map(space) < 0)
+		return isl_bool_error;
+	return isl_space_has_tuple_id(space, isl_dim_out);
+}
+
 __isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space,
 	enum isl_dim_type type)
 {
@@ -594,6 +612,28 @@
 	return isl_id_copy(space->tuple_id[type - isl_dim_in]);
 }
 
+/* Return the identifier of the domain tuple of the map space "space",
+ * assuming it has one.
+ */
+__isl_give isl_id *isl_space_get_domain_tuple_id(
+	__isl_keep isl_space *space)
+{
+	if (isl_space_check_is_map(space) < 0)
+		return NULL;
+	return isl_space_get_tuple_id(space, isl_dim_in);
+}
+
+/* Return the identifier of the range tuple of the map space "space",
+ * assuming it has one.
+ */
+__isl_give isl_id *isl_space_get_range_tuple_id(
+	__isl_keep isl_space *space)
+{
+	if (isl_space_check_is_map(space) < 0)
+		return NULL;
+	return isl_space_get_tuple_id(space, isl_dim_out);
+}
+
 __isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space,
 	enum isl_dim_type type, __isl_take isl_id *id)
 {
@@ -615,6 +655,28 @@
 	return NULL;
 }
 
+/* Replace the identifier of the domain tuple of the map space "space"
+ * by "id".
+ */
+__isl_give isl_space *isl_space_set_domain_tuple_id(
+	__isl_take isl_space *space, __isl_take isl_id *id)
+{
+	if (isl_space_check_is_map(space) < 0)
+		space = isl_space_free(space);
+	return isl_space_set_tuple_id(space, isl_dim_in, id);
+}
+
+/* Replace the identifier of the range tuple of the map space "space"
+ * by "id".
+ */
+__isl_give isl_space *isl_space_set_range_tuple_id(
+	__isl_take isl_space *space, __isl_take isl_id *id)
+{
+	if (isl_space_check_is_map(space) < 0)
+		space = isl_space_free(space);
+	return isl_space_set_tuple_id(space, isl_dim_out, id);
+}
+
 __isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space,
 	enum isl_dim_type type)
 {
diff --git a/lib/External/isl/isl_tab_pip.c b/lib/External/isl/isl_tab_pip.c
index b8659e0..5a3148b 100644
--- a/lib/External/isl/isl_tab_pip.c
+++ b/lib/External/isl/isl_tab_pip.c
@@ -5934,7 +5934,7 @@
 			pma = isl_pw_multi_aff_free(pma);
 		} else if (subs) {
 			pma = isl_pw_multi_aff_substitute(pma,
-					isl_dim_in, n_in - 1, min_expr_pa);
+					n_in - 1, min_expr_pa);
 		} else {
 			isl_bool split;
 			split = need_split_set(opt->p[i].set, cst);
diff --git a/lib/External/isl/isl_test.c b/lib/External/isl/isl_test.c
index d609442..4d82f1e 100644
--- a/lib/External/isl/isl_test.c
+++ b/lib/External/isl/isl_test.c
@@ -7833,6 +7833,15 @@
 		"[n, m] -> { [1, 1, m] : 0 < m <= n }",
 		"[n, m] -> { [1, 1, 1] : 0 < m <= n }"
 	    } },
+	/* An input with implicit equality constraints among the parameters. */
+	{ "[N, M] -> { [a, b] : M >= 3 and 9 + 3M <= a <= 29 + 2N + 11M and "
+			    "2b >= M + a and 5 - 2N - M + a <= 2b <= 3 + a and "
+			    "3b >= 15 + a }",
+	  2, {
+		"[N, M] -> { [(21), (12)] : M = 3 and N >= 0 }",
+		"[N, M] -> { [(61 + 2N), (32 + N)] : M = 3 and N >= 0 }",
+	     }
+	},
 };
 
 /* Check that "vertex" corresponds to one of the vertices in data->vertex.
@@ -8693,6 +8702,34 @@
 	return 0;
 }
 
+/* Perform a projection on a basic set that is known to be empty
+ * but that has not been assigned a canonical representation.
+ * Earlier versions of isl would run into a stack overflow
+ * on this example.
+ */
+static int test_empty_projection(isl_ctx *ctx)
+{
+	const char *str;
+	isl_bool empty;
+	isl_basic_set *bset;
+
+	str = "{ [a, b, c, d, e, f, g, h] : 5f = 1 + 4a - b + 5c - d - 2e and "
+		"3h = 2 + b + c and 14c >= 9 - 3a + 25b and "
+		"4c <= 50 - 3a + 23b and 6b <= -39 + a and "
+		"9g >= -6 + 3a + b + c and e < a + b - 2d and "
+		"7d >= -5 + 2a + 2b and 5g >= -14 + a - 4b + d + 2e and "
+		"9g <= -28 - 5b - 2c + 3d + 6e }";
+	bset = isl_basic_set_read_from_str(ctx, str);
+	empty = isl_basic_set_is_empty(bset);
+	bset = isl_basic_set_params(bset);
+	isl_basic_set_free(bset);
+
+	if (empty < 0)
+		return -1;
+
+	return 0;
+}
+
 int test_fixed_power(isl_ctx *ctx)
 {
 	const char *str;
@@ -9241,133 +9278,6 @@
 }
 
 struct {
-	const char *set;
-	const char *ma;
-	const char *res;
-} preimage_tests[] = {
-	{ "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }",
-	  "{ A[j,i] -> B[i,j] }",
-	  "{ A[j,i] : 0 <= i < 10 and 0 <= j < 100 }" },
-	{ "{ rat: B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
-	  "{ A[a,b] -> B[a/2,b/6] }",
-	  "{ rat: A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 }" },
-	{ "{ B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
-	  "{ A[a,b] -> B[a/2,b/6] }",
-	  "{ A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 and "
-		    "exists i,j : a = 2 i and b = 6 j }" },
-	{ "[n] -> { S[i] : 0 <= i <= 100 }", "[n] -> { S[n] }",
-	  "[n] -> { : 0 <= n <= 100 }" },
-	{ "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
-	  "{ A[a] -> B[2a] }",
-	  "{ A[a] : 0 <= a < 50 and exists b : a = 2 b }" },
-	{ "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
-	  "{ A[a] -> B[([a/2])] }",
-	  "{ A[a] : 0 <= a < 200 and exists b : [a/2] = 4 b }" },
-	{ "{ B[i,j,k] : 0 <= i,j,k <= 100 }",
-	  "{ A[a] -> B[a,a,a/3] }",
-	  "{ A[a] : 0 <= a <= 100 and exists b : a = 3 b }" },
-	{ "{ B[i,j] : j = [(i)/2] } ", "{ A[i,j] -> B[i/3,j] }",
-	  "{ A[i,j] : j = [(i)/6] and exists a : i = 3 a }" },
-};
-
-static int test_preimage_basic_set(isl_ctx *ctx)
-{
-	int i;
-	isl_basic_set *bset1, *bset2;
-	isl_multi_aff *ma;
-	int equal;
-
-	for (i = 0; i < ARRAY_SIZE(preimage_tests); ++i) {
-		bset1 = isl_basic_set_read_from_str(ctx, preimage_tests[i].set);
-		ma = isl_multi_aff_read_from_str(ctx, preimage_tests[i].ma);
-		bset2 = isl_basic_set_read_from_str(ctx, preimage_tests[i].res);
-		bset1 = isl_basic_set_preimage_multi_aff(bset1, ma);
-		equal = isl_basic_set_is_equal(bset1, bset2);
-		isl_basic_set_free(bset1);
-		isl_basic_set_free(bset2);
-		if (equal < 0)
-			return -1;
-		if (!equal)
-			isl_die(ctx, isl_error_unknown, "bad preimage",
-				return -1);
-	}
-
-	return 0;
-}
-
-struct {
-	const char *map;
-	const char *ma;
-	const char *res;
-} preimage_domain_tests[] = {
-	{ "{ B[i,j] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }",
-	  "{ A[j,i] -> B[i,j] }",
-	  "{ A[j,i] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }" },
-	{ "{ B[i] -> C[i]; D[i] -> E[i] }",
-	  "{ A[i] -> B[i + 1] }",
-	  "{ A[i] -> C[i + 1] }" },
-	{ "{ B[i] -> C[i]; B[i] -> E[i] }",
-	  "{ A[i] -> B[i + 1] }",
-	  "{ A[i] -> C[i + 1]; A[i] -> E[i + 1] }" },
-	{ "{ B[i] -> C[([i/2])] }",
-	  "{ A[i] -> B[2i] }",
-	  "{ A[i] -> C[i] }" },
-	{ "{ B[i,j] -> C[([i/2]), ([(i+j)/3])] }",
-	  "{ A[i] -> B[([i/5]), ([i/7])] }",
-	  "{ A[i] -> C[([([i/5])/2]), ([(([i/5])+([i/7]))/3])] }" },
-	{ "[N] -> { B[i] -> C[([N/2]), i, ([N/3])] }",
-	  "[N] -> { A[] -> B[([N/5])] }",
-	  "[N] -> { A[] -> C[([N/2]), ([N/5]), ([N/3])] }" },
-	{ "{ B[i] -> C[i] : exists a : i = 5 a }",
-	  "{ A[i] -> B[2i] }",
-	  "{ A[i] -> C[2i] : exists a : 2i = 5 a }" },
-	{ "{ B[i] -> C[i] : exists a : i = 2 a; "
-	    "B[i] -> D[i] : exists a : i = 2 a + 1 }",
-	  "{ A[i] -> B[2i] }",
-	  "{ A[i] -> C[2i] }" },
-	{ "{ A[i] -> B[i] }", "{ C[i] -> A[(i + floor(i/3))/2] }",
-	  "{ C[i] -> B[j] : 2j = i + floor(i/3) }" },
-};
-
-static int test_preimage_union_map(isl_ctx *ctx)
-{
-	int i;
-	isl_union_map *umap1, *umap2;
-	isl_multi_aff *ma;
-	int equal;
-
-	for (i = 0; i < ARRAY_SIZE(preimage_domain_tests); ++i) {
-		umap1 = isl_union_map_read_from_str(ctx,
-						preimage_domain_tests[i].map);
-		ma = isl_multi_aff_read_from_str(ctx,
-						preimage_domain_tests[i].ma);
-		umap2 = isl_union_map_read_from_str(ctx,
-						preimage_domain_tests[i].res);
-		umap1 = isl_union_map_preimage_domain_multi_aff(umap1, ma);
-		equal = isl_union_map_is_equal(umap1, umap2);
-		isl_union_map_free(umap1);
-		isl_union_map_free(umap2);
-		if (equal < 0)
-			return -1;
-		if (!equal)
-			isl_die(ctx, isl_error_unknown, "bad preimage",
-				return -1);
-	}
-
-	return 0;
-}
-
-static int test_preimage(isl_ctx *ctx)
-{
-	if (test_preimage_basic_set(ctx) < 0)
-		return -1;
-	if (test_preimage_union_map(ctx) < 0)
-		return -1;
-
-	return 0;
-}
-
-struct {
 	const char *ma1;
 	const char *ma;
 	const char *res;
@@ -10813,7 +10723,6 @@
 	{ "list", &test_list },
 	{ "align parameters", &test_align_parameters },
 	{ "drop unused parameters", &test_drop_unused_parameters },
-	{ "preimage", &test_preimage },
 	{ "pullback", &test_pullback },
 	{ "AST", &test_ast },
 	{ "AST build", &test_ast_build },
@@ -10825,6 +10734,7 @@
 	{ "slice", &test_slice },
 	{ "fixed power", &test_fixed_power },
 	{ "sample", &test_sample },
+	{ "empty projection", &test_empty_projection },
 	{ "output", &test_output },
 	{ "vertices", &test_vertices },
 	{ "chambers", &test_chambers },
diff --git a/lib/External/isl/isl_test2.cc b/lib/External/isl/isl_test2.cc
new file mode 100644
index 0000000..7b64d6f
--- /dev/null
+++ b/lib/External/isl/isl_test2.cc
@@ -0,0 +1,192 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <isl/cpp.h>
+
+/* A binary isl function that appears in the C++ bindings
+ * as a unary method in a class T, taking an extra argument
+ * of type A1 and returning an object of type R.
+ */
+template <typename A1, typename R, typename T>
+using binary_fn = R (T::*)(A1) const;
+
+/* A function for selecting an overload of a pointer to a unary C++ method
+ * based on the single argument type.
+ * The object type and the return type are meant to be deduced.
+ */
+template <typename A1, typename R, typename T>
+static binary_fn<A1, R, T> const arg(const binary_fn<A1, R, T> &fn)
+{
+	return fn;
+}
+
+/* A description of the inputs and the output of a binary operation.
+ */
+struct binary {
+	const char *arg1;
+	const char *arg2;
+	const char *res;
+};
+
+/* A template function for checking whether two objects
+ * of the same (isl) type are (obviously) equal.
+ * The spelling depends on the isl type and
+ * in particular on whether an equality method is available or
+ * whether only obvious equality can be tested.
+ */
+template <typename T, typename std::decay<decltype(
+	std::declval<T>().is_equal(std::declval<T>()))>::type = true>
+static bool is_equal(const T &a, const T &b)
+{
+	return a.is_equal(b);
+}
+template <typename T, typename std::decay<decltype(
+	std::declval<T>().plain_is_equal(std::declval<T>()))>::type = true>
+static bool is_equal(const T &a, const T &b)
+{
+	return a.plain_is_equal(b);
+}
+
+/* A helper macro for throwing an isl::exception_invalid with message "msg".
+ */
+#define THROW_INVALID(msg) \
+	isl::exception::throw_error(isl_error_invalid, msg, __FILE__, __LINE__)
+
+/* Run a sequence of tests of method "fn" with stringification "name" and
+ * with inputs and output described by "test",
+ * throwing an exception when an unexpected result is produced.
+ */
+template <typename R, typename T, typename A1>
+static void test(isl::ctx ctx, R (T::*fn)(A1) const, const std::string &name,
+	const std::vector<binary> &tests)
+{
+	for (const auto &test : tests) {
+		T obj(ctx, test.arg1);
+		A1 arg1(ctx, test.arg2);
+		R expected(ctx, test.res);
+		const auto &res = (obj.*fn)(arg1);
+		std::ostringstream ss;
+
+		if (is_equal(expected, res))
+			continue;
+
+		ss << name << "(" << test.arg1 << ", " << test.arg2 << ") =\n"
+		   << res << "\n"
+		   << "expecting:\n"
+		   << test.res;
+		THROW_INVALID(ss.str().c_str());
+	}
+}
+
+/* A helper macro that calls test with as implicit initial argument "ctx" and
+ * as extra argument a stringification of "FN".
+ */
+#define C(FN, ...) test(ctx, FN, #FN, __VA_ARGS__)
+
+/* Perform some basic preimage tests.
+ */
+static void test_preimage(isl::ctx ctx)
+{
+	C(arg<isl::multi_aff>(&isl::set::preimage), {
+	{ "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }",
+	  "{ A[j,i] -> B[i,j] }",
+	  "{ A[j,i] : 0 <= i < 10 and 0 <= j < 100 }" },
+	{ "{ rat: B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
+	  "{ A[a,b] -> B[a/2,b/6] }",
+	  "{ rat: A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 }" },
+	{ "{ B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
+	  "{ A[a,b] -> B[a/2,b/6] }",
+	  "{ A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 and "
+		    "exists i,j : a = 2 i and b = 6 j }" },
+	{ "[n] -> { S[i] : 0 <= i <= 100 }", "[n] -> { S[n] }",
+	  "[n] -> { : 0 <= n <= 100 }" },
+	{ "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
+	  "{ A[a] -> B[2a] }",
+	  "{ A[a] : 0 <= a < 50 and exists b : a = 2 b }" },
+	{ "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
+	  "{ A[a] -> B[([a/2])] }",
+	  "{ A[a] : 0 <= a < 200 and exists b : [a/2] = 4 b }" },
+	{ "{ B[i,j,k] : 0 <= i,j,k <= 100 }",
+	  "{ A[a] -> B[a,a,a/3] }",
+	  "{ A[a] : 0 <= a <= 100 and exists b : a = 3 b }" },
+	{ "{ B[i,j] : j = [(i)/2] } ", "{ A[i,j] -> B[i/3,j] }",
+	  "{ A[i,j] : j = [(i)/6] and exists a : i = 3 a }" },
+	});
+
+	C(arg<isl::multi_aff>(&isl::union_map::preimage_domain), {
+	{ "{ B[i,j] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }",
+	  "{ A[j,i] -> B[i,j] }",
+	  "{ A[j,i] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }" },
+	{ "{ B[i] -> C[i]; D[i] -> E[i] }",
+	  "{ A[i] -> B[i + 1] }",
+	  "{ A[i] -> C[i + 1] }" },
+	{ "{ B[i] -> C[i]; B[i] -> E[i] }",
+	  "{ A[i] -> B[i + 1] }",
+	  "{ A[i] -> C[i + 1]; A[i] -> E[i + 1] }" },
+	{ "{ B[i] -> C[([i/2])] }",
+	  "{ A[i] -> B[2i] }",
+	  "{ A[i] -> C[i] }" },
+	{ "{ B[i,j] -> C[([i/2]), ([(i+j)/3])] }",
+	  "{ A[i] -> B[([i/5]), ([i/7])] }",
+	  "{ A[i] -> C[([([i/5])/2]), ([(([i/5])+([i/7]))/3])] }" },
+	{ "[N] -> { B[i] -> C[([N/2]), i, ([N/3])] }",
+	  "[N] -> { A[] -> B[([N/5])] }",
+	  "[N] -> { A[] -> C[([N/2]), ([N/5]), ([N/3])] }" },
+	{ "{ B[i] -> C[i] : exists a : i = 5 a }",
+	  "{ A[i] -> B[2i] }",
+	  "{ A[i] -> C[2i] : exists a : 2i = 5 a }" },
+	{ "{ B[i] -> C[i] : exists a : i = 2 a; "
+	    "B[i] -> D[i] : exists a : i = 2 a + 1 }",
+	  "{ A[i] -> B[2i] }",
+	  "{ A[i] -> C[2i] }" },
+	{ "{ A[i] -> B[i] }", "{ C[i] -> A[(i + floor(i/3))/2] }",
+	  "{ C[i] -> B[j] : 2j = i + floor(i/3) }" },
+	});
+
+	C(arg<isl::multi_aff>(&isl::union_map::preimage_range), {
+	{ "[M] -> { A[a] -> B[a] }", "[M] -> { C[] -> B[floor(M/2)] }",
+	  "[M] -> { A[floor(M/2)] -> C[] }" },
+	});
+}
+
+/* The list of tests to perform.
+ */
+static std::vector<std::pair<const char *, void (*)(isl::ctx)>> tests =
+{
+	{ "preimage", &test_preimage },
+};
+
+/* Perform some basic checks by means of the C++ bindings.
+ */
+int main(int argc, char **argv)
+{
+	int ret = EXIT_SUCCESS;
+	struct isl_ctx *ctx;
+	struct isl_options *options;
+
+	options = isl_options_new_with_defaults();
+	assert(options);
+	argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL);
+	ctx = isl_ctx_alloc_with_options(&isl_options_args, options);
+
+	try {
+		for (const auto &f : tests) {
+			std::cout << f.first << "\n";
+			f.second(ctx);
+		}
+	} catch (const isl::exception &e) {
+		std::cerr << e.what() << "\n";
+		ret = EXIT_FAILURE;
+	}
+
+	isl_ctx_free(ctx);
+	return ret;
+}
diff --git a/lib/External/isl/isl_test_cpp.cc b/lib/External/isl/isl_test_cpp.cc
index 6d448f0..d606a21 100644
--- a/lib/External/isl/isl_test_cpp.cc
+++ b/lib/External/isl/isl_test_cpp.cc
@@ -13,7 +13,7 @@
 #include <string.h>
 
 #include <isl/options.h>
-#include <isl/cpp.h>
+#include <isl/typed_cpp.h>
 
 static void die_impl(const char *file, int line, const char *message)
 {
@@ -284,6 +284,27 @@
 	assert(count_ast_fail == 2);
 }
 
+/* Basic test of the templated interface.
+ *
+ * Intersecting the domain of an access relation
+ * with statement instances should be allowed,
+ * while intersecting the range with statement instances
+ * should result in a compile-time error.
+ */
+static void test_typed(isl::ctx ctx)
+{
+	struct ST {};
+	struct AR {};
+	isl::typed::map<ST, AR> access(ctx, "{ S[i, j] -> A[i] }");
+	isl::typed::set<ST> instances(ctx, "{ S[i, j] : 0 <= i, j < 10 }");
+
+#ifndef COMPILE_ERROR
+	access.intersect_domain(instances);
+#else
+	access.intersect_range(instances);
+#endif
+}
+
 /* Test the (unchecked) isl C++ interface
  *
  * This includes:
@@ -297,6 +318,7 @@
  *  - Schedule trees
  *  - AST generation
  *  - AST expression generation
+ *  - Templated interface
  */
 int main()
 {
@@ -315,6 +337,7 @@
 	test_schedule_tree(ctx);
 	test_ast_build(ctx);
 	test_ast_build_expr(ctx);
+	test_typed(ctx);
 
 	isl_ctx_free(ctx);
 
diff --git a/lib/External/isl/isl_test_cpp_failed.sh b/lib/External/isl/isl_test_cpp_failed.sh
new file mode 100755
index 0000000..090a89e
--- /dev/null
+++ b/lib/External/isl/isl_test_cpp_failed.sh
@@ -0,0 +1,8 @@
+#/bin/sh
+# Check that isl_test_cpp_failed CANNOT be built.
+# Note that the failed build may leave behind a temporary dependence
+# tracking object, which should be removed.
+make isl_test_cpp_failed
+ret=$?
+rm -f .deps/isl_test_cpp_failed-isl_test_cpp.Tpo
+test $ret -ne 0
diff --git a/lib/External/isl/isl_test_python.py b/lib/External/isl/isl_test_python.py
index 5373f96..443f5a1 100755
--- a/lib/External/isl/isl_test_python.py
+++ b/lib/External/isl/isl_test_python.py
@@ -183,7 +183,7 @@
 	assert(not list[1].is_equal(list[2]))
 
 	def fail(bs):
-		raise "fail"
+		raise Exception("fail")
 
 	caught = False
 	try:
@@ -217,7 +217,7 @@
 	assert(not us.every_set(not_in_A))
 
 	def fail(s):
-		raise "fail"
+		raise Exception("fail")
 
 	caught = False
 	try:
@@ -289,7 +289,7 @@
 	assert(count[0] == 8)
 
 	def fail_map(node):
-		raise "fail"
+		raise Exception("fail")
 		return node
 	caught = False
 	try:
@@ -318,7 +318,7 @@
 	assert(not root.every_descendant(is_not_domain))
 
 	def fail(node):
-		raise "fail"
+		raise Exception("fail")
 	caught = False
 	try:
 		root.every_descendant(fail)
@@ -392,7 +392,7 @@
 	def fail_inc_count_ast(node, build):
 		count_ast_fail[0] += 1
 		if do_fail:
-			raise "fail"
+			raise Exception("fail")
 		return node
 	build = isl.ast_build()
 	build = build.set_at_each_domain(fail_inc_count_ast)
diff --git a/lib/External/isl/isl_union_map.c b/lib/External/isl/isl_union_map.c
index bd93dcc..2ea129b 100644
--- a/lib/External/isl/isl_union_map.c
+++ b/lib/External/isl/isl_union_map.c
@@ -523,11 +523,27 @@
 	return umap;
 }
 
+/* This function performs the same operation as isl_union_map_from_map,
+ * but is considered as a function on an isl_map when exported.
+ */
+__isl_give isl_union_map *isl_map_to_union_map(__isl_take isl_map *map)
+{
+	return isl_union_map_from_map(map);
+}
+
 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
 {
 	return isl_union_map_from_map(set_to_map(set));
 }
 
+/* This function performs the same operation as isl_union_set_from_set,
+ * but is considered as a function on an isl_set when exported.
+ */
+__isl_give isl_union_set *isl_set_to_union_set(__isl_take isl_set *set)
+{
+	return isl_union_set_from_set(set);
+}
+
 __isl_give isl_union_map *isl_union_map_from_basic_map(
 	__isl_take isl_basic_map *bmap)
 {
@@ -731,11 +747,27 @@
 	return NULL;
 }
 
+/* This function performs the same operation as isl_map_from_union_map,
+ * but is considered as a function on an isl_union_map when exported.
+ */
+__isl_give isl_map *isl_union_map_as_map(__isl_take isl_union_map *umap)
+{
+	return isl_map_from_union_map(umap);
+}
+
 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset)
 {
 	return isl_map_from_union_map(uset);
 }
 
+/* This function performs the same operation as isl_set_from_union_set,
+ * but is considered as a function on an isl_union_set when exported.
+ */
+__isl_give isl_set *isl_union_set_as_set(__isl_take isl_union_set *uset)
+{
+	return isl_set_from_union_set(uset);
+}
+
 /* Extract the map in "umap" that lives in the given space (ignoring
  * parameters).
  */
diff --git a/lib/External/isl/isl_union_templ.c b/lib/External/isl/isl_union_templ.c
index 9439d9b..d16ccd9 100644
--- a/lib/External/isl/isl_union_templ.c
+++ b/lib/External/isl/isl_union_templ.c
@@ -543,6 +543,14 @@
 	return u;
 }
 
+/* This function performs the same operation as isl_union_pw_*_from_pw_*,
+ * but is considered as a function on an isl_pw_* when exported.
+ */
+__isl_give UNION *FN(FN(PART,to_union),BASE)(__isl_take PART *part)
+{
+	return FN(FN(UNION,from),BASE)(part);
+}
+
 S(UNION,match_bin_data) {
 	UNION *u2;
 	UNION *res;
diff --git a/lib/External/isl/isl_val.c b/lib/External/isl/isl_val.c
index dc6f714..3744aa7 100644
--- a/lib/External/isl/isl_val.c
+++ b/lib/External/isl/isl_val.c
@@ -15,6 +15,7 @@
 #define EL_BASE val
 
 #include <isl_list_templ.c>
+#include <isl_list_read_templ.c>
 
 /* Allocate an isl_val object with indeterminate value.
  */
diff --git a/lib/External/isl/isl_vertices.c b/lib/External/isl/isl_vertices.c
index 120deab..fd1a2ee 100644
--- a/lib/External/isl/isl_vertices.c
+++ b/lib/External/isl/isl_vertices.c
@@ -324,12 +324,11 @@
  * and map the resulting vertices back.
  */
 static __isl_give isl_vertices *lower_dim_vertices(
-	__isl_keep isl_basic_set *bset)
+	__isl_take isl_basic_set *bset)
 {
 	isl_morph *morph;
 	isl_vertices *vertices;
 
-	bset = isl_basic_set_copy(bset);
 	morph = isl_basic_set_full_compression(bset);
 	bset = isl_morph_basic_set(isl_morph_copy(morph), bset);
 
@@ -344,6 +343,37 @@
 }
 
 /* Compute the parametric vertices and the chamber decomposition
+ * of a parametric polytope "bset" that is not full-dimensional.
+ * Additionally, free both "copy" and "tab".
+ */
+static __isl_give isl_vertices *lower_dim_vertices_free(
+	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *copy,
+	struct isl_tab *tab)
+{
+	isl_basic_set_free(copy);
+	isl_tab_free(tab);
+	return lower_dim_vertices(bset);
+}
+
+/* Detect implicit equality constraints in "bset" using the tableau
+ * representation "tab".
+ * Return a copy of "bset" with the implicit equality constraints
+ * made explicit, leaving the original "bset" unmodified.
+ */
+static __isl_give isl_basic_set *detect_implicit_equality_constraints(
+	__isl_keep isl_basic_set *bset, struct isl_tab *tab)
+{
+	if (isl_tab_detect_implicit_equalities(tab) < 0)
+		return NULL;
+
+	bset = isl_basic_set_copy(bset);
+	bset = isl_basic_set_cow(bset);
+	bset = isl_basic_set_update_from_tab(bset, tab);
+
+	return bset;
+}
+
+/* Compute the parametric vertices and the chamber decomposition
  * of the parametric polytope defined using the same constraints
  * as "bset".  "bset" is assumed to have no existentially quantified
  * variables.
@@ -352,10 +382,23 @@
  * We simply run through all combinations of d constraints,
  * with d the number of set variables, and check if those d constraints
  * define a vertex.  To avoid the generation of duplicate vertices,
- * which we may happen if a vertex is defined by more that d constraints,
+ * which may happen if a vertex is defined by more than d constraints,
  * we make sure we only generate the vertex for the d constraints with
  * smallest index.
  *
+ * Only potential vertices with a full-dimensional activity domain
+ * are considered.  However, if the input has (implicit) equality
+ * constraints among the parameters, then activity domain
+ * should be considered full-dimensional if it does not satisfy
+ * any extra equality constraints beyond those of the input.
+ * The implicit equality constraints of the input are therefore first detected.
+ * If there are any, then the input is mapped to a lower dimensional space
+ * such that the check for full-dimensional activity domains
+ * can be performed with respect to a full-dimensional space.
+ * Note that it is important to leave "bset" unmodified while detecting
+ * equality constraints since the inequality constraints of "bset"
+ * are assumed to correspond to those of the tableau.
+ *
  * We set up a tableau and keep track of which facets have been
  * selected.  The tableau is marked strict_redundant so that we can be
  * sure that any constraint that is marked redundant (and that is not
@@ -378,6 +421,7 @@
 	struct isl_tab *tab;
 	int level;
 	int init;
+	isl_size n_eq;
 	isl_size nvar;
 	int *selection = NULL;
 	int selected;
@@ -386,6 +430,8 @@
 	struct isl_vertex_list *list = NULL;
 	int n_vertices = 0;
 	isl_vertices *vertices;
+	isl_basic_set *copy;
+	isl_basic_set *test;
 
 	if (!bset)
 		return NULL;
@@ -394,7 +440,7 @@
 		return vertices_empty(bset);
 
 	if (bset->n_eq != 0)
-		return lower_dim_vertices(bset);
+		return lower_dim_vertices(isl_basic_set_copy(bset));
 
 	if (isl_basic_set_check_no_locals(bset) < 0)
 		return NULL;
@@ -405,27 +451,35 @@
 	if (nvar == 0)
 		return vertices_0D(bset);
 
-	bset = isl_basic_set_copy(bset);
-	bset = isl_basic_set_set_rational(bset);
-	if (!bset)
+	copy = isl_basic_set_copy(bset);
+	copy = isl_basic_set_set_rational(copy);
+	if (!copy)
 		return NULL;
 
-	tab = isl_tab_from_basic_set(bset, 0);
+	tab = isl_tab_from_basic_set(copy, 0);
 	if (!tab)
 		goto error;
 	tab->strict_redundant = 1;
 
 	if (tab->empty)	{
-		vertices = vertices_empty(bset);
-		isl_basic_set_free(bset);
+		vertices = vertices_empty(copy);
+		isl_basic_set_free(copy);
 		isl_tab_free(tab);
 		return vertices;
 	}
 
-	selection = isl_alloc_array(bset->ctx, int, bset->n_ineq);
-	snap = isl_alloc_array(bset->ctx, struct isl_tab_undo *, bset->n_ineq);
-	facets = isl_mat_alloc(bset->ctx, nvar, nvar);
-	if ((bset->n_ineq && (!selection || !snap)) || !facets)
+	test = detect_implicit_equality_constraints(bset, tab);
+	n_eq = isl_basic_set_n_equality(test);
+	if (n_eq < 0)
+		test = isl_basic_set_free(test);
+	if (n_eq < 0 || n_eq > 0)
+		return lower_dim_vertices_free(test, copy, tab);
+	isl_basic_set_free(test);
+
+	selection = isl_alloc_array(copy->ctx, int, copy->n_ineq);
+	snap = isl_alloc_array(copy->ctx, struct isl_tab_undo *, copy->n_ineq);
+	facets = isl_mat_alloc(copy->ctx, nvar, nvar);
+	if ((copy->n_ineq && (!selection || !snap)) || !facets)
 		goto error;
 
 	level = 0;
@@ -433,7 +487,7 @@
 	selected = 0;
 
 	while (level >= 0) {
-		if (level >= bset->n_ineq ||
+		if (level >= copy->n_ineq ||
 		    (!init && selection[level] != SELECTED)) {
 			--level;
 			init = 0;
@@ -442,7 +496,7 @@
 		if (init) {
 			isl_bool ok;
 			snap[level] = isl_tab_snap(tab);
-			ok = can_select(bset, level, tab, facets, selected,
+			ok = can_select(copy, level, tab, facets, selected,
 					selection);
 			if (ok < 0)
 				goto error;
@@ -459,7 +513,7 @@
 		}
 		if (selected == nvar) {
 			if (tab->n_dead == nvar) {
-				isl_bool added = add_vertex(&list, bset, tab);
+				isl_bool added = add_vertex(&list, copy, tab);
 				if (added < 0)
 					goto error;
 				if (added)
@@ -478,9 +532,9 @@
 
 	isl_tab_free(tab);
 
-	vertices = vertices_from_list(bset, n_vertices, list);
+	vertices = vertices_from_list(copy, n_vertices, list);
 
-	vertices = compute_chambers(bset, vertices);
+	vertices = compute_chambers(copy, vertices);
 
 	return vertices;
 error:
@@ -489,7 +543,7 @@
 	free(selection);
 	free(snap);
 	isl_tab_free(tab);
-	isl_basic_set_free(bset);
+	isl_basic_set_free(copy);
 	return NULL;
 }
 
@@ -862,6 +916,7 @@
 {
 	int i;
 	isl_ctx *ctx;
+	isl_size n_eq;
 	isl_vec *sample = NULL;
 	struct isl_tab *tab = NULL;
 	struct isl_tab_undo *snap;
@@ -879,6 +934,12 @@
 		goto error;
 
 	bset = isl_basic_set_params(bset);
+	n_eq = isl_basic_set_n_equality(bset);
+	if (n_eq < 0)
+		goto error;
+	if (n_eq > 0)
+		isl_die(isl_basic_set_get_ctx(bset), isl_error_internal,
+			"expecting full-dimensional input", goto error);
 
 	tab = isl_tab_from_basic_set(bset, 1);
 	if (!tab)
diff --git a/lib/External/isl/ltmain.sh b/lib/External/isl/ltmain.sh
index 0cb7f90..48cea9b 100644
--- a/lib/External/isl/ltmain.sh
+++ b/lib/External/isl/ltmain.sh
@@ -1,12 +1,12 @@
 #! /bin/sh
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2014-01-03.01
+##               by inline-source v2018-07-24.06
 
-# libtool (GNU libtool) 2.4.6
+# libtool (GNU libtool) 2.4.6.42-b88ce-dirty
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -31,8 +31,8 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-14"
-package_revision=2.4.6
+VERSION=2.4.6.42-b88ce-dirty
+package_revision=2.4.6.42
 
 
 ## ------ ##
@@ -64,34 +64,25 @@
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2015-01-20.17; # UTC
+scriptversion=2018-07-24.06; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
 
-# Copyright (C) 2004-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2004-2018 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
 
 ## ------ ##
@@ -140,9 +131,6 @@
 	fi"
 done
 
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -159,6 +147,26 @@
 fi
 
 
+# func_unset VAR
+# --------------
+# Portably unset VAR.
+# In some shells, an 'unset VAR' statement leaves a non-zero return
+# status if VAR is already unset, which might be problematic if the
+# statement is used at the end of a function (thus poisoning its return
+# value) or when 'set -e' is active (causing even a spurious abort of
+# the script in this case).
+func_unset ()
+{
+    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
+}
+
+
+# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
+func_unset CDPATH
+
+# Make sure ${,E,F}GREP behave sanely.
+func_unset GREP_OPTIONS
+
 
 ## ------------------------- ##
 ## Locate command utilities. ##
@@ -259,7 +267,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
   rm -f conftest.sed
   SED=$func_path_progs_result
 }
@@ -295,7 +303,7 @@
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
   GREP=$func_path_progs_result
 }
 
@@ -387,7 +395,7 @@
 # putting '$debug_cmd' at the start of all your functions, you can get
 # bash to show function call trace with:
 #
-#    debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
 debug_cmd=${debug_cmd-":"}
 exit_cmd=:
 
@@ -580,16 +588,16 @@
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1+=\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_for_eval "$2"
-    eval "$1=\$$1\\ \$func_quote_for_eval_result"
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
   }
 fi
 
@@ -1091,85 +1099,199 @@
 }
 
 
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-#   i) func_quote_for_eval_result
-#      double-quoted, suitable for a subsequent eval
-#  ii) func_quote_for_eval_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.
-func_quote_for_eval ()
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
 {
     $debug_cmd
 
-    func_quote_for_eval_unquoted_result=
-    func_quote_for_eval_result=
-    while test 0 -lt $#; do
-      case $1 in
+    func_quote_portable_result=$2
+
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
+      fi
+
+      # Quote for eval.
+      case $func_quote_portable_result in
         *[\\\`\"\$]*)
-	  _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
-        *)
-          _G_unquoted_arg=$1 ;;
-      esac
-      if test -n "$func_quote_for_eval_unquoted_result"; then
-	func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
-      else
-        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
-      fi
+          case $func_quote_portable_result in
+            *[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
 
-      case $_G_unquoted_arg in
-        # Double-quote args containing shell metacharacters to delay
-        # word splitting, command substitution and variable expansion
-        # for a subsequent eval.
-        # Many Bourne shells cannot handle close brackets correctly
-        # in scan sets, so we specify it separately.
-        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-          _G_quoted_arg=\"$_G_unquoted_arg\"
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
           ;;
-        *)
-          _G_quoted_arg=$_G_unquoted_arg
-	  ;;
+        *) ;;
       esac
-
-      if test -n "$func_quote_for_eval_result"; then
-	func_append func_quote_for_eval_result " $_G_quoted_arg"
-      else
-        func_append func_quote_for_eval_result "$_G_quoted_arg"
-      fi
-      shift
+      break
     done
+
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
 }
 
 
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
+
+
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero or more
+# specifiers listed below separated by ',' character.  This function returns two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         be used later in func_quote to get output like: 'echo "a b"' instead
+#         of 'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
 {
-    $debug_cmd
-
-    case $1 in
-      *[\\\`\"]*)
-	_G_arg=`$ECHO "$1" | $SED \
-	    -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
-      *)
-        _G_arg=$1 ;;
-    esac
-
-    case $_G_arg in
-      # Double-quote args containing shell metacharacters to delay
-      # word splitting and command substitution for a subsequent eval.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-        _G_arg=\"$_G_arg\"
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
         ;;
     esac
 
-    func_quote_for_expand_result=$_G_arg
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
+        ;;
+    esac
+}
+
+
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
 }
 
 
@@ -1215,8 +1337,8 @@
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_for_expand "$_G_cmd"
-    eval "func_notquiet $func_quote_for_expand_result"
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1241,8 +1363,8 @@
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_for_expand "$_G_cmd"
-      eval "func_echo $func_quote_for_expand_result"
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
     }
 
     $opt_dry_run || {
@@ -1369,30 +1491,26 @@
 # End:
 #! /bin/sh
 
-# Set a version string for this script.
-scriptversion=2015-10-07.11; # UTC
-
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
 
-# Copyright (C) 2010-2015 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2010-2018 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# <https://opensource.org/license/MIT>, and GPL version 3 or later
+# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# Please report bugs or propose patches to:
+# <https://github.com/gnulib-modules/bootstrap/issues>
 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
+# Set a version string for this script.
+scriptversion=2018-07-24.06; # UTC
 
 
 ## ------ ##
@@ -1415,7 +1533,7 @@
 #
 # In order for the '--version' option to work, you will need to have a
 # suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
+# starting with '# Written by ' and ending with '# Copyright'.
 #
 # For '-h' and '--help' to work, you will also need a one line
 # description of your script's purpose in a comment directly above the
@@ -1427,7 +1545,7 @@
 # to display verbose messages only when your user has specified
 # '--verbose'.
 #
-# After sourcing this file, you can plug processing for additional
+# After sourcing this file, you can plug in processing for additional
 # options by amending the variables from the 'Configuration' section
 # below, and following the instructions in the 'Option parsing'
 # section further down.
@@ -1476,8 +1594,8 @@
 ## ------------------------- ##
 
 # This section contains functions for adding, removing, and running hooks
-# to the main code.  A hook is just a named list of of function, that can
-# be run in order later on.
+# in the main code.  A hook is just a list of function names that can be
+# run in order later on.
 
 # func_hookable FUNC_NAME
 # -----------------------
@@ -1510,7 +1628,8 @@
 
 # func_remove_hook FUNC_NAME HOOK_FUNC
 # ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+# Remove HOOK_FUNC from the list of hook functions to be called by
+# FUNC_NAME.
 func_remove_hook ()
 {
     $debug_cmd
@@ -1519,10 +1638,28 @@
 }
 
 
+# func_propagate_result FUNC_NAME_A FUNC_NAME_B
+# ---------------------------------------------
+# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
+# *_result variable of FUNC_NAME_B.
+func_propagate_result ()
+{
+    $debug_cmd
+
+    func_propagate_result_result=:
+    if eval "test \"\${${1}_result+set}\" = set"
+    then
+      eval "${2}_result=\$${1}_result"
+    else
+      func_propagate_result_result=false
+    fi
+}
+
+
 # func_run_hooks FUNC_NAME [ARG]...
 # ---------------------------------
 # Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
+# It's assumed that the list of hook functions contains nothing more
 # than a whitespace-delimited list of legal shell function names, and
 # no effort is wasted trying to catch shell meta-characters or preserve
 # whitespace.
@@ -1530,26 +1667,21 @@
 {
     $debug_cmd
 
-    _G_rc_run_hooks=false
-
     case " $hookable_fns " in
       *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+      *) func_fatal_error "'$1' does not support hook functions." ;;
     esac
 
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      if eval $_G_hook '"$@"'; then
-        # store returned options list back into positional
-        # parameters for next 'cmd' execution.
-        eval _G_hook_result=\$${_G_hook}_result
-        eval set dummy "$_G_hook_result"; shift
-        _G_rc_run_hooks=:
+      func_unset "${_G_hook}_result"
+      eval $_G_hook '${1+"$@"}'
+      func_propagate_result $_G_hook func_run_hooks
+      if $func_propagate_result_result; then
+        eval set dummy "$func_run_hooks_result"; shift
       fi
     done
-
-    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
 }
 
 
@@ -1559,14 +1691,16 @@
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, you may remove/edit
-# any options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
-# hook's caller know that it should pay attention to
-# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
-# arguments are left untouched by the hook and therefore caller will ignore the
-# result variable.
+# full positional parameter list from your hook function.  You may remove
+# or edit any options that you action, and then pass back the remaining
+# unprocessed options in '<hooked_function_name>_result', escaped
+# suitably for 'eval'.
+#
+# The '<hooked_function_name>_result' variable is automatically unset
+# before your hook gets called; for best performance, only set the
+# *_result variable when necessary (i.e. don't call the 'func_quote'
+# function unnecessarily because it can be an expensive operation on some
+# machines).
 #
 # Like this:
 #
@@ -1578,11 +1712,8 @@
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#        # No change in '$@' (ignored completely by this hook).  There is
-#        # no need to do the equivalent (but slower) action:
-#        # func_quote_for_eval ${1+"$@"}
-#        # my_options_prep_result=$func_quote_for_eval_result
-#        false
+#        # No change in '$@' (ignored completely by this hook).  Leave
+#        # my_options_prep_result variable intact.
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1593,7 +1724,7 @@
 #
 #        args_changed=false
 #
-#        # Note that for efficiency, we parse as many options as we can
+#        # Note that, for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
@@ -1610,18 +1741,17 @@
 #                         args_changed=:
 #                         ;;
 #            *)           # Make sure the first unrecognised option "$_G_opt"
-#                         # is added back to "$@", we could need that later
-#                         # if $args_changed is true.
+#                         # is added back to "$@" in case we need it later,
+#                         # if $args_changed was set to 'true'.
 #                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
 #          esac
 #        done
 #
+#        # Only call 'func_quote' here if we processed at least one argument.
 #        if $args_changed; then
-#          func_quote_for_eval ${1+"$@"}
-#          my_silent_option_result=$func_quote_for_eval_result
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
 #        fi
-#
-#        $args_changed
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1632,8 +1762,6 @@
 #
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
-#
-#        false
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
@@ -1649,13 +1777,8 @@
 {
     $debug_cmd
 
-    _G_func_options_finish_exit=false
-    if func_run_hooks func_options ${1+"$@"}; then
-      func_options_finish_result=$func_run_hooks_result
-      _G_func_options_finish_exit=:
-    fi
-
-    $_G_func_options_finish_exit
+    func_run_hooks func_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_finish
 }
 
 
@@ -1668,28 +1791,27 @@
 {
     $debug_cmd
 
-    _G_rc_options=false
+    _G_options_quoted=false
 
     for my_func in options_prep parse_options validate_options options_finish
     do
-      if eval func_$my_func '${1+"$@"}'; then
-        eval _G_res_var='$'"func_${my_func}_result"
-        eval set dummy "$_G_res_var" ; shift
-        _G_rc_options=:
+      func_unset func_${my_func}_result
+      func_unset func_run_hooks_result
+      eval func_$my_func '${1+"$@"}'
+      func_propagate_result func_$my_func func_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_options_result"; shift
+        _G_options_quoted=:
       fi
     done
 
-    # Save modified positional parameters for caller.  As a top-level
-    # options-parser function we always need to set the 'func_options_result'
-    # variable (regardless the $_G_rc_options value).
-    if $_G_rc_options; then
-      func_options_result=$_G_res_var
-    else
-      func_quote_for_eval ${1+"$@"}
-      func_options_result=$func_quote_for_eval_result
-    fi
-
-    $_G_rc_options
+    $_G_options_quoted || {
+      # As we (func_options) are top-level options-parser function and
+      # nobody quoted "$@" for us yet, we need to do it explicitly for
+      # caller.
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    }
 }
 
 
@@ -1699,8 +1821,7 @@
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
 # needs to propagate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
+# modified list must be put in 'func_run_hooks_result' before returning.
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1710,14 +1831,8 @@
     opt_verbose=false
     opt_warning_types=
 
-    _G_rc_options_prep=false
-    if func_run_hooks func_options_prep ${1+"$@"}; then
-      _G_rc_options_prep=:
-      # save modified positional parameters for caller
-      func_options_prep_result=$func_run_hooks_result
-    fi
-
-    $_G_rc_options_prep
+    func_run_hooks func_options_prep ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_prep
 }
 
 
@@ -1729,27 +1844,32 @@
 {
     $debug_cmd
 
-    func_parse_options_result=
-
-    _G_rc_parse_options=false
+    _G_parse_options_requote=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      if func_run_hooks func_parse_options ${1+"$@"}; then
-        eval set dummy "$func_run_hooks_result"; shift
-        _G_rc_parse_options=:
+      func_run_hooks func_parse_options ${1+"$@"}
+      func_propagate_result func_run_hooks func_parse_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_parse_options_result"; shift
+        # Even though we may have changed "$@", we passed the "$@" array
+        # down into the hook and it quoted it for us (because we are in
+        # this if-branch).  No need to quote it again.
+        _G_parse_options_requote=false
       fi
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
+      # We expect that one of the options parsed in this function matches
+      # and thus we remove _G_opt from "$@" and need to re-quote.
       _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode"
+                      func_echo "enabling shell trace mode" >&2
                       $debug_cmd
                       ;;
 
@@ -1760,7 +1880,7 @@
 
         --warnings|--warning|-W)
                       if test $# = 0 && func_missing_arg $_G_opt; then
-                        _G_rc_parse_options=:
+                        _G_parse_options_requote=:
                         break
                       fi
                       case " $warning_categories $1" in
@@ -1815,7 +1935,7 @@
                       shift
                       ;;
 
-        --)           _G_rc_parse_options=: ; break ;;
+        --)           _G_parse_options_requote=: ; break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
         *)            set dummy "$_G_opt" ${1+"$@"}; shift
                       _G_match_parse_options=false
@@ -1823,17 +1943,16 @@
                       ;;
       esac
 
-      $_G_match_parse_options && _G_rc_parse_options=:
+      if $_G_match_parse_options; then
+        _G_parse_options_requote=:
+      fi
     done
 
-
-    if $_G_rc_parse_options; then
+    if $_G_parse_options_requote; then
       # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      func_parse_options_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
     fi
-
-    $_G_rc_parse_options
 }
 
 
@@ -1846,21 +1965,14 @@
 {
     $debug_cmd
 
-    _G_rc_validate_options=false
-
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    if func_run_hooks func_validate_options ${1+"$@"}; then
-      # save modified positional parameters for caller
-      func_validate_options_result=$func_run_hooks_result
-      _G_rc_validate_options=:
-    fi
+    func_run_hooks func_validate_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_validate_options
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
-
-    $_G_rc_validate_options
 }
 
 
@@ -1916,8 +2028,8 @@
 
 # func_split_equals STRING
 # ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables
+# after splitting STRING at the '=' sign.
 test -z "$_G_HAVE_XSI_OPS" \
     && (eval 'x=a/b/c;
       test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
@@ -1932,8 +2044,9 @@
 
       func_split_equals_lhs=${1%%=*}
       func_split_equals_rhs=${1#*=}
-      test "x$func_split_equals_lhs" = "x$1" \
-        && func_split_equals_rhs=
+      if test "x$func_split_equals_lhs" = "x$1"; then
+        func_split_equals_rhs=
+      fi
   }'
 else
   # ...otherwise fall back to using expr, which is often a shell builtin.
@@ -2011,31 +2124,44 @@
 # func_version
 # ------------
 # Echo version message to standard output and exit.
+# The version message is extracted from the calling file's header
+# comments, with leading '# ' stripped:
+#   1. First display the progname and version
+#   2. Followed by the header comment line matching  /^# Written by /
+#   3. Then a blank line followed by the first following line matching
+#      /^# Copyright /
+#   4. Immediately followed by any lines between the previous matches,
+#      except lines preceding the intervening completely blank line.
+# For example, see the header comments of this file.
 func_version ()
 {
     $debug_cmd
 
     printf '%s\n' "$progname $scriptversion"
     $SED -n '
-        /(C)/!b go
-        :more
-        /\./!{
-          N
-          s|\n# | |
-          b more
+        /^# Written by /!b
+        s|^# ||; p; n
+
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
         }
-        :go
-        /^# Written by /,/# warranty; / {
-          s|^# ||
-          s|^# *$||
-          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-          p
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
         }
-        /^# Written by / {
-          s|^# ||
-          p
-        }
-        /^warranty; /q' < "$progpath"
+
+        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+        G
+        s|\(\n\)\n*|\1|g
+        p; q' < "$progpath"
 
     exit $?
 }
@@ -2045,12 +2171,12 @@
 # mode: shell-script
 # sh-indentation: 2
 # eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
 # time-stamp-time-zone: "UTC"
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6'
+scriptversion='(GNU libtool) 2.4.6.42-b88ce-dirty'
 
 
 # func_echo ARG...
@@ -2141,7 +2267,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-14
+       version:        $progname (GNU libtool) 2.4.6.42-b88ce-dirty
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
@@ -2197,7 +2323,7 @@
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
+    func_fatal_error ${1+"$@"} \
       "See the $PACKAGE documentation for more information." \
       "Fatal configuration error."
 }
@@ -2375,11 +2501,9 @@
 
     if $_G_rc_lt_options_prep; then
       # Pass back the list of options.
-      func_quote_for_eval ${1+"$@"}
-      libtool_options_prep_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
     fi
-
-    $_G_rc_lt_options_prep
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2482,11 +2606,9 @@
 
     if $_G_rc_lt_parse_options; then
       # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      libtool_parse_options_result=$func_quote_for_eval_result
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
     fi
-
-    $_G_rc_lt_parse_options
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -2543,8 +2665,8 @@
     }
 
     # Pass back the unparsed argument list
-    func_quote_for_eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_for_eval_result
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3510,8 +3632,8 @@
       esac
     done
 
-    func_quote_for_eval "$libobj"
-    test "X$libobj" != "X$func_quote_for_eval_result" \
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3584,8 +3706,8 @@
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_for_eval "$srcfile"
-    qsrcfile=$func_quote_for_eval_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4188,8 +4310,8 @@
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_for_eval "$nonopt"
-      install_prog="$func_quote_for_eval_result "
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
       arg=$1
       shift
     else
@@ -4199,8 +4321,8 @@
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_for_eval "$arg"
-    func_append install_prog "$func_quote_for_eval_result"
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4257,12 +4379,12 @@
       esac
 
       # Aesthetically quote the argument.
-      func_quote_for_eval "$arg"
-      func_append install_prog " $func_quote_for_eval_result"
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
       if test -n "$arg2"; then
-	func_quote_for_eval "$arg2"
+	func_quote_arg pretty "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_for_eval_result"
+      func_append install_shared_prog " $func_quote_arg_result"
     done
 
     test -z "$install_prog" && \
@@ -4273,8 +4395,8 @@
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-	func_quote_for_eval "$install_override_mode"
-	func_append install_shared_prog " -m $func_quote_for_eval_result"
+	func_quote_arg pretty "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_arg_result"
       fi
     fi
 
@@ -4570,8 +4692,8 @@
 	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
 	        $opt_quiet || {
-	          func_quote_for_expand "$relink_command"
-		  eval "func_echo $func_quote_for_expand_result"
+	          func_quote_arg expand,pretty "$relink_command"
+		  eval "func_echo $func_quote_arg_result"
 	        }
 	        if eval "$relink_command"; then :
 	          else
@@ -5350,7 +5472,8 @@
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5360,7 +5483,7 @@
 \$1
 _LTECHO_EOF'
 }
-    ECHO=\"$qECHO\"
+    ECHO=$qECHO
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6703,9 +6826,9 @@
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_for_eval "$arg"
-      qarg=$func_quote_for_eval_unquoted_result
-      func_append libtool_args " $func_quote_for_eval_result"
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7303,9 +7426,9 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $func_quote_for_eval_result"
-	  func_append compiler_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $func_quote_arg_result"
+	  func_append compiler_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7319,10 +7442,10 @@
 	save_ifs=$IFS; IFS=,
 	for flag in $args; do
 	  IFS=$save_ifs
-          func_quote_for_eval "$flag"
-	  func_append arg " $wl$func_quote_for_eval_result"
-	  func_append compiler_flags " $wl$func_quote_for_eval_result"
-	  func_append linker_flags " $func_quote_for_eval_result"
+          func_quote_arg pretty "$flag"
+	  func_append arg " $wl$func_quote_arg_result"
+	  func_append compiler_flags " $wl$func_quote_arg_result"
+	  func_append linker_flags " $func_quote_arg_result"
 	done
 	IFS=$save_ifs
 	func_stripname ' ' '' "$arg"
@@ -7346,8 +7469,8 @@
 
       # -msg_* for osf cc
       -msg_*)
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7368,14 +7491,12 @@
       # -stdlib=*            select c++ std lib with clang
       # -fsanitize=*         Clang/GCC memory and address sanitizer
       # -fuse-ld=*           Linker select flags for GCC
-      # -static-*            direct GCC to link specific libraries statically
-      # -fcilkplus           Cilk Plus language extension features for C/C++
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+      -specs=*|-fsanitize=*|-fuse-ld=*)
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7396,15 +7517,15 @@
 	  continue
         else
 	  # Otherwise treat like 'Some other compiler flag' below
-	  func_quote_for_eval "$arg"
-	  arg=$func_quote_for_eval_result
+	  func_quote_arg pretty "$arg"
+	  arg=$func_quote_arg_result
         fi
 	;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+        func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
 
       *.$objext)
@@ -7524,8 +7645,8 @@
       *)
 	# Unknown arguments in both finalize_command and compile_command need
 	# to be aesthetically quoted because they are evaled later.
-	func_quote_for_eval "$arg"
-	arg=$func_quote_for_eval_result
+	func_quote_arg pretty "$arg"
+	arg=$func_quote_arg_result
 	;;
       esac # arg
 
@@ -7666,10 +7787,7 @@
 	case $pass in
 	dlopen) libs=$dlfiles ;;
 	dlpreopen) libs=$dlprefiles ;;
-	link)
-	  libs="$deplibs %DEPLIBS%"
-	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-	  ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
 	esac
       fi
       if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7988,19 +8106,19 @@
 	    # It is a libtool convenience library, so add in its objects.
 	    func_append convenience " $ladir/$objdir/$old_library"
 	    func_append old_convenience " $ladir/$objdir/$old_library"
-	    tmp_libs=
-	    for deplib in $dependency_libs; do
-	      deplibs="$deplib $deplibs"
-	      if $opt_preserve_dup_deps; then
-		case "$tmp_libs " in
-		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
-		esac
-	      fi
-	      func_append tmp_libs " $deplib"
-	    done
 	  elif test prog != "$linkmode" && test lib != "$linkmode"; then
 	    func_fatal_error "'$lib' is not a convenience library"
 	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_preserve_dup_deps; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done
 	  continue
 	fi # $pass = conv
 
@@ -8924,9 +9042,6 @@
 	    revision=$number_minor
 	    lt_irix_increment=no
 	    ;;
-	  *)
-	    func_fatal_configuration "$modename: unknown library version type '$version_type'"
-	    ;;
 	  esac
 	  ;;
 	no)
@@ -10037,8 +10152,8 @@
 	    for cmd in $concat_cmds; do
 	      IFS=$save_ifs
 	      $opt_quiet || {
-		  func_quote_for_expand "$cmd"
-		  eval "func_echo $func_quote_for_expand_result"
+		  func_quote_arg expand,pretty "$cmd"
+		  eval "func_echo $func_quote_arg_result"
 	      }
 	      $opt_dry_run || eval "$cmd" || {
 		lt_exit=$?
@@ -10131,8 +10246,8 @@
 	  eval cmd=\"$cmd\"
 	  IFS=$save_ifs
 	  $opt_quiet || {
-	    func_quote_for_expand "$cmd"
-	    eval "func_echo $func_quote_for_expand_result"
+	    func_quote_arg expand,pretty "$cmd"
+	    eval "func_echo $func_quote_arg_result"
 	  }
 	  $opt_dry_run || eval "$cmd" || {
 	    lt_exit=$?
@@ -10606,12 +10721,13 @@
 	  elif eval var_value=\$$var; test -z "$var_value"; then
 	    relink_command="$var=; export $var; $relink_command"
 	  else
-	    func_quote_for_eval "$var_value"
-	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	    func_quote_arg pretty "$var_value"
+	    relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
 	  fi
 	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+	func_quote eval cd "`pwd`"
+	func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
+	relink_command=$func_quote_arg_unquoted_result
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10851,13 +10967,15 @@
 	elif eval var_value=\$$var; test -z "$var_value"; then
 	  relink_command="$var=; export $var; $relink_command"
 	else
-	  func_quote_for_eval "$var_value"
-	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  func_quote_arg pretty,unquoted "$var_value"
+	  relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
 	fi
       done
       # Quote the link command for shipping.
-      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      func_quote eval cd "`pwd`"
+      relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      func_quote_arg pretty,unquoted "$relink_command"
+      relink_command=$func_quote_arg_unquoted_result
       if test yes = "$hardcode_automatic"; then
 	relink_command=
       fi
diff --git a/lib/External/isl/m4/ax_detect_clang.m4 b/lib/External/isl/m4/ax_detect_clang.m4
index 85920a2..e5cc7aa 100644
--- a/lib/External/isl/m4/ax_detect_clang.m4
+++ b/lib/External/isl/m4/ax_detect_clang.m4
@@ -75,7 +75,7 @@
 AC_LANG_PUSH(C++)
 
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CLANG_CXXFLAGS $CPPFLAGS"
+CPPFLAGS="$CLANG_CXXFLAGS -I$srcdir $CPPFLAGS"
 AC_CHECK_HEADER([clang/Basic/SourceLocation.h], [],
 	[AC_ERROR([clang header file not found])])
 AC_EGREP_HEADER([getDefaultTargetTriple], [llvm/Support/Host.h], [],
@@ -194,6 +194,8 @@
 	#include <clang/Basic/TargetOptions.h>
 	#include <clang/Lex/PreprocessorOptions.h>
 	#include <clang/Frontend/CompilerInstance.h>
+
+	#include "set_lang_defaults_arg4.h"
 ], [
 	using namespace clang;
 	CompilerInstance *Clang;
@@ -201,7 +203,8 @@
 	llvm::Triple T(TO.Triple);
 	PreprocessorOptions PO;
 	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
-			T, PO, LangStandard::lang_unspecified);
+			T, setLangDefaultsArg4(PO),
+			LangStandard::lang_unspecified);
 ], [AC_DEFINE([SETLANGDEFAULTS_TAKES_5_ARGUMENTS], [],
 	[Define if CompilerInvocation::setLangDefaults takes 5 arguments])])
 AC_TRY_COMPILE([
diff --git a/lib/External/isl/m4/libtool.m4 b/lib/External/isl/m4/libtool.m4
index a6d21ae..2b73e38 100644
--- a/lib/External/isl/m4/libtool.m4
+++ b/lib/External/isl/m4/libtool.m4
@@ -1,6 +1,6 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996-2001, 2003-2018 Free Software Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -219,8 +219,8 @@
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
-# which needs '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC and
+# ICC, which need '.lib').
 libext=a
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -1041,8 +1041,8 @@
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
-      echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
-      $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
@@ -1492,9 +1492,22 @@
 m4_defun([_LT_PROG_AR],
 [AC_CHECK_TOOLS(AR, [ar], false)
 : ${AR=ar}
-: ${AR_FLAGS=cr}
 _LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because thats what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
+         [Flags to create an archive])
 
 AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
   [lt_cv_ar_at_file=no
@@ -2206,26 +2219,35 @@
 striplib=
 old_striplib=
 AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  AC_MSG_RESULT([yes])
+if test -z "$STRIP"; then
+  AC_MSG_RESULT([no])
 else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-  darwin*)
-    if test -n "$STRIP"; then
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    AC_MSG_RESULT([yes])
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
-    else
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+      fi
+      ;;
+    *)
       AC_MSG_RESULT([no])
-    fi
-    ;;
-  *)
-    AC_MSG_RESULT([no])
-    ;;
-  esac
+      ;;
+    esac
+  fi
 fi
 _LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
 _LT_DECL([], [striplib], [1])
@@ -2564,8 +2586,8 @@
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -2621,7 +2643,7 @@
     ;;
 
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -2886,18 +2908,6 @@
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -3557,7 +3567,7 @@
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd* | netbsdelf*-gnu)
+netbsd*)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
@@ -4021,7 +4031,7 @@
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++,
+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
@@ -4063,8 +4073,7 @@
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
-    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
 	mv -f "$nlist"T "$nlist"
@@ -4436,7 +4445,7 @@
 	    ;;
 	esac
 	;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
 	;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4704,12 +4713,6 @@
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
-      # flang / f18. f95 an alias for gfortran or flang on Debian
-      flang* | f18* | f95*)
-	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -4937,7 +4940,7 @@
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -4945,7 +4948,7 @@
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -4954,9 +4957,6 @@
       ;;
     esac
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    _LT_TAGVAR(link_all_deplibs, $1)=no
-    ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -5005,23 +5005,20 @@
 
   case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
+    # Microsoft Visual C++ or Intel C++ Compiler.
     if test yes != "$GCC"; then
       with_gnu_ld=no
     fi
     ;;
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     ;;
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    _LT_TAGVAR(link_all_deplibs, $1)=no
-    ;;
   esac
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5180,6 +5177,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     interix[[3-9]]*)
@@ -5276,7 +5274,7 @@
       fi
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
@@ -5397,7 +5395,7 @@
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
 	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
@@ -5580,12 +5578,12 @@
 
     cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
+      # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       case $cc_basename in
-      cl*)
-	# Native MSVC
+      cl* | icl*)
+	# Native MSVC or ICC
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5626,7 +5624,7 @@
           fi'
 	;;
       *)
-	# Assume MSVC wrapper
+	# Assume MSVC and ICC wrapper
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Tell ltmain to make .lib files, not .a files.
@@ -5797,7 +5795,6 @@
 	if test yes = "$lt_cv_irix_exported_symbol"; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
 	fi
-	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
 	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5819,7 +5816,7 @@
       esac
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
@@ -5886,6 +5883,7 @@
 	emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     osf3*)
@@ -6445,7 +6443,7 @@
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -6656,8 +6654,8 @@
 
       cygwin* | mingw* | pw32* | cegcc*)
 	case $GXX,$cc_basename in
-	,cl* | no,cl*)
-	  # Native MSVC
+	,cl* | no,cl* | ,icl* | no,icl*)
+	  # Native MSVC or ICC
 	  # hardcode_libdir_flag_spec is actually meaningless, as there is
 	  # no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6755,6 +6753,7 @@
 	  emximp -o $lib $output_objdir/$libname.def'
 	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
 	;;
 
       dgux*)
@@ -6820,7 +6819,7 @@
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6885,7 +6884,7 @@
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
 	    if test yes = "$GXX"; then
@@ -7224,7 +7223,7 @@
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
 	    else
 	      # FIXME: insert proper C++ library support
@@ -7308,7 +7307,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
@@ -7319,7 +7318,7 @@
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff --git a/lib/External/isl/m4/ltoptions.m4 b/lib/External/isl/m4/ltoptions.m4
index 94b0829..07421d9 100644
--- a/lib/External/isl/m4/ltoptions.m4
+++ b/lib/External/isl/m4/ltoptions.m4
@@ -1,6 +1,6 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2018 Free Software
 #   Foundation, Inc.
 #   Written by Gary V. Vaughan, 2004
 #
diff --git a/lib/External/isl/m4/ltsugar.m4 b/lib/External/isl/m4/ltsugar.m4
index 48bc934..3985c56 100644
--- a/lib/External/isl/m4/ltsugar.m4
+++ b/lib/External/isl/m4/ltsugar.m4
@@ -1,6 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Copyright (C) 2004-2005, 2007-2008, 2011-2018 Free Software
 # Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
diff --git a/lib/External/isl/m4/ltversion.m4 b/lib/External/isl/m4/ltversion.m4
index fa04b52..7f9a3ad 100644
--- a/lib/External/isl/m4/ltversion.m4
+++ b/lib/External/isl/m4/ltversion.m4
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004, 2011-2018 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 4221 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.6.42-b88ce-dirty])
+m4_define([LT_PACKAGE_REVISION], [2.4.6.42])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.6.42-b88ce-dirty'
+macro_revision='2.4.6.42'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
diff --git a/lib/External/isl/m4/lt~obsolete.m4 b/lib/External/isl/m4/lt~obsolete.m4
index c6b26f8..54ea1c4 100644
--- a/lib/External/isl/m4/lt~obsolete.m4
+++ b/lib/External/isl/m4/lt~obsolete.m4
@@ -1,6 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2018 Free Software
 #   Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
diff --git a/lib/External/isl/missing b/lib/External/isl/missing
index 625aeb1..8d0eaad 100755
--- a/lib/External/isl/missing
+++ b/lib/External/isl/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/lib/External/isl/polyhedron_remove_redundant_equalities.c b/lib/External/isl/polyhedron_remove_redundant_equalities.c
new file mode 100644
index 0000000..2de47ac
--- /dev/null
+++ b/lib/External/isl/polyhedron_remove_redundant_equalities.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016      Sven Verdoolaege
+ *
+ * Use of this software is governed by the MIT license
+ *
+ * Written by Sven Verdoolaege.
+ */
+
+/* This program takes a (possibly parametric) polyhedron as input and
+ * prints print a full-dimensional polyhedron with the same number
+ * of integer points.
+ */
+
+#include <isl/options.h>
+#include <isl/printer.h>
+#include <isl/set.h>
+
+#include "isl_morph.h"
+
+int main(int argc, char **argv)
+{
+	isl_ctx *ctx;
+	isl_printer *p;
+	isl_basic_set *bset;
+	isl_morph *morph;
+	struct isl_options *options;
+
+	options = isl_options_new_with_defaults();
+	argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL);
+	ctx = isl_ctx_alloc_with_options(&isl_options_args, options);
+
+	bset = isl_basic_set_read_from_file(ctx, stdin);
+
+	morph = isl_basic_set_variable_compression(bset, isl_dim_set);
+	bset = isl_morph_basic_set(morph, bset);
+
+	p = isl_printer_to_file(ctx, stdout);
+	p = isl_printer_print_basic_set(p, bset);
+	p = isl_printer_end_line(p);
+	isl_printer_free(p);
+
+	isl_basic_set_free(bset);
+	isl_ctx_free(ctx);
+	return 0;
+}
diff --git a/lib/External/isl/py-compile b/lib/External/isl/py-compile
old mode 100644
new mode 100755
index 9f8baf7..e56d98d
--- a/lib/External/isl/py-compile
+++ b/lib/External/isl/py-compile
@@ -1,9 +1,9 @@
 #!/bin/sh
 # py-compile - Compile a Python program
 
-scriptversion=2018-03-07.03; # UTC
+scriptversion=2020-02-19.23; # UTC
 
-# Copyright (C) 2000-2018 Free Software Foundation, Inc.
+# Copyright (C) 2000-2020 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -115,8 +115,27 @@
     filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)"
 fi
 
+python_major=$($PYTHON -V 2>&1 | sed -e 's/.* //;s/\..*$//;1q')
+if test -z "$python_major"; then
+  echo "$me: could not determine $PYTHON major version, guessing 3" >&2
+  python_major=3
+fi
+
+# The old way to import libraries was deprecated.
+if test "$python_major" -le 2; then
+  import_lib=imp
+  import_test="hasattr(imp, 'get_tag')"
+  import_call=imp.cache_from_source
+  import_arg2=', False' # needed in one call and not the other
+else
+  import_lib=importlib
+  import_test="hasattr(sys.implementation, 'cache_tag')"
+  import_call=importlib.util.cache_from_source
+  import_arg2=
+fi
+
 $PYTHON -c "
-import sys, os, py_compile, imp
+import sys, os, py_compile, $import_lib
 
 files = '''$files'''
 
@@ -129,15 +148,15 @@
 	    continue
     sys.stdout.write(file)
     sys.stdout.flush()
-    if hasattr(imp, 'get_tag'):
-        py_compile.compile(filepath, imp.cache_from_source(filepath), path)
+    if $import_test:
+        py_compile.compile(filepath, $import_call(filepath), path)
     else:
         py_compile.compile(filepath, filepath + 'c', path)
 sys.stdout.write('\n')" || exit $?
 
 # this will fail for python < 1.5, but that doesn't matter ...
 $PYTHON -O -c "
-import sys, os, py_compile, imp
+import sys, os, py_compile, $import_lib
 
 # pypy does not use .pyo optimization
 if hasattr(sys, 'pypy_translation_info'):
@@ -153,8 +172,8 @@
 	    continue
     sys.stdout.write(file)
     sys.stdout.flush()
-    if hasattr(imp, 'get_tag'):
-        py_compile.compile(filepath, imp.cache_from_source(filepath, False), path)
+    if $import_test:
+        py_compile.compile(filepath, $import_call(filepath$import_arg2), path)
     else:
         py_compile.compile(filepath, filepath + 'o', path)
 sys.stdout.write('\n')" 2>/dev/null || :
diff --git a/lib/External/isl/test-driver b/lib/External/isl/test-driver
index b8521a4..9759384 100755
--- a/lib/External/isl/test-driver
+++ b/lib/External/isl/test-driver
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -42,11 +42,13 @@
 {
   cat <<END
 Usage:
-  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
-              [--expect-failure={yes|no}] [--color-tests={yes|no}]
-              [--enable-hard-errors={yes|no}] [--]
+  test-driver --test-name NAME --log-file PATH --trs-file PATH
+              [--expect-failure {yes|no}] [--color-tests {yes|no}]
+              [--enable-hard-errors {yes|no}] [--]
               TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+
 The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+See the GNU Automake documentation for information.
 END
 }